summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/axis-fifo/axis-fifo.c232
-rw-r--r--drivers/staging/axis-fifo/axis-fifo.txt5
-rw-r--r--drivers/staging/fbtft/fbtft-core.c4
-rw-r--r--drivers/staging/gpib/Kconfig255
-rw-r--r--drivers/staging/gpib/Makefile20
-rw-r--r--drivers/staging/gpib/TODO24
-rw-r--r--drivers/staging/gpib/agilent_82350b/Makefile2
-rw-r--r--drivers/staging/gpib/agilent_82350b/agilent_82350b.c896
-rw-r--r--drivers/staging/gpib/agilent_82350b/agilent_82350b.h157
-rw-r--r--drivers/staging/gpib/agilent_82357a/Makefile4
-rw-r--r--drivers/staging/gpib/agilent_82357a/agilent_82357a.c1691
-rw-r--r--drivers/staging/gpib/agilent_82357a/agilent_82357a.h182
-rw-r--r--drivers/staging/gpib/cb7210/Makefile3
-rw-r--r--drivers/staging/gpib/cb7210/cb7210.c1598
-rw-r--r--drivers/staging/gpib/cb7210/cb7210.h203
-rw-r--r--drivers/staging/gpib/cec/Makefile3
-rw-r--r--drivers/staging/gpib/cec/cec.h20
-rw-r--r--drivers/staging/gpib/cec/cec_gpib.c393
-rw-r--r--drivers/staging/gpib/common/Makefile6
-rw-r--r--drivers/staging/gpib/common/gpib_os.c2271
-rw-r--r--drivers/staging/gpib/common/iblib.c717
-rw-r--r--drivers/staging/gpib/common/ibsys.h34
-rw-r--r--drivers/staging/gpib/eastwood/Makefile3
-rw-r--r--drivers/staging/gpib/eastwood/fluke_gpib.c1180
-rw-r--r--drivers/staging/gpib/eastwood/fluke_gpib.h146
-rw-r--r--drivers/staging/gpib/fmh_gpib/Makefile2
-rw-r--r--drivers/staging/gpib/fmh_gpib/fmh_gpib.c1754
-rw-r--r--drivers/staging/gpib/fmh_gpib/fmh_gpib.h177
-rw-r--r--drivers/staging/gpib/gpio/Makefile4
-rw-r--r--drivers/staging/gpib/gpio/gpib_bitbang.c1469
-rw-r--r--drivers/staging/gpib/hp_82335/Makefile4
-rw-r--r--drivers/staging/gpib/hp_82335/hp82335.c371
-rw-r--r--drivers/staging/gpib/hp_82335/hp82335.h52
-rw-r--r--drivers/staging/gpib/hp_82341/Makefile2
-rw-r--r--drivers/staging/gpib/hp_82341/hp_82341.c907
-rw-r--r--drivers/staging/gpib/hp_82341/hp_82341.h165
-rw-r--r--drivers/staging/gpib/include/amcc5920.h49
-rw-r--r--drivers/staging/gpib/include/amccs5933.h59
-rw-r--r--drivers/staging/gpib/include/gpibP.h41
-rw-r--r--drivers/staging/gpib/include/gpib_cmd.h112
-rw-r--r--drivers/staging/gpib/include/gpib_pci_ids.h23
-rw-r--r--drivers/staging/gpib/include/gpib_proto.h49
-rw-r--r--drivers/staging/gpib/include/gpib_state_machines.h23
-rw-r--r--drivers/staging/gpib/include/gpib_types.h381
-rw-r--r--drivers/staging/gpib/include/nec7210.h141
-rw-r--r--drivers/staging/gpib/include/nec7210_registers.h218
-rw-r--r--drivers/staging/gpib/include/plx9050.h72
-rw-r--r--drivers/staging/gpib/include/quancom_pci.h22
-rw-r--r--drivers/staging/gpib/include/tms9914.h280
-rw-r--r--drivers/staging/gpib/include/tnt4882_registers.h192
-rw-r--r--drivers/staging/gpib/ines/Makefile3
-rw-r--r--drivers/staging/gpib/ines/ines.h165
-rw-r--r--drivers/staging/gpib/ines/ines_gpib.c1500
-rw-r--r--drivers/staging/gpib/lpvo_usb_gpib/Makefile3
-rw-r--r--drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c2025
-rw-r--r--drivers/staging/gpib/nec7210/Makefile4
-rw-r--r--drivers/staging/gpib/nec7210/board.h19
-rw-r--r--drivers/staging/gpib/nec7210/nec7210.c1121
-rw-r--r--drivers/staging/gpib/ni_usb/Makefile4
-rw-r--r--drivers/staging/gpib/ni_usb/ni_usb_gpib.c2678
-rw-r--r--drivers/staging/gpib/ni_usb/ni_usb_gpib.h226
-rw-r--r--drivers/staging/gpib/pc2/Makefile5
-rw-r--r--drivers/staging/gpib/pc2/pc2_gpib.c684
-rw-r--r--drivers/staging/gpib/tms9914/Makefile6
-rw-r--r--drivers/staging/gpib/tms9914/tms9914.c914
-rw-r--r--drivers/staging/gpib/tnt4882/Makefile6
-rw-r--r--drivers/staging/gpib/tnt4882/mite.c133
-rw-r--r--drivers/staging/gpib/tnt4882/mite.h234
-rw-r--r--drivers/staging/gpib/tnt4882/tnt4882_gpib.c1838
-rw-r--r--drivers/staging/gpib/uapi/gpib.h104
-rw-r--r--drivers/staging/gpib/uapi/gpib_ioctl.h167
-rw-r--r--drivers/staging/greybus/audio_codec.c16
-rw-r--r--drivers/staging/greybus/audio_helper.c9
-rw-r--r--drivers/staging/greybus/audio_topology.c24
-rw-r--r--drivers/staging/greybus/uart.c8
-rw-r--r--drivers/staging/iio/addac/adt7316.c102
-rw-r--r--drivers/staging/iio/frequency/ad9834.c3
-rw-r--r--drivers/staging/iio/frequency/ad9834.h10
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc2235.c4
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2722.c6
-rw-r--r--drivers/staging/media/av7110/av7110.c2
-rw-r--r--drivers/staging/media/av7110/av7110_ca.c2
-rw-r--r--drivers/staging/media/av7110/av7110_v4l.c4
-rw-r--r--drivers/staging/media/imx/imx-media-csc-scaler.c2
-rw-r--r--drivers/staging/media/ipu3/ipu3.c3
-rw-r--r--drivers/staging/media/ipu3/ipu3.h1
-rw-r--r--drivers/staging/media/ipu7/ipu7-isys-csi-phy.c4
-rw-r--r--drivers/staging/media/ipu7/ipu7-isys-csi2.c4
-rw-r--r--drivers/staging/media/ipu7/ipu7-isys-video.c7
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_dec.c2
-rw-r--r--drivers/staging/media/tegra-video/tegra20.c2
-rw-r--r--drivers/staging/most/Kconfig2
-rw-r--r--drivers/staging/most/Makefile1
-rw-r--r--drivers/staging/most/i2c/Kconfig13
-rw-r--r--drivers/staging/most/i2c/Makefile4
-rw-r--r--drivers/staging/most/i2c/i2c.c374
-rw-r--r--drivers/staging/nvec/nvec_ps2.c12
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_ap.c312
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_efuse.c3
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_ieee80211.c38
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_io.c48
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme.c76
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c80
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_pwrctrl.c10
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_security.c235
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_sta_mgt.c6
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_wlan_util.c19
-rw-r--r--drivers/staging/rtl8723bs/hal/hal_com.c65
-rw-r--r--drivers/staging/rtl8723bs/hal/hal_intf.c5
-rw-r--r--drivers/staging/rtl8723bs/hal/odm.c13
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c33
-rw-r--r--drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c16
-rw-r--r--drivers/staging/rtl8723bs/hal/sdio_halinit.c15
-rw-r--r--drivers/staging/rtl8723bs/hal/sdio_ops.c5
-rw-r--r--drivers/staging/rtl8723bs/include/basic_types.h3
-rw-r--r--drivers/staging/rtl8723bs/include/drv_types.h7
-rw-r--r--drivers/staging/rtl8723bs/include/hal_com.h2
-rw-r--r--drivers/staging/rtl8723bs/include/hal_com_reg.h4
-rw-r--r--drivers/staging/rtl8723bs/include/hal_intf.h2
-rw-r--r--drivers/staging/rtl8723bs/include/rtl8723b_hal.h2
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_mlme.h4
-rw-r--r--drivers/staging/rtl8723bs/include/rtw_mlme_ext.h4
-rw-r--r--drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c3
-rw-r--r--drivers/staging/rtl8723bs/os_dep/sdio_intf.c2
-rw-r--r--drivers/staging/sm750fb/sm750.c13
-rw-r--r--drivers/staging/sm750fb/sm750_accel.c10
-rw-r--r--drivers/staging/vc04_services/Kconfig49
-rw-r--r--drivers/staging/vc04_services/Makefile14
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c5
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835.c3
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835.h3
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/Kconfig13
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/Makefile6
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/TODO17
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c2011
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h142
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/controls.c1399
-rw-r--r--drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h112
-rw-r--r--drivers/staging/vc04_services/interface/TESTING125
-rw-r--r--drivers/staging/vc04_services/interface/TODO28
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c1473
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h164
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c112
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h60
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h41
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c4016
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h596
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c157
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h22
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c1354
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h113
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/Kconfig7
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/Makefile4
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-common.h65
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h124
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h45
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h108
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h109
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h406
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h752
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c1948
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h162
164 files changed, 585 insertions, 45296 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 075e775d3868..2f92cd698bef 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -48,6 +48,4 @@ source "drivers/staging/axis-fifo/Kconfig"
source "drivers/staging/vme_user/Kconfig"
-source "drivers/staging/gpib/Kconfig"
-
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index e681e403509c..f5b8876aa536 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -13,4 +13,3 @@ obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
-obj-$(CONFIG_GPIB) += gpib/
diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c
index 811bfdc578d8..509d620d6ce7 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -88,16 +88,8 @@
#define XLLF_INT_TC_MASK 0x08000000 /* Transmit complete */
#define XLLF_INT_RC_MASK 0x04000000 /* Receive complete */
#define XLLF_INT_TSE_MASK 0x02000000 /* Transmit length mismatch */
-#define XLLF_INT_TRC_MASK 0x01000000 /* Transmit reset complete */
-#define XLLF_INT_RRC_MASK 0x00800000 /* Receive reset complete */
-#define XLLF_INT_TFPF_MASK 0x00400000 /* Tx FIFO Programmable Full */
-#define XLLF_INT_TFPE_MASK 0x00200000 /* Tx FIFO Programmable Empty */
-#define XLLF_INT_RFPF_MASK 0x00100000 /* Rx FIFO Programmable Full */
-#define XLLF_INT_RFPE_MASK 0x00080000 /* Rx FIFO Programmable Empty */
-#define XLLF_INT_ALL_MASK 0xfff80000 /* All the ints */
-#define XLLF_INT_ERROR_MASK 0xf2000000 /* Error status ints */
-#define XLLF_INT_RXERROR_MASK 0xe0000000 /* Receive Error status ints */
-#define XLLF_INT_TXERROR_MASK 0x12000000 /* Transmit Error status ints */
+
+#define XLLF_INT_CLEAR_ALL GENMASK(31, 0)
/* ----------------------------
* globals
@@ -125,7 +117,6 @@ MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out;
struct axis_fifo {
int id;
- int irq; /* interrupt */
void __iomem *base_addr; /* kernel space memory */
unsigned int rx_fifo_depth; /* max words in the receive fifo */
@@ -137,8 +128,6 @@ struct axis_fifo {
struct mutex read_lock; /* lock for reading */
wait_queue_head_t write_queue; /* wait queue for asynchronos write */
struct mutex write_lock; /* lock for writing */
- unsigned int write_flags; /* write file flags */
- unsigned int read_flags; /* read file flags */
struct device *dt_device; /* device created from the device tree */
struct miscdevice miscdev;
@@ -165,7 +154,7 @@ static void reset_ip_core(struct axis_fifo *fifo)
XLLF_INT_RPORE_MASK | XLLF_INT_RPUE_MASK |
XLLF_INT_TPOE_MASK | XLLF_INT_TSE_MASK,
fifo->base_addr + XLLF_IER_OFFSET);
- iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
+ iowrite32(XLLF_INT_CLEAR_ALL, fifo->base_addr + XLLF_ISR_OFFSET);
}
/**
@@ -195,7 +184,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf,
int ret;
u32 tmp_buf[READ_BUF_SIZE];
- if (fifo->read_flags & O_NONBLOCK) {
+ if (f->f_flags & O_NONBLOCK) {
/*
* Device opened in non-blocking mode. Try to lock it and then
* check if any packet is available.
@@ -337,7 +326,7 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
if (words_to_write > (fifo->tx_fifo_depth - 4))
return -EINVAL;
- if (fifo->write_flags & O_NONBLOCK) {
+ if (f->f_flags & O_NONBLOCK) {
/*
* Device opened in non-blocking mode. Try to lock it and then
* check if there is any room to write the given buffer.
@@ -396,106 +385,36 @@ end_unlock:
static irqreturn_t axis_fifo_irq(int irq, void *dw)
{
- struct axis_fifo *fifo = (struct axis_fifo *)dw;
- unsigned int pending_interrupts;
-
- do {
- pending_interrupts = ioread32(fifo->base_addr +
- XLLF_IER_OFFSET) &
- ioread32(fifo->base_addr
- + XLLF_ISR_OFFSET);
- if (pending_interrupts & XLLF_INT_RC_MASK) {
- /* packet received */
-
- /* wake the reader process if it is waiting */
- wake_up(&fifo->read_queue);
-
- /* clear interrupt */
- iowrite32(XLLF_INT_RC_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TC_MASK) {
- /* packet sent */
-
- /* wake the writer process if it is waiting */
- wake_up(&fifo->write_queue);
-
- iowrite32(XLLF_INT_TC_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TFPF_MASK) {
- /* transmit fifo programmable full */
-
- iowrite32(XLLF_INT_TFPF_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TFPE_MASK) {
- /* transmit fifo programmable empty */
-
- iowrite32(XLLF_INT_TFPE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RFPF_MASK) {
- /* receive fifo programmable full */
-
- iowrite32(XLLF_INT_RFPF_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RFPE_MASK) {
- /* receive fifo programmable empty */
-
- iowrite32(XLLF_INT_RFPE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TRC_MASK) {
- /* transmit reset complete interrupt */
-
- iowrite32(XLLF_INT_TRC_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RRC_MASK) {
- /* receive reset complete interrupt */
-
- iowrite32(XLLF_INT_RRC_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RPURE_MASK) {
- /* receive fifo under-read error interrupt */
- dev_err(fifo->dt_device,
- "receive under-read interrupt\n");
-
- iowrite32(XLLF_INT_RPURE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RPORE_MASK) {
- /* receive over-read error interrupt */
- dev_err(fifo->dt_device,
- "receive over-read interrupt\n");
-
- iowrite32(XLLF_INT_RPORE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_RPUE_MASK) {
- /* receive underrun error interrupt */
- dev_err(fifo->dt_device,
- "receive underrun error interrupt\n");
-
- iowrite32(XLLF_INT_RPUE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TPOE_MASK) {
- /* transmit overrun error interrupt */
- dev_err(fifo->dt_device,
- "transmit overrun error interrupt\n");
-
- iowrite32(XLLF_INT_TPOE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts & XLLF_INT_TSE_MASK) {
- /* transmit length mismatch error interrupt */
- dev_err(fifo->dt_device,
- "transmit length mismatch error interrupt\n");
-
- iowrite32(XLLF_INT_TSE_MASK & XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- } else if (pending_interrupts) {
- /* unknown interrupt type */
- dev_err(fifo->dt_device,
- "unknown interrupt(s) 0x%x\n",
- pending_interrupts);
-
- iowrite32(XLLF_INT_ALL_MASK,
- fifo->base_addr + XLLF_ISR_OFFSET);
- }
- } while (pending_interrupts);
+ struct axis_fifo *fifo = dw;
+ u32 isr, ier, intr;
+
+ ier = ioread32(fifo->base_addr + XLLF_IER_OFFSET);
+ isr = ioread32(fifo->base_addr + XLLF_ISR_OFFSET);
+ intr = ier & isr;
+
+ if (intr & XLLF_INT_RC_MASK)
+ wake_up(&fifo->read_queue);
+
+ if (intr & XLLF_INT_TC_MASK)
+ wake_up(&fifo->write_queue);
+
+ if (intr & XLLF_INT_RPURE_MASK)
+ dev_err(fifo->dt_device, "receive under-read interrupt\n");
+
+ if (intr & XLLF_INT_RPORE_MASK)
+ dev_err(fifo->dt_device, "receive over-read interrupt\n");
+
+ if (intr & XLLF_INT_RPUE_MASK)
+ dev_err(fifo->dt_device, "receive underrun error interrupt\n");
+
+ if (intr & XLLF_INT_TPOE_MASK)
+ dev_err(fifo->dt_device, "transmit overrun error interrupt\n");
+
+ if (intr & XLLF_INT_TSE_MASK)
+ dev_err(fifo->dt_device,
+ "transmit length mismatch error interrupt\n");
+
+ iowrite32(XLLF_INT_CLEAR_ALL, fifo->base_addr + XLLF_ISR_OFFSET);
return IRQ_HANDLED;
}
@@ -504,27 +423,15 @@ static int axis_fifo_open(struct inode *inod, struct file *f)
{
struct axis_fifo *fifo = container_of(f->private_data,
struct axis_fifo, miscdev);
+ unsigned int flags = f->f_flags & O_ACCMODE;
+
f->private_data = fifo;
- if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
- ((f->f_flags & O_ACCMODE) == O_RDWR)) {
- if (fifo->has_tx_fifo) {
- fifo->write_flags = f->f_flags;
- } else {
- dev_err(fifo->dt_device, "tried to open device for write but the transmit fifo is disabled\n");
- return -EPERM;
- }
- }
+ if ((flags == O_WRONLY || flags == O_RDWR) && !fifo->has_tx_fifo)
+ return -EPERM;
- if (((f->f_flags & O_ACCMODE) == O_RDONLY) ||
- ((f->f_flags & O_ACCMODE) == O_RDWR)) {
- if (fifo->has_rx_fifo) {
- fifo->read_flags = f->f_flags;
- } else {
- dev_err(fifo->dt_device, "tried to open device for read but the receive fifo is disabled\n");
- return -EPERM;
- }
- }
+ if ((flags == O_RDONLY || flags == O_RDWR) && !fifo->has_rx_fifo)
+ return -EPERM;
return 0;
}
@@ -575,30 +482,14 @@ static void axis_fifo_debugfs_init(struct axis_fifo *fifo)
&axis_fifo_debugfs_regs_fops);
}
-/* read named property from the device tree */
-static int get_dts_property(struct axis_fifo *fifo,
- char *name, unsigned int *var)
-{
- int rc;
-
- rc = of_property_read_u32(fifo->dt_device->of_node, name, var);
- if (rc) {
- dev_err(fifo->dt_device, "couldn't read IP dts property '%s'",
- name);
- return rc;
- }
- dev_dbg(fifo->dt_device, "dts property '%s' = %u\n",
- name, *var);
-
- return 0;
-}
-
static int axis_fifo_parse_dt(struct axis_fifo *fifo)
{
int ret;
unsigned int value;
+ struct device_node *node = fifo->dt_device->of_node;
- ret = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width", &value);
+ ret = of_property_read_u32(node, "xlnx,axi-str-rxd-tdata-width",
+ &value);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,axi-str-rxd-tdata-width property\n");
goto end;
@@ -608,7 +499,8 @@ static int axis_fifo_parse_dt(struct axis_fifo *fifo)
goto end;
}
- ret = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width", &value);
+ ret = of_property_read_u32(node, "xlnx,axi-str-txd-tdata-width",
+ &value);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,axi-str-txd-tdata-width property\n");
goto end;
@@ -618,30 +510,32 @@ static int axis_fifo_parse_dt(struct axis_fifo *fifo)
goto end;
}
- ret = get_dts_property(fifo, "xlnx,rx-fifo-depth",
- &fifo->rx_fifo_depth);
+ ret = of_property_read_u32(node, "xlnx,rx-fifo-depth",
+ &fifo->rx_fifo_depth);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,rx-fifo-depth property\n");
ret = -EIO;
goto end;
}
- ret = get_dts_property(fifo, "xlnx,tx-fifo-depth",
- &fifo->tx_fifo_depth);
+ ret = of_property_read_u32(node, "xlnx,tx-fifo-depth",
+ &fifo->tx_fifo_depth);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,tx-fifo-depth property\n");
ret = -EIO;
goto end;
}
- ret = get_dts_property(fifo, "xlnx,use-rx-data", &fifo->has_rx_fifo);
+ ret = of_property_read_u32(node, "xlnx,use-rx-data",
+ &fifo->has_rx_fifo);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,use-rx-data property\n");
ret = -EIO;
goto end;
}
- ret = get_dts_property(fifo, "xlnx,use-tx-data", &fifo->has_tx_fifo);
+ ret = of_property_read_u32(node, "xlnx,use-tx-data",
+ &fifo->has_tx_fifo);
if (ret) {
dev_err(fifo->dt_device, "missing xlnx,use-tx-data property\n");
ret = -EIO;
@@ -659,6 +553,7 @@ static int axis_fifo_probe(struct platform_device *pdev)
struct axis_fifo *fifo = NULL;
char *device_name;
int rc = 0; /* error return value */
+ int irq;
/* ----------------------------
* init wrapper device
@@ -693,8 +588,6 @@ static int axis_fifo_probe(struct platform_device *pdev)
if (IS_ERR(fifo->base_addr))
return PTR_ERR(fifo->base_addr);
- dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
-
/* ----------------------------
* init IP
* ----------------------------
@@ -712,17 +605,16 @@ static int axis_fifo_probe(struct platform_device *pdev)
*/
/* get IRQ resource */
- rc = platform_get_irq(pdev, 0);
- if (rc < 0)
- return rc;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
/* request IRQ */
- fifo->irq = rc;
- rc = devm_request_irq(fifo->dt_device, fifo->irq, &axis_fifo_irq, 0,
+ rc = devm_request_irq(fifo->dt_device, irq, &axis_fifo_irq, 0,
DRIVER_NAME, fifo);
if (rc) {
dev_err(fifo->dt_device, "couldn't allocate interrupt %i\n",
- fifo->irq);
+ irq);
return rc;
}
@@ -764,6 +656,8 @@ static void axis_fifo_remove(struct platform_device *pdev)
static const struct of_device_id axis_fifo_of_match[] = {
{ .compatible = "xlnx,axi-fifo-mm-s-4.1", },
+ { .compatible = "xlnx,axi-fifo-mm-s-4.2", },
+ { .compatible = "xlnx,axi-fifo-mm-s-4.3", },
{},
};
MODULE_DEVICE_TABLE(of, axis_fifo_of_match);
@@ -806,4 +700,4 @@ module_exit(axis_fifo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jacob Feder <jacobsfeder@gmail.com>");
-MODULE_DESCRIPTION("Xilinx AXI-Stream FIFO v4.1 IP core driver");
+MODULE_DESCRIPTION("Xilinx AXI-Stream FIFO IP core driver");
diff --git a/drivers/staging/axis-fifo/axis-fifo.txt b/drivers/staging/axis-fifo/axis-fifo.txt
index 5828e1b8e822..413b81a53202 100644
--- a/drivers/staging/axis-fifo/axis-fifo.txt
+++ b/drivers/staging/axis-fifo/axis-fifo.txt
@@ -14,7 +14,10 @@ AXI4-Lite interface. DOES NOT support:
- AXI4 (non-lite)
Required properties:
-- compatible: Should be "xlnx,axi-fifo-mm-s-4.1"
+- compatible: Should be one of:
+ "xlnx,axi-fifo-mm-s-4.1"
+ "xlnx,axi-fifo-mm-s-4.2"
+ "xlnx,axi-fifo-mm-s-4.3"
- interrupt-names: Should be "interrupt"
- interrupt-parent: Should be <&intc>
- interrupts: Should contain interrupts lines.
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index 9e7b84071174..8a5ccc8ae0a1 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -1171,8 +1171,8 @@ int fbtft_probe_common(struct fbtft_display *display,
par->pdev = pdev;
if (display->buswidth == 0) {
- dev_err(dev, "buswidth is not set\n");
- return -EINVAL;
+ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n");
+ goto out_release;
}
/* write register functions */
diff --git a/drivers/staging/gpib/Kconfig b/drivers/staging/gpib/Kconfig
deleted file mode 100644
index aa01538d5beb..000000000000
--- a/drivers/staging/gpib/Kconfig
+++ /dev/null
@@ -1,255 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-menuconfig GPIB
- tristate "Linux GPIB drivers"
- help
- Enable support for GPIB cards and dongles for Linux. GPIB
- is the General Purpose Interface Bus which conforms to the
- IEEE488 standard.
-
- This set of drivers can be used with the corresponding user
- space library that can be found on Sourceforge under linux-gpib.
- Select the drivers for your hardware from the list.
-
-if GPIB
-
-config GPIB_COMMON
- tristate "GPIB core"
- help
-
- Core common driver for all GPIB drivers. It provides the
- interface for the userland library
-
- To compile this driver as a module, choose M here: the module will be
- called gpib_common
-
-config GPIB_AGILENT_82350B
- tristate "Agilent 8235xx PCI(e) adapters"
- depends on PCI
- select GPIB_COMMON
- select GPIB_TMS9914
- help
- Enable support for HP/Agilent/Keysight boards
- 82350A
- 82350B
- 82351A
-
- To compile this driver as a module, choose M here: the module will be
- called agilent_82350b.
-
-config GPIB_AGILENT_82357A
- tristate "Agilent 82357a/b USB dongles"
- select GPIB_COMMON
- depends on USB
- help
- Enable support for Agilent/Keysight 82357x USB dongles.
-
- To compile this driver as a module, choose M here: the module will be
- called agilent_82357a.
-
-config GPIB_CEC_PCI
- tristate "CEC PCI board"
- depends on PCI
- depends on HAS_IOPORT
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- Enable support for Capital Equipment Corporation PCI-488
- and Keithly KPCI-488 boards.
-
- To compile this driver as a module, choose M here: the module will be
- called cec_gpib.
-
-config GPIB_NI_PCI_ISA
- tristate "NI PCI/ISA compatible boards"
- depends on ISA_BUS || PCI || PCMCIA
- depends on HAS_IOPORT
- depends on PCMCIA || !PCMCIA
- depends on HAS_IOPORT_MAP
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- Enable support for National Instruments boards based
- on TNT4882 chips:
- AT-GPIB (with NAT4882 chip)
- AT-GPIB (with NEC7210 chip)
- AT-GPIB/TNT
- PCI-GPIB
- PCIe-GPIB
- PCI-GPIB+
- PCM-GPIB
- PXI-GPIB
- PCMCIA-GPIB
- and Capital Equipment Corporation CEC-488 board.
-
- To compile this driver as a module, choose M here: the module will be
- called tnt4882.
-
-config GPIB_CB7210
- tristate "Measurement Computing compatible boards"
- depends on HAS_IOPORT
- depends on ISA_BUS || PCI || PCMCIA
- depends on PCMCIA || !PCMCIA
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- Enable support for Measurement Computing (Computer Boards):
- CPCI_GPIB, ISA-GPIB, ISA-GPIB/LC, PCI-GPIB/1M, PCI-GPIB/300K and
- PCMCIA-GPIB
- Quancom PCIGPIB-1 with MC cb7210 chip
-
- To compile this driver as a module, choose M here: the module will be
-
-config GPIB_NI_USB
- tristate "NI USB dongles"
- select GPIB_COMMON
- depends on USB
- help
- Enable support for National Instruments
- GPIB-USB-B
- GPIB-USB-HS
- GPIB-USB-HS+
- Keithly
- KUSB-488
- KUSB-488A
- Measurement Computing (Computer Boards)
- USB-488
-
- To compile this driver as a module, choose M here: the module will be
- called ni_usb.
-
-config GPIB_FLUKE
- tristate "Fluke"
- depends on OF
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- GPIB driver for Fluke based cda devices.
-
- To compile this driver as a module, choose M here: the module will be
- called fluke_gpib
-
-config GPIB_FMH
- tristate "FMH FPGA based devices"
- select GPIB_COMMON
- select GPIB_NEC7210
- depends on !PPC
- depends on OF && PCI
- help
- GPIB driver for fmhess FPGA based devices
-
- To compile this driver as a module, choose M here: the module will be
- called fmh_gpib
-
-config GPIB_GPIO
- tristate "RPi GPIO bitbang"
- depends on ARCH_BCM2835 || COMPILE_TEST
- select GPIB_COMMON
- help
- GPIB bitbang driver Raspberry Pi GPIO adapters
-
- To compile this driver as a module, choose M here: the module will be
- called gpib_bitbang
-
-config GPIB_HP82335
- tristate "HP82335/HP27209"
- depends on ISA_BUS
- select GPIB_COMMON
- select GPIB_TMS9914
- help
- GPIB driver for HP82335 and HP27209 boards
-
- To compile this driver as a module, choose M here: the module will be
- called hp82335
-
-
-config GPIB_HP82341
- tristate "HP82341x"
- select GPIB_COMMON
- select GPIB_TMS9914
- depends on ISA_BUS || EISA
- help
- GPIB driver for HP82341 A/B/C/D boards
-
- To compile this driver as a module, choose M here: the module will be
- called hp82341
-
-config GPIB_INES
- tristate "INES"
- depends on PCI || ISA_BUS || PCMCIA
- depends on PCMCIA || !PCMCIA
- depends on HAS_IOPORT
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- GPIB driver for Ines compatible boards
- Ines
- GPIB-HS-NT
- GPIB for Compact PCI
- GPIB for PCI
- GPIB for PCMCIA
- GPIB PC/104
- Hameg
- HO80-2
- Quancom
- PCIGPIB-1 based on Ines iGPIB 72010 chip
-
- To compile this driver as a module, choose M here: the module will be
- called ines_gpib
- called cb7210.
-
-config GPIB_PCMCIA
- def_bool y
- depends on PCMCIA && (GPIB_NI_PCI_ISA || GPIB_CB7210 || GPIB_INES)
- help
- Enable PCMCIA/CArdbus support for National Instruments,
- measurement computing boards and Ines boards.
-
-config GPIB_LPVO
- tristate "LPVO DIY USB GPIB"
- select GPIB_COMMON
- depends on USB
- help
- Enable support for LPVO Self-made usb-gpib adapter
-
- To compile this driver as a module, choose M here: the module will be
- called lpvo_usb_gpib
-
-config GPIB_PC2
- tristate "PC2 PC2a"
- depends on ISA_BUS
- depends on HAS_IOPORT
- select GPIB_COMMON
- select GPIB_NEC7210
- help
- Enable support for pc2 and pc2a compatible adapters
- Capital Equipment Corporation PC-488
- CONTEC GP-IB(PC)
- Hameg HO80
- Iotech GP488B
- Keithly MBC-488
- Measurement Computing ISA-GPIB-PCA2
- National Instruments PCII, PCIIa and PCII/IIa
-
- To compile this driver as a module, choose M here: the module will be
- called pc2_gpib
-
-
-config GPIB_TMS9914
- tristate
- select GPIB_COMMON
- help
- Enable support for TMS 9914 chip.
-
- To compile this driver as a module, choose M here: the module will be
- called tms9914
-
-config GPIB_NEC7210
- tristate
- select GPIB_COMMON
- help
- Enable support for NEC 7210 compatible chips.
-
- To compile this driver as a module, choose M here: the module will be
- called nec7210
-
-endif # GPIB
diff --git a/drivers/staging/gpib/Makefile b/drivers/staging/gpib/Makefile
deleted file mode 100644
index d0e88f5c0844..000000000000
--- a/drivers/staging/gpib/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-
-subdir-ccflags-y += -I$(src)/include -I$(src)/uapi
-
-obj-$(CONFIG_GPIB_AGILENT_82350B) += agilent_82350b/
-obj-$(CONFIG_GPIB_AGILENT_82357A) += agilent_82357a/
-obj-$(CONFIG_GPIB_CB7210) += cb7210/
-obj-$(CONFIG_GPIB_CEC_PCI) += cec/
-obj-$(CONFIG_GPIB_COMMON) += common/
-obj-$(CONFIG_GPIB_FLUKE) += eastwood/
-obj-$(CONFIG_GPIB_FMH) += fmh_gpib/
-obj-$(CONFIG_GPIB_GPIO) += gpio/
-obj-$(CONFIG_GPIB_HP82335) += hp_82335/
-obj-$(CONFIG_GPIB_HP82341) += hp_82341/
-obj-$(CONFIG_GPIB_INES) += ines/
-obj-$(CONFIG_GPIB_LPVO) += lpvo_usb_gpib/
-obj-$(CONFIG_GPIB_NEC7210) += nec7210/
-obj-$(CONFIG_GPIB_NI_USB) += ni_usb/
-obj-$(CONFIG_GPIB_PC2) += pc2/
-obj-$(CONFIG_GPIB_TMS9914) += tms9914/
-obj-$(CONFIG_GPIB_NI_PCI_ISA) += tnt4882/
diff --git a/drivers/staging/gpib/TODO b/drivers/staging/gpib/TODO
deleted file mode 100644
index ab41a7f9ca5b..000000000000
--- a/drivers/staging/gpib/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
-TODO:
-- checkpatch.pl fixes
- These checks should be ignored:
- CHECK:ALLOC_SIZEOF_STRUCT: Prefer kmalloc(sizeof(*board->private_data)...) over kmalloc(sizeof(struct xxx_priv)...)
- ./gpio/gpib_bitbang.c:50: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parenthese
- This warning will be addressed later: WARNING:UNDOCUMENTED_DT_STRING: DT compatible string
-- tidy-up comments:
- - there are some "//comments" and "// comments" scattered around
- - sometimes they are misaligned
- - sometimes "// comments" are interleaved with "/* comments */"
- - multiline comments should start with initial almost-blank line:
- /*
- * Good
- * multiline
- * comment
- */
- /* Bad
- * multiline
- * comment
- */
-- resolve XXX notes where possible
-- fix FIXME notes
-- clean-up commented-out code
-- fix typos
diff --git a/drivers/staging/gpib/agilent_82350b/Makefile b/drivers/staging/gpib/agilent_82350b/Makefile
deleted file mode 100644
index f24e1e713a63..000000000000
--- a/drivers/staging/gpib/agilent_82350b/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_GPIB_AGILENT_82350B) += agilent_82350b.o
diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
deleted file mode 100644
index 01a5bb43cd2d..000000000000
--- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c
+++ /dev/null
@@ -1,896 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2002, 2004 by Frank Mori Hess *
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "agilent_82350b.h"
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/dma.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for Agilent 82350b");
-
-static int read_transfer_counter(struct agilent_82350b_priv *a_priv);
-static unsigned short read_and_clear_event_status(struct gpib_board *board);
-static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count);
-static int agilent_82350b_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written);
-
-static int agilent_82350b_accel_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- struct tms9914_priv *tms_priv = &a_priv->tms9914_priv;
- int retval = 0;
- unsigned short event_status;
- int i, num_fifo_bytes;
- /* hardware doesn't support checking for end-of-string character when using fifo */
- if (tms_priv->eos_flags & REOS)
- return tms9914_read(board, tms_priv, buffer, length, end, bytes_read);
-
- clear_bit(DEV_CLEAR_BN, &tms_priv->state);
-
- read_and_clear_event_status(board);
- *end = 0;
- *bytes_read = 0;
- if (length == 0)
- return 0;
- /* disable fifo for the moment */
- writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- /* handle corner case of board not in holdoff and one byte might slip in early */
- if (tms_priv->holdoff_active == 0 && length > 1) {
- size_t num_bytes;
-
- retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0 || *end)
- return retval;
- ++buffer;
- --length;
- }
- tms9914_set_holdoff_mode(tms_priv, TMS9914_HOLDOFF_EOI);
- tms9914_release_holdoff(tms_priv);
- i = 0;
- num_fifo_bytes = length - 1;
- /* disable BI interrupts */
- write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BIIE, IMR0);
- while (i < num_fifo_bytes && *end == 0) {
- int block_size;
- int j;
- int count;
-
- block_size = min(num_fifo_bytes - i, agilent_82350b_fifo_size);
- set_transfer_counter(a_priv, block_size);
- writeb(ENABLE_TI_TO_SRAM | DIRECTION_GPIB_TO_HOST,
- a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- if (agilent_82350b_fifo_is_halted(a_priv))
- writeb(RESTART_STREAM_BIT, a_priv->gpib_base + STREAM_STATUS_REG);
-
- clear_bit(READ_READY_BN, &tms_priv->state);
-
- retval = wait_event_interruptible(board->wait,
- ((event_status =
- read_and_clear_event_status(board)) &
- (TERM_COUNT_STATUS_BIT |
- BUFFER_END_STATUS_BIT)) ||
- test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- if (retval) {
- retval = -ERESTARTSYS;
- break;
- }
- count = block_size - read_transfer_counter(a_priv);
- for (j = 0; j < count && i < num_fifo_bytes; ++j)
- buffer[i++] = readb(a_priv->sram_base + j);
- if (event_status & BUFFER_END_STATUS_BIT) {
- clear_bit(RECEIVED_END_BN, &tms_priv->state);
-
- tms_priv->holdoff_active = 1;
- *end = 1;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- retval = -EINTR;
- break;
- }
- }
- /* re-enable BI interrupts */
- write_byte(tms_priv, tms_priv->imr0_bits, IMR0);
- *bytes_read += i;
- buffer += i;
- length -= i;
- writeb(DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- if (retval < 0)
- return retval;
- /* read last bytes if we havn't received an END yet */
- if (*end == 0) {
- size_t num_bytes;
- /* try to make sure we holdoff after last byte read */
- retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static int translate_wait_return_value(struct gpib_board *board, int retval)
-
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- struct tms9914_priv *tms_priv = &a_priv->tms9914_priv;
-
- if (retval)
- return -ERESTARTSYS;
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state))
- return -EINTR;
- return 0;
-}
-
-static int agilent_82350b_accel_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- struct tms9914_priv *tms_priv = &a_priv->tms9914_priv;
- int i, j;
- unsigned short event_status;
- int retval = 0;
- int fifotransferlength = length;
- int block_size = 0;
- size_t num_bytes;
-
- *bytes_written = 0;
- if (send_eoi)
- --fifotransferlength;
-
- clear_bit(DEV_CLEAR_BN, &tms_priv->state);
-
- writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
-
- event_status = read_and_clear_event_status(board);
-
-#ifdef EXPERIMENTAL
- /* wait for previous BO to complete if any */
- retval = wait_event_interruptible(board->wait,
- test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
- test_bit(WRITE_READY_BN, &tms_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- retval = translate_wait_return_value(board, retval);
-
- if (retval)
- return retval;
-#endif
-
- if (fifotransferlength > 0) {
- retval = agilent_82350b_write(board, buffer, 1, 0, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
-
- write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BOIE, IMR0);
- for (i = 1; i < fifotransferlength;) {
- clear_bit(WRITE_READY_BN, &tms_priv->state);
-
- block_size = min(fifotransferlength - i, agilent_82350b_fifo_size);
- set_transfer_counter(a_priv, block_size);
- for (j = 0; j < block_size; ++j, ++i) {
- /* load data into board's sram */
- writeb(buffer[i], a_priv->sram_base + j);
- }
- writeb(ENABLE_TI_TO_SRAM, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
-
- if (agilent_82350b_fifo_is_halted(a_priv))
- writeb(RESTART_STREAM_BIT, a_priv->gpib_base + STREAM_STATUS_REG);
-
- retval = wait_event_interruptible(board->wait,
- ((event_status =
- read_and_clear_event_status(board)) &
- TERM_COUNT_STATUS_BIT) ||
- test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- num_bytes = block_size - read_transfer_counter(a_priv);
-
- *bytes_written += num_bytes;
- retval = translate_wait_return_value(board, retval);
- if (retval)
- break;
- }
- write_byte(tms_priv, tms_priv->imr0_bits, IMR0);
- if (retval < 0)
- return retval;
-
- if (send_eoi) {
- retval = agilent_82350b_write(board, buffer + fifotransferlength, 1, send_eoi,
- &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static unsigned short read_and_clear_event_status(struct gpib_board *board)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- unsigned long flags;
- unsigned short status;
-
- spin_lock_irqsave(&board->spinlock, flags);
- status = a_priv->event_status_bits;
- a_priv->event_status_bits = 0;
- spin_unlock_irqrestore(&board->spinlock, flags);
- return status;
-}
-
-static irqreturn_t agilent_82350b_interrupt(int irq, void *arg)
-
-{
- int tms9914_status1 = 0, tms9914_status2 = 0;
- int event_status;
- struct gpib_board *board = arg;
- struct agilent_82350b_priv *a_priv = board->private_data;
- unsigned long flags;
- irqreturn_t retval = IRQ_NONE;
-
- spin_lock_irqsave(&board->spinlock, flags);
- event_status = readb(a_priv->gpib_base + EVENT_STATUS_REG);
- if (event_status & IRQ_STATUS_BIT)
- retval = IRQ_HANDLED;
-
- if (event_status & TMS9914_IRQ_STATUS_BIT) {
- tms9914_status1 = read_byte(&a_priv->tms9914_priv, ISR0);
- tms9914_status2 = read_byte(&a_priv->tms9914_priv, ISR1);
- tms9914_interrupt_have_status(board, &a_priv->tms9914_priv, tms9914_status1,
- tms9914_status2);
- }
- /* write-clear status bits */
- if (event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT)) {
- writeb(event_status & (BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT),
- a_priv->gpib_base + EVENT_STATUS_REG);
- a_priv->event_status_bits |= event_status;
- wake_up_interruptible(&board->wait);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-static void agilent_82350b_detach(struct gpib_board *board);
-
-static int read_transfer_counter(struct agilent_82350b_priv *a_priv)
-{
- int lo, mid, value;
-
- lo = readb(a_priv->gpib_base + XFER_COUNT_LO_REG);
- mid = readb(a_priv->gpib_base + XFER_COUNT_MID_REG);
- value = (lo & 0xff) | ((mid << 8) & 0x7f00);
- value = ~(value - 1) & 0x7fff;
- return value;
-}
-
-static void set_transfer_counter(struct agilent_82350b_priv *a_priv, int count)
-{
- int complement = -count;
-
- writeb(complement & 0xff, a_priv->gpib_base + XFER_COUNT_LO_REG);
- writeb((complement >> 8) & 0xff, a_priv->gpib_base + XFER_COUNT_MID_REG);
- /* I don't think the hi count reg is even used, but oh well */
- writeb((complement >> 16) & 0xf, a_priv->gpib_base + XFER_COUNT_HI_REG);
-}
-
-/* wrappers for interface functions */
-static int agilent_82350b_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
-}
-
-static int agilent_82350b_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int agilent_82350b_command(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
-}
-
-static int agilent_82350b_take_control(struct gpib_board *board, int synchronous)
-
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_take_control_workaround(board, &priv->tms9914_priv, synchronous);
-}
-
-static int agilent_82350b_go_to_standby(struct gpib_board *board)
-
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_go_to_standby(board, &priv->tms9914_priv);
-}
-
-static int agilent_82350b_request_system_control(struct gpib_board *board, int request_control)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
-
- if (request_control) {
- a_priv->card_mode_bits |= CM_SYSTEM_CONTROLLER_BIT;
- if (a_priv->model != MODEL_82350A)
- writeb(IC_SYSTEM_CONTROLLER_BIT, a_priv->gpib_base + INTERNAL_CONFIG_REG);
- } else {
- a_priv->card_mode_bits &= ~CM_SYSTEM_CONTROLLER_BIT;
- if (a_priv->model != MODEL_82350A)
- writeb(0, a_priv->gpib_base + INTERNAL_CONFIG_REG);
- }
- writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG);
- return tms9914_request_system_control(board, &a_priv->tms9914_priv, request_control);
-}
-
-static void agilent_82350b_interface_clear(struct gpib_board *board, int assert)
-
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_interface_clear(board, &priv->tms9914_priv, assert);
-}
-
-static void agilent_82350b_remote_enable(struct gpib_board *board, int enable)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_remote_enable(board, &priv->tms9914_priv, enable);
-}
-
-static int agilent_82350b_enable_eos(struct gpib_board *board, u8 eos_byte,
- int compare_8_bits)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
-}
-
-static void agilent_82350b_disable_eos(struct gpib_board *board)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_disable_eos(board, &priv->tms9914_priv);
-}
-
-static unsigned int agilent_82350b_update_status(struct gpib_board *board,
- unsigned int clear_mask)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
-}
-
-static int agilent_82350b_primary_address(struct gpib_board *board,
- unsigned int address)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_primary_address(board, &priv->tms9914_priv, address);
-}
-
-static int agilent_82350b_secondary_address(struct gpib_board *board,
- unsigned int address, int enable)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
-}
-
-static int agilent_82350b_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
-}
-
-static void agilent_82350b_parallel_poll_configure(struct gpib_board *board,
- u8 config)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
-}
-
-static void agilent_82350b_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
-}
-
-static void agilent_82350b_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
-}
-
-static u8 agilent_82350b_serial_poll_status(struct gpib_board *board)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_serial_poll_status(board, &priv->tms9914_priv);
-}
-
-static int agilent_82350b_line_status(const struct gpib_board *board)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- return tms9914_line_status(board, &priv->tms9914_priv);
-}
-
-static int agilent_82350b_t1_delay(struct gpib_board *board, unsigned int nanosec)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- static const int nanosec_per_clock = 30;
- unsigned int value;
-
- tms9914_t1_delay(board, &a_priv->tms9914_priv, nanosec);
-
- value = (nanosec + nanosec_per_clock - 1) / nanosec_per_clock;
- if (value > 0xff)
- value = 0xff;
- writeb(value, a_priv->gpib_base + T1_DELAY_REG);
- return value * nanosec_per_clock;
-}
-
-static void agilent_82350b_return_to_local(struct gpib_board *board)
-{
- struct agilent_82350b_priv *priv = board->private_data;
-
- tms9914_return_to_local(board, &priv->tms9914_priv);
-}
-
-static int agilent_82350b_allocate_private(struct gpib_board *board)
-{
- board->private_data = kzalloc(sizeof(struct agilent_82350b_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- return 0;
-}
-
-static void agilent_82350b_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static int init_82350a_hardware(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- static const unsigned int firmware_length = 5302;
- unsigned int borg_status;
- static const unsigned int timeout = 1000;
- int i, j;
- const char *firmware_data = config->init_data;
- const unsigned int plx_cntrl_static_bits = PLX9050_WAITO_NOT_USER0_SELECT_BIT |
- PLX9050_USER0_OUTPUT_BIT |
- PLX9050_LLOCK_NOT_USER1_SELECT_BIT |
- PLX9050_USER1_OUTPUT_BIT |
- PLX9050_USER2_OUTPUT_BIT |
- PLX9050_USER3_OUTPUT_BIT |
- PLX9050_PCI_READ_MODE_BIT |
- PLX9050_PCI_WRITE_MODE_BIT |
- PLX9050_PCI_RETRY_DELAY_BITS(64) |
- PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT;
-
- /* load borg data */
- borg_status = readb(a_priv->borg_base);
- if ((borg_status & BORG_DONE_BIT))
- return 0;
- /* need to programme borg */
- if (!config->init_data || config->init_data_length != firmware_length) {
- dev_err(board->gpib_dev, "the 82350A board requires firmware after powering on.\n");
- return -EIO;
- }
- dev_dbg(board->gpib_dev, "Loading firmware...\n");
-
- /* tickle the borg */
- writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT,
- a_priv->plx_base + PLX9050_CNTRL_REG);
- usleep_range(1000, 2000);
- writel(plx_cntrl_static_bits, a_priv->plx_base + PLX9050_CNTRL_REG);
- usleep_range(1000, 2000);
- writel(plx_cntrl_static_bits | PLX9050_USER3_DATA_BIT,
- a_priv->plx_base + PLX9050_CNTRL_REG);
- usleep_range(1000, 2000);
-
- for (i = 0; i < config->init_data_length; ++i) {
- for (j = 0; j < timeout && (readb(a_priv->borg_base) & BORG_READY_BIT) == 0; ++j) {
- if (need_resched())
- schedule();
- usleep_range(10, 20);
- }
- if (j == timeout) {
- dev_err(board->gpib_dev, "timed out loading firmware.\n");
- return -ETIMEDOUT;
- }
- writeb(firmware_data[i], a_priv->gpib_base + CONFIG_DATA_REG);
- }
- for (j = 0; j < timeout && (readb(a_priv->borg_base) & BORG_DONE_BIT) == 0; ++j) {
- if (need_resched())
- schedule();
- usleep_range(10, 20);
- }
- if (j == timeout) {
- dev_err(board->gpib_dev, "timed out waiting for firmware load to complete.\n");
- return -ETIMEDOUT;
- }
- dev_dbg(board->gpib_dev, " ...done.\n");
- return 0;
-}
-
-static int test_sram(struct gpib_board *board)
-
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- unsigned int i;
- const unsigned int sram_length = pci_resource_len(a_priv->pci_device, SRAM_82350A_REGION);
- /* test SRAM */
- const unsigned int byte_mask = 0xff;
-
- for (i = 0; i < sram_length; ++i) {
- writeb(i & byte_mask, a_priv->sram_base + i);
- if (need_resched())
- schedule();
- }
- for (i = 0; i < sram_length; ++i) {
- unsigned int read_value = readb(a_priv->sram_base + i);
-
- if ((i & byte_mask) != read_value) {
- dev_err(board->gpib_dev, "SRAM test failed at %d wanted %d got %d\n",
- i, (i & byte_mask), read_value);
- return -EIO;
- }
- if (need_resched())
- schedule();
- }
- dev_dbg(board->gpib_dev, "SRAM test passed 0x%x bytes checked\n", sram_length);
- return 0;
-}
-
-static int agilent_82350b_generic_attach(struct gpib_board *board,
- const struct gpib_board_config *config,
- int use_fifos)
-
-{
- struct agilent_82350b_priv *a_priv;
- struct tms9914_priv *tms_priv;
- int retval;
-
- board->status = 0;
-
- if (agilent_82350b_allocate_private(board))
- return -ENOMEM;
- a_priv = board->private_data;
- a_priv->using_fifos = use_fifos;
- tms_priv = &a_priv->tms9914_priv;
- tms_priv->read_byte = tms9914_iomem_read_byte;
- tms_priv->write_byte = tms9914_iomem_write_byte;
- tms_priv->offset = 1;
-
- /* find board */
- a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT,
- PCI_DEVICE_ID_82350B, NULL);
- if (a_priv->pci_device) {
- a_priv->model = MODEL_82350B;
- dev_dbg(board->gpib_dev, "Agilent 82350B board found\n");
-
- } else {
- a_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_AGILENT,
- PCI_DEVICE_ID_82351A, NULL);
- if (a_priv->pci_device) {
- a_priv->model = MODEL_82351A;
- dev_dbg(board->gpib_dev, "Agilent 82351B board found\n");
-
- } else {
- a_priv->pci_device = gpib_pci_get_subsys(config, PCI_VENDOR_ID_PLX,
- PCI_DEVICE_ID_PLX_9050,
- PCI_VENDOR_ID_HP,
- PCI_SUBDEVICE_ID_82350A,
- a_priv->pci_device);
- if (a_priv->pci_device) {
- a_priv->model = MODEL_82350A;
- dev_dbg(board->gpib_dev, "HP/Agilent 82350A board found\n");
- } else {
- dev_err(board->gpib_dev, "no 82350/82351 board found\n");
- return -ENODEV;
- }
- }
- }
- if (pci_enable_device(a_priv->pci_device)) {
- dev_err(board->gpib_dev, "error enabling pci device\n");
- return -EIO;
- }
- if (pci_request_regions(a_priv->pci_device, DRV_NAME))
- return -ENOMEM;
- switch (a_priv->model) {
- case MODEL_82350A:
- a_priv->plx_base = ioremap(pci_resource_start(a_priv->pci_device, PLX_MEM_REGION),
- pci_resource_len(a_priv->pci_device, PLX_MEM_REGION));
- dev_dbg(board->gpib_dev, "plx base address remapped to 0x%p\n", a_priv->plx_base);
- a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device,
- GPIB_82350A_REGION),
- pci_resource_len(a_priv->pci_device,
- GPIB_82350A_REGION));
- dev_dbg(board->gpib_dev, "chip base address remapped to 0x%p\n", a_priv->gpib_base);
- tms_priv->mmiobase = a_priv->gpib_base + TMS9914_BASE_REG;
- a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device,
- SRAM_82350A_REGION),
- pci_resource_len(a_priv->pci_device,
- SRAM_82350A_REGION));
- dev_dbg(board->gpib_dev, "sram base address remapped to 0x%p\n", a_priv->sram_base);
- a_priv->borg_base = ioremap(pci_resource_start(a_priv->pci_device,
- BORG_82350A_REGION),
- pci_resource_len(a_priv->pci_device,
- BORG_82350A_REGION));
- dev_dbg(board->gpib_dev, "borg base address remapped to 0x%p\n", a_priv->borg_base);
-
- retval = init_82350a_hardware(board, config);
- if (retval < 0)
- return retval;
- break;
- case MODEL_82350B:
- case MODEL_82351A:
- a_priv->gpib_base = ioremap(pci_resource_start(a_priv->pci_device, GPIB_REGION),
- pci_resource_len(a_priv->pci_device, GPIB_REGION));
- dev_dbg(board->gpib_dev, "chip base address remapped to 0x%p\n", a_priv->gpib_base);
- tms_priv->mmiobase = a_priv->gpib_base + TMS9914_BASE_REG;
- a_priv->sram_base = ioremap(pci_resource_start(a_priv->pci_device, SRAM_REGION),
- pci_resource_len(a_priv->pci_device, SRAM_REGION));
- dev_dbg(board->gpib_dev, "sram base address remapped to 0x%p\n", a_priv->sram_base);
- a_priv->misc_base = ioremap(pci_resource_start(a_priv->pci_device, MISC_REGION),
- pci_resource_len(a_priv->pci_device, MISC_REGION));
- dev_dbg(board->gpib_dev, "misc base address remapped to 0x%p\n", a_priv->misc_base);
- break;
- default:
- dev_err(board->gpib_dev, "invalid board\n");
- return -ENODEV;
- }
-
- retval = test_sram(board);
- if (retval < 0)
- return retval;
-
- if (request_irq(a_priv->pci_device->irq, agilent_82350b_interrupt,
- IRQF_SHARED, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to obtain irq %d\n", a_priv->pci_device->irq);
- return -EIO;
- }
- a_priv->irq = a_priv->pci_device->irq;
- dev_dbg(board->gpib_dev, " IRQ %d\n", a_priv->irq);
-
- writeb(0, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG);
- a_priv->card_mode_bits = ENABLE_PCI_IRQ_BIT;
- writeb(a_priv->card_mode_bits, a_priv->gpib_base + CARD_MODE_REG);
-
- if (a_priv->model == MODEL_82350A) {
- /* enable PCI interrupts for 82350a */
- writel(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR2_POLARITY_BIT |
- PLX9050_PCI_INTR_EN_BIT,
- a_priv->plx_base + PLX9050_INTCSR_REG);
- }
-
- if (use_fifos) {
- writeb(ENABLE_BUFFER_END_EVENTS_BIT | ENABLE_TERM_COUNT_EVENTS_BIT,
- a_priv->gpib_base + EVENT_ENABLE_REG);
- writeb(ENABLE_TERM_COUNT_INTERRUPT_BIT | ENABLE_BUFFER_END_INTERRUPT_BIT |
- ENABLE_TMS9914_INTERRUPTS_BIT, a_priv->gpib_base + INTERRUPT_ENABLE_REG);
- /* write-clear event status bits */
- writeb(BUFFER_END_STATUS_BIT | TERM_COUNT_STATUS_BIT,
- a_priv->gpib_base + EVENT_STATUS_REG);
- } else {
- writeb(0, a_priv->gpib_base + EVENT_ENABLE_REG);
- writeb(ENABLE_TMS9914_INTERRUPTS_BIT,
- a_priv->gpib_base + INTERRUPT_ENABLE_REG);
- }
- board->t1_nano_sec = agilent_82350b_t1_delay(board, 2000);
- tms9914_board_reset(tms_priv);
-
- tms9914_online(board, tms_priv);
-
- return 0;
-}
-
-static int agilent_82350b_unaccel_attach(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- return agilent_82350b_generic_attach(board, config, 0);
-}
-
-static int agilent_82350b_accel_attach(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- return agilent_82350b_generic_attach(board, config, 1);
-}
-
-static void agilent_82350b_detach(struct gpib_board *board)
-{
- struct agilent_82350b_priv *a_priv = board->private_data;
- struct tms9914_priv *tms_priv;
-
- if (a_priv) {
- if (a_priv->plx_base) /* disable interrupts */
- writel(0, a_priv->plx_base + PLX9050_INTCSR_REG);
-
- tms_priv = &a_priv->tms9914_priv;
- if (a_priv->irq)
- free_irq(a_priv->irq, board);
- if (a_priv->gpib_base) {
- tms9914_board_reset(tms_priv);
- if (a_priv->misc_base)
- iounmap(a_priv->misc_base);
- if (a_priv->borg_base)
- iounmap(a_priv->borg_base);
- if (a_priv->sram_base)
- iounmap(a_priv->sram_base);
- if (a_priv->gpib_base)
- iounmap(a_priv->gpib_base);
- if (a_priv->plx_base)
- iounmap(a_priv->plx_base);
- pci_release_regions(a_priv->pci_device);
- }
- if (a_priv->pci_device)
- pci_dev_put(a_priv->pci_device);
- }
- agilent_82350b_free_private(board);
-}
-
-static struct gpib_interface agilent_82350b_unaccel_interface = {
- .name = "agilent_82350b_unaccel",
- .attach = agilent_82350b_unaccel_attach,
- .detach = agilent_82350b_detach,
- .read = agilent_82350b_read,
- .write = agilent_82350b_write,
- .command = agilent_82350b_command,
- .request_system_control = agilent_82350b_request_system_control,
- .take_control = agilent_82350b_take_control,
- .go_to_standby = agilent_82350b_go_to_standby,
- .interface_clear = agilent_82350b_interface_clear,
- .remote_enable = agilent_82350b_remote_enable,
- .enable_eos = agilent_82350b_enable_eos,
- .disable_eos = agilent_82350b_disable_eos,
- .parallel_poll = agilent_82350b_parallel_poll,
- .parallel_poll_configure = agilent_82350b_parallel_poll_configure,
- .parallel_poll_response = agilent_82350b_parallel_poll_response,
- .local_parallel_poll_mode = NULL, /* XXX */
- .line_status = agilent_82350b_line_status,
- .update_status = agilent_82350b_update_status,
- .primary_address = agilent_82350b_primary_address,
- .secondary_address = agilent_82350b_secondary_address,
- .serial_poll_response = agilent_82350b_serial_poll_response,
- .serial_poll_status = agilent_82350b_serial_poll_status,
- .t1_delay = agilent_82350b_t1_delay,
- .return_to_local = agilent_82350b_return_to_local,
-};
-
-static struct gpib_interface agilent_82350b_interface = {
- .name = "agilent_82350b",
- .attach = agilent_82350b_accel_attach,
- .detach = agilent_82350b_detach,
- .read = agilent_82350b_accel_read,
- .write = agilent_82350b_accel_write,
- .command = agilent_82350b_command,
- .request_system_control = agilent_82350b_request_system_control,
- .take_control = agilent_82350b_take_control,
- .go_to_standby = agilent_82350b_go_to_standby,
- .interface_clear = agilent_82350b_interface_clear,
- .remote_enable = agilent_82350b_remote_enable,
- .enable_eos = agilent_82350b_enable_eos,
- .disable_eos = agilent_82350b_disable_eos,
- .parallel_poll = agilent_82350b_parallel_poll,
- .parallel_poll_configure = agilent_82350b_parallel_poll_configure,
- .parallel_poll_response = agilent_82350b_parallel_poll_response,
- .local_parallel_poll_mode = NULL, /* XXX */
- .line_status = agilent_82350b_line_status,
- .update_status = agilent_82350b_update_status,
- .primary_address = agilent_82350b_primary_address,
- .secondary_address = agilent_82350b_secondary_address,
- .serial_poll_response = agilent_82350b_serial_poll_response,
- .serial_poll_status = agilent_82350b_serial_poll_status,
- .t1_delay = agilent_82350b_t1_delay,
- .return_to_local = agilent_82350b_return_to_local,
-};
-
-static int agilent_82350b_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-
-{
- return 0;
-}
-
-static const struct pci_device_id agilent_82350b_pci_table[] = {
- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_HP,
- PCI_SUBDEVICE_ID_82350A, 0, 0, 0 },
- { PCI_VENDOR_ID_AGILENT, PCI_DEVICE_ID_82350B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_AGILENT, PCI_DEVICE_ID_82351A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, agilent_82350b_pci_table);
-
-static struct pci_driver agilent_82350b_pci_driver = {
- .name = DRV_NAME,
- .id_table = agilent_82350b_pci_table,
- .probe = &agilent_82350b_pci_probe
-};
-
-static int __init agilent_82350b_init_module(void)
-{
- int result;
-
- result = pci_register_driver(&agilent_82350b_pci_driver);
- if (result) {
- pr_err("pci_register_driver failed: error = %d\n", result);
- return result;
- }
-
- result = gpib_register_driver(&agilent_82350b_unaccel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_unaccel;
- }
-
- result = gpib_register_driver(&agilent_82350b_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_interface;
- }
-
- return 0;
-
-err_interface:
- gpib_unregister_driver(&agilent_82350b_unaccel_interface);
-err_unaccel:
- pci_unregister_driver(&agilent_82350b_pci_driver);
-
- return result;
-}
-
-static void __exit agilent_82350b_exit_module(void)
-{
- gpib_unregister_driver(&agilent_82350b_interface);
- gpib_unregister_driver(&agilent_82350b_unaccel_interface);
-
- pci_unregister_driver(&agilent_82350b_pci_driver);
-}
-
-module_init(agilent_82350b_init_module);
-module_exit(agilent_82350b_exit_module);
diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h b/drivers/staging/gpib/agilent_82350b/agilent_82350b.h
deleted file mode 100644
index ef841957297f..000000000000
--- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002, 2004 by Frank Mori Hess *
- ***************************************************************************/
-
-#include "gpibP.h"
-#include "plx9050.h"
-#include "tms9914.h"
-
-enum pci_vendor_ids {
- PCI_VENDOR_ID_AGILENT = 0x15bc,
-};
-
-enum pci_device_ids {
- PCI_DEVICE_ID_82350B = 0x0b01,
- PCI_DEVICE_ID_82351A = 0x1218
-};
-
-enum pci_subdevice_ids {
- PCI_SUBDEVICE_ID_82350A = 0x10b0,
-};
-
-enum pci_regions_82350a {
- PLX_MEM_REGION = 0,
- PLX_IO_REGION = 1,
- GPIB_82350A_REGION = 2,
- SRAM_82350A_REGION = 3,
- BORG_82350A_REGION = 4
-};
-
-enum pci_regions_82350b {
- GPIB_REGION = 0,
- SRAM_REGION = 1,
- MISC_REGION = 2,
-};
-
-enum board_model {
- MODEL_82350A,
- MODEL_82350B,
- MODEL_82351A
-};
-
-/* struct which defines private_data for board */
-struct agilent_82350b_priv {
- struct tms9914_priv tms9914_priv;
- struct pci_dev *pci_device;
- void __iomem *plx_base; /* 82350a only */
- void __iomem *gpib_base;
- void __iomem *sram_base;
- void __iomem *misc_base;
- void __iomem *borg_base;
- int irq;
- unsigned short card_mode_bits;
- unsigned short event_status_bits;
- enum board_model model;
- bool using_fifos;
-};
-
-/* registers */
-enum agilent_82350b_gpib_registers
-
-{
- CARD_MODE_REG = 0x1,
- CONFIG_DATA_REG = 0x2, /* 82350A specific */
- INTERRUPT_ENABLE_REG = 0x3,
- EVENT_STATUS_REG = 0x4,
- EVENT_ENABLE_REG = 0x5,
- STREAM_STATUS_REG = 0x7,
- DEBUG_RAM0_REG = 0x8,
- DEBUG_RAM1_REG = 0x9,
- DEBUG_RAM2_REG = 0xa,
- DEBUG_RAM3_REG = 0xb,
- XFER_COUNT_LO_REG = 0xc,
- XFER_COUNT_MID_REG = 0xd,
- XFER_COUNT_HI_REG = 0xe,
- TMS9914_BASE_REG = 0x10,
- INTERNAL_CONFIG_REG = 0x18,
- IMR0_READ_REG = 0x19, /* read */
- T1_DELAY_REG = 0x19, /* write */
- IMR1_READ_REG = 0x1a,
- ADR_READ_REG = 0x1b,
- SPMR_READ_REG = 0x1c,
- PPR_READ_REG = 0x1d,
- CDOR_READ_REG = 0x1e,
- SRAM_ACCESS_CONTROL_REG = 0x1f,
-};
-
-enum card_mode_bits
-
-{
- ACTIVE_CONTROLLER_BIT = 0x2, /* read-only */
- CM_SYSTEM_CONTROLLER_BIT = 0x8,
- ENABLE_BUS_MONITOR_BIT = 0x10,
- ENABLE_PCI_IRQ_BIT = 0x20,
-};
-
-enum interrupt_enable_bits
-
-{
- ENABLE_TMS9914_INTERRUPTS_BIT = 0x1,
- ENABLE_BUFFER_END_INTERRUPT_BIT = 0x10,
- ENABLE_TERM_COUNT_INTERRUPT_BIT = 0x20,
-};
-
-enum event_enable_bits
-
-{
- ENABLE_BUFFER_END_EVENTS_BIT = 0x10,
- ENABLE_TERM_COUNT_EVENTS_BIT = 0x20,
-};
-
-enum event_status_bits
-
-{
- TMS9914_IRQ_STATUS_BIT = 0x1,
- IRQ_STATUS_BIT = 0x2,
- BUFFER_END_STATUS_BIT = 0x10, /* write-clear */
- TERM_COUNT_STATUS_BIT = 0x20, /* write-clear */
-};
-
-enum stream_status_bits
-
-{
- HALTED_STATUS_BIT = 0x1, /* read */
- RESTART_STREAM_BIT = 0x1, /* write */
-};
-
-enum internal_config_bits
-
-{
- IC_SYSTEM_CONTROLLER_BIT = 0x80,
-};
-
-enum sram_access_control_bits
-
-{
- DIRECTION_GPIB_TO_HOST = 0x20, /* transfer direction */
- ENABLE_TI_TO_SRAM = 0x40, /* enable fifo */
- ENABLE_FAST_TALKER = 0x80 /* added for 82350A (not used) */
-};
-
-enum borg_bits
-
-{
- BORG_READY_BIT = 0x40,
- BORG_DONE_BIT = 0x80
-};
-
-static const int agilent_82350b_fifo_size = 0x8000;
-
-static inline int agilent_82350b_fifo_is_halted(struct agilent_82350b_priv *a_priv)
-
-{
- return readb(a_priv->gpib_base + STREAM_STATUS_REG) & HALTED_STATUS_BIT;
-}
-
diff --git a/drivers/staging/gpib/agilent_82357a/Makefile b/drivers/staging/gpib/agilent_82357a/Makefile
deleted file mode 100644
index 81a55c257a6e..000000000000
--- a/drivers/staging/gpib/agilent_82357a/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-obj-$(CONFIG_GPIB_AGILENT_82357A) += agilent_82357a.o
-
-
diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c b/drivers/staging/gpib/agilent_82357a/agilent_82357a.c
deleted file mode 100644
index 77c8e549b208..000000000000
--- a/drivers/staging/gpib/agilent_82357a/agilent_82357a.c
+++ /dev/null
@@ -1,1691 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * driver for Agilent 82357A/B usb to gpib adapters *
- * copyright : (C) 2004 by Frank Mori Hess *
- ***************************************************************************/
-
-#define _GNU_SOURCE
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "agilent_82357a.h"
-#include "gpibP.h"
-#include "tms9914.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for Agilent 82357A/B usb adapters");
-
-#define MAX_NUM_82357A_INTERFACES 128
-static struct usb_interface *agilent_82357a_driver_interfaces[MAX_NUM_82357A_INTERFACES];
-static DEFINE_MUTEX(agilent_82357a_hotplug_lock); // protect board insertion and removal
-
-static unsigned int agilent_82357a_update_status(struct gpib_board *board,
- unsigned int clear_mask);
-
-static int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous);
-
-static void agilent_82357a_bulk_complete(struct urb *urb)
-{
- struct agilent_82357a_urb_ctx *context = urb->context;
-
- complete(&context->complete);
-}
-
-static void agilent_82357a_timeout_handler(struct timer_list *t)
-{
- struct agilent_82357a_priv *a_priv = timer_container_of(a_priv, t,
- bulk_timer);
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
-
- context->timed_out = 1;
- complete(&context->complete);
-}
-
-static int agilent_82357a_send_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,
- int data_length, int *actual_data_length,
- int timeout_msecs)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int out_pipe;
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
-
- *actual_data_length = 0;
- retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENODEV;
- }
- if (a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -EAGAIN;
- }
- a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_pipe = usb_sndbulkpipe(usb_dev, a_priv->bulk_out_endpoint);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, out_pipe, data, data_length,
- &agilent_82357a_bulk_complete, context);
-
- if (timeout_msecs)
- mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
-
- retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n", retval);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- goto cleanup;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- if (wait_for_completion_interruptible(&context->complete)) {
- retval = -ERESTARTSYS;
- goto cleanup;
- }
- if (context->timed_out) {
- retval = -ETIMEDOUT;
- } else {
- retval = a_priv->bulk_urb->status;
- *actual_data_length = a_priv->bulk_urb->actual_length;
- }
-cleanup:
- if (timeout_msecs) {
- if (timer_pending(&a_priv->bulk_timer))
- timer_delete_sync(&a_priv->bulk_timer);
- }
- mutex_lock(&a_priv->bulk_alloc_lock);
- if (a_priv->bulk_urb) {
- usb_kill_urb(a_priv->bulk_urb);
- usb_free_urb(a_priv->bulk_urb);
- a_priv->bulk_urb = NULL;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return retval;
-}
-
-static int agilent_82357a_receive_bulk_msg(struct agilent_82357a_priv *a_priv, void *data,
- int data_length, int *actual_data_length,
- int timeout_msecs)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
- struct agilent_82357a_urb_ctx *context = &a_priv->context;
-
- *actual_data_length = 0;
- retval = mutex_lock_interruptible(&a_priv->bulk_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENODEV;
- }
- if (a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -EAGAIN;
- }
- a_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->bulk_urb) {
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- in_pipe = usb_rcvbulkpipe(usb_dev, AGILENT_82357_BULK_IN_ENDPOINT);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(a_priv->bulk_urb, usb_dev, in_pipe, data, data_length,
- &agilent_82357a_bulk_complete, context);
-
- if (timeout_msecs)
- mod_timer(&a_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
-
- retval = usb_submit_urb(a_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- goto cleanup;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- if (wait_for_completion_interruptible(&context->complete)) {
- retval = -ERESTARTSYS;
- goto cleanup;
- }
- if (context->timed_out) {
- retval = -ETIMEDOUT;
- goto cleanup;
- }
- retval = a_priv->bulk_urb->status;
- *actual_data_length = a_priv->bulk_urb->actual_length;
-cleanup:
- if (timeout_msecs)
- timer_delete_sync(&a_priv->bulk_timer);
-
- mutex_lock(&a_priv->bulk_alloc_lock);
- if (a_priv->bulk_urb) {
- usb_kill_urb(a_priv->bulk_urb);
- usb_free_urb(a_priv->bulk_urb);
- a_priv->bulk_urb = NULL;
- }
- mutex_unlock(&a_priv->bulk_alloc_lock);
- return retval;
-}
-
-static int agilent_82357a_receive_control_msg(struct agilent_82357a_priv *a_priv, __u8 request,
- __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size, int timeout_msecs)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
-
- retval = mutex_lock_interruptible(&a_priv->control_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- mutex_unlock(&a_priv->control_alloc_lock);
- return -ENODEV;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- in_pipe = usb_rcvctrlpipe(usb_dev, AGILENT_82357_CONTROL_ENDPOINT);
- retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data,
- size, timeout_msecs);
- mutex_unlock(&a_priv->control_alloc_lock);
- return retval;
-}
-
-static void agilent_82357a_dump_raw_block(const u8 *raw_data, int length)
-{
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true);
-}
-
-static int agilent_82357a_write_registers(struct agilent_82357a_priv *a_priv,
- const struct agilent_82357a_register_pairlet *writes,
- int num_writes)
-{
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- int j;
- static const int bytes_per_write = 2;
- static const int header_length = 2;
- static const int max_writes = 31;
-
- if (num_writes > max_writes) {
- dev_err(&usb_dev->dev, "bug! num_writes=%i too large\n", num_writes);
- return -EIO;
- }
- out_data_length = num_writes * bytes_per_write + header_length;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
-
- out_data[i++] = DATA_PIPE_CMD_WR_REGS;
- out_data[i++] = num_writes;
- for (j = 0; j < num_writes; j++) {
- out_data[i++] = writes[j].address;
- out_data[i++] = writes[j].value;
- }
-
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return retval;
- }
- in_data_length = 0x20;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, 1000);
- mutex_unlock(&a_priv->bulk_transfer_lock);
-
- if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_dump_raw_block(in_data, bytes_read);
- kfree(in_data);
- return -EIO;
- }
- if (in_data[0] != (0xff & ~DATA_PIPE_CMD_WR_REGS)) {
- dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_WR_REGS\n", in_data[0]);
- return -EIO;
- }
- if (in_data[1]) {
- dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_WR_REGS response\n",
- in_data[1]);
- return -EIO;
- }
- kfree(in_data);
- return 0;
-}
-
-static int agilent_82357a_read_registers(struct agilent_82357a_priv *a_priv,
- struct agilent_82357a_register_pairlet *reads,
- int num_reads, int blocking)
-{
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- int j;
- static const int header_length = 2;
- static const int max_reads = 62;
-
- if (num_reads > max_reads) {
- dev_err(&usb_dev->dev, "bug! num_reads=%i too large\n", num_reads);
- return -EIO;
- }
- out_data_length = num_reads + header_length;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
-
- out_data[i++] = DATA_PIPE_CMD_RD_REGS;
- out_data[i++] = num_reads;
- for (j = 0; j < num_reads; j++)
- out_data[i++] = reads[j].address;
-
- if (blocking) {
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- } else {
- retval = mutex_trylock(&a_priv->bulk_transfer_lock);
- if (retval == 0) {
- kfree(out_data);
- return -EAGAIN;
- }
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return retval;
- }
- in_data_length = 0x20;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, 10000);
- mutex_unlock(&a_priv->bulk_transfer_lock);
-
- if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_dump_raw_block(in_data, bytes_read);
- kfree(in_data);
- return -EIO;
- }
- i = 0;
- if (in_data[i++] != (0xff & ~DATA_PIPE_CMD_RD_REGS)) {
- dev_err(&usb_dev->dev, "bulk command=0x%x != ~DATA_PIPE_CMD_RD_REGS\n", in_data[0]);
- return -EIO;
- }
- if (in_data[i++]) {
- dev_err(&usb_dev->dev, "nonzero error code 0x%x in DATA_PIPE_CMD_RD_REGS response\n",
- in_data[1]);
- return -EIO;
- }
- for (j = 0; j < num_reads; j++)
- reads[j].value = in_data[i++];
- kfree(in_data);
- return 0;
-}
-
-static int agilent_82357a_abort(struct agilent_82357a_priv *a_priv, int flush)
-{
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval = 0;
- int receive_control_retval;
- u16 wIndex = 0;
- u8 *status_data;
- static const unsigned int status_data_len = 2;
-
- status_data = kmalloc(status_data_len, GFP_KERNEL);
- if (!status_data)
- return -ENOMEM;
-
- if (flush)
- wIndex |= XA_FLUSH;
- receive_control_retval = agilent_82357a_receive_control_msg(a_priv,
- agilent_82357a_control_request,
- USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, XFER_ABORT,
- wIndex, status_data,
- status_data_len, 100);
- if (receive_control_retval < 0) {
- dev_err(&usb_dev->dev, "82357a_receive_control_msg() returned %i\n",
- receive_control_retval);
- retval = -EIO;
- goto cleanup;
- }
- if (status_data[0] != (~XFER_ABORT & 0xff)) {
- dev_err(&usb_dev->dev, "major code=0x%x != ~XFER_ABORT\n", status_data[0]);
- retval = -EIO;
- goto cleanup;
- }
- switch (status_data[1]) {
- case UGP_SUCCESS:
- retval = 0;
- break;
- case UGP_ERR_FLUSHING:
- if (flush) {
- retval = 0;
- break;
- }
- fallthrough;
- case UGP_ERR_FLUSHING_ALREADY:
- default:
- dev_err(&usb_dev->dev, "abort returned error code=0x%x\n", status_data[1]);
- retval = -EIO;
- break;
- }
-
-cleanup:
- kfree(status_data);
- return retval;
-}
-
-// interface functions
-int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written);
-
-static int agilent_82357a_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *nbytes)
-{
- int retval;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- int out_data_length, in_data_length;
- int bytes_written, bytes_read;
- int i = 0;
- u8 trailing_flags;
- unsigned long start_jiffies = jiffies;
- int msec_timeout;
-
- *nbytes = 0;
- *end = 0;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_data_length = 0x9;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_READ;
- out_data[i++] = 0; // primary address when ARF_NO_ADDR is not set
- out_data[i++] = 0; // secondary address when ARF_NO_ADDR is not set
- out_data[i] = ARF_NO_ADDRESS | ARF_END_ON_EOI;
- if (a_priv->eos_mode & REOS)
- out_data[i] |= ARF_END_ON_EOS_CHAR;
- ++i;
- out_data[i++] = length & 0xff;
- out_data[i++] = (length >> 8) & 0xff;
- out_data[i++] = (length >> 16) & 0xff;
- out_data[i++] = (length >> 24) & 0xff;
- out_data[i++] = a_priv->eos_char;
- msec_timeout = (board->usec_timeout + 999) / 1000;
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &bytes_written, msec_timeout);
- kfree(out_data);
- if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0)
- return retval;
- return -EIO;
- }
- in_data_length = length + 1;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- if (board->usec_timeout != 0)
- msec_timeout -= jiffies_to_msecs(jiffies - start_jiffies) - 1;
- if (msec_timeout >= 0) {
- retval = agilent_82357a_receive_bulk_msg(a_priv, in_data, in_data_length,
- &bytes_read, msec_timeout);
- } else {
- retval = -ETIMEDOUT;
- bytes_read = 0;
- }
- if (retval == -ETIMEDOUT) {
- int extra_bytes_read;
- int extra_bytes_retval;
-
- agilent_82357a_abort(a_priv, 1);
- extra_bytes_retval = agilent_82357a_receive_bulk_msg(a_priv, in_data + bytes_read,
- in_data_length - bytes_read,
- &extra_bytes_read, 100);
- bytes_read += extra_bytes_read;
- if (extra_bytes_retval) {
- dev_err(&usb_dev->dev, "extra_bytes_retval=%i, bytes_read=%i\n",
- extra_bytes_retval, bytes_read);
- agilent_82357a_abort(a_priv, 0);
- }
- } else if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- agilent_82357a_abort(a_priv, 0);
- }
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (bytes_read > length + 1) {
- bytes_read = length + 1;
- dev_warn(&usb_dev->dev, "bytes_read > length? truncating");
- }
-
- if (bytes_read >= 1) {
- memcpy(buffer, in_data, bytes_read - 1);
- trailing_flags = in_data[bytes_read - 1];
- *nbytes = bytes_read - 1;
- if (trailing_flags & (ATRF_EOI | ATRF_EOS))
- *end = 1;
- }
- kfree(in_data);
-
- /*
- * Fix for a bug in 9914A that does not return the contents of ADSR
- * when the board is in listener active state and ATN is not asserted.
- * Set ATN here to obtain a valid board level ibsta
- */
- agilent_82357a_take_control_internal(board, 0);
-
- // FIXME check trailing flags for error
- return retval;
-}
-
-static ssize_t agilent_82357a_generic_write(struct gpib_board *board,
- u8 *buffer, size_t length,
- int send_commands, int send_eoi,
- size_t *bytes_written)
-{
- int retval;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data = NULL;
- u8 *status_data = NULL;
- int out_data_length;
- int raw_bytes_written;
- int i = 0, j;
- int msec_timeout;
- unsigned short bsr, adsr;
- struct agilent_82357a_register_pairlet read_reg;
-
- *bytes_written = 0;
- if (!a_priv->bus_interface)
- return -ENODEV;
-
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- out_data_length = length + 0x8;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = DATA_PIPE_CMD_WRITE;
- out_data[i++] = 0; // primary address when AWF_NO_ADDRESS is not set
- out_data[i++] = 0; // secondary address when AWF_NO_ADDRESS is not set
- out_data[i] = AWF_NO_ADDRESS | AWF_NO_FAST_TALKER_FIRST_BYTE;
- if (send_commands)
- out_data[i] |= AWF_ATN | AWF_NO_FAST_TALKER;
- if (send_eoi)
- out_data[i] |= AWF_SEND_EOI;
- ++i;
- out_data[i++] = length & 0xff;
- out_data[i++] = (length >> 8) & 0xff;
- out_data[i++] = (length >> 16) & 0xff;
- out_data[i++] = (length >> 24) & 0xff;
- for (j = 0; j < length; j++)
- out_data[i++] = buffer[j];
-
- clear_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);
-
- msec_timeout = (board->usec_timeout + 999) / 1000;
- retval = mutex_lock_interruptible(&a_priv->bulk_transfer_lock);
- if (retval) {
- kfree(out_data);
- return retval;
- }
- retval = agilent_82357a_send_bulk_msg(a_priv, out_data, i, &raw_bytes_written,
- msec_timeout);
- kfree(out_data);
- if (retval || raw_bytes_written != i) {
- agilent_82357a_abort(a_priv, 0);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, raw_bytes_written=%i, i=%i\n",
- retval, raw_bytes_written, i);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0)
- return retval;
- return -EIO;
- }
-
- retval = wait_event_interruptible(board->wait,
- test_bit(AIF_WRITE_COMPLETE_BN,
- &a_priv->interrupt_flags) ||
- test_bit(TIMO_NUM, &board->status));
- if (retval) {
- dev_dbg(&usb_dev->dev, "wait write complete interrupted\n");
- agilent_82357a_abort(a_priv, 0);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ERESTARTSYS;
- }
-
- if (test_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags) == 0) {
- dev_dbg(&usb_dev->dev, "write timed out ibs %i, tmo %i\n",
- test_bit(TIMO_NUM, &board->status), msec_timeout);
-
- agilent_82357a_abort(a_priv, 0);
-
- mutex_unlock(&a_priv->bulk_transfer_lock);
-
- read_reg.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -ETIMEDOUT;
- }
-
- bsr = read_reg.value;
- dev_dbg(&usb_dev->dev, "write aborted bsr 0x%x\n", bsr);
-
- if (send_commands) {/* check for no listeners */
- if ((bsr & BSR_ATN_BIT) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {
- dev_dbg(&usb_dev->dev, "No listener on command\n");
- clear_bit(TIMO_NUM, &board->status);
- return -ENOTCONN; // no listener on bus
- }
- } else {
- read_reg.address = ADSR;
- retval = agilent_82357a_read_registers(a_priv, &read_reg, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -ETIMEDOUT;
- }
- adsr = read_reg.value;
- if ((adsr & HR_TA) && !(bsr & (BSR_NDAC_BIT | BSR_NRFD_BIT))) {
- dev_dbg(&usb_dev->dev, "No listener on write\n");
- clear_bit(TIMO_NUM, &board->status);
- return -ECOMM;
- }
- }
-
- return -ETIMEDOUT;
- }
-
- status_data = kmalloc(STATUS_DATA_LEN, GFP_KERNEL);
- if (!status_data) {
- mutex_unlock(&a_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
-
- retval = agilent_82357a_receive_control_msg(a_priv, agilent_82357a_control_request,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- XFER_STATUS, 0, status_data, STATUS_DATA_LEN,
- 100);
- mutex_unlock(&a_priv->bulk_transfer_lock);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "receive_control_msg() returned %i\n", retval);
- kfree(status_data);
- return -EIO;
- }
- *bytes_written = (u32)status_data[2];
- *bytes_written |= (u32)status_data[3] << 8;
- *bytes_written |= (u32)status_data[4] << 16;
- *bytes_written |= (u32)status_data[5] << 24;
-
- kfree(status_data);
- return 0;
-}
-
-static int agilent_82357a_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-{
- return agilent_82357a_generic_write(board, buffer, length, 0, send_eoi, bytes_written);
-}
-
-int agilent_82357a_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- return agilent_82357a_generic_write(board, buffer, length, 1, 0, bytes_written);
-}
-
-int agilent_82357a_take_control_internal(struct gpib_board *board, int synchronous)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- write.address = AUXCR;
- if (synchronous)
- write.value = AUX_TCS;
- else
- write.value = AUX_TCA;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
-
- return retval;
-}
-
-static int agilent_82357a_take_control(struct gpib_board *board, int synchronous)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- const int timeout = 10;
- int i;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
-
-/*
- * It looks like the 9914 does not handle tcs properly.
- * See comment above tms9914_take_control_workaround() in
- * drivers/gpib/tms9914/tms9914_aux.c
- */
- if (synchronous)
- return -ETIMEDOUT;
-
- agilent_82357a_take_control_internal(board, synchronous);
- // busy wait until ATN is asserted
- for (i = 0; i < timeout; ++i) {
- agilent_82357a_update_status(board, 0);
- if (test_bit(ATN_NUM, &board->status))
- break;
- udelay(1);
- }
- if (i == timeout)
- return -ETIMEDOUT;
- return 0;
-}
-
-static int agilent_82357a_go_to_standby(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
-
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_GTS;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return 0;
-}
-
-static int agilent_82357a_request_system_control(struct gpib_board *board, int request_control)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet writes[2];
- int retval;
- int i = 0;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
-
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- /* 82357B needs bit to be set in 9914 AUXCR register */
- writes[i].address = AUXCR;
- if (request_control) {
- writes[i].value = AUX_RQC;
- a_priv->hw_control_bits |= SYSTEM_CONTROLLER;
- } else {
- return -EINVAL;
- }
- ++i;
- writes[i].address = HW_CONTROL;
- writes[i].value = a_priv->hw_control_bits;
- ++i;
- retval = agilent_82357a_write_registers(a_priv, writes, i);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
-}
-
-static void agilent_82357a_interface_clear(struct gpib_board *board, int assert)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- if (!a_priv->bus_interface)
- return; // -ENODEV;
-
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_SIC;
- if (assert) {
- write.value |= AUX_CS;
- a_priv->is_cic = 1;
- }
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
-}
-
-static void agilent_82357a_remote_enable(struct gpib_board *board, int enable)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- if (!a_priv->bus_interface)
- return; //-ENODEV;
-
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = AUXCR;
- write.value = AUX_SRE;
- if (enable)
- write.value |= AUX_CS;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- a_priv->ren_state = enable;
- return;// 0;
-}
-
-static int agilent_82357a_enable_eos(struct gpib_board *board, u8 eos_byte,
- int compare_8_bits)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- if (compare_8_bits == 0)
- return -EOPNOTSUPP;
-
- a_priv->eos_char = eos_byte;
- a_priv->eos_mode = REOS | BIN;
- return 0;
-}
-
-static void agilent_82357a_disable_eos(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
-
- a_priv->eos_mode &= ~REOS;
-}
-
-static unsigned int agilent_82357a_update_status(struct gpib_board *board,
- unsigned int clear_mask)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet address_status, bus_status;
- int retval;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- board->status &= ~clear_mask;
- if (a_priv->is_cic)
- set_bit(CIC_NUM, &board->status);
- else
- clear_bit(CIC_NUM, &board->status);
- address_status.address = ADSR;
- retval = agilent_82357a_read_registers(a_priv, &address_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return board->status;
- }
- // check for remote/local
- if (address_status.value & HR_REM)
- set_bit(REM_NUM, &board->status);
- else
- clear_bit(REM_NUM, &board->status);
- // check for lockout
- if (address_status.value & HR_LLO)
- set_bit(LOK_NUM, &board->status);
- else
- clear_bit(LOK_NUM, &board->status);
- // check for ATN
- if (address_status.value & HR_ATN)
- set_bit(ATN_NUM, &board->status);
- else
- clear_bit(ATN_NUM, &board->status);
- // check for talker/listener addressed
- if (address_status.value & HR_TA)
- set_bit(TACS_NUM, &board->status);
- else
- clear_bit(TACS_NUM, &board->status);
- if (address_status.value & HR_LA)
- set_bit(LACS_NUM, &board->status);
- else
- clear_bit(LACS_NUM, &board->status);
-
- bus_status.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return board->status;
- }
- if (bus_status.value & BSR_SRQ_BIT)
- set_bit(SRQI_NUM, &board->status);
- else
- clear_bit(SRQI_NUM, &board->status);
-
- return board->status;
-}
-
-static int agilent_82357a_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- // put primary address in address0
- write.address = ADR;
- write.value = address & ADDRESS_MASK;
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- return retval;
-}
-
-static int agilent_82357a_secondary_address(struct gpib_board *board,
- unsigned int address, int enable)
-{
- if (enable)
- return -EOPNOTSUPP;
- return 0;
-}
-
-static int agilent_82357a_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet writes[2];
- struct agilent_82357a_register_pairlet read;
- int retval;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- // execute parallel poll
- writes[0].address = AUXCR;
- writes[0].value = AUX_CS | AUX_RPP;
- writes[1].address = HW_CONTROL;
- writes[1].value = a_priv->hw_control_bits & ~NOT_PARALLEL_POLL;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- udelay(2); // silly, since usb write will take way longer
- read.address = CPTR;
- retval = agilent_82357a_read_registers(a_priv, &read, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return retval;
- }
- *result = read.value;
- // clear parallel poll state
- writes[0].address = HW_CONTROL;
- writes[0].value = a_priv->hw_control_bits | NOT_PARALLEL_POLL;
- writes[1].address = AUXCR;
- writes[1].value = AUX_RPP;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return retval;
- }
- return 0;
-}
-
-static void agilent_82357a_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- // board can only be system controller
- return;// 0;
-}
-
-static void agilent_82357a_parallel_poll_response(struct gpib_board *board, int ist)
-{
- // board can only be system controller
- return;// 0;
-}
-
-static void agilent_82357a_serial_poll_response(struct gpib_board *board, u8 status)
-{
- // board can only be system controller
- return;// 0;
-}
-
-static u8 agilent_82357a_serial_poll_status(struct gpib_board *board)
-{
- // board can only be system controller
- return 0;
-}
-
-static void agilent_82357a_return_to_local(struct gpib_board *board)
-{
- // board can only be system controller
- return;// 0;
-}
-
-static int agilent_82357a_line_status(const struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet bus_status;
- int retval;
- int status = VALID_ALL;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- bus_status.address = BSR;
- retval = agilent_82357a_read_registers(a_priv, &bus_status, 1, 0);
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return retval;
- }
- if (bus_status.value & BSR_REN_BIT)
- status |= BUS_REN;
- if (bus_status.value & BSR_IFC_BIT)
- status |= BUS_IFC;
- if (bus_status.value & BSR_SRQ_BIT)
- status |= BUS_SRQ;
- if (bus_status.value & BSR_EOI_BIT)
- status |= BUS_EOI;
- if (bus_status.value & BSR_NRFD_BIT)
- status |= BUS_NRFD;
- if (bus_status.value & BSR_NDAC_BIT)
- status |= BUS_NDAC;
- if (bus_status.value & BSR_DAV_BIT)
- status |= BUS_DAV;
- if (bus_status.value & BSR_ATN_BIT)
- status |= BUS_ATN;
- return status;
-}
-
-static unsigned short nanosec_to_fast_talker_bits(unsigned int *nanosec)
-{
- static const int nanosec_per_bit = 21;
- static const int max_value = 0x72;
- static const int min_value = 0x11;
- unsigned short bits;
-
- bits = (*nanosec + nanosec_per_bit / 2) / nanosec_per_bit;
- if (bits < min_value)
- bits = min_value;
- if (bits > max_value)
- bits = max_value;
- *nanosec = bits * nanosec_per_bit;
- return bits;
-}
-
-static int agilent_82357a_t1_delay(struct gpib_board *board, unsigned int nanosec)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- struct agilent_82357a_register_pairlet write;
- int retval;
-
- if (!a_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- write.address = FAST_TALKER_T1;
- write.value = nanosec_to_fast_talker_bits(&nanosec);
- retval = agilent_82357a_write_registers(a_priv, &write, 1);
- if (retval)
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return nanosec;
-}
-
-static void agilent_82357a_interrupt_complete(struct urb *urb)
-{
- struct gpib_board *board = urb->context;
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int retval;
- u8 *transfer_buffer = urb->transfer_buffer;
- unsigned long interrupt_flags;
-
- switch (urb->status) {
- /* success */
- case 0:
- break;
- /* unlinked, don't resubmit */
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* other error, resubmit */
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
- return;
- }
-
- interrupt_flags = transfer_buffer[0];
- if (test_bit(AIF_READ_COMPLETE_BN, &interrupt_flags))
- set_bit(AIF_READ_COMPLETE_BN, &a_priv->interrupt_flags);
- if (test_bit(AIF_WRITE_COMPLETE_BN, &interrupt_flags))
- set_bit(AIF_WRITE_COMPLETE_BN, &a_priv->interrupt_flags);
- if (test_bit(AIF_SRQ_BN, &interrupt_flags))
- set_bit(SRQI_NUM, &board->status);
-
- wake_up_interruptible(&board->wait);
-
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
-}
-
-static int agilent_82357a_setup_urbs(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev;
- int int_pipe;
- int retval;
-
- retval = mutex_lock_interruptible(&a_priv->interrupt_alloc_lock);
- if (retval)
- return retval;
- if (!a_priv->bus_interface) {
- retval = -ENODEV;
- goto setup_exit;
- }
-
- a_priv->interrupt_buffer = kmalloc(INTERRUPT_BUF_LEN, GFP_KERNEL);
- if (!a_priv->interrupt_buffer) {
- retval = -ENOMEM;
- goto setup_exit;
- }
- a_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!a_priv->interrupt_urb) {
- retval = -ENOMEM;
- goto setup_exit;
- }
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- int_pipe = usb_rcvintpipe(usb_dev, a_priv->interrupt_in_endpoint);
- usb_fill_int_urb(a_priv->interrupt_urb, usb_dev, int_pipe, a_priv->interrupt_buffer,
- INTERRUPT_BUF_LEN, &agilent_82357a_interrupt_complete, board, 1);
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);
- if (retval) {
- usb_free_urb(a_priv->interrupt_urb);
- a_priv->interrupt_urb = NULL;
- dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);
- goto setup_exit;
- }
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- return 0;
-
-setup_exit:
- kfree(a_priv->interrupt_buffer);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- return retval;
-}
-
-static void agilent_82357a_cleanup_urbs(struct agilent_82357a_priv *a_priv)
-{
- if (a_priv && a_priv->bus_interface) {
- if (a_priv->interrupt_urb)
- usb_kill_urb(a_priv->interrupt_urb);
- if (a_priv->bulk_urb)
- usb_kill_urb(a_priv->bulk_urb);
- }
-};
-
-static void agilent_82357a_release_urbs(struct agilent_82357a_priv *a_priv)
-{
- if (a_priv) {
- usb_free_urb(a_priv->interrupt_urb);
- a_priv->interrupt_urb = NULL;
- kfree(a_priv->interrupt_buffer);
- }
-}
-
-static int agilent_82357a_allocate_private(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv;
-
- board->private_data = kzalloc(sizeof(struct agilent_82357a_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- a_priv = board->private_data;
- mutex_init(&a_priv->bulk_transfer_lock);
- mutex_init(&a_priv->bulk_alloc_lock);
- mutex_init(&a_priv->control_alloc_lock);
- mutex_init(&a_priv->interrupt_alloc_lock);
- return 0;
-}
-
-static void agilent_82357a_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-#define INIT_NUM_REG_WRITES 18
-static int agilent_82357a_init(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet hw_control;
- struct agilent_82357a_register_pairlet writes[INIT_NUM_REG_WRITES];
- int retval;
- unsigned int nanosec;
-
- writes[0].address = LED_CONTROL;
- writes[0].value = FAIL_LED_ON;
- writes[1].address = RESET_TO_POWERUP;
- writes[1].value = RESET_SPACEBALL;
- retval = agilent_82357a_write_registers(a_priv, writes, 2);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(usec_to_jiffies(2000)))
- return -ERESTARTSYS;
- writes[0].address = AUXCR;
- writes[0].value = AUX_NBAF;
- writes[1].address = AUXCR;
- writes[1].value = AUX_HLDE;
- writes[2].address = AUXCR;
- writes[2].value = AUX_TON;
- writes[3].address = AUXCR;
- writes[3].value = AUX_LON;
- writes[4].address = AUXCR;
- writes[4].value = AUX_RSV2;
- writes[5].address = AUXCR;
- writes[5].value = AUX_INVAL;
- writes[6].address = AUXCR;
- writes[6].value = AUX_RPP;
- writes[7].address = AUXCR;
- writes[7].value = AUX_STDL;
- writes[8].address = AUXCR;
- writes[8].value = AUX_VSTDL;
- writes[9].address = FAST_TALKER_T1;
- nanosec = board->t1_nano_sec;
- writes[9].value = nanosec_to_fast_talker_bits(&nanosec);
- board->t1_nano_sec = nanosec;
- writes[10].address = ADR;
- writes[10].value = board->pad & ADDRESS_MASK;
- writes[11].address = PPR;
- writes[11].value = 0;
- writes[12].address = SPMR;
- writes[12].value = 0;
- writes[13].address = PROTOCOL_CONTROL;
- writes[13].value = WRITE_COMPLETE_INTERRUPT_EN;
- writes[14].address = IMR0;
- writes[14].value = HR_BOIE | HR_BIIE;
- writes[15].address = IMR1;
- writes[15].value = HR_SRQIE;
- // turn off reset state
- writes[16].address = AUXCR;
- writes[16].value = AUX_CHIP_RESET;
- writes[17].address = LED_CONTROL;
- writes[17].value = FIRMWARE_LED_CONTROL;
- retval = agilent_82357a_write_registers(a_priv, writes, INIT_NUM_REG_WRITES);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- hw_control.address = HW_CONTROL;
- retval = agilent_82357a_read_registers(a_priv, &hw_control, 1, 1);
- if (retval) {
- dev_err(&usb_dev->dev, "read_registers() returned error\n");
- return -EIO;
- }
- a_priv->hw_control_bits = (hw_control.value & ~0x7) | NOT_TI_RESET | NOT_PARALLEL_POLL;
-
- return 0;
-}
-
-static inline int agilent_82357a_device_match(struct usb_interface *interface,
- const struct gpib_board_config *config)
-{
- struct usb_device * const usbdev = interface_to_usbdev(interface);
-
- if (gpib_match_device_path(&interface->dev, config->device_path) == 0)
- return 0;
- if (config->serial_number &&
- strcmp(usbdev->serial, config->serial_number) != 0)
- return 0;
-
- return 1;
-}
-
-static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- int retval;
- int i;
- unsigned int product_id;
- struct agilent_82357a_priv *a_priv;
- struct usb_device *usb_dev;
-
- if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))
- return -ERESTARTSYS;
-
- retval = agilent_82357a_allocate_private(board);
- if (retval < 0) {
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- a_priv = board->private_data;
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] &&
- !usb_get_intfdata(agilent_82357a_driver_interfaces[i]) &&
- agilent_82357a_device_match(agilent_82357a_driver_interfaces[i], config)) {
- a_priv->bus_interface = agilent_82357a_driver_interfaces[i];
- usb_set_intfdata(agilent_82357a_driver_interfaces[i], board);
- usb_dev = interface_to_usbdev(a_priv->bus_interface);
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- dev_err(board->gpib_dev,
- "No supported adapters found, have you loaded its firmware?\n");
- retval = -ENODEV;
- goto attach_fail;
- }
- product_id = le16_to_cpu(interface_to_usbdev(a_priv->bus_interface)->descriptor.idProduct);
- switch (product_id) {
- case USB_DEVICE_ID_AGILENT_82357A:
- a_priv->bulk_out_endpoint = AGILENT_82357A_BULK_OUT_ENDPOINT;
- a_priv->interrupt_in_endpoint = AGILENT_82357A_INTERRUPT_IN_ENDPOINT;
- break;
- case USB_DEVICE_ID_AGILENT_82357B:
- a_priv->bulk_out_endpoint = AGILENT_82357B_BULK_OUT_ENDPOINT;
- a_priv->interrupt_in_endpoint = AGILENT_82357B_INTERRUPT_IN_ENDPOINT;
- break;
- default:
- dev_err(&usb_dev->dev, "bug, unhandled product_id in switch?\n");
- retval = -EIO;
- goto attach_fail;
- }
-
- retval = agilent_82357a_setup_urbs(board);
- if (retval < 0)
- goto attach_fail;
-
- timer_setup(&a_priv->bulk_timer, agilent_82357a_timeout_handler, 0);
-
- board->t1_nano_sec = 800;
-
- retval = agilent_82357a_init(board);
-
- if (retval < 0) {
- agilent_82357a_cleanup_urbs(a_priv);
- agilent_82357a_release_urbs(a_priv);
- goto attach_fail;
- }
-
- dev_info(&usb_dev->dev, "bus %d dev num %d attached to gpib%d, interface %i\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
-
-attach_fail:
- agilent_82357a_free_private(board);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
-}
-
-static int agilent_82357a_go_idle(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(a_priv->bus_interface);
- struct agilent_82357a_register_pairlet writes[0x20];
- int retval;
-
- // turn on tms9914 reset state
- writes[0].address = AUXCR;
- writes[0].value = AUX_CS | AUX_CHIP_RESET;
- a_priv->hw_control_bits &= ~NOT_TI_RESET;
- writes[1].address = HW_CONTROL;
- writes[1].value = a_priv->hw_control_bits;
- writes[2].address = PROTOCOL_CONTROL;
- writes[2].value = 0;
- writes[3].address = IMR0;
- writes[3].value = 0;
- writes[4].address = IMR1;
- writes[4].value = 0;
- writes[5].address = LED_CONTROL;
- writes[5].value = 0;
- retval = agilent_82357a_write_registers(a_priv, writes, 6);
- if (retval) {
- dev_err(&usb_dev->dev, "write_registers() returned error\n");
- return -EIO;
- }
- return 0;
-}
-
-static void agilent_82357a_detach(struct gpib_board *board)
-{
- struct agilent_82357a_priv *a_priv;
-
- mutex_lock(&agilent_82357a_hotplug_lock);
-
- a_priv = board->private_data;
- if (a_priv) {
- if (a_priv->bus_interface) {
- agilent_82357a_go_idle(board);
- usb_set_intfdata(a_priv->bus_interface, NULL);
- }
- mutex_lock(&a_priv->control_alloc_lock);
- mutex_lock(&a_priv->bulk_alloc_lock);
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- agilent_82357a_release_urbs(a_priv);
- agilent_82357a_free_private(board);
- }
- mutex_unlock(&agilent_82357a_hotplug_lock);
-}
-
-static struct gpib_interface agilent_82357a_gpib_interface = {
- .name = "agilent_82357a",
- .attach = agilent_82357a_attach,
- .detach = agilent_82357a_detach,
- .read = agilent_82357a_read,
- .write = agilent_82357a_write,
- .command = agilent_82357a_command,
- .take_control = agilent_82357a_take_control,
- .go_to_standby = agilent_82357a_go_to_standby,
- .request_system_control = agilent_82357a_request_system_control,
- .interface_clear = agilent_82357a_interface_clear,
- .remote_enable = agilent_82357a_remote_enable,
- .enable_eos = agilent_82357a_enable_eos,
- .disable_eos = agilent_82357a_disable_eos,
- .parallel_poll = agilent_82357a_parallel_poll,
- .parallel_poll_configure = agilent_82357a_parallel_poll_configure,
- .parallel_poll_response = agilent_82357a_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = agilent_82357a_line_status,
- .update_status = agilent_82357a_update_status,
- .primary_address = agilent_82357a_primary_address,
- .secondary_address = agilent_82357a_secondary_address,
- .serial_poll_response = agilent_82357a_serial_poll_response,
- .serial_poll_status = agilent_82357a_serial_poll_status,
- .t1_delay = agilent_82357a_t1_delay,
- .return_to_local = agilent_82357a_return_to_local,
- .no_7_bit_eos = 1,
- .skip_check_for_command_acceptors = 1
-};
-
-// Table with the USB-devices: just now only testing IDs
-static struct usb_device_id agilent_82357a_driver_device_table[] = {
- {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357A)},
- {USB_DEVICE(USB_VENDOR_ID_AGILENT, USB_DEVICE_ID_AGILENT_82357B)},
- {} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, agilent_82357a_driver_device_table);
-
-static int agilent_82357a_driver_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- int i;
- char *path;
- static const int path_length = 1024;
- struct usb_device *usb_dev;
-
- if (mutex_lock_interruptible(&agilent_82357a_hotplug_lock))
- return -ERESTARTSYS;
- usb_dev = usb_get_dev(interface_to_usbdev(interface));
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (!agilent_82357a_driver_interfaces[i]) {
- agilent_82357a_driver_interfaces[i] = interface;
- usb_set_intfdata(interface, NULL);
- dev_dbg(&usb_dev->dev, "set bus interface %i to address 0x%p\n",
- i, interface);
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- usb_put_dev(usb_dev);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- dev_err(&usb_dev->dev, "out of space in agilent_82357a_driver_interfaces[]\n");
- return -1;
- }
- path = kmalloc(path_length, GFP_KERNEL);
- if (!path) {
- usb_put_dev(usb_dev);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return -ENOMEM;
- }
- usb_make_path(usb_dev, path, path_length);
- dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path);
- kfree(path);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return 0;
-}
-
-static void agilent_82357a_driver_disconnect(struct usb_interface *interface)
-{
- int i;
- struct usb_device *usb_dev = interface_to_usbdev(interface);
-
- mutex_lock(&agilent_82357a_hotplug_lock);
-
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- struct gpib_board *board = usb_get_intfdata(interface);
-
- if (board) {
- struct agilent_82357a_priv *a_priv = board->private_data;
-
- if (a_priv) {
- mutex_lock(&a_priv->control_alloc_lock);
- mutex_lock(&a_priv->bulk_alloc_lock);
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- a_priv->bus_interface = NULL;
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- mutex_unlock(&a_priv->bulk_alloc_lock);
- mutex_unlock(&a_priv->control_alloc_lock);
- }
- }
- agilent_82357a_driver_interfaces[i] = NULL;
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES)
- dev_err(&usb_dev->dev, "unable to find interface - bug?\n");
- usb_put_dev(usb_dev);
-
- mutex_unlock(&agilent_82357a_hotplug_lock);
-}
-
-static int agilent_82357a_driver_suspend(struct usb_interface *interface, pm_message_t message)
-{
- int i, retval;
- struct usb_device *usb_dev = interface_to_usbdev(interface);
-
- mutex_lock(&agilent_82357a_hotplug_lock);
-
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- struct gpib_board *board = usb_get_intfdata(interface);
-
- if (board) {
- struct agilent_82357a_priv *a_priv = board->private_data;
-
- if (a_priv) {
- agilent_82357a_abort(a_priv, 0);
- agilent_82357a_abort(a_priv, 0);
- retval = agilent_82357a_go_idle(board);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to go idle, retval=%i\n",
- retval);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- mutex_lock(&a_priv->interrupt_alloc_lock);
- agilent_82357a_cleanup_urbs(a_priv);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib %d, interface %i suspended\n",
- usb_dev->bus->busnum, usb_dev->devnum,
- board->minor, i);
- }
- }
- break;
- }
- }
-
- mutex_unlock(&agilent_82357a_hotplug_lock);
-
- return 0;
-}
-
-static int agilent_82357a_driver_resume(struct usb_interface *interface)
-{
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- struct gpib_board *board;
- int i, retval = 0;
-
- mutex_lock(&agilent_82357a_hotplug_lock);
-
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i) {
- if (agilent_82357a_driver_interfaces[i] == interface) {
- board = usb_get_intfdata(interface);
- if (board)
- break;
- }
- }
- if (i == MAX_NUM_82357A_INTERFACES) {
- retval = -ENOENT;
- goto resume_exit;
- }
-
- struct agilent_82357a_priv *a_priv = board->private_data;
-
- if (a_priv) {
- if (a_priv->interrupt_urb) {
- mutex_lock(&a_priv->interrupt_alloc_lock);
- retval = usb_submit_urb(a_priv->interrupt_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb in resume, retval=%i\n",
- retval);
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- mutex_unlock(&a_priv->interrupt_alloc_lock);
- }
- retval = agilent_82357a_init(board);
- if (retval < 0) {
- mutex_unlock(&agilent_82357a_hotplug_lock);
- return retval;
- }
- // set/unset system controller
- retval = agilent_82357a_request_system_control(board, board->master);
- // toggle ifc if master
- if (board->master) {
- agilent_82357a_interface_clear(board, 1);
- usleep_range(200, 250);
- agilent_82357a_interface_clear(board, 0);
- }
- // assert/unassert REN
- agilent_82357a_remote_enable(board, a_priv->ren_state);
-
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib%d, interface %i resumed\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- }
-
-resume_exit:
- mutex_unlock(&agilent_82357a_hotplug_lock);
-
- return retval;
-}
-
-static struct usb_driver agilent_82357a_bus_driver = {
- .name = DRV_NAME,
- .probe = agilent_82357a_driver_probe,
- .disconnect = agilent_82357a_driver_disconnect,
- .suspend = agilent_82357a_driver_suspend,
- .resume = agilent_82357a_driver_resume,
- .id_table = agilent_82357a_driver_device_table,
-};
-
-static int __init agilent_82357a_init_module(void)
-{
- int i;
- int ret;
-
- for (i = 0; i < MAX_NUM_82357A_INTERFACES; ++i)
- agilent_82357a_driver_interfaces[i] = NULL;
-
- ret = usb_register(&agilent_82357a_bus_driver);
- if (ret) {
- pr_err("usb_register failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&agilent_82357a_gpib_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- usb_deregister(&agilent_82357a_bus_driver);
- return ret;
- }
-
- return 0;
-}
-
-static void __exit agilent_82357a_exit_module(void)
-{
- gpib_unregister_driver(&agilent_82357a_gpib_interface);
- usb_deregister(&agilent_82357a_bus_driver);
-}
-
-module_init(agilent_82357a_init_module);
-module_exit(agilent_82357a_exit_module);
diff --git a/drivers/staging/gpib/agilent_82357a/agilent_82357a.h b/drivers/staging/gpib/agilent_82357a/agilent_82357a.h
deleted file mode 100644
index 33ac558e5552..000000000000
--- a/drivers/staging/gpib/agilent_82357a/agilent_82357a.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2004 by Frank Mori Hess *
- ***************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/completion.h>
-#include <linux/usb.h>
-#include <linux/timer.h>
-#include <linux/compiler_attributes.h>
-#include "gpibP.h"
-#include "tms9914.h"
-
-enum usb_vendor_ids {
- USB_VENDOR_ID_AGILENT = 0x0957
-};
-
-enum usb_device_ids {
- USB_DEVICE_ID_AGILENT_82357A = 0x0107,
- USB_DEVICE_ID_AGILENT_82357A_PREINIT = 0x0007, // device id before firmware is loaded
- USB_DEVICE_ID_AGILENT_82357B = 0x0718, // device id before firmware is loaded
- USB_DEVICE_ID_AGILENT_82357B_PREINIT = 0x0518, // device id before firmware is loaded
-};
-
-enum endpoint_addresses {
- AGILENT_82357_CONTROL_ENDPOINT = 0x0,
- AGILENT_82357_BULK_IN_ENDPOINT = 0x2,
- AGILENT_82357A_BULK_OUT_ENDPOINT = 0x4,
- AGILENT_82357A_INTERRUPT_IN_ENDPOINT = 0x6,
- AGILENT_82357B_BULK_OUT_ENDPOINT = 0x6,
- AGILENT_82357B_INTERRUPT_IN_ENDPOINT = 0x8,
-};
-
-enum bulk_commands {
- DATA_PIPE_CMD_WRITE = 0x1,
- DATA_PIPE_CMD_READ = 0x3,
- DATA_PIPE_CMD_WR_REGS = 0x4,
- DATA_PIPE_CMD_RD_REGS = 0x5
-};
-
-enum agilent_82357a_read_flags {
- ARF_END_ON_EOI = 0x1,
- ARF_NO_ADDRESS = 0x2,
- ARF_END_ON_EOS_CHAR = 0x4,
- ARF_SPOLL = 0x8
-};
-
-enum agilent_82357a_trailing_read_flags {
- ATRF_EOI = 0x1,
- ATRF_ATN = 0x2,
- ATRF_IFC = 0x4,
- ATRF_EOS = 0x8,
- ATRF_ABORT = 0x10,
- ATRF_COUNT = 0x20,
- ATRF_DEAD_BUS = 0x40,
- ATRF_UNADDRESSED = 0x80
-};
-
-enum agilent_82357a_write_flags {
- AWF_SEND_EOI = 0x1,
- AWF_NO_FAST_TALKER_FIRST_BYTE = 0x2,
- AWF_NO_FAST_TALKER = 0x4,
- AWF_NO_ADDRESS = 0x8,
- AWF_ATN = 0x10,
- AWF_SEPARATE_HEADER = 0x80
-};
-
-enum agilent_82357a_interrupt_flag_bit_numbers {
- AIF_SRQ_BN = 0,
- AIF_WRITE_COMPLETE_BN = 1,
- AIF_READ_COMPLETE_BN = 2,
-};
-
-enum agilent_82357_error_codes {
- UGP_SUCCESS = 0,
- UGP_ERR_INVALID_CMD = 1,
- UGP_ERR_INVALID_PARAM = 2,
- UGP_ERR_INVALID_REG = 3,
- UGP_ERR_GPIB_READ = 4,
- UGP_ERR_GPIB_WRITE = 5,
- UGP_ERR_FLUSHING = 6,
- UGP_ERR_FLUSHING_ALREADY = 7,
- UGP_ERR_UNSUPPORTED = 8,
- UGP_ERR_OTHER = 9
-};
-
-enum agilent_82357_control_values {
- XFER_ABORT = 0xa0,
- XFER_STATUS = 0xb0,
-};
-
-enum xfer_status_bits {
- XS_COMPLETED = 0x1,
- XS_READ = 0x2,
-};
-
-enum xfer_status_completion_bits {
- XSC_EOI = 0x1,
- XSC_ATN = 0x2,
- XSC_IFC = 0x4,
- XSC_EOS = 0x8,
- XSC_ABORT = 0x10,
- XSC_COUNT = 0x20,
- XSC_DEAD_BUS = 0x40,
- XSC_BUS_NOT_ADDRESSED = 0x80
-};
-
-enum xfer_abort_type {
- XA_FLUSH = 0x1
-};
-
-#define STATUS_DATA_LEN 8
-#define INTERRUPT_BUF_LEN 8
-
-struct agilent_82357a_urb_ctx {
- struct completion complete;
- unsigned timed_out : 1;
-};
-
-// struct which defines local data for each 82357 device
-struct agilent_82357a_priv {
- struct usb_interface *bus_interface;
- unsigned short eos_char;
- unsigned short eos_mode;
- unsigned short hw_control_bits;
- unsigned long interrupt_flags;
- struct urb *bulk_urb;
- struct urb *interrupt_urb;
- u8 *interrupt_buffer;
- struct mutex bulk_transfer_lock; // bulk transfer lock
- struct mutex bulk_alloc_lock; // bulk transfer allocation lock
- struct mutex interrupt_alloc_lock; // interrupt allocation lock
- struct mutex control_alloc_lock; // control message allocation lock
- struct timer_list bulk_timer;
- struct agilent_82357a_urb_ctx context;
- unsigned int bulk_out_endpoint;
- unsigned int interrupt_in_endpoint;
- unsigned is_cic : 1;
- unsigned ren_state : 1;
-};
-
-struct agilent_82357a_register_pairlet {
- short address;
- unsigned short value;
-};
-
-enum firmware_registers {
- HW_CONTROL = 0xa,
- LED_CONTROL = 0xb,
- RESET_TO_POWERUP = 0xc,
- PROTOCOL_CONTROL = 0xd,
- FAST_TALKER_T1 = 0xe
-};
-
-enum hardware_control_bits {
- NOT_TI_RESET = 0x1,
- SYSTEM_CONTROLLER = 0x2,
- NOT_PARALLEL_POLL = 0x4,
- OSCILLATOR_5V_ON = 0x8,
- OUTPUT_5V_ON = 0x20,
- CPLD_3V_ON = 0x80,
-};
-
-enum led_control_bits {
- FIRMWARE_LED_CONTROL = 0x1,
- FAIL_LED_ON = 0x20,
- READY_LED_ON = 0x40,
- ACCESS_LED_ON = 0x80
-};
-
-enum reset_to_powerup_bits {
- RESET_SPACEBALL = 0x1, // wait 2 millisec after sending
-};
-
-enum protocol_control_bits {
- WRITE_COMPLETE_INTERRUPT_EN = 0x1,
-};
-
-static const int agilent_82357a_control_request = 0x4;
-
diff --git a/drivers/staging/gpib/cb7210/Makefile b/drivers/staging/gpib/cb7210/Makefile
deleted file mode 100644
index d239ae80b415..000000000000
--- a/drivers/staging/gpib/cb7210/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_GPIB_CB7210) += cb7210.o
-
-
diff --git a/drivers/staging/gpib/cb7210/cb7210.c b/drivers/staging/gpib/cb7210/cb7210.c
deleted file mode 100644
index 3e2397898a9b..000000000000
--- a/drivers/staging/gpib/cb7210/cb7210.c
+++ /dev/null
@@ -1,1598 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * Measurement Computing boards using cb7210.2 and cbi488.2 chips
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "cb7210.h"
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/dma.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include "gpib_pci_ids.h"
-#include "quancom_pci.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver Measurement Computing boards using cb7210.2 and cbi488.2");
-
-static int cb7210_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read);
-
- static inline int have_fifo_word(const struct cb7210_priv *cb_priv)
-{
- if (((cb7210_read_byte(cb_priv, HS_STATUS)) &
- (HS_RX_MSB_NOT_EMPTY | HS_RX_LSB_NOT_EMPTY)) ==
- (HS_RX_MSB_NOT_EMPTY | HS_RX_LSB_NOT_EMPTY))
- return 1;
- else
- return 0;
-}
-
-static inline void input_fifo_enable(struct gpib_board *board, int enable)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- if (enable) {
- cb_priv->in_fifo_half_full = 0;
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
-
- cb7210_write_byte(cb_priv, HS_RX_ENABLE | HS_TX_ENABLE | HS_CLR_SRQ_INT |
- HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT | cb_priv->hs_mode_bits,
- HS_MODE);
-
- cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
-
- cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL);
-
- cb_priv->hs_mode_bits |= HS_RX_ENABLE;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
- } else {
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
-
- cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, nec7210_iobase(cb_priv) +
- HS_MODE);
-
- clear_bit(READ_READY_BN, &nec_priv->state);
- }
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static int fifo_read(struct gpib_board *board, struct cb7210_priv *cb_priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- int hs_status;
- u16 word;
- unsigned long flags;
-
- *bytes_read = 0;
- if (cb_priv->fifo_iobase == 0) {
- dev_err(board->gpib_dev, "fifo iobase is zero!\n");
- return -EIO;
- }
- *end = 0;
- if (length <= cb7210_fifo_size) {
- dev_err(board->gpib_dev, " bug! fifo read length < fifo size\n");
- return -EINVAL;
- }
-
- input_fifo_enable(board, 1);
-
- while (*bytes_read + cb7210_fifo_size < length) {
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI);
-
- if (wait_event_interruptible(board->wait,
- (cb_priv->in_fifo_half_full &&
- have_fifo_word(cb_priv)) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- break;
- }
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
-
- while (have_fifo_word(cb_priv)) {
- word = inw(cb_priv->fifo_iobase + DIR);
- buffer[(*bytes_read)++] = word & 0xff;
- buffer[(*bytes_read)++] = (word >> 8) & 0xff;
- }
-
- cb_priv->in_fifo_half_full = 0;
-
- hs_status = cb7210_read_byte(cb_priv, HS_STATUS);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state)) {
- *end = 1;
- break;
- }
- if (hs_status & HS_FIFO_FULL)
- break;
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) {
- retval = -EINTR;
- break;
- }
- }
- hs_status = cb7210_read_byte(cb_priv, HS_STATUS);
- if (hs_status & HS_RX_LSB_NOT_EMPTY) {
- word = inw(cb_priv->fifo_iobase + DIR);
- buffer[(*bytes_read)++] = word & 0xff;
- }
-
- input_fifo_enable(board, 0);
-
- if (wait_event_interruptible(board->wait,
- test_bit(READ_READY_BN, &nec_priv->state) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- if (test_bit(READ_READY_BN, &nec_priv->state)) {
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDA);
- buffer[(*bytes_read)++] = nec7210_read_data_in(board, nec_priv, end);
- }
-
- return retval;
-}
-
-static int cb7210_accel_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval;
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- size_t num_bytes;
-
- *bytes_read = 0;
- // deal with limitations of fifo
- if (length < cb7210_fifo_size + 3 || (nec_priv->auxa_bits & HR_REOS))
- return cb7210_read(board, buffer, length, end, bytes_read);
- *end = 0;
-
- nec7210_release_rfd_holdoff(board, nec_priv);
-
- if (wait_event_interruptible(board->wait,
- test_bit(READ_READY_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- return -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- return -EINTR;
-
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
- buffer[(*bytes_read)++] = nec7210_read_data_in(board, nec_priv, end);
- if (*end)
- return 0;
-
- nec7210_release_rfd_holdoff(board, nec_priv);
-
- retval = fifo_read(board, cb_priv, &buffer[*bytes_read], length - *bytes_read - 1,
- end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
- if (*end)
- return 0;
-
- retval = cb7210_read(board, &buffer[*bytes_read], 1, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
-
- return 0;
-}
-
-static int output_fifo_empty(const struct cb7210_priv *cb_priv)
-{
- if ((cb7210_read_byte(cb_priv, HS_STATUS) & (HS_TX_MSB_NOT_EMPTY | HS_TX_LSB_NOT_EMPTY))
- == 0)
- return 1;
- else
- return 0;
-}
-
-static inline void output_fifo_enable(struct gpib_board *board, int enable)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- if (enable) {
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO);
-
- cb7210_write_byte(cb_priv, HS_RX_ENABLE | HS_TX_ENABLE | HS_CLR_SRQ_INT |
- HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT | cb_priv->hs_mode_bits,
- HS_MODE);
-
- cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK;
- cb_priv->hs_mode_bits |= HS_TX_ENABLE;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
-
- cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL);
-
- clear_bit(WRITE_READY_BN, &nec_priv->state);
-
- } else {
- cb_priv->hs_mode_bits &= ~HS_ENABLE_MASK;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
-
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, HR_DOIE);
- }
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static int fifo_write(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- size_t count = 0;
- ssize_t retval = 0;
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned int num_bytes, i;
- unsigned long flags;
-
- *bytes_written = 0;
- if (cb_priv->fifo_iobase == 0) {
- dev_err(board->gpib_dev, "fifo iobase is zero!\n");
- return -EINVAL;
- }
- if (length == 0)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &nec_priv->state);
- clear_bit(BUS_ERROR_BN, &nec_priv->state);
-
- output_fifo_enable(board, 1);
-
- while (count < length) {
- // wait until byte is ready to be sent
- if (wait_event_interruptible(board->wait,
- cb_priv->out_fifo_half_empty ||
- output_fifo_empty(cb_priv) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- break;
- }
- if (test_bit(TIMO_NUM, &board->status) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state))
- break;
-
- if (output_fifo_empty(cb_priv))
- num_bytes = cb7210_fifo_size - cb7210_fifo_width;
- else
- num_bytes = cb7210_fifo_size / 2;
- if (num_bytes + count > length)
- num_bytes = length - count;
- if (num_bytes % cb7210_fifo_width) {
- dev_err(board->gpib_dev, " bug! fifo write with odd number of bytes\n");
- retval = -EINVAL;
- break;
- }
-
- spin_lock_irqsave(&board->spinlock, flags);
- for (i = 0; i < num_bytes / cb7210_fifo_width; i++) {
- u16 word;
-
- word = buffer[count++] & 0xff;
- word |= (buffer[count++] << 8) & 0xff00;
- outw(word, cb_priv->fifo_iobase + CDOR);
- }
- cb_priv->out_fifo_half_empty = 0;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits |
- HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT, HS_MODE);
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
- spin_unlock_irqrestore(&board->spinlock, flags);
- }
- // wait last byte has been sent
- if (wait_event_interruptible(board->wait,
- output_fifo_empty(cb_priv) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(BUS_ERROR_BN, &nec_priv->state))
- retval = -EIO;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
-
- output_fifo_enable(board, 0);
-
- *bytes_written = count;
- return retval;
-}
-
-static int cb7210_accel_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned long fast_chunk_size, leftover;
- int retval;
- size_t num_bytes;
-
- *bytes_written = 0;
- if (length > cb7210_fifo_width)
- fast_chunk_size = length - 1;
- else
- fast_chunk_size = 0;
- fast_chunk_size -= fast_chunk_size % cb7210_fifo_width;
- leftover = length - fast_chunk_size;
-
- retval = fifo_write(board, buffer, fast_chunk_size, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
-
- retval = nec7210_write(board, nec_priv, buffer + fast_chunk_size, leftover,
- send_eoi, &num_bytes);
- *bytes_written += num_bytes;
- return retval;
-}
-
-static int cb7210_line_status(const struct gpib_board *board)
-{
- int status = VALID_ALL;
- int bsr_bits;
- struct cb7210_priv *cb_priv;
-
- cb_priv = board->private_data;
-
- bsr_bits = cb7210_paged_read_byte(cb_priv, BUS_STATUS, BUS_STATUS_PAGE);
-
- if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BUS_REN;
- if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BUS_IFC;
- if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BUS_SRQ;
- if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BUS_EOI;
- if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BUS_NRFD;
- if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BUS_NDAC;
- if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BUS_DAV;
- if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BUS_ATN;
-
- return status;
-}
-
-static int cb7210_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned int retval;
-
- retval = nec7210_t1_delay(board, nec_priv, nano_sec);
-
- if (nano_sec <= 350) {
- write_byte(nec_priv, AUX_HI_SPEED, AUXMR);
- retval = 350;
- } else {
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- }
- return retval;
-}
-
-static irqreturn_t cb7210_locked_internal_interrupt(struct gpib_board *board);
-
-/*
- * GPIB interrupt service routines
- */
-
-static irqreturn_t cb_pci_interrupt(int irq, void *arg)
-{
- int bits;
- struct gpib_board *board = arg;
- struct cb7210_priv *priv = board->private_data;
-
- // first task check if this is really our interrupt in a shared irq environment
- switch (priv->pci_chip) {
- case PCI_CHIP_AMCC_S5933:
- if ((inl(priv->amcc_iobase + INTCSR_REG) &
- (INBOX_INTR_CS_BIT | INTR_ASSERTED_BIT)) == 0)
- return IRQ_NONE;
-
- // read incoming mailbox to clear mailbox full flag
- inl(priv->amcc_iobase + INCOMING_MAILBOX_REG(3));
- // clear amccs5933 interrupt
- bits = INBOX_FULL_INTR_BIT | INBOX_BYTE_BITS(3) |
- INBOX_SELECT_BITS(3) | INBOX_INTR_CS_BIT;
- outl(bits, priv->amcc_iobase + INTCSR_REG);
- break;
- case PCI_CHIP_QUANCOM:
- if ((inb(nec7210_iobase(priv) + QUANCOM_IRQ_CONTROL_STATUS_REG) &
- QUANCOM_IRQ_ASSERTED_BIT))
- outb(QUANCOM_IRQ_ENABLE_BIT, nec7210_iobase(priv) +
- QUANCOM_IRQ_CONTROL_STATUS_REG);
- break;
- default:
- break;
- }
- return cb7210_locked_internal_interrupt(arg);
-}
-
-static irqreturn_t cb7210_internal_interrupt(struct gpib_board *board)
-{
- int hs_status, status1, status2;
- struct cb7210_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- int clear_bits;
-
- if ((priv->hs_mode_bits & HS_ENABLE_MASK)) {
- status1 = 0;
- hs_status = cb7210_read_byte(priv, HS_STATUS);
- } else {
- hs_status = 0;
- status1 = read_byte(nec_priv, ISR1);
- }
- status2 = read_byte(nec_priv, ISR2);
- nec7210_interrupt_have_status(board, nec_priv, status1, status2);
-
- dev_dbg(board->gpib_dev, "status 0x%x, mode 0x%x\n", hs_status, priv->hs_mode_bits);
-
- clear_bits = 0;
-
- if (hs_status & HS_HALF_FULL) {
- if (priv->hs_mode_bits & HS_TX_ENABLE)
- priv->out_fifo_half_empty = 1;
- else if (priv->hs_mode_bits & HS_RX_ENABLE)
- priv->in_fifo_half_full = 1;
- clear_bits |= HS_CLR_HF_INT;
- }
-
- if (hs_status & HS_SRQ_INT) {
- set_bit(SRQI_NUM, &board->status);
- clear_bits |= HS_CLR_SRQ_INT;
- }
-
- if ((hs_status & HS_EOI_INT)) {
- clear_bits |= HS_CLR_EOI_EMPTY_INT;
- set_bit(RECEIVED_END_BN, &nec_priv->state);
- if ((nec_priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDE)
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- }
-
- if ((priv->hs_mode_bits & HS_TX_ENABLE) &&
- (hs_status & (HS_TX_MSB_NOT_EMPTY | HS_TX_LSB_NOT_EMPTY)) == 0)
- clear_bits |= HS_CLR_EOI_EMPTY_INT;
-
- if (clear_bits) {
- cb7210_write_byte(priv, priv->hs_mode_bits | clear_bits, HS_MODE);
- cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE);
- wake_up_interruptible(&board->wait);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t cb7210_locked_internal_interrupt(struct gpib_board *board)
-{
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = cb7210_internal_interrupt(board);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-static irqreturn_t cb7210_interrupt(int irq, void *arg)
-{
- return cb7210_internal_interrupt(arg);
-}
-
-static int cb_pci_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_config *config);
-
-static void cb_pci_detach(struct gpib_board *board);
-static void cb_isa_detach(struct gpib_board *board);
-
-// wrappers for interface functions
-static int cb7210_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-}
-
-static int cb7210_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int cb7210_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int cb7210_take_control(struct gpib_board *board, int synchronous)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int cb7210_go_to_standby(struct gpib_board *board)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int cb7210_request_system_control(struct gpib_board *board, int request_control)
-{
- struct cb7210_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- if (request_control)
- priv->hs_mode_bits |= HS_SYS_CONTROL;
- else
- priv->hs_mode_bits &= ~HS_SYS_CONTROL;
-
- cb7210_write_byte(priv, priv->hs_mode_bits, HS_MODE);
- return nec7210_request_system_control(board, nec_priv, request_control);
-}
-
-static void cb7210_interface_clear(struct gpib_board *board, int assert)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void cb7210_remote_enable(struct gpib_board *board, int enable)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int cb7210_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void cb7210_disable_eos(struct gpib_board *board)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int cb7210_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int cb7210_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int cb7210_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int cb7210_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void cb7210_parallel_poll_configure(struct gpib_board *board, u8 configuration)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
-}
-
-static void cb7210_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void cb7210_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct cb7210_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static u8 cb7210_serial_poll_status(struct gpib_board *board)
-{
- struct cb7210_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static void cb7210_return_to_local(struct gpib_board *board)
-{
- struct cb7210_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- write_byte(nec_priv, AUX_RTL2, AUXMR);
- udelay(1);
- write_byte(nec_priv, AUX_RTL, AUXMR);
-}
-
-static struct gpib_interface cb_pci_unaccel_interface = {
- .name = "cbi_pci_unaccel",
- .attach = cb_pci_attach,
- .detach = cb_pci_detach,
- .read = cb7210_read,
- .write = cb7210_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_pci_accel_interface = {
- .name = "cbi_pci_accel",
- .attach = cb_pci_attach,
- .detach = cb_pci_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_pci_interface = {
- .name = "cbi_pci",
- .attach = cb_pci_attach,
- .detach = cb_pci_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_isa_unaccel_interface = {
- .name = "cbi_isa_unaccel",
- .attach = cb_isa_attach,
- .detach = cb_isa_detach,
- .read = cb7210_read,
- .write = cb7210_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_isa_interface = {
- .name = "cbi_isa",
- .attach = cb_isa_attach,
- .detach = cb_isa_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_isa_accel_interface = {
- .name = "cbi_isa_accel",
- .attach = cb_isa_attach,
- .detach = cb_isa_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static int cb7210_allocate_private(struct gpib_board *board)
-{
- struct cb7210_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct cb7210_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct cb7210_priv));
- init_nec7210_private(&priv->nec7210_priv);
- return 0;
-}
-
-static void cb7210_generic_detach(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-// generic part of attach functions shared by all cb7210 boards
-static int cb7210_generic_attach(struct gpib_board *board)
-{
- struct cb7210_priv *cb_priv;
- struct nec7210_priv *nec_priv;
-
- board->status = 0;
-
- if (cb7210_allocate_private(board))
- return -ENOMEM;
- cb_priv = board->private_data;
- nec_priv = &cb_priv->nec7210_priv;
- nec_priv->read_byte = nec7210_locking_ioport_read_byte;
- nec_priv->write_byte = nec7210_locking_ioport_write_byte;
- nec_priv->offset = cb7210_reg_offset;
- nec_priv->type = CB7210;
- return 0;
-}
-
-static int cb7210_init(struct cb7210_priv *cb_priv, struct gpib_board *board)
-{
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
-
- cb7210_write_byte(cb_priv, HS_RESET7210, HS_INT_LEVEL);
- cb7210_write_byte(cb_priv, irq_bits(cb_priv->irq), HS_INT_LEVEL);
-
- nec7210_board_reset(nec_priv, board);
- cb7210_write_byte(cb_priv, HS_TX_ENABLE | HS_RX_ENABLE | HS_CLR_SRQ_INT |
- HS_CLR_EOI_EMPTY_INT | HS_CLR_HF_INT, HS_MODE);
-
- cb_priv->hs_mode_bits = HS_HF_INT_EN;
- cb7210_write_byte(cb_priv, cb_priv->hs_mode_bits, HS_MODE);
-
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- /*
- * set clock register for maximum (20 MHz) driving frequency
- * ICR should be set to clock in megahertz (1-15) and to zero
- * for clocks faster than 15 MHz (max 20MHz)
- */
- write_byte(nec_priv, ICR | 0, AUXMR);
-
- if (cb_priv->pci_chip == PCI_CHIP_QUANCOM) {
- /* change interrupt polarity */
- nec_priv->auxb_bits |= HR_INV;
- write_byte(nec_priv, nec_priv->auxb_bits, AUXMR);
- }
- nec7210_board_online(nec_priv, board);
-
- /* poll so we can detect assertion of ATN */
- if (gpib_request_pseudo_irq(board, cb_pci_interrupt)) {
- pr_err("failed to allocate pseudo_irq\n");
- return -1;
- }
- return 0;
-}
-
-static int cb_pci_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct cb7210_priv *cb_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- int bits;
- int retval;
-
- retval = cb7210_generic_attach(board);
- if (retval)
- return retval;
-
- cb_priv = board->private_data;
- nec_priv = &cb_priv->nec7210_priv;
-
- cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_CBOARDS,
- PCI_DEVICE_ID_CBOARDS_PCI_GPIB, NULL);
- if (cb_priv->pci_device)
- cb_priv->pci_chip = PCI_CHIP_AMCC_S5933;
- if (!cb_priv->pci_device) {
- cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_CBOARDS,
- PCI_DEVICE_ID_CBOARDS_CPCI_GPIB, NULL);
- if (cb_priv->pci_device)
- cb_priv->pci_chip = PCI_CHIP_AMCC_S5933;
- }
- if (!cb_priv->pci_device) {
- cb_priv->pci_device = gpib_pci_get_device(config, PCI_VENDOR_ID_QUANCOM,
- PCI_DEVICE_ID_QUANCOM_GPIB, NULL);
- if (cb_priv->pci_device) {
- cb_priv->pci_chip = PCI_CHIP_QUANCOM;
- nec_priv->offset = 4;
- }
- }
- if (!cb_priv->pci_device) {
- dev_err(board->gpib_dev, "no supported boards found.\n");
- return -ENODEV;
- }
-
- if (pci_enable_device(cb_priv->pci_device)) {
- dev_err(board->gpib_dev, "error enabling pci device\n");
- return -EIO;
- }
-
- if (pci_request_regions(cb_priv->pci_device, DRV_NAME))
- return -EBUSY;
- switch (cb_priv->pci_chip) {
- case PCI_CHIP_AMCC_S5933:
- cb_priv->amcc_iobase = pci_resource_start(cb_priv->pci_device, 0);
- nec_priv->iobase = pci_resource_start(cb_priv->pci_device, 1);
- cb_priv->fifo_iobase = pci_resource_start(cb_priv->pci_device, 2);
- break;
- case PCI_CHIP_QUANCOM:
- nec_priv->iobase = pci_resource_start(cb_priv->pci_device, 0);
- cb_priv->fifo_iobase = nec_priv->iobase;
- break;
- default:
- dev_err(board->gpib_dev, "bug! unhandled pci_chip=%i\n", cb_priv->pci_chip);
- return -EIO;
- }
- isr_flags |= IRQF_SHARED;
- if (request_irq(cb_priv->pci_device->irq, cb_pci_interrupt, isr_flags, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n",
- cb_priv->pci_device->irq);
- return -EBUSY;
- }
- cb_priv->irq = cb_priv->pci_device->irq;
-
- switch (cb_priv->pci_chip) {
- case PCI_CHIP_AMCC_S5933:
- // make sure mailbox flags are clear
- inl(cb_priv->amcc_iobase + INCOMING_MAILBOX_REG(3));
- // enable interrupts on amccs5933 chip
- bits = INBOX_FULL_INTR_BIT | INBOX_BYTE_BITS(3) | INBOX_SELECT_BITS(3) |
- INBOX_INTR_CS_BIT;
- outl(bits, cb_priv->amcc_iobase + INTCSR_REG);
- break;
- default:
- break;
- }
- return cb7210_init(cb_priv, board);
-}
-
-static void cb_pci_detach(struct gpib_board *board)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (cb_priv) {
- gpib_free_pseudo_irq(board);
- nec_priv = &cb_priv->nec7210_priv;
- if (cb_priv->irq) {
- // disable amcc interrupts
- outl(0, cb_priv->amcc_iobase + INTCSR_REG);
- free_irq(cb_priv->irq, board);
- }
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- pci_release_regions(cb_priv->pci_device);
- }
- if (cb_priv->pci_device)
- pci_dev_put(cb_priv->pci_device);
- }
- cb7210_generic_detach(board);
-}
-
-static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- int isr_flags = 0;
- struct cb7210_priv *cb_priv;
- struct nec7210_priv *nec_priv;
- unsigned int bits;
- int retval;
-
- retval = cb7210_generic_attach(board);
- if (retval)
- return retval;
- cb_priv = board->private_data;
- nec_priv = &cb_priv->nec7210_priv;
- if (!request_region(config->ibbase, cb7210_iosize, DRV_NAME)) {
- dev_err(board->gpib_dev, "ioports starting at 0x%x are already in use\n",
- config->ibbase);
- return -EBUSY;
- }
- nec_priv->iobase = config->ibbase;
- cb_priv->fifo_iobase = nec7210_iobase(cb_priv);
-
- bits = irq_bits(config->ibirq);
- if (bits == 0)
- dev_err(board->gpib_dev, "board incapable of using irq %i, try 2-5, 7, 10, or 11\n",
- config->ibirq);
-
- // install interrupt handler
- if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", config->ibirq);
- return -EBUSY;
- }
- cb_priv->irq = config->ibirq;
-
- return cb7210_init(cb_priv, board);
-}
-
-static void cb_isa_detach(struct gpib_board *board)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (cb_priv) {
- gpib_free_pseudo_irq(board);
- nec_priv = &cb_priv->nec7210_priv;
- if (cb_priv->irq)
- free_irq(cb_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- release_region(nec7210_iobase(cb_priv), cb7210_iosize);
- }
- }
- cb7210_generic_detach(board);
-}
-
-static int cb7210_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return 0;
-}
-
-static const struct pci_device_id cb7210_pci_table[] = {
- {PCI_VENDOR_ID_CBOARDS, PCI_DEVICE_ID_CBOARDS_PCI_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- {PCI_VENDOR_ID_CBOARDS, PCI_DEVICE_ID_CBOARDS_CPCI_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- {PCI_VENDOR_ID_QUANCOM, PCI_DEVICE_ID_QUANCOM_GPIB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb7210_pci_table);
-
-static struct pci_driver cb7210_pci_driver = {
- .name = DRV_NAME,
- .id_table = cb7210_pci_table,
- .probe = &cb7210_pci_probe
-};
-
-/***************************************************************************
- * Support for computer boards pcmcia-gpib card
- *
- * Based on gpib PCMCIA client driver written by Claus Schroeter
- * (clausi@chemie.fu-berlin.de), which was adapted from the
- * pcmcia skeleton example (presumably David Hinds)
- ***************************************************************************/
-
-#ifdef CONFIG_GPIB_PCMCIA
-
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-/*
- * The event() function is this driver's Card Services event handler.
- * It will be called by Card Services when an appropriate card status
- * event is received. The config() and release() entry points are
- * used to configure or release a socket, in response to card insertion
- * and ejection events. They are invoked from the gpib event
- * handler.
- */
-
-static int cb_gpib_config(struct pcmcia_device *link);
-static void cb_gpib_release(struct pcmcia_device *link);
-static int cb_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static void cb_pcmcia_detach(struct gpib_board *board);
-
-/*
- * A linked list of "instances" of the gpib device. Each actual
- * PCMCIA card corresponds to one device instance, and is described
- * by one dev_link_t structure (defined in ds.h).
- *
- * You may not want to use a linked list for this -- for example, the
- * memory card driver uses an array of dev_link_t pointers, where minor
- * device numbers are used to derive the corresponding array index.
- */
-
-static struct pcmcia_device *curr_dev;
-
-/*
- * A dev_link_t structure has fields for most things that are needed
- * to keep track of a socket, but there will usually be some device
- * specific information that also needs to be kept track of. The
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
- * A driver needs to provide a dev_node_t structure for each device
- * on a card. In some cases, there is only one device per card (for
- * example, ethernet cards, modems). In other cases, there may be
- * many actual or logical devices (SCSI adapters, memory cards with
- * multiple partitions). The dev_node_t structures need to be kept
- * in a linked list starting at the 'dev' field of a dev_link_t
- * structure. We allocate them in the card's private data structure,
- * because they generally can't be allocated dynamically.
- */
-
-struct local_info {
- struct pcmcia_device *p_dev;
- struct gpib_board *dev;
-};
-
-/*
- * gpib_attach() creates an "instance" of the driver, allocating
- * local data structures for one device. The device is registered
- * with Card Services.
- *
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a
- * card insertion event.
- */
-
-static int cb_gpib_probe(struct pcmcia_device *link)
-{
- struct local_info *info;
- int ret;
-
- /* Allocate space for private device-specific data */
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- /* The io structure describes IO port mapping */
- link->resource[0]->end = 16;
- link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
- link->resource[1]->end = 16;
- link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
- link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
- link->io_lines = 10;
-
- /* General socket configuration */
- link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
- link->config_index = 1;
- link->config_regs = PRESENT_OPTION;
-
- /* Register with Card Services */
- curr_dev = link;
- ret = cb_gpib_config(link);
- if (ret)
- goto free_info;
-
- return 0;
-
-free_info:
- kfree(info);
- return ret;
-}
-
-/*
- * This deletes a driver "instance". The device is de-registered
- * with Card Services. If it has been released, all local data
- * structures are freed. Otherwise, the structures will be freed
- * when the device is released.
- */
-
-static void cb_gpib_remove(struct pcmcia_device *link)
-{
- struct local_info *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (info->dev)
- cb_pcmcia_detach(info->dev);
- cb_gpib_release(link);
-
- //free_netdev(dev);
- kfree(info);
-}
-
-static int cb_gpib_config_iteration(struct pcmcia_device *link, void *priv_data)
-{
- return pcmcia_request_io(link);
-}
-
-/*
- * gpib_config() is scheduled to run after a CARD_INSERTION event
- * is received, to configure the PCMCIA socket, and to make the
- * ethernet device available to the system.
- */
-
-static int cb_gpib_config(struct pcmcia_device *link)
-{
- int retval;
-
- retval = pcmcia_loop_config(link, &cb_gpib_config_iteration, NULL);
- if (retval) {
- dev_warn(&link->dev, "no configuration found\n");
- cb_gpib_release(link);
- return -ENODEV;
- }
-
- /*
- * This actually configures the PCMCIA socket -- setting up
- * the I/O windows and the interrupt mapping.
- */
- retval = pcmcia_enable_device(link);
- if (retval) {
- dev_warn(&link->dev, "pcmcia_enable_device failed\n");
- cb_gpib_release(link);
- return -ENODEV;
- }
-
- return 0;
-} /* gpib_config */
-
-/*
- * After a card is removed, gpib_release() will unregister the net
- * device, and release the PCMCIA configuration. If the device is
- * still open, this will be postponed until it is closed.
- */
-
-static void cb_gpib_release(struct pcmcia_device *link)
-{
- pcmcia_disable_device(link);
-}
-
-static int cb_gpib_suspend(struct pcmcia_device *link)
-{
- //struct local_info *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (link->open)
- dev_warn(&link->dev, "Device still open\n");
- //netif_device_detach(dev);
-
- return 0;
-}
-
-static int cb_gpib_resume(struct pcmcia_device *link)
-{
- //struct local_info *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- /*if (link->open) {
- * ni_gpib_probe(dev); / really?
- * //netif_device_attach(dev);
- *
- */
- return cb_gpib_config(link);
-}
-
-/*====================================================================*/
-
-static struct pcmcia_device_id cb_pcmcia_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0005),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, cb_pcmcia_ids);
-
-static struct pcmcia_driver cb_gpib_cs_driver = {
- .name = "cb_gpib_cs",
- .owner = THIS_MODULE,
- .id_table = cb_pcmcia_ids,
- .probe = cb_gpib_probe,
- .remove = cb_gpib_remove,
- .suspend = cb_gpib_suspend,
- .resume = cb_gpib_resume,
-};
-
-static void cb_pcmcia_cleanup_module(void)
-{
- pcmcia_unregister_driver(&cb_gpib_cs_driver);
-}
-
-static struct gpib_interface cb_pcmcia_unaccel_interface = {
- .name = "cbi_pcmcia_unaccel",
- .attach = cb_pcmcia_attach,
- .detach = cb_pcmcia_detach,
- .read = cb7210_read,
- .write = cb7210_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_pcmcia_interface = {
- .name = "cbi_pcmcia",
- .attach = cb_pcmcia_attach,
- .detach = cb_pcmcia_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static struct gpib_interface cb_pcmcia_accel_interface = {
- .name = "cbi_pcmcia_accel",
- .attach = cb_pcmcia_attach,
- .detach = cb_pcmcia_detach,
- .read = cb7210_accel_read,
- .write = cb7210_accel_write,
- .command = cb7210_command,
- .take_control = cb7210_take_control,
- .go_to_standby = cb7210_go_to_standby,
- .request_system_control = cb7210_request_system_control,
- .interface_clear = cb7210_interface_clear,
- .remote_enable = cb7210_remote_enable,
- .enable_eos = cb7210_enable_eos,
- .disable_eos = cb7210_disable_eos,
- .parallel_poll = cb7210_parallel_poll,
- .parallel_poll_configure = cb7210_parallel_poll_configure,
- .parallel_poll_response = cb7210_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = cb7210_line_status,
- .update_status = cb7210_update_status,
- .primary_address = cb7210_primary_address,
- .secondary_address = cb7210_secondary_address,
- .serial_poll_response = cb7210_serial_poll_response,
- .serial_poll_status = cb7210_serial_poll_status,
- .t1_delay = cb7210_t1_delay,
- .return_to_local = cb7210_return_to_local,
-};
-
-static int cb_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct cb7210_priv *cb_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- if (!curr_dev) {
- dev_err(board->gpib_dev, "no cb pcmcia cards found\n");
- return -ENODEV;
- }
-
- retval = cb7210_generic_attach(board);
- if (retval)
- return retval;
-
- cb_priv = board->private_data;
- nec_priv = &cb_priv->nec7210_priv;
-
- if (!request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]),
- DRV_NAME)) {
- dev_err(board->gpib_dev, "ioports starting at 0x%lx are already in use\n",
- (unsigned long)curr_dev->resource[0]->start);
- return -EBUSY;
- }
- nec_priv->iobase = curr_dev->resource[0]->start;
- cb_priv->fifo_iobase = curr_dev->resource[0]->start;
-
- if (request_irq(curr_dev->irq, cb7210_interrupt, IRQF_SHARED, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to request IRQ %d\n", curr_dev->irq);
- return -EBUSY;
- }
- cb_priv->irq = curr_dev->irq;
-
- return cb7210_init(cb_priv, board);
-}
-
-static void cb_pcmcia_detach(struct gpib_board *board)
-{
- struct cb7210_priv *cb_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (cb_priv) {
- nec_priv = &cb_priv->nec7210_priv;
- gpib_free_pseudo_irq(board);
- if (cb_priv->irq)
- free_irq(cb_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- release_region(nec7210_iobase(cb_priv), cb7210_iosize);
- }
- }
- cb7210_generic_detach(board);
-}
-
-#endif /* CONFIG_GPIB_PCMCIA */
-
-static int __init cb7210_init_module(void)
-{
- int ret;
-
- ret = pci_register_driver(&cb7210_pci_driver);
- if (ret) {
- pr_err("pci_register_driver failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&cb_pci_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci;
- }
-
- ret = gpib_register_driver(&cb_isa_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_isa;
- }
-
- ret = gpib_register_driver(&cb_pci_accel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci_accel;
- }
-
- ret = gpib_register_driver(&cb_pci_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci_unaccel;
- }
-
- ret = gpib_register_driver(&cb_isa_accel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_isa_accel;
- }
-
- ret = gpib_register_driver(&cb_isa_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_isa_unaccel;
- }
-
-#ifdef CONFIG_GPIB_PCMCIA
- ret = gpib_register_driver(&cb_pcmcia_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia;
- }
-
- ret = gpib_register_driver(&cb_pcmcia_accel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_accel;
- }
-
- ret = gpib_register_driver(&cb_pcmcia_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_unaccel;
- }
-
- ret = pcmcia_register_driver(&cb_gpib_cs_driver);
- if (ret) {
- pr_err("pcmcia_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_driver;
- }
-#endif
-
- return 0;
-
-#ifdef CONFIG_GPIB_PCMCIA
-err_pcmcia_driver:
- gpib_unregister_driver(&cb_pcmcia_unaccel_interface);
-err_pcmcia_unaccel:
- gpib_unregister_driver(&cb_pcmcia_accel_interface);
-err_pcmcia_accel:
- gpib_unregister_driver(&cb_pcmcia_interface);
-err_pcmcia:
-#endif
- gpib_unregister_driver(&cb_isa_unaccel_interface);
-err_isa_unaccel:
- gpib_unregister_driver(&cb_isa_accel_interface);
-err_isa_accel:
- gpib_unregister_driver(&cb_pci_unaccel_interface);
-err_pci_unaccel:
- gpib_unregister_driver(&cb_pci_accel_interface);
-err_pci_accel:
- gpib_unregister_driver(&cb_isa_interface);
-err_isa:
- gpib_unregister_driver(&cb_pci_interface);
-err_pci:
- pci_unregister_driver(&cb7210_pci_driver);
-
- return ret;
-}
-
-static void __exit cb7210_exit_module(void)
-{
- gpib_unregister_driver(&cb_pci_interface);
- gpib_unregister_driver(&cb_isa_interface);
- gpib_unregister_driver(&cb_pci_accel_interface);
- gpib_unregister_driver(&cb_pci_unaccel_interface);
- gpib_unregister_driver(&cb_isa_accel_interface);
- gpib_unregister_driver(&cb_isa_unaccel_interface);
-#ifdef CONFIG_GPIB_PCMCIA
- gpib_unregister_driver(&cb_pcmcia_interface);
- gpib_unregister_driver(&cb_pcmcia_accel_interface);
- gpib_unregister_driver(&cb_pcmcia_unaccel_interface);
- cb_pcmcia_cleanup_module();
-#endif
-
- pci_unregister_driver(&cb7210_pci_driver);
-}
-
-module_init(cb7210_init_module);
-module_exit(cb7210_exit_module);
diff --git a/drivers/staging/gpib/cb7210/cb7210.h b/drivers/staging/gpib/cb7210/cb7210.h
deleted file mode 100644
index ddc841ff87ae..000000000000
--- a/drivers/staging/gpib/cb7210/cb7210.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#include "nec7210.h"
-#include "gpibP.h"
-#include "amccs5933.h"
-
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-enum {
- PCI_DEVICE_ID_CBOARDS_PCI_GPIB = 0x6,
- PCI_DEVICE_ID_CBOARDS_CPCI_GPIB = 0xe,
-};
-
-enum pci_chip {
- PCI_CHIP_NONE = 0,
- PCI_CHIP_AMCC_S5933,
- PCI_CHIP_QUANCOM
-};
-
-// struct which defines private_data for cb7210 boards
-struct cb7210_priv {
- struct nec7210_priv nec7210_priv;
- struct pci_dev *pci_device;
- // base address of amccs5933 pci chip
- unsigned long amcc_iobase;
- unsigned long fifo_iobase;
- unsigned int irq;
- enum pci_chip pci_chip;
- u8 hs_mode_bits;
- unsigned out_fifo_half_empty : 1;
- unsigned in_fifo_half_full : 1;
-};
-
-// pci-gpib register offset
-static const int cb7210_reg_offset = 1;
-
-// uses 10 ioports
-static const int cb7210_iosize = 10;
-
-// fifo size in bytes
-static const int cb7210_fifo_size = 2048;
-static const int cb7210_fifo_width = 2;
-
-// cb7210 specific registers and bits
-enum cb7210_regs {
- BUS_STATUS = 0x7,
-};
-
-enum cb7210_page_in {
- BUS_STATUS_PAGE = 1,
-};
-
-enum hs_regs {
- // write registers
- HS_MODE = 0x8, /* HS_MODE register */
- HS_INT_LEVEL = 0x9, /* HS_INT_LEVEL register */
- // read registers
- HS_STATUS = 0x8, /* HS_STATUS register */
-};
-
-static inline u32 nec7210_iobase(const struct cb7210_priv *cb_priv)
-{
- return cb_priv->nec7210_priv.iobase;
-}
-
-static inline int cb7210_page_in_bits(unsigned int page)
-{
- return 0x50 | (page & 0xf);
-}
-
-static inline u8 cb7210_paged_read_byte(struct cb7210_priv *cb_priv,
- unsigned int register_num, unsigned int page)
-{
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- u8 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset);
- udelay(1);
- retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
- return retval;
-}
-
-// don't use for register_num < 8, since it doesn't lock
-static inline u8 cb7210_read_byte(const struct cb7210_priv *cb_priv,
- enum hs_regs register_num)
-{
- const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- u8 retval;
-
- retval = inb(nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
- return retval;
-}
-
-static inline void cb7210_paged_write_byte(struct cb7210_priv *cb_priv, u8 data,
- unsigned int register_num, unsigned int page)
-{
- struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- outb(cb7210_page_in_bits(page), nec7210_iobase(cb_priv) + AUXMR * nec_priv->offset);
- udelay(1);
- outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
-}
-
-// don't use for register_num < 8, since it doesn't lock
-static inline void cb7210_write_byte(const struct cb7210_priv *cb_priv, u8 data,
- enum hs_regs register_num)
-{
- const struct nec7210_priv *nec_priv = &cb_priv->nec7210_priv;
-
- outb(data, nec7210_iobase(cb_priv) + register_num * nec_priv->offset);
-}
-
-enum bus_status_bits {
- BSR_ATN_BIT = 0x1,
- BSR_EOI_BIT = 0x2,
- BSR_SRQ_BIT = 0x4,
- BSR_IFC_BIT = 0x8,
- BSR_REN_BIT = 0x10,
- BSR_DAV_BIT = 0x20,
- BSR_NRFD_BIT = 0x40,
- BSR_NDAC_BIT = 0x80,
-};
-
-/* CBI 488.2 HS control */
-
-/*
- * when both bit 0 and 1 are set, it
- * 1 clears the transmit state machine to an initial condition
- * 2 clears any residual interrupts left latched on cbi488.2
- * 3 resets all control bits in HS_MODE to zero
- * 4 enables TX empty interrupts
- * when both bit 0 and 1 are zero, then the high speed mode is disabled
- */
-enum hs_mode_bits {
- HS_ENABLE_MASK = 0x3,
- HS_TX_ENABLE = (1 << 0),
- HS_RX_ENABLE = (1 << 1),
- HS_HF_INT_EN = (1 << 3),
- HS_CLR_SRQ_INT = (1 << 4),
- HS_CLR_EOI_EMPTY_INT = (1 << 5),
- HS_CLR_HF_INT = (1 << 6),
- HS_SYS_CONTROL = (1 << 7),
-};
-
-/* CBI 488.2 status */
-enum hs_status_bits {
- HS_FIFO_FULL = (1 << 0),
- HS_HALF_FULL = (1 << 1),
- HS_SRQ_INT = (1 << 2),
- HS_EOI_INT = (1 << 3),
- HS_TX_MSB_NOT_EMPTY = (1 << 4),
- HS_RX_MSB_NOT_EMPTY = (1 << 5),
- HS_TX_LSB_NOT_EMPTY = (1 << 6),
- HS_RX_LSB_NOT_EMPTY = (1 << 7),
-};
-
-/* CBI488.2 hs_int_level register */
-enum hs_int_level_bits {
- HS_RESET7210 = (1 << 7),
-};
-
-static inline unsigned int irq_bits(unsigned int irq)
-{
- switch (irq) {
- case 2:
- case 3:
- case 4:
- case 5:
- return irq - 1;
- case 7:
- return 0x5;
- case 10:
- return 0x6;
- case 11:
- return 0x7;
- default:
- return 0;
- }
-}
-
-enum cb7210_aux_cmds {
-/*
- * AUX_RTL2 is an undocumented aux command which causes cb7210 to assert
- * (and keep asserted) local rtl message. This is used in conjunction
- * with the (stupid) cb7210 implementation
- * of the normal nec7210 AUX_RTL aux command, which
- * causes the rtl message to toggle between on and off.
- */
- AUX_RTL2 = 0xd,
- AUX_LO_SPEED = 0x40,
- AUX_HI_SPEED = 0x41,
-};
diff --git a/drivers/staging/gpib/cec/Makefile b/drivers/staging/gpib/cec/Makefile
deleted file mode 100644
index b7141e23d4e0..000000000000
--- a/drivers/staging/gpib/cec/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-
-obj-$(CONFIG_GPIB_CEC_PCI) += cec_gpib.o
-
diff --git a/drivers/staging/gpib/cec/cec.h b/drivers/staging/gpib/cec/cec.h
deleted file mode 100644
index 3ce2869c7429..000000000000
--- a/drivers/staging/gpib/cec/cec.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#include "nec7210.h"
-#include "gpibP.h"
-#include "plx9050.h"
-
-struct cec_priv {
- struct nec7210_priv nec7210_priv;
- struct pci_dev *pci_device;
- // base address for plx9052 pci chip
- unsigned long plx_iobase;
- unsigned int irq;
-};
-
-// offset between consecutive nec7210 registers
-static const int cec_reg_offset = 1;
diff --git a/drivers/staging/gpib/cec/cec_gpib.c b/drivers/staging/gpib/cec/cec_gpib.c
deleted file mode 100644
index dbf9b95baabc..000000000000
--- a/drivers/staging/gpib/cec/cec_gpib.c
+++ /dev/null
@@ -1,393 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "cec.h"
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/bitops.h>
-#include <asm/dma.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for CEC PCI and PCMCIA boards");
-
-/*
- * GPIB interrupt service routines
- */
-
-static irqreturn_t cec_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct cec_priv *priv = board->private_data;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = nec7210_interrupt(board, &priv->nec7210_priv);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-#define CEC_VENDOR_ID 0x12fc
-#define CEC_DEV_ID 0x5cec
-#define CEC_SUBID 0x9050
-
-static int cec_pci_attach(struct gpib_board *board, const struct gpib_board_config *config);
-
-static void cec_pci_detach(struct gpib_board *board);
-
-// wrappers for interface functions
-static int cec_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-}
-
-static int cec_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int cec_command(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int cec_take_control(struct gpib_board *board, int synchronous)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int cec_go_to_standby(struct gpib_board *board)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int cec_request_system_control(struct gpib_board *board, int request_control)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
-}
-
-static void cec_interface_clear(struct gpib_board *board, int assert)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void cec_remote_enable(struct gpib_board *board, int enable)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int cec_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void cec_disable_eos(struct gpib_board *board)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int cec_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int cec_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int cec_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int cec_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void cec_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
-}
-
-static void cec_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void cec_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static u8 cec_serial_poll_status(struct gpib_board *board)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static int cec_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct cec_priv *priv = board->private_data;
-
- return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec);
-}
-
-static void cec_return_to_local(struct gpib_board *board)
-{
- struct cec_priv *priv = board->private_data;
-
- nec7210_return_to_local(board, &priv->nec7210_priv);
-}
-
-static struct gpib_interface cec_pci_interface = {
- .name = "cec_pci",
- .attach = cec_pci_attach,
- .detach = cec_pci_detach,
- .read = cec_read,
- .write = cec_write,
- .command = cec_command,
- .take_control = cec_take_control,
- .go_to_standby = cec_go_to_standby,
- .request_system_control = cec_request_system_control,
- .interface_clear = cec_interface_clear,
- .remote_enable = cec_remote_enable,
- .enable_eos = cec_enable_eos,
- .disable_eos = cec_disable_eos,
- .parallel_poll = cec_parallel_poll,
- .parallel_poll_configure = cec_parallel_poll_configure,
- .parallel_poll_response = cec_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL, // XXX
- .update_status = cec_update_status,
- .primary_address = cec_primary_address,
- .secondary_address = cec_secondary_address,
- .serial_poll_response = cec_serial_poll_response,
- .serial_poll_status = cec_serial_poll_status,
- .t1_delay = cec_t1_delay,
- .return_to_local = cec_return_to_local,
-};
-
-static int cec_allocate_private(struct gpib_board *board)
-{
- struct cec_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct cec_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct cec_priv));
- init_nec7210_private(&priv->nec7210_priv);
- return 0;
-}
-
-static void cec_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static int cec_generic_attach(struct gpib_board *board)
-{
- struct cec_priv *cec_priv;
- struct nec7210_priv *nec_priv;
-
- board->status = 0;
-
- if (cec_allocate_private(board))
- return -ENOMEM;
- cec_priv = board->private_data;
- nec_priv = &cec_priv->nec7210_priv;
- nec_priv->read_byte = nec7210_ioport_read_byte;
- nec_priv->write_byte = nec7210_ioport_write_byte;
- nec_priv->offset = cec_reg_offset;
- nec_priv->type = NEC7210; // guess
- return 0;
-}
-
-static void cec_init(struct cec_priv *cec_priv, const struct gpib_board *board)
-{
- struct nec7210_priv *nec_priv = &cec_priv->nec7210_priv;
-
- nec7210_board_reset(nec_priv, board);
-
- /* set internal counter register for 8 MHz input clock */
- write_byte(nec_priv, ICR | 8, AUXMR);
-
- nec7210_board_online(nec_priv, board);
-}
-
-static int cec_pci_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct cec_priv *cec_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- int retval;
-
- retval = cec_generic_attach(board);
- if (retval)
- return retval;
-
- cec_priv = board->private_data;
- nec_priv = &cec_priv->nec7210_priv;
-
- // find board
- cec_priv->pci_device = NULL;
- while ((cec_priv->pci_device =
- gpib_pci_get_device(config, CEC_VENDOR_ID,
- CEC_DEV_ID, cec_priv->pci_device))) {
- // check for board with plx9050 controller
- if (cec_priv->pci_device->subsystem_device == CEC_SUBID)
- break;
- }
- if (!cec_priv->pci_device) {
- dev_err(board->gpib_dev, "no cec PCI board found\n");
- return -ENODEV;
- }
-
- if (pci_enable_device(cec_priv->pci_device)) {
- dev_err(board->gpib_dev, "error enabling pci device\n");
- return -EIO;
- }
-
- if (pci_request_regions(cec_priv->pci_device, "cec-gpib"))
- return -EBUSY;
-
- cec_priv->plx_iobase = pci_resource_start(cec_priv->pci_device, 1);
- nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3);
-
- isr_flags |= IRQF_SHARED;
- if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", cec_priv->pci_device->irq);
- return -EBUSY;
- }
- cec_priv->irq = cec_priv->pci_device->irq;
- if (gpib_request_pseudo_irq(board, cec_interrupt)) {
- dev_err(board->gpib_dev, "failed to allocate pseudo irq\n");
- return -1;
- }
- cec_init(cec_priv, board);
-
- // enable interrupts on plx chip
- outl(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR1_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT,
- cec_priv->plx_iobase + PLX9050_INTCSR_REG);
-
- return 0;
-}
-
-static void cec_pci_detach(struct gpib_board *board)
-{
- struct cec_priv *cec_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (cec_priv) {
- nec_priv = &cec_priv->nec7210_priv;
- gpib_free_pseudo_irq(board);
- if (cec_priv->irq) {
- // disable plx9050 interrupts
- outl(0, cec_priv->plx_iobase + PLX9050_INTCSR_REG);
- free_irq(cec_priv->irq, board);
- }
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- pci_release_regions(cec_priv->pci_device);
- }
- if (cec_priv->pci_device)
- pci_dev_put(cec_priv->pci_device);
- }
- cec_free_private(board);
-}
-
-static int cec_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return 0;
-}
-
-static const struct pci_device_id cec_pci_table[] = {
- {CEC_VENDOR_ID, CEC_DEV_ID, PCI_ANY_ID, CEC_SUBID, 0, 0, 0 },
- {0}
-};
-MODULE_DEVICE_TABLE(pci, cec_pci_table);
-
-static struct pci_driver cec_pci_driver = {
- .name = DRV_NAME,
- .id_table = cec_pci_table,
- .probe = &cec_pci_probe
-};
-
-static int __init cec_init_module(void)
-{
- int result;
-
- result = pci_register_driver(&cec_pci_driver);
- if (result) {
- pr_err("pci_register_driver failed: error = %d\n", result);
- return result;
- }
-
- result = gpib_register_driver(&cec_pci_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- return result;
- }
-
- return 0;
-}
-
-static void cec_exit_module(void)
-{
- gpib_unregister_driver(&cec_pci_interface);
-
- pci_unregister_driver(&cec_pci_driver);
-}
-
-module_init(cec_init_module);
-module_exit(cec_exit_module);
diff --git a/drivers/staging/gpib/common/Makefile b/drivers/staging/gpib/common/Makefile
deleted file mode 100644
index 460586edb574..000000000000
--- a/drivers/staging/gpib/common/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-
-obj-$(CONFIG_GPIB_COMMON) += gpib_common.o
-
-gpib_common-objs := gpib_os.o iblib.o
-
-
diff --git a/drivers/staging/gpib/common/gpib_os.c b/drivers/staging/gpib/common/gpib_os.c
deleted file mode 100644
index 9dbbac8b8436..000000000000
--- a/drivers/staging/gpib/common/gpib_os.c
+++ /dev/null
@@ -1,2271 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2001, 2004 by Frank Mori Hess
- ***************************************************************************
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-
-#include "ibsys.h"
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-#include <linux/fcntl.h>
-#include <linux/kmod.h>
-#include <linux/uaccess.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB base support");
-MODULE_ALIAS_CHARDEV_MAJOR(GPIB_CODE);
-
-static int board_type_ioctl(struct gpib_file_private *file_priv,
- struct gpib_board *board, unsigned long arg);
-static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg);
-static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg);
-static int command_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg);
-static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg);
-static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg);
-static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg);
-static int wait_ioctl(struct gpib_file_private *file_priv,
- struct gpib_board *board, unsigned long arg);
-static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg);
-static int online_ioctl(struct gpib_board *board, unsigned long arg);
-static int remote_enable_ioctl(struct gpib_board *board, unsigned long arg);
-static int take_control_ioctl(struct gpib_board *board, unsigned long arg);
-static int line_status_ioctl(struct gpib_board *board, unsigned long arg);
-static int pad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg);
-static int sad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg);
-static int eos_ioctl(struct gpib_board *board, unsigned long arg);
-static int request_service_ioctl(struct gpib_board *board, unsigned long arg);
-static int request_service2_ioctl(struct gpib_board *board, unsigned long arg);
-static int iobase_ioctl(struct gpib_board_config *config, unsigned long arg);
-static int irq_ioctl(struct gpib_board_config *config, unsigned long arg);
-static int dma_ioctl(struct gpib_board_config *config, unsigned long arg);
-static int autospoll_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg);
-static int mutex_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg);
-static int timeout_ioctl(struct gpib_board *board, unsigned long arg);
-static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg);
-static int board_info_ioctl(const struct gpib_board *board, unsigned long arg);
-static int ppc_ioctl(struct gpib_board *board, unsigned long arg);
-static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg);
-static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg);
-static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg);
-static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg);
-static int select_pci_ioctl(struct gpib_board_config *config, unsigned long arg);
-static int select_device_path_ioctl(struct gpib_board_config *config, unsigned long arg);
-static int event_ioctl(struct gpib_board *board, unsigned long arg);
-static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg);
-static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg);
-
-static int cleanup_open_devices(struct gpib_file_private *file_priv, struct gpib_board *board);
-
-static int pop_gpib_event_nolock(struct gpib_board *board,
- struct gpib_event_queue *queue, short *event_type);
-
-/*
- * Timer functions
- */
-
-/* Watchdog timeout routine */
-
-static void watchdog_timeout(struct timer_list *t)
-{
- struct gpib_board *board = timer_container_of(board, t, timer);
-
- set_bit(TIMO_NUM, &board->status);
- wake_up_interruptible(&board->wait);
-}
-
-/* install timer interrupt handler */
-void os_start_timer(struct gpib_board *board, unsigned int usec_timeout)
-/* Starts the timeout task */
-{
- if (timer_pending(&board->timer)) {
- dev_err(board->gpib_dev, "bug! timer already running?\n");
- return;
- }
- clear_bit(TIMO_NUM, &board->status);
-
- if (usec_timeout > 0) {
- board->timer.function = watchdog_timeout;
- /* set number of ticks */
- mod_timer(&board->timer, jiffies + usec_to_jiffies(usec_timeout));
- }
-}
-
-void os_remove_timer(struct gpib_board *board)
-/* Removes the timeout task */
-{
- if (timer_pending(&board->timer))
- timer_delete_sync(&board->timer);
-}
-
-int io_timed_out(struct gpib_board *board)
-{
- if (test_bit(TIMO_NUM, &board->status))
- return 1;
- return 0;
-}
-
-/*
- * this is a function instead of a constant because of Suse
- * defining HZ to be a function call to get_hz()
- */
-static inline int pseudo_irq_period(void)
-{
- return (HZ + 99) / 100;
-}
-
-static void pseudo_irq_handler(struct timer_list *t)
-{
- struct gpib_pseudo_irq *pseudo_irq = timer_container_of(pseudo_irq, t,
- timer);
-
- if (pseudo_irq->handler)
- pseudo_irq->handler(0, pseudo_irq->board);
- else
- pr_err("gpib: bug! pseudo_irq.handler is NULL\n");
-
- if (atomic_read(&pseudo_irq->active))
- mod_timer(&pseudo_irq->timer, jiffies + pseudo_irq_period());
-}
-
-int gpib_request_pseudo_irq(struct gpib_board *board, irqreturn_t (*handler)(int, void *))
-{
- if (timer_pending(&board->pseudo_irq.timer) || board->pseudo_irq.handler) {
- dev_err(board->gpib_dev, "only one pseudo interrupt per board allowed\n");
- return -1;
- }
-
- board->pseudo_irq.handler = handler;
- board->pseudo_irq.timer.function = pseudo_irq_handler;
- board->pseudo_irq.board = board;
-
- atomic_set(&board->pseudo_irq.active, 1);
-
- mod_timer(&board->pseudo_irq.timer, jiffies + pseudo_irq_period());
-
- return 0;
-}
-EXPORT_SYMBOL(gpib_request_pseudo_irq);
-
-void gpib_free_pseudo_irq(struct gpib_board *board)
-{
- atomic_set(&board->pseudo_irq.active, 0);
-
- timer_delete_sync(&board->pseudo_irq.timer);
- board->pseudo_irq.handler = NULL;
-}
-EXPORT_SYMBOL(gpib_free_pseudo_irq);
-
-static const unsigned int serial_timeout = 1000000;
-
-unsigned int num_status_bytes(const struct gpib_status_queue *dev)
-{
- if (!dev)
- return 0;
- return dev->num_status_bytes;
-}
-
-// push status byte onto back of status byte fifo
-int push_status_byte(struct gpib_board *board, struct gpib_status_queue *device, u8 poll_byte)
-{
- struct list_head *head = &device->status_bytes;
- struct gpib_status_byte *status;
- static const unsigned int max_num_status_bytes = 1024;
- int retval;
-
- if (num_status_bytes(device) >= max_num_status_bytes) {
- u8 lost_byte;
-
- device->dropped_byte = 1;
- retval = pop_status_byte(board, device, &lost_byte);
- if (retval < 0)
- return retval;
- }
-
- status = kmalloc(sizeof(*status), GFP_KERNEL);
- if (!status)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&status->list);
- status->poll_byte = poll_byte;
-
- list_add_tail(&status->list, head);
-
- device->num_status_bytes++;
-
- dev_dbg(board->gpib_dev, "pushed status byte 0x%x, %i in queue\n",
- (int)poll_byte, num_status_bytes(device));
-
- return 0;
-}
-
-// pop status byte from front of status byte fifo
-int pop_status_byte(struct gpib_board *board, struct gpib_status_queue *device, u8 *poll_byte)
-{
- struct list_head *head = &device->status_bytes;
- struct list_head *front = head->next;
- struct gpib_status_byte *status;
-
- if (num_status_bytes(device) == 0)
- return -EIO;
-
- if (front == head)
- return -EIO;
-
- if (device->dropped_byte) {
- device->dropped_byte = 0;
- return -EPIPE;
- }
-
- status = list_entry(front, struct gpib_status_byte, list);
- *poll_byte = status->poll_byte;
-
- list_del(front);
- kfree(status);
-
- device->num_status_bytes--;
-
- dev_dbg(board->gpib_dev, "popped status byte 0x%x, %i in queue\n",
- (int)*poll_byte, num_status_bytes(device));
-
- return 0;
-}
-
-struct gpib_status_queue *get_gpib_status_queue(struct gpib_board *board, unsigned int pad, int sad)
-{
- struct gpib_status_queue *device;
- struct list_head *list_ptr;
- const struct list_head *head = &board->device_list;
-
- for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) {
- device = list_entry(list_ptr, struct gpib_status_queue, list);
- if (gpib_address_equal(device->pad, device->sad, pad, sad))
- return device;
- }
-
- return NULL;
-}
-
-int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad,
- unsigned int usec_timeout, u8 *poll_byte)
-{
- struct gpib_status_queue *device;
-
- device = get_gpib_status_queue(board, pad, sad);
- if (num_status_bytes(device))
- return pop_status_byte(board, device, poll_byte);
- else
- return dvrsp(board, pad, sad, usec_timeout, poll_byte);
-}
-
-int autopoll_all_devices(struct gpib_board *board)
-{
- int retval;
-
- if (mutex_lock_interruptible(&board->user_mutex))
- return -ERESTARTSYS;
- if (mutex_lock_interruptible(&board->big_gpib_mutex)) {
- mutex_unlock(&board->user_mutex);
- return -ERESTARTSYS;
- }
-
- dev_dbg(board->gpib_dev, "autopoll has board lock\n");
-
- retval = serial_poll_all(board, serial_timeout);
- if (retval < 0) {
- mutex_unlock(&board->big_gpib_mutex);
- mutex_unlock(&board->user_mutex);
- return retval;
- }
-
- dev_dbg(board->gpib_dev, "complete\n");
- /*
- * need to wake wait queue in case someone is
- * waiting on RQS
- */
- wake_up_interruptible(&board->wait);
- mutex_unlock(&board->big_gpib_mutex);
- mutex_unlock(&board->user_mutex);
-
- return retval;
-}
-
-static int setup_serial_poll(struct gpib_board *board, unsigned int usec_timeout)
-{
- u8 cmd_string[8];
- int i;
- size_t bytes_written;
- int ret;
-
- os_start_timer(board, usec_timeout);
- ret = ibcac(board, 1, 1);
- if (ret < 0) {
- os_remove_timer(board);
- return ret;
- }
-
- i = 0;
- cmd_string[i++] = UNL;
- cmd_string[i++] = MLA(board->pad); /* controller's listen address */
- if (board->sad >= 0)
- cmd_string[i++] = MSA(board->sad);
- cmd_string[i++] = SPE; // serial poll enable
-
- ret = board->interface->command(board, cmd_string, i, &bytes_written);
- if (ret < 0 || bytes_written < i) {
- dev_dbg(board->gpib_dev, "failed to setup serial poll\n");
- os_remove_timer(board);
- return -EIO;
- }
- os_remove_timer(board);
-
- return 0;
-}
-
-static int read_serial_poll_byte(struct gpib_board *board, unsigned int pad,
- int sad, unsigned int usec_timeout, u8 *result)
-{
- u8 cmd_string[8];
- int end_flag;
- int ret;
- int i;
- size_t nbytes;
-
- dev_dbg(board->gpib_dev, "entering pad=%i sad=%i\n", pad, sad);
-
- os_start_timer(board, usec_timeout);
- ret = ibcac(board, 1, 1);
- if (ret < 0) {
- os_remove_timer(board);
- return ret;
- }
-
- i = 0;
- // send talk address
- cmd_string[i++] = MTA(pad);
- if (sad >= 0)
- cmd_string[i++] = MSA(sad);
-
- ret = board->interface->command(board, cmd_string, i, &nbytes);
- if (ret < 0 || nbytes < i) {
- dev_err(board->gpib_dev, "failed to setup serial poll\n");
- os_remove_timer(board);
- return -EIO;
- }
-
- ibgts(board);
-
- // read poll result
- ret = board->interface->read(board, result, 1, &end_flag, &nbytes);
- if (ret < 0 || nbytes < 1) {
- dev_err(board->gpib_dev, "serial poll failed\n");
- os_remove_timer(board);
- return -EIO;
- }
- os_remove_timer(board);
-
- return 0;
-}
-
-static int cleanup_serial_poll(struct gpib_board *board, unsigned int usec_timeout)
-{
- u8 cmd_string[8];
- int ret;
- size_t bytes_written;
-
- os_start_timer(board, usec_timeout);
- ret = ibcac(board, 1, 1);
- if (ret < 0) {
- os_remove_timer(board);
- return ret;
- }
-
- cmd_string[0] = SPD; /* disable serial poll bytes */
- cmd_string[1] = UNT;
- ret = board->interface->command(board, cmd_string, 2, &bytes_written);
- if (ret < 0 || bytes_written < 2) {
- dev_err(board->gpib_dev, "failed to disable serial poll\n");
- os_remove_timer(board);
- return -EIO;
- }
- os_remove_timer(board);
-
- return 0;
-}
-
-static int serial_poll_single(struct gpib_board *board, unsigned int pad, int sad,
- unsigned int usec_timeout, u8 *result)
-{
- int retval, cleanup_retval;
-
- retval = setup_serial_poll(board, usec_timeout);
- if (retval < 0)
- return retval;
- retval = read_serial_poll_byte(board, pad, sad, usec_timeout, result);
- cleanup_retval = cleanup_serial_poll(board, usec_timeout);
- if (retval < 0)
- return retval;
- if (cleanup_retval < 0)
- return retval;
-
- return 0;
-}
-
-int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout)
-{
- int retval = 0;
- struct list_head *cur;
- const struct list_head *head = NULL;
- struct gpib_status_queue *device;
- u8 result;
- unsigned int num_bytes = 0;
-
- head = &board->device_list;
- if (head->next == head)
- return 0;
-
- retval = setup_serial_poll(board, usec_timeout);
- if (retval < 0)
- return retval;
-
- for (cur = head->next; cur != head; cur = cur->next) {
- device = list_entry(cur, struct gpib_status_queue, list);
- retval = read_serial_poll_byte(board,
- device->pad, device->sad, usec_timeout, &result);
- if (retval < 0)
- continue;
- if (result & request_service_bit) {
- retval = push_status_byte(board, device, result);
- if (retval < 0)
- continue;
- num_bytes++;
- }
- }
-
- retval = cleanup_serial_poll(board, usec_timeout);
- if (retval < 0)
- return retval;
-
- return num_bytes;
-}
-
-/*
- * DVRSP
- * This function performs a serial poll of the device with primary
- * address pad and secondary address sad. If the device has no
- * secondary address, pass a negative number in for this argument. At the
- * end of a successful serial poll the response is returned in result.
- * SPD and UNT are sent at the completion of the poll.
- */
-
-int dvrsp(struct gpib_board *board, unsigned int pad, int sad,
- unsigned int usec_timeout, u8 *result)
-{
- int status = ibstatus(board);
- int retval;
-
- if ((status & CIC) == 0) {
- dev_err(board->gpib_dev, "not CIC during serial poll\n");
- return -1;
- }
-
- if (pad > MAX_GPIB_PRIMARY_ADDRESS || sad > MAX_GPIB_SECONDARY_ADDRESS || sad < -1) {
- dev_err(board->gpib_dev, "bad address for serial poll");
- return -1;
- }
-
- retval = serial_poll_single(board, pad, sad, usec_timeout, result);
- if (io_timed_out(board))
- retval = -ETIMEDOUT;
-
- return retval;
-}
-
-static struct gpib_descriptor *handle_to_descriptor(const struct gpib_file_private *file_priv,
- int handle)
-{
- if (handle < 0 || handle >= GPIB_MAX_NUM_DESCRIPTORS) {
- pr_err("gpib: invalid handle %i\n", handle);
- return NULL;
- }
-
- return file_priv->descriptors[handle];
-}
-
-static int init_gpib_file_private(struct gpib_file_private *priv)
-{
- memset(priv, 0, sizeof(*priv));
- atomic_set(&priv->holding_mutex, 0);
- priv->descriptors[0] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL);
- if (!priv->descriptors[0]) {
- pr_err("gpib: failed to allocate default board descriptor\n");
- return -ENOMEM;
- }
- init_gpib_descriptor(priv->descriptors[0]);
- priv->descriptors[0]->is_board = 1;
- mutex_init(&priv->descriptors_mutex);
- return 0;
-}
-
-int ibopen(struct inode *inode, struct file *filep)
-{
- unsigned int minor = iminor(inode);
- struct gpib_board *board;
- struct gpib_file_private *priv;
-
- if (minor >= GPIB_MAX_NUM_BOARDS) {
- pr_err("gpib: invalid minor number of device file\n");
- return -ENXIO;
- }
-
- board = &board_array[minor];
-
- filep->private_data = kmalloc(sizeof(struct gpib_file_private), GFP_KERNEL);
- if (!filep->private_data)
- return -ENOMEM;
-
- priv = filep->private_data;
- init_gpib_file_private((struct gpib_file_private *)filep->private_data);
-
- if (board->use_count == 0) {
- int retval;
-
- retval = request_module("gpib%i", minor);
- if (retval)
- dev_dbg(board->gpib_dev, "request module returned %i\n", retval);
- }
- if (board->interface) {
- if (!try_module_get(board->provider_module)) {
- dev_err(board->gpib_dev, "try_module_get() failed\n");
- return -EIO;
- }
- board->use_count++;
- priv->got_module = 1;
- }
- return 0;
-}
-
-int ibclose(struct inode *inode, struct file *filep)
-{
- unsigned int minor = iminor(inode);
- struct gpib_board *board;
- struct gpib_file_private *priv = filep->private_data;
- struct gpib_descriptor *desc;
-
- if (minor >= GPIB_MAX_NUM_BOARDS) {
- pr_err("gpib: invalid minor number of device file\n");
- return -ENODEV;
- }
-
- board = &board_array[minor];
-
- if (priv) {
- desc = handle_to_descriptor(priv, 0);
- if (desc) {
- if (desc->autopoll_enabled) {
- dev_dbg(board->gpib_dev, "decrementing autospollers\n");
- if (board->autospollers > 0)
- board->autospollers--;
- else
- dev_err(board->gpib_dev,
- "Attempt to decrement zero autospollers\n");
- }
- } else {
- dev_err(board->gpib_dev, "Unexpected null gpib_descriptor\n");
- }
-
- cleanup_open_devices(priv, board);
-
- if (atomic_read(&priv->holding_mutex))
- mutex_unlock(&board->user_mutex);
-
- if (priv->got_module && board->use_count) {
- module_put(board->provider_module);
- --board->use_count;
- }
-
- kfree(filep->private_data);
- filep->private_data = NULL;
- }
-
- return 0;
-}
-
-long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
- unsigned int minor = iminor(file_inode(filep));
- struct gpib_board *board;
- struct gpib_file_private *file_priv = filep->private_data;
- long retval = -ENOTTY;
-
- if (minor >= GPIB_MAX_NUM_BOARDS) {
- pr_err("gpib: invalid minor number of device file\n");
- return -ENODEV;
- }
- board = &board_array[minor];
-
- if (mutex_lock_interruptible(&board->big_gpib_mutex))
- return -ERESTARTSYS;
-
- dev_dbg(board->gpib_dev, "ioctl %d, interface=%s, use=%d, onl=%d\n",
- cmd & 0xff,
- board->interface ? board->interface->name : "",
- board->use_count,
- board->online);
-
- switch (cmd) {
- case CFCBOARDTYPE:
- retval = board_type_ioctl(file_priv, board, arg);
- goto done;
- case IBONL:
- retval = online_ioctl(board, arg);
- goto done;
- default:
- break;
- }
- if (!board->interface) {
- dev_err(board->gpib_dev, "no gpib board configured\n");
- retval = -ENODEV;
- goto done;
- }
- if (file_priv->got_module == 0) {
- if (!try_module_get(board->provider_module)) {
- dev_err(board->gpib_dev, "try_module_get() failed\n");
- retval = -EIO;
- goto done;
- }
- file_priv->got_module = 1;
- board->use_count++;
- }
- switch (cmd) {
- case CFCBASE:
- retval = iobase_ioctl(&board->config, arg);
- goto done;
- case CFCIRQ:
- retval = irq_ioctl(&board->config, arg);
- goto done;
- case CFCDMA:
- retval = dma_ioctl(&board->config, arg);
- goto done;
- case IBAUTOSPOLL:
- retval = autospoll_ioctl(board, file_priv, arg);
- goto done;
- case IBBOARD_INFO:
- retval = board_info_ioctl(board, arg);
- goto done;
- case IBMUTEX:
- /*
- * Need to unlock board->big_gpib_mutex before potentially locking board->user_mutex
- * to maintain consistent locking order
- */
- mutex_unlock(&board->big_gpib_mutex);
- return mutex_ioctl(board, file_priv, arg);
- case IBPAD:
- retval = pad_ioctl(board, file_priv, arg);
- goto done;
- case IBSAD:
- retval = sad_ioctl(board, file_priv, arg);
- goto done;
- case IBSELECT_PCI:
- retval = select_pci_ioctl(&board->config, arg);
- goto done;
- case IBSELECT_DEVICE_PATH:
- retval = select_device_path_ioctl(&board->config, arg);
- goto done;
- default:
- break;
- }
-
- if (!board->online) {
- retval = -EINVAL;
- goto done;
- }
-
- switch (cmd) {
- case IBEVENT:
- retval = event_ioctl(board, arg);
- goto done;
- case IBCLOSEDEV:
- retval = close_dev_ioctl(filep, board, arg);
- goto done;
- case IBOPENDEV:
- retval = open_dev_ioctl(filep, board, arg);
- goto done;
- case IBSPOLL_BYTES:
- retval = status_bytes_ioctl(board, arg);
- goto done;
- case IBWAIT:
- retval = wait_ioctl(file_priv, board, arg);
- if (retval == -ERESTARTSYS)
- return retval;
- goto done;
- case IBLINES:
- retval = line_status_ioctl(board, arg);
- goto done;
- case IBLOC:
- board->interface->return_to_local(board);
- retval = 0;
- goto done;
- default:
- break;
- }
-
- spin_lock(&board->locking_pid_spinlock);
- if (current->pid != board->locking_pid) {
- spin_unlock(&board->locking_pid_spinlock);
- retval = -EPERM;
- goto done;
- }
- spin_unlock(&board->locking_pid_spinlock);
-
- switch (cmd) {
- case IB_T1_DELAY:
- retval = t1_delay_ioctl(board, arg);
- goto done;
- case IBCAC:
- retval = take_control_ioctl(board, arg);
- goto done;
- case IBCMD:
- /*
- * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex
- * before we call them.
- */
- mutex_unlock(&board->big_gpib_mutex);
- return command_ioctl(file_priv, board, arg);
- case IBEOS:
- retval = eos_ioctl(board, arg);
- goto done;
- case IBGTS:
- retval = ibgts(board);
- goto done;
- case IBPPC:
- retval = ppc_ioctl(board, arg);
- goto done;
- case IBPP2_SET:
- retval = set_local_ppoll_mode_ioctl(board, arg);
- goto done;
- case IBPP2_GET:
- retval = get_local_ppoll_mode_ioctl(board, arg);
- goto done;
- case IBQUERY_BOARD_RSV:
- retval = query_board_rsv_ioctl(board, arg);
- goto done;
- case IBRD:
- /*
- * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex
- * before we call them.
- */
- mutex_unlock(&board->big_gpib_mutex);
- return read_ioctl(file_priv, board, arg);
- case IBRPP:
- retval = parallel_poll_ioctl(board, arg);
- goto done;
- case IBRSC:
- retval = request_system_control_ioctl(board, arg);
- goto done;
- case IBRSP:
- retval = serial_poll_ioctl(board, arg);
- goto done;
- case IBRSV:
- retval = request_service_ioctl(board, arg);
- goto done;
- case IBRSV2:
- retval = request_service2_ioctl(board, arg);
- goto done;
- case IBSIC:
- retval = interface_clear_ioctl(board, arg);
- goto done;
- case IBSRE:
- retval = remote_enable_ioctl(board, arg);
- goto done;
- case IBTMO:
- retval = timeout_ioctl(board, arg);
- goto done;
- case IBWRT:
- /*
- * IO ioctls can take a long time, we need to unlock board->big_gpib_mutex
- * before we call them.
- */
- mutex_unlock(&board->big_gpib_mutex);
- return write_ioctl(file_priv, board, arg);
- default:
- retval = -ENOTTY;
- goto done;
- }
-
-done:
- mutex_unlock(&board->big_gpib_mutex);
- dev_dbg(board->gpib_dev, "ioctl done status = 0x%lx\n", board->status);
- return retval;
-}
-
-static int board_type_ioctl(struct gpib_file_private *file_priv,
- struct gpib_board *board, unsigned long arg)
-{
- struct list_head *list_ptr;
- struct gpib_board_type_ioctl cmd;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (board->online)
- return -EBUSY;
-
- retval = copy_from_user(&cmd, (void __user *)arg,
- sizeof(struct gpib_board_type_ioctl));
- if (retval)
- return -EFAULT;
-
- for (list_ptr = registered_drivers.next; list_ptr != &registered_drivers;
- list_ptr = list_ptr->next) {
- struct gpib_interface_list *entry;
-
- entry = list_entry(list_ptr, struct gpib_interface_list, list);
- if (strcmp(entry->interface->name, cmd.name) == 0) {
- int i;
- int had_module = file_priv->got_module;
-
- if (board->use_count) {
- for (i = 0; i < board->use_count; ++i)
- module_put(board->provider_module);
- board->interface = NULL;
- file_priv->got_module = 0;
- }
- board->interface = entry->interface;
- board->provider_module = entry->module;
- for (i = 0; i < board->use_count; ++i) {
- if (!try_module_get(entry->module)) {
- board->use_count = i;
- return -EIO;
- }
- }
- if (had_module == 0) {
- if (!try_module_get(entry->module))
- return -EIO;
- ++board->use_count;
- }
- file_priv->got_module = 1;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static int read_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg)
-{
- struct gpib_read_write_ioctl read_cmd;
- u8 __user *userbuf;
- unsigned long remain;
- int end_flag = 0;
- int retval;
- ssize_t read_ret = 0;
- struct gpib_descriptor *desc;
- size_t nbytes;
-
- retval = copy_from_user(&read_cmd, (void __user *)arg, sizeof(read_cmd));
- if (retval)
- return -EFAULT;
-
- if (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count)
- return -EINVAL;
-
- desc = handle_to_descriptor(file_priv, read_cmd.handle);
- if (!desc)
- return -EINVAL;
-
- if (WARN_ON_ONCE(sizeof(userbuf) > sizeof(read_cmd.buffer_ptr)))
- return -EFAULT;
-
- userbuf = (u8 __user *)(unsigned long)read_cmd.buffer_ptr;
- userbuf += read_cmd.completed_transfer_count;
-
- remain = read_cmd.requested_transfer_count - read_cmd.completed_transfer_count;
-
- /* Check write access to buffer */
- if (!access_ok(userbuf, remain))
- return -EFAULT;
-
- atomic_set(&desc->io_in_progress, 1);
-
- /* Read buffer loads till we fill the user supplied buffer */
- while (remain > 0 && end_flag == 0) {
- nbytes = 0;
- read_ret = ibrd(board, board->buffer, (board->buffer_length < remain) ?
- board->buffer_length : remain, &end_flag, &nbytes);
- if (nbytes == 0)
- break;
- retval = copy_to_user(userbuf, board->buffer, nbytes);
- if (retval) {
- retval = -EFAULT;
- break;
- }
- remain -= nbytes;
- userbuf += nbytes;
- if (read_ret < 0)
- break;
- }
- read_cmd.completed_transfer_count = read_cmd.requested_transfer_count - remain;
- read_cmd.end = end_flag;
- /*
- * suppress errors (for example due to timeout or interruption by device clear)
- * if all bytes got sent. This prevents races that can occur in the various drivers
- * if a device receives a device clear immediately after a transfer completes and
- * the driver code wasn't careful enough to handle that case.
- */
- if (remain == 0 || end_flag)
- read_ret = 0;
- if (retval == 0)
- retval = copy_to_user((void __user *)arg, &read_cmd, sizeof(read_cmd));
-
- atomic_set(&desc->io_in_progress, 0);
-
- wake_up_interruptible(&board->wait);
- if (retval)
- return -EFAULT;
-
- return read_ret;
-}
-
-static int command_ioctl(struct gpib_file_private *file_priv,
- struct gpib_board *board, unsigned long arg)
-{
- struct gpib_read_write_ioctl cmd;
- u8 __user *userbuf;
- unsigned long remain;
- int retval;
- int fault = 0;
- struct gpib_descriptor *desc;
- size_t bytes_written;
- int no_clear_io_in_prog;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- if (cmd.completed_transfer_count > cmd.requested_transfer_count)
- return -EINVAL;
-
- desc = handle_to_descriptor(file_priv, cmd.handle);
- if (!desc)
- return -EINVAL;
-
- userbuf = (u8 __user *)(unsigned long)cmd.buffer_ptr;
- userbuf += cmd.completed_transfer_count;
-
- no_clear_io_in_prog = cmd.end;
- cmd.end = 0;
-
- remain = cmd.requested_transfer_count - cmd.completed_transfer_count;
-
- /* Check read access to buffer */
- if (!access_ok(userbuf, remain))
- return -EFAULT;
-
- /*
- * Write buffer loads till we empty the user supplied buffer.
- * Call drivers at least once, even if remain is zero, in
- * order to allow them to insure previous commands were
- * completely finished, in the case of a restarted ioctl.
- */
-
- atomic_set(&desc->io_in_progress, 1);
-
- do {
- fault = copy_from_user(board->buffer, userbuf, (board->buffer_length < remain) ?
- board->buffer_length : remain);
- if (fault) {
- retval = -EFAULT;
- bytes_written = 0;
- } else {
- retval = ibcmd(board, board->buffer, (board->buffer_length < remain) ?
- board->buffer_length : remain, &bytes_written);
- }
- remain -= bytes_written;
- userbuf += bytes_written;
- if (retval < 0) {
- atomic_set(&desc->io_in_progress, 0);
-
- wake_up_interruptible(&board->wait);
- break;
- }
- } while (remain > 0);
-
- cmd.completed_transfer_count = cmd.requested_transfer_count - remain;
-
- if (fault == 0)
- fault = copy_to_user((void __user *)arg, &cmd, sizeof(cmd));
-
- /*
- * no_clear_io_in_prog (cmd.end) is true when io_in_progress should
- * not be set to zero because the cmd in progress is the address setup
- * operation for an async read or write. This causes CMPL not to be set
- * in general_ibstatus until the async read or write completes.
- */
- if (!no_clear_io_in_prog || fault)
- atomic_set(&desc->io_in_progress, 0);
-
- wake_up_interruptible(&board->wait);
- if (fault)
- return -EFAULT;
-
- return retval;
-}
-
-static int write_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg)
-{
- struct gpib_read_write_ioctl write_cmd;
- u8 __user *userbuf;
- unsigned long remain;
- int retval = 0;
- int fault;
- struct gpib_descriptor *desc;
-
- fault = copy_from_user(&write_cmd, (void __user *)arg, sizeof(write_cmd));
- if (fault)
- return -EFAULT;
-
- if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count)
- return -EINVAL;
-
- desc = handle_to_descriptor(file_priv, write_cmd.handle);
- if (!desc)
- return -EINVAL;
-
- userbuf = (u8 __user *)(unsigned long)write_cmd.buffer_ptr;
- userbuf += write_cmd.completed_transfer_count;
-
- remain = write_cmd.requested_transfer_count - write_cmd.completed_transfer_count;
-
- /* Check read access to buffer */
- if (!access_ok(userbuf, remain))
- return -EFAULT;
-
- atomic_set(&desc->io_in_progress, 1);
-
- /* Write buffer loads till we empty the user supplied buffer */
- while (remain > 0) {
- int send_eoi;
- size_t bytes_written = 0;
-
- send_eoi = remain <= board->buffer_length && write_cmd.end;
- fault = copy_from_user(board->buffer, userbuf, (board->buffer_length < remain) ?
- board->buffer_length : remain);
- if (fault) {
- retval = -EFAULT;
- break;
- }
- retval = ibwrt(board, board->buffer, (board->buffer_length < remain) ?
- board->buffer_length : remain, send_eoi, &bytes_written);
- remain -= bytes_written;
- userbuf += bytes_written;
- if (retval < 0)
- break;
- }
- write_cmd.completed_transfer_count = write_cmd.requested_transfer_count - remain;
- /*
- * suppress errors (for example due to timeout or interruption by device clear)
- * if all bytes got sent. This prevents races that can occur in the various drivers
- * if a device receives a device clear immediately after a transfer completes and
- * the driver code wasn't careful enough to handle that case.
- */
- if (remain == 0)
- retval = 0;
- if (fault == 0)
- fault = copy_to_user((void __user *)arg, &write_cmd, sizeof(write_cmd));
-
- atomic_set(&desc->io_in_progress, 0);
-
- wake_up_interruptible(&board->wait);
- if (fault)
- return -EFAULT;
-
- return retval;
-}
-
-static int status_bytes_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_status_queue *device;
- struct gpib_spoll_bytes_ioctl cmd;
- int retval;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- device = get_gpib_status_queue(board, cmd.pad, cmd.sad);
- if (!device)
- cmd.num_bytes = 0;
- else
- cmd.num_bytes = num_status_bytes(device);
-
- retval = copy_to_user((void __user *)arg, &cmd, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int increment_open_device_count(struct gpib_board *board, struct list_head *head,
- unsigned int pad, int sad)
-{
- struct list_head *list_ptr;
- struct gpib_status_queue *device;
-
- /*
- * first see if address has already been opened, then increment
- * open count
- */
- for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) {
- device = list_entry(list_ptr, struct gpib_status_queue, list);
- if (gpib_address_equal(device->pad, device->sad, pad, sad)) {
- dev_dbg(board->gpib_dev, "incrementing open count for pad %i, sad %i\n",
- device->pad, device->sad);
- device->reference_count++;
- return 0;
- }
- }
-
- /* otherwise we need to allocate a new struct gpib_status_queue */
- device = kmalloc(sizeof(struct gpib_status_queue), GFP_ATOMIC);
- if (!device)
- return -ENOMEM;
- init_gpib_status_queue(device);
- device->pad = pad;
- device->sad = sad;
- device->reference_count = 1;
-
- list_add(&device->list, head);
-
- dev_dbg(board->gpib_dev, "opened pad %i, sad %i\n", device->pad, device->sad);
-
- return 0;
-}
-
-static int subtract_open_device_count(struct gpib_board *board, struct list_head *head,
- unsigned int pad, int sad, unsigned int count)
-{
- struct gpib_status_queue *device;
- struct list_head *list_ptr;
-
- for (list_ptr = head->next; list_ptr != head; list_ptr = list_ptr->next) {
- device = list_entry(list_ptr, struct gpib_status_queue, list);
- if (gpib_address_equal(device->pad, device->sad, pad, sad)) {
- dev_dbg(board->gpib_dev, "decrementing open count for pad %i, sad %i\n",
- device->pad, device->sad);
- if (count > device->reference_count) {
- dev_err(board->gpib_dev, "bug! in %s()\n", __func__);
- return -EINVAL;
- }
- device->reference_count -= count;
- if (device->reference_count == 0) {
- dev_dbg(board->gpib_dev, "closing pad %i, sad %i\n",
- device->pad, device->sad);
- list_del(list_ptr);
- kfree(device);
- }
- return 0;
- }
- }
- dev_err(board->gpib_dev, "bug! tried to close address that was never opened!\n");
- return -EINVAL;
-}
-
-static inline int decrement_open_device_count(struct gpib_board *board, struct list_head *head,
- unsigned int pad, int sad)
-{
- return subtract_open_device_count(board, head, pad, sad, 1);
-}
-
-static int cleanup_open_devices(struct gpib_file_private *file_priv, struct gpib_board *board)
-{
- int retval = 0;
- int i;
-
- for (i = 0; i < GPIB_MAX_NUM_DESCRIPTORS; i++) {
- struct gpib_descriptor *desc;
-
- desc = file_priv->descriptors[i];
- if (!desc)
- continue;
-
- if (desc->is_board == 0) {
- retval = decrement_open_device_count(board, &board->device_list, desc->pad,
- desc->sad);
- if (retval < 0)
- return retval;
- }
- kfree(desc);
- file_priv->descriptors[i] = NULL;
- }
-
- return 0;
-}
-
-static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg)
-{
- struct gpib_open_dev_ioctl open_dev_cmd;
- int retval;
- struct gpib_file_private *file_priv = filep->private_data;
- int i;
-
- retval = copy_from_user(&open_dev_cmd, (void __user *)arg, sizeof(open_dev_cmd));
- if (retval)
- return -EFAULT;
-
- if (mutex_lock_interruptible(&file_priv->descriptors_mutex))
- return -ERESTARTSYS;
- for (i = 0; i < GPIB_MAX_NUM_DESCRIPTORS; i++)
- if (!file_priv->descriptors[i])
- break;
- if (i == GPIB_MAX_NUM_DESCRIPTORS) {
- mutex_unlock(&file_priv->descriptors_mutex);
- return -ERANGE;
- }
- file_priv->descriptors[i] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL);
- if (!file_priv->descriptors[i]) {
- mutex_unlock(&file_priv->descriptors_mutex);
- return -ENOMEM;
- }
- init_gpib_descriptor(file_priv->descriptors[i]);
-
- file_priv->descriptors[i]->pad = open_dev_cmd.pad;
- file_priv->descriptors[i]->sad = open_dev_cmd.sad;
- file_priv->descriptors[i]->is_board = open_dev_cmd.is_board;
- mutex_unlock(&file_priv->descriptors_mutex);
-
- retval = increment_open_device_count(board, &board->device_list, open_dev_cmd.pad,
- open_dev_cmd.sad);
- if (retval < 0)
- return retval;
-
- /*
- * clear stuck srq state, since we may be able to find service request on
- * the new device
- */
- atomic_set(&board->stuck_srq, 0);
-
- open_dev_cmd.handle = i;
- retval = copy_to_user((void __user *)arg, &open_dev_cmd, sizeof(open_dev_cmd));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int close_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned long arg)
-{
- struct gpib_close_dev_ioctl cmd;
- struct gpib_file_private *file_priv = filep->private_data;
- int retval;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- if (cmd.handle >= GPIB_MAX_NUM_DESCRIPTORS)
- return -EINVAL;
- if (!file_priv->descriptors[cmd.handle])
- return -EINVAL;
-
- retval = decrement_open_device_count(board, &board->device_list,
- file_priv->descriptors[cmd.handle]->pad,
- file_priv->descriptors[cmd.handle]->sad);
- if (retval < 0)
- return retval;
-
- kfree(file_priv->descriptors[cmd.handle]);
- file_priv->descriptors[cmd.handle] = NULL;
-
- return 0;
-}
-
-static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_serial_poll_ioctl serial_cmd;
- int retval;
-
- retval = copy_from_user(&serial_cmd, (void __user *)arg, sizeof(serial_cmd));
- if (retval)
- return -EFAULT;
-
- retval = get_serial_poll_byte(board, serial_cmd.pad, serial_cmd.sad, board->usec_timeout,
- &serial_cmd.status_byte);
- if (retval < 0)
- return retval;
-
- retval = copy_to_user((void __user *)arg, &serial_cmd, sizeof(serial_cmd));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int wait_ioctl(struct gpib_file_private *file_priv, struct gpib_board *board,
- unsigned long arg)
-{
- struct gpib_wait_ioctl wait_cmd;
- int retval;
- struct gpib_descriptor *desc;
-
- retval = copy_from_user(&wait_cmd, (void __user *)arg, sizeof(wait_cmd));
- if (retval)
- return -EFAULT;
-
- desc = handle_to_descriptor(file_priv, wait_cmd.handle);
- if (!desc)
- return -EINVAL;
-
- retval = ibwait(board, wait_cmd.wait_mask, wait_cmd.clear_mask,
- wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc);
- if (retval < 0)
- return retval;
-
- retval = copy_to_user((void __user *)arg, &wait_cmd, sizeof(wait_cmd));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int parallel_poll_ioctl(struct gpib_board *board, unsigned long arg)
-{
- u8 poll_byte;
- int retval;
-
- retval = ibrpp(board, &poll_byte);
- if (retval < 0)
- return retval;
-
- retval = copy_to_user((void __user *)arg, &poll_byte, sizeof(poll_byte));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int online_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_online_ioctl online_cmd;
- int retval;
- void __user *init_data = NULL;
-
- board->config.init_data = NULL;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- retval = copy_from_user(&online_cmd, (void __user *)arg, sizeof(online_cmd));
- if (retval)
- return -EFAULT;
- if (online_cmd.init_data_length > 0) {
- board->config.init_data = vmalloc(online_cmd.init_data_length);
- if (!board->config.init_data)
- return -ENOMEM;
- if (WARN_ON_ONCE(sizeof(init_data) > sizeof(online_cmd.init_data_ptr)))
- return -EFAULT;
- init_data = (void __user *)(unsigned long)(online_cmd.init_data_ptr);
- retval = copy_from_user(board->config.init_data, init_data,
- online_cmd.init_data_length);
- if (retval) {
- vfree(board->config.init_data);
- return -EFAULT;
- }
- board->config.init_data_length = online_cmd.init_data_length;
- } else {
- board->config.init_data = NULL;
- board->config.init_data_length = 0;
- }
- if (online_cmd.online)
- retval = ibonline(board);
- else
- retval = iboffline(board);
- if (board->config.init_data) {
- vfree(board->config.init_data);
- board->config.init_data = NULL;
- board->config.init_data_length = 0;
- }
- return retval;
-}
-
-static int remote_enable_ioctl(struct gpib_board *board, unsigned long arg)
-{
- int enable;
- int retval;
-
- retval = copy_from_user(&enable, (void __user *)arg, sizeof(enable));
- if (retval)
- return -EFAULT;
-
- return ibsre(board, enable);
-}
-
-static int take_control_ioctl(struct gpib_board *board, unsigned long arg)
-{
- int synchronous;
- int retval;
-
- retval = copy_from_user(&synchronous, (void __user *)arg, sizeof(synchronous));
- if (retval)
- return -EFAULT;
-
- return ibcac(board, synchronous, 1);
-}
-
-static int line_status_ioctl(struct gpib_board *board, unsigned long arg)
-{
- short lines;
- int retval;
-
- retval = iblines(board, &lines);
- if (retval < 0)
- return retval;
-
- retval = copy_to_user((void __user *)arg, &lines, sizeof(lines));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int pad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg)
-{
- struct gpib_pad_ioctl cmd;
- int retval;
- struct gpib_descriptor *desc;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- desc = handle_to_descriptor(file_priv, cmd.handle);
- if (!desc)
- return -EINVAL;
-
- if (desc->is_board) {
- retval = ibpad(board, cmd.pad);
- if (retval < 0)
- return retval;
- } else {
- retval = decrement_open_device_count(board, &board->device_list, desc->pad,
- desc->sad);
- if (retval < 0)
- return retval;
-
- desc->pad = cmd.pad;
-
- retval = increment_open_device_count(board, &board->device_list, desc->pad,
- desc->sad);
- if (retval < 0)
- return retval;
- }
-
- return 0;
-}
-
-static int sad_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg)
-{
- struct gpib_sad_ioctl cmd;
- int retval;
- struct gpib_descriptor *desc;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- desc = handle_to_descriptor(file_priv, cmd.handle);
- if (!desc)
- return -EINVAL;
-
- if (desc->is_board) {
- retval = ibsad(board, cmd.sad);
- if (retval < 0)
- return retval;
- } else {
- retval = decrement_open_device_count(board, &board->device_list, desc->pad,
- desc->sad);
- if (retval < 0)
- return retval;
-
- desc->sad = cmd.sad;
-
- retval = increment_open_device_count(board, &board->device_list, desc->pad,
- desc->sad);
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static int eos_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_eos_ioctl eos_cmd;
- int retval;
-
- retval = copy_from_user(&eos_cmd, (void __user *)arg, sizeof(eos_cmd));
- if (retval)
- return -EFAULT;
-
- return ibeos(board, eos_cmd.eos, eos_cmd.eos_flags);
-}
-
-static int request_service_ioctl(struct gpib_board *board, unsigned long arg)
-{
- u8 status_byte;
- int retval;
-
- retval = copy_from_user(&status_byte, (void __user *)arg, sizeof(status_byte));
- if (retval)
- return -EFAULT;
-
- return ibrsv2(board, status_byte, status_byte & request_service_bit);
-}
-
-static int request_service2_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_request_service2 request_service2_cmd;
- int retval;
-
- retval = copy_from_user(&request_service2_cmd, (void __user *)arg,
- sizeof(struct gpib_request_service2));
- if (retval)
- return -EFAULT;
-
- return ibrsv2(board, request_service2_cmd.status_byte,
- request_service2_cmd.new_reason_for_service);
-}
-
-static int iobase_ioctl(struct gpib_board_config *config, unsigned long arg)
-{
- u64 base_addr;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- retval = copy_from_user(&base_addr, (void __user *)arg, sizeof(base_addr));
- if (retval)
- return -EFAULT;
-
- if (WARN_ON_ONCE(sizeof(void *) > sizeof(base_addr)))
- return -EFAULT;
- config->ibbase = base_addr;
-
- return 0;
-}
-
-static int irq_ioctl(struct gpib_board_config *config, unsigned long arg)
-{
- unsigned int irq;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- retval = copy_from_user(&irq, (void __user *)arg, sizeof(irq));
- if (retval)
- return -EFAULT;
-
- config->ibirq = irq;
-
- return 0;
-}
-
-static int dma_ioctl(struct gpib_board_config *config, unsigned long arg)
-{
- unsigned int dma_channel;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- retval = copy_from_user(&dma_channel, (void __user *)arg, sizeof(dma_channel));
- if (retval)
- return -EFAULT;
-
- config->ibdma = dma_channel;
-
- return 0;
-}
-
-static int autospoll_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg)
-{
- short enable;
- int retval;
- struct gpib_descriptor *desc;
-
- retval = copy_from_user(&enable, (void __user *)arg, sizeof(enable));
- if (retval)
- return -EFAULT;
-
- desc = handle_to_descriptor(file_priv, 0); /* board handle is 0 */
-
- if (enable) {
- if (!desc->autopoll_enabled) {
- board->autospollers++;
- desc->autopoll_enabled = 1;
- }
- retval = 0;
- } else {
- if (desc->autopoll_enabled) {
- desc->autopoll_enabled = 0;
- if (board->autospollers > 0) {
- board->autospollers--;
- retval = 0;
- } else {
- dev_err(board->gpib_dev,
- "tried to set number of autospollers negative\n");
- retval = -EINVAL;
- }
- } else {
- dev_err(board->gpib_dev, "autopoll disable requested before enable\n");
- retval = -EINVAL;
- }
- }
- return retval;
-}
-
-static int mutex_ioctl(struct gpib_board *board, struct gpib_file_private *file_priv,
- unsigned long arg)
-{
- int retval, lock_mutex;
-
- retval = copy_from_user(&lock_mutex, (void __user *)arg, sizeof(lock_mutex));
- if (retval)
- return -EFAULT;
-
- if (lock_mutex) {
- retval = mutex_lock_interruptible(&board->user_mutex);
- if (retval)
- return -ERESTARTSYS;
-
- spin_lock(&board->locking_pid_spinlock);
- board->locking_pid = current->pid;
- spin_unlock(&board->locking_pid_spinlock);
-
- atomic_set(&file_priv->holding_mutex, 1);
-
- dev_dbg(board->gpib_dev, "locked board mutex\n");
- } else {
- spin_lock(&board->locking_pid_spinlock);
- if (current->pid != board->locking_pid) {
- dev_err(board->gpib_dev, "bug! pid %i tried to release mutex held by pid %i\n",
- current->pid, board->locking_pid);
- spin_unlock(&board->locking_pid_spinlock);
- return -EPERM;
- }
- board->locking_pid = 0;
- spin_unlock(&board->locking_pid_spinlock);
-
- atomic_set(&file_priv->holding_mutex, 0);
-
- mutex_unlock(&board->user_mutex);
- dev_dbg(board->gpib_dev, "unlocked board mutex\n");
- }
- return 0;
-}
-
-static int timeout_ioctl(struct gpib_board *board, unsigned long arg)
-{
- unsigned int timeout;
- int retval;
-
- retval = copy_from_user(&timeout, (void __user *)arg, sizeof(timeout));
- if (retval)
- return -EFAULT;
-
- board->usec_timeout = timeout;
- dev_dbg(board->gpib_dev, "timeout set to %i usec\n", timeout);
-
- return 0;
-}
-
-static int ppc_ioctl(struct gpib_board *board, unsigned long arg)
-{
- struct gpib_ppoll_config_ioctl cmd;
- int retval;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- if (cmd.set_ist) {
- board->ist = 1;
- board->interface->parallel_poll_response(board, board->ist);
- } else if (cmd.clear_ist) {
- board->ist = 0;
- board->interface->parallel_poll_response(board, board->ist);
- }
-
- if (cmd.config) {
- retval = ibppc(board, cmd.config);
- if (retval < 0)
- return retval;
- }
-
- return 0;
-}
-
-static int set_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg)
-{
- short cmd;
- int retval;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- if (!board->interface->local_parallel_poll_mode)
- return -ENOENT;
- board->local_ppoll_mode = cmd != 0;
- board->interface->local_parallel_poll_mode(board, board->local_ppoll_mode);
-
- return 0;
-}
-
-static int get_local_ppoll_mode_ioctl(struct gpib_board *board, unsigned long arg)
-{
- short cmd;
- int retval;
-
- cmd = board->local_ppoll_mode;
- retval = copy_to_user((void __user *)arg, &cmd, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int query_board_rsv_ioctl(struct gpib_board *board, unsigned long arg)
-{
- int status;
- int retval;
-
- status = board->interface->serial_poll_status(board);
-
- retval = copy_to_user((void __user *)arg, &status, sizeof(status));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int board_info_ioctl(const struct gpib_board *board, unsigned long arg)
-{
- struct gpib_board_info_ioctl info = { };
- int retval;
-
- info.pad = board->pad;
- info.sad = board->sad;
- info.parallel_poll_configuration = board->parallel_poll_configuration;
- info.is_system_controller = board->master;
- if (board->autospollers)
- info.autopolling = 1;
- else
- info.autopolling = 0;
- info.t1_delay = board->t1_nano_sec;
- info.ist = board->ist;
- info.no_7_bit_eos = board->interface->no_7_bit_eos;
- retval = copy_to_user((void __user *)arg, &info, sizeof(info));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int interface_clear_ioctl(struct gpib_board *board, unsigned long arg)
-{
- unsigned int usec_duration;
- int retval;
-
- retval = copy_from_user(&usec_duration, (void __user *)arg, sizeof(usec_duration));
- if (retval)
- return -EFAULT;
-
- return ibsic(board, usec_duration);
-}
-
-static int select_pci_ioctl(struct gpib_board_config *config, unsigned long arg)
-{
- struct gpib_select_pci_ioctl selection;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- retval = copy_from_user(&selection, (void __user *)arg, sizeof(selection));
- if (retval)
- return -EFAULT;
-
- config->pci_bus = selection.pci_bus;
- config->pci_slot = selection.pci_slot;
-
- return 0;
-}
-
-static int select_device_path_ioctl(struct gpib_board_config *config, unsigned long arg)
-{
- struct gpib_select_device_path_ioctl *selection;
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- selection = vmalloc(sizeof(struct gpib_select_device_path_ioctl));
- if (!selection)
- return -ENOMEM;
-
- retval = copy_from_user(selection, (void __user *)arg,
- sizeof(struct gpib_select_device_path_ioctl));
- if (retval) {
- vfree(selection);
- return -EFAULT;
- }
-
- selection->device_path[sizeof(selection->device_path) - 1] = '\0';
- kfree(config->device_path);
- config->device_path = NULL;
- if (strlen(selection->device_path) > 0)
- config->device_path = kstrdup(selection->device_path, GFP_KERNEL);
-
- vfree(selection);
- return 0;
-}
-
-unsigned int num_gpib_events(const struct gpib_event_queue *queue)
-{
- return queue->num_events;
-}
-
-static int push_gpib_event_nolock(struct gpib_board *board, short event_type)
-{
- struct gpib_event_queue *queue = &board->event_queue;
- struct list_head *head = &queue->event_head;
- struct gpib_event *event;
- static const unsigned int max_num_events = 1024;
- int retval;
-
- if (num_gpib_events(queue) >= max_num_events) {
- short lost_event;
-
- queue->dropped_event = 1;
- retval = pop_gpib_event_nolock(board, queue, &lost_event);
- if (retval < 0)
- return retval;
- }
-
- event = kmalloc(sizeof(struct gpib_event), GFP_ATOMIC);
- if (!event) {
- queue->dropped_event = 1;
- dev_err(board->gpib_dev, "failed to allocate memory for event\n");
- return -ENOMEM;
- }
-
- INIT_LIST_HEAD(&event->list);
- event->event_type = event_type;
-
- list_add_tail(&event->list, head);
-
- queue->num_events++;
-
- dev_dbg(board->gpib_dev, "pushed event %i, %i in queue\n",
- (int)event_type, num_gpib_events(queue));
-
- return 0;
-}
-
-// push event onto back of event queue
-int push_gpib_event(struct gpib_board *board, short event_type)
-{
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&board->event_queue.lock, flags);
- retval = push_gpib_event_nolock(board, event_type);
- spin_unlock_irqrestore(&board->event_queue.lock, flags);
-
- if (event_type == EVENT_DEV_TRG)
- board->status |= DTAS;
- if (event_type == EVENT_DEV_CLR)
- board->status |= DCAS;
-
- return retval;
-}
-EXPORT_SYMBOL(push_gpib_event);
-
-static int pop_gpib_event_nolock(struct gpib_board *board,
- struct gpib_event_queue *queue, short *event_type)
-{
- struct list_head *head = &queue->event_head;
- struct list_head *front = head->next;
- struct gpib_event *event;
-
- if (num_gpib_events(queue) == 0) {
- *event_type = EVENT_NONE;
- return 0;
- }
-
- if (front == head)
- return -EIO;
-
- if (queue->dropped_event) {
- queue->dropped_event = 0;
- return -EPIPE;
- }
-
- event = list_entry(front, struct gpib_event, list);
- *event_type = event->event_type;
-
- list_del(front);
- kfree(event);
-
- queue->num_events--;
-
- dev_dbg(board->gpib_dev, "popped event %i, %i in queue\n",
- (int)*event_type, num_gpib_events(queue));
-
- return 0;
-}
-
-// pop event from front of event queue
-int pop_gpib_event(struct gpib_board *board, struct gpib_event_queue *queue, short *event_type)
-{
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&queue->lock, flags);
- retval = pop_gpib_event_nolock(board, queue, event_type);
- spin_unlock_irqrestore(&queue->lock, flags);
- return retval;
-}
-
-static int event_ioctl(struct gpib_board *board, unsigned long arg)
-{
- short user_event;
- int retval;
- short event;
-
- retval = pop_gpib_event(board, &board->event_queue, &event);
- if (retval < 0)
- return retval;
-
- user_event = event;
-
- retval = copy_to_user((void __user *)arg, &user_event, sizeof(user_event));
- if (retval)
- return -EFAULT;
-
- return 0;
-}
-
-static int request_system_control_ioctl(struct gpib_board *board, unsigned long arg)
-{
- int request_control;
- int retval;
-
- retval = copy_from_user(&request_control, (void __user *)arg, sizeof(request_control));
- if (retval)
- return -EFAULT;
-
- return ibrsc(board, request_control);
-}
-
-static int t1_delay_ioctl(struct gpib_board *board, unsigned long arg)
-{
- unsigned int cmd;
- unsigned int delay;
- int retval;
-
- if (!board->interface->t1_delay)
- return -ENOENT;
-
- retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd));
- if (retval)
- return -EFAULT;
-
- delay = cmd;
-
- retval = board->interface->t1_delay(board, delay);
- if (retval < 0)
- return retval;
-
- board->t1_nano_sec = retval;
- return 0;
-}
-
-static const struct file_operations ib_fops = {
- .owner = THIS_MODULE,
- .llseek = NULL,
- .unlocked_ioctl = &ibioctl,
- .compat_ioctl = &ibioctl,
- .open = &ibopen,
- .release = &ibclose,
-};
-
-struct gpib_board board_array[GPIB_MAX_NUM_BOARDS];
-
-LIST_HEAD(registered_drivers);
-
-void init_gpib_descriptor(struct gpib_descriptor *desc)
-{
- desc->pad = 0;
- desc->sad = -1;
- desc->is_board = 0;
- desc->autopoll_enabled = 0;
- atomic_set(&desc->io_in_progress, 0);
-}
-
-int gpib_register_driver(struct gpib_interface *interface, struct module *provider_module)
-{
- struct gpib_interface_list *entry;
-
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
-
- entry->interface = interface;
- entry->module = provider_module;
- list_add(&entry->list, &registered_drivers);
-
- return 0;
-}
-EXPORT_SYMBOL(gpib_register_driver);
-
-void gpib_unregister_driver(struct gpib_interface *interface)
-{
- int i;
- struct list_head *list_ptr;
-
- for (i = 0; i < GPIB_MAX_NUM_BOARDS; i++) {
- struct gpib_board *board = &board_array[i];
-
- if (board->interface == interface) {
- if (board->use_count > 0)
- pr_warn("gpib: Warning: deregistered interface %s in use\n",
- interface->name);
- iboffline(board);
- board->interface = NULL;
- }
- }
- for (list_ptr = registered_drivers.next; list_ptr != &registered_drivers;) {
- struct gpib_interface_list *entry;
-
- entry = list_entry(list_ptr, struct gpib_interface_list, list);
- list_ptr = list_ptr->next;
- if (entry->interface == interface) {
- list_del(&entry->list);
- kfree(entry);
- }
- }
-}
-EXPORT_SYMBOL(gpib_unregister_driver);
-
-static void init_gpib_board_config(struct gpib_board_config *config)
-{
- memset(config, 0, sizeof(struct gpib_board_config));
- config->pci_bus = -1;
- config->pci_slot = -1;
-}
-
-void init_gpib_board(struct gpib_board *board)
-{
- board->interface = NULL;
- board->provider_module = NULL;
- board->buffer = NULL;
- board->buffer_length = 0;
- board->status = 0;
- init_waitqueue_head(&board->wait);
- mutex_init(&board->user_mutex);
- mutex_init(&board->big_gpib_mutex);
- board->locking_pid = 0;
- spin_lock_init(&board->locking_pid_spinlock);
- spin_lock_init(&board->spinlock);
- timer_setup(&board->timer, NULL, 0);
- board->dev = NULL;
- board->gpib_dev = NULL;
- init_gpib_board_config(&board->config);
- board->private_data = NULL;
- board->use_count = 0;
- INIT_LIST_HEAD(&board->device_list);
- board->pad = 0;
- board->sad = -1;
- board->usec_timeout = 3000000;
- board->parallel_poll_configuration = 0;
- board->online = 0;
- board->autospollers = 0;
- board->autospoll_task = NULL;
- init_event_queue(&board->event_queue);
- board->minor = -1;
- init_gpib_pseudo_irq(&board->pseudo_irq);
- board->master = 1;
- atomic_set(&board->stuck_srq, 0);
- board->local_ppoll_mode = 0;
-}
-
-int gpib_allocate_board(struct gpib_board *board)
-{
- if (!board->buffer) {
- board->buffer_length = 0x4000;
- board->buffer = vmalloc(board->buffer_length);
- if (!board->buffer) {
- board->buffer_length = 0;
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-void gpib_deallocate_board(struct gpib_board *board)
-{
- short dummy;
-
- if (board->buffer) {
- vfree(board->buffer);
- board->buffer = NULL;
- board->buffer_length = 0;
- }
- while (num_gpib_events(&board->event_queue))
- pop_gpib_event(board, &board->event_queue, &dummy);
-}
-
-static void init_board_array(struct gpib_board *board_array, unsigned int length)
-{
- int i;
-
- for (i = 0; i < length; i++) {
- init_gpib_board(&board_array[i]);
- board_array[i].minor = i;
- }
-}
-
-void init_gpib_status_queue(struct gpib_status_queue *device)
-{
- INIT_LIST_HEAD(&device->list);
- INIT_LIST_HEAD(&device->status_bytes);
- device->num_status_bytes = 0;
- device->reference_count = 0;
- device->dropped_byte = 0;
-}
-
-static struct class *gpib_class;
-
-static int __init gpib_common_init_module(void)
-{
- int i;
-
- pr_info("GPIB core driver\n");
- init_board_array(board_array, GPIB_MAX_NUM_BOARDS);
- if (register_chrdev(GPIB_CODE, "gpib", &ib_fops)) {
- pr_err("gpib: can't get major %d\n", GPIB_CODE);
- return -EIO;
- }
- gpib_class = class_create("gpib_common");
- if (IS_ERR(gpib_class)) {
- pr_err("gpib: failed to create gpib class\n");
- unregister_chrdev(GPIB_CODE, "gpib");
- return PTR_ERR(gpib_class);
- }
- for (i = 0; i < GPIB_MAX_NUM_BOARDS; ++i)
- board_array[i].gpib_dev = device_create(gpib_class, NULL,
- MKDEV(GPIB_CODE, i), NULL, "gpib%i", i);
-
- return 0;
-}
-
-static void __exit gpib_common_exit_module(void)
-{
- int i;
-
- for (i = 0; i < GPIB_MAX_NUM_BOARDS; ++i)
- device_destroy(gpib_class, MKDEV(GPIB_CODE, i));
-
- class_destroy(gpib_class);
- unregister_chrdev(GPIB_CODE, "gpib");
-}
-
-int gpib_match_device_path(struct device *dev, const char *device_path_in)
-{
- if (device_path_in) {
- char *device_path;
-
- device_path = kobject_get_path(&dev->kobj, GFP_KERNEL);
- if (!device_path) {
- dev_err(dev, "kobject_get_path returned NULL.");
- return 0;
- }
- if (strcmp(device_path_in, device_path) != 0) {
- kfree(device_path);
- return 0;
- }
- kfree(device_path);
- }
- return 1;
-}
-EXPORT_SYMBOL(gpib_match_device_path);
-
-struct pci_dev *gpib_pci_get_device(const struct gpib_board_config *config, unsigned int vendor_id,
- unsigned int device_id, struct pci_dev *from)
-{
- struct pci_dev *pci_device = from;
-
- while ((pci_device = pci_get_device(vendor_id, device_id, pci_device))) {
- if (config->pci_bus >= 0 && config->pci_bus != pci_device->bus->number)
- continue;
- if (config->pci_slot >= 0 && config->pci_slot !=
- PCI_SLOT(pci_device->devfn))
- continue;
- if (gpib_match_device_path(&pci_device->dev, config->device_path) == 0)
- continue;
- return pci_device;
- }
- return NULL;
-}
-EXPORT_SYMBOL(gpib_pci_get_device);
-
-struct pci_dev *gpib_pci_get_subsys(const struct gpib_board_config *config, unsigned int vendor_id,
- unsigned int device_id, unsigned int ss_vendor,
- unsigned int ss_device,
- struct pci_dev *from)
-{
- struct pci_dev *pci_device = from;
-
- while ((pci_device = pci_get_subsys(vendor_id, device_id,
- ss_vendor, ss_device, pci_device))) {
- if (config->pci_bus >= 0 && config->pci_bus != pci_device->bus->number)
- continue;
- if (config->pci_slot >= 0 && config->pci_slot !=
- PCI_SLOT(pci_device->devfn))
- continue;
- if (gpib_match_device_path(&pci_device->dev, config->device_path) == 0)
- continue;
- return pci_device;
- }
- return NULL;
-}
-EXPORT_SYMBOL(gpib_pci_get_subsys);
-
-module_init(gpib_common_init_module);
-module_exit(gpib_common_exit_module);
-
diff --git a/drivers/staging/gpib/common/iblib.c b/drivers/staging/gpib/common/iblib.c
deleted file mode 100644
index 7cbb6a467177..000000000000
--- a/drivers/staging/gpib/common/iblib.c
+++ /dev/null
@@ -1,717 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "ibsys.h"
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/vmalloc.h>
-
-/*
- * IBCAC
- * Return to the controller active state from the
- * controller standby state, i.e., turn ATN on. Note
- * that in order to enter the controller active state
- * from the controller idle state, ibsic must be called.
- * If sync is non-zero, attempt to take control synchronously.
- * If fallback_to_async is non-zero, try to take control asynchronously
- * if synchronous attempt fails.
- */
-int ibcac(struct gpib_board *board, int sync, int fallback_to_async)
-{
- int status = ibstatus(board);
- int retval;
-
- if ((status & CIC) == 0)
- return -EINVAL;
-
- if (status & ATN)
- return 0;
-
- if (sync && (status & LACS) == 0)
- /*
- * tcs (take control synchronously) can only possibly work when
- * controller is listener. Error code also needs to be -ETIMEDOUT
- * or it will giveout without doing fallback.
- */
- retval = -ETIMEDOUT;
- else
- retval = board->interface->take_control(board, sync);
-
- if (retval < 0 && fallback_to_async) {
- if (sync && retval == -ETIMEDOUT)
- retval = board->interface->take_control(board, 0);
- }
- board->interface->update_status(board, 0);
-
- return retval;
-}
-
-/*
- * After ATN is asserted, it should cause any connected devices
- * to start listening for command bytes and leave acceptor idle state.
- * So if ATN is asserted and neither NDAC or NRFD are asserted,
- * then there are no devices and ibcmd should error out immediately.
- * Some gpib hardware sees itself asserting NDAC/NRFD when it
- * is controller in charge, in which case this check will
- * do nothing useful (but shouldn't cause any harm either).
- * Drivers that don't need this check (ni_usb for example) may
- * set the skip_check_for_command_acceptors flag in their
- * gpib_interface_struct to avoid useless overhead.
- */
-static int check_for_command_acceptors(struct gpib_board *board)
-{
- int lines;
-
- if (board->interface->skip_check_for_command_acceptors)
- return 0;
- if (!board->interface->line_status)
- return 0;
-
- udelay(2); // allow time for devices to respond to ATN if it was just asserted
-
- lines = board->interface->line_status(board);
- if (lines < 0)
- return lines;
-
- if ((lines & VALID_NRFD) && (lines & VALID_NDAC)) {
- if ((lines & BUS_NRFD) == 0 && (lines & BUS_NDAC) == 0)
- return -ENOTCONN;
- }
-
- return 0;
-}
-
-/*
- * IBCMD
- * Write cnt command bytes from buf to the GPIB. The
- * command operation terminates only on I/O complete.
- *
- * NOTE:
- * 1. Prior to beginning the command, the interface is
- * placed in the controller active state.
- * 2. Before calling ibcmd for the first time, ibsic
- * must be called to initialize the GPIB and enable
- * the interface to leave the controller idle state.
- */
-int ibcmd(struct gpib_board *board, u8 *buf, size_t length, size_t *bytes_written)
-{
- ssize_t ret = 0;
- int status;
-
- *bytes_written = 0;
-
- status = ibstatus(board);
-
- if ((status & CIC) == 0)
- return -EINVAL;
-
- os_start_timer(board, board->usec_timeout);
-
- ret = ibcac(board, 1, 1);
- if (ret == 0) {
- ret = check_for_command_acceptors(board);
- if (ret == 0)
- ret = board->interface->command(board, buf, length, bytes_written);
- }
-
- os_remove_timer(board);
-
- if (io_timed_out(board))
- ret = -ETIMEDOUT;
-
- return ret;
-}
-
-/*
- * IBGTS
- * Go to the controller standby state from the controller
- * active state, i.e., turn ATN off.
- */
-
-int ibgts(struct gpib_board *board)
-{
- int status = ibstatus(board);
- int retval;
-
- if ((status & CIC) == 0)
- return -EINVAL;
-
- retval = board->interface->go_to_standby(board); /* go to standby */
-
- board->interface->update_status(board, 0);
-
- return retval;
-}
-
-static int autospoll_wait_should_wake_up(struct gpib_board *board)
-{
- int retval;
-
- mutex_lock(&board->big_gpib_mutex);
-
- retval = board->master && board->autospollers > 0 &&
- !atomic_read(&board->stuck_srq) &&
- test_and_clear_bit(SRQI_NUM, &board->status);
-
- mutex_unlock(&board->big_gpib_mutex);
- return retval;
-}
-
-static int autospoll_thread(void *board_void)
-{
- struct gpib_board *board = board_void;
- int retval = 0;
-
- dev_dbg(board->gpib_dev, "entering autospoll thread\n");
-
- while (1) {
- wait_event_interruptible(board->wait,
- kthread_should_stop() ||
- autospoll_wait_should_wake_up(board));
- dev_dbg(board->gpib_dev, "autospoll wait satisfied\n");
- if (kthread_should_stop())
- break;
-
- mutex_lock(&board->big_gpib_mutex);
- /* make sure we are still good after we have lock */
- if (board->autospollers <= 0 || board->master == 0) {
- mutex_unlock(&board->big_gpib_mutex);
- continue;
- }
- mutex_unlock(&board->big_gpib_mutex);
-
- if (try_module_get(board->provider_module)) {
- retval = autopoll_all_devices(board);
- module_put(board->provider_module);
- } else {
- dev_err(board->gpib_dev, "try_module_get() failed!\n");
- }
- if (retval <= 0) {
- dev_err(board->gpib_dev, "stuck SRQ\n");
-
- atomic_set(&board->stuck_srq, 1); // XXX could be better
- set_bit(SRQI_NUM, &board->status);
- }
- }
- return retval;
-}
-
-int ibonline(struct gpib_board *board)
-{
- int retval;
-
- if (board->online)
- return -EBUSY;
- if (!board->interface)
- return -ENODEV;
- retval = gpib_allocate_board(board);
- if (retval < 0)
- return retval;
-
- board->dev = NULL;
- board->local_ppoll_mode = 0;
- retval = board->interface->attach(board, &board->config);
- if (retval < 0) {
- board->interface->detach(board);
- return retval;
- }
- /*
- * nios2nommu on 2.6.11 uclinux kernel has weird problems
- * with autospoll thread causing huge slowdowns
- */
-#ifndef CONFIG_NIOS2
- board->autospoll_task = kthread_run(&autospoll_thread, board,
- "gpib%d_autospoll_kthread", board->minor);
- retval = IS_ERR(board->autospoll_task);
- if (retval) {
- dev_err(board->gpib_dev, "failed to create autospoll thread\n");
- board->interface->detach(board);
- return retval;
- }
-#endif
- board->online = 1;
- dev_dbg(board->gpib_dev, "board online\n");
-
- return 0;
-}
-
-/* XXX need to make sure board is generally not in use (grab board lock?) */
-int iboffline(struct gpib_board *board)
-{
- int retval;
-
- if (board->online == 0)
- return 0;
- if (!board->interface)
- return -ENODEV;
-
- if (board->autospoll_task && !IS_ERR(board->autospoll_task)) {
- retval = kthread_stop(board->autospoll_task);
- if (retval)
- dev_err(board->gpib_dev, "kthread_stop returned %i\n", retval);
- board->autospoll_task = NULL;
- }
-
- board->interface->detach(board);
- gpib_deallocate_board(board);
- board->online = 0;
- dev_dbg(board->gpib_dev, "board offline\n");
-
- return 0;
-}
-
-/*
- * IBLINES
- * Poll the GPIB control lines and return their status in buf.
- *
- * LSB (bits 0-7) - VALID lines mask (lines that can be monitored).
- * Next LSB (bits 8-15) - STATUS lines mask (lines that are currently set).
- *
- */
-int iblines(const struct gpib_board *board, short *lines)
-{
- int retval;
-
- *lines = 0;
- if (!board->interface->line_status)
- return 0;
- retval = board->interface->line_status(board);
- if (retval < 0)
- return retval;
- *lines = retval;
- return 0;
-}
-
-/*
- * IBRD
- * Read up to 'length' bytes of data from the GPIB into buf. End
- * on detection of END (EOI and or EOS) and set 'end_flag'.
- *
- * NOTE:
- * 1. The interface is placed in the controller standby
- * state prior to beginning the read.
- * 2. Prior to calling ibrd, the intended devices as well
- * as the interface board itself must be addressed by
- * calling ibcmd.
- */
-
-int ibrd(struct gpib_board *board, u8 *buf, size_t length, int *end_flag, size_t *nbytes)
-{
- ssize_t ret = 0;
- int retval;
- size_t bytes_read;
-
- *nbytes = 0;
- *end_flag = 0;
- if (length == 0)
- return 0;
-
- if (board->master) {
- retval = ibgts(board);
- if (retval < 0)
- return retval;
- }
- /*
- * XXX resetting timer here could cause timeouts take longer than they should,
- * since read_ioctl calls this
- * function in a loop, there is probably a similar problem with writes/commands
- */
- os_start_timer(board, board->usec_timeout);
-
- do {
- ret = board->interface->read(board, buf, length - *nbytes, end_flag, &bytes_read);
- if (ret < 0)
- goto ibrd_out;
-
- buf += bytes_read;
- *nbytes += bytes_read;
- if (need_resched())
- schedule();
- } while (ret == 0 && *nbytes > 0 && *nbytes < length && *end_flag == 0);
-ibrd_out:
- os_remove_timer(board);
-
- return ret;
-}
-
-/*
- * IBRPP
- * Conduct a parallel poll and return the byte in buf.
- *
- * NOTE:
- * 1. Prior to conducting the poll the interface is placed
- * in the controller active state.
- */
-int ibrpp(struct gpib_board *board, u8 *result)
-{
- int retval = 0;
-
- os_start_timer(board, board->usec_timeout);
- retval = ibcac(board, 1, 1);
- if (retval)
- return -1;
-
- retval = board->interface->parallel_poll(board, result);
-
- os_remove_timer(board);
- return retval;
-}
-
-int ibppc(struct gpib_board *board, u8 configuration)
-{
- configuration &= 0x1f;
- board->interface->parallel_poll_configure(board, configuration);
- board->parallel_poll_configuration = configuration;
-
- return 0;
-}
-
-int ibrsv2(struct gpib_board *board, u8 status_byte, int new_reason_for_service)
-{
- int board_status = ibstatus(board);
- const unsigned int MSS = status_byte & request_service_bit;
-
- if ((board_status & CIC))
- return -EINVAL;
-
- if (MSS == 0 && new_reason_for_service)
- return -EINVAL;
-
- if (board->interface->serial_poll_response2) {
- board->interface->serial_poll_response2(board, status_byte, new_reason_for_service);
- // fall back on simpler serial_poll_response if the behavior would be the same
- } else if (board->interface->serial_poll_response &&
- (MSS == 0 || (MSS && new_reason_for_service))) {
- board->interface->serial_poll_response(board, status_byte);
- } else {
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-/*
- * IBSIC
- * Send IFC for at least 100 microseconds.
- *
- * NOTE:
- * 1. Ibsic must be called prior to the first call to
- * ibcmd in order to initialize the bus and enable the
- * interface to leave the controller idle state.
- */
-int ibsic(struct gpib_board *board, unsigned int usec_duration)
-{
- if (board->master == 0)
- return -EINVAL;
-
- if (usec_duration < 100)
- usec_duration = 100;
- if (usec_duration > 1000)
- usec_duration = 1000;
-
- dev_dbg(board->gpib_dev, "sending interface clear, delay = %ius\n", usec_duration);
- board->interface->interface_clear(board, 1);
- udelay(usec_duration);
- board->interface->interface_clear(board, 0);
-
- return 0;
-}
-
-int ibrsc(struct gpib_board *board, int request_control)
-{
- int retval;
-
- if (!board->interface->request_system_control)
- return -EPERM;
-
- retval = board->interface->request_system_control(board, request_control);
-
- if (retval)
- return retval;
-
- board->master = request_control != 0;
-
- return 0;
-}
-
-/*
- * IBSRE
- * Send REN true if v is non-zero or false if v is zero.
- */
-int ibsre(struct gpib_board *board, int enable)
-{
- if (board->master == 0)
- return -EINVAL;
-
- board->interface->remote_enable(board, enable); /* set or clear REN */
- if (!enable)
- usleep_range(100, 150);
-
- return 0;
-}
-
-/*
- * IBPAD
- * change the GPIB address of the interface board. The address
- * must be 0 through 30. ibonl resets the address to PAD.
- */
-int ibpad(struct gpib_board *board, unsigned int addr)
-{
- if (addr > MAX_GPIB_PRIMARY_ADDRESS)
- return -EINVAL;
-
- board->pad = addr;
- if (board->online)
- board->interface->primary_address(board, board->pad);
- dev_dbg(board->gpib_dev, "set primary addr to %i\n", board->pad);
- return 0;
-}
-
-/*
- * IBSAD
- * change the secondary GPIB address of the interface board.
- * The address must be 0 through 30, or negative disables. ibonl resets the
- * address to SAD.
- */
-int ibsad(struct gpib_board *board, int addr)
-{
- if (addr > MAX_GPIB_SECONDARY_ADDRESS)
- return -EINVAL;
- board->sad = addr;
- if (board->online) {
- if (board->sad >= 0)
- board->interface->secondary_address(board, board->sad, 1);
- else
- board->interface->secondary_address(board, 0, 0);
- }
- dev_dbg(board->gpib_dev, "set secondary addr to %i\n", board->sad);
-
- return 0;
-}
-
-/*
- * IBEOS
- * Set the end-of-string modes for I/O operations to v.
- *
- */
-int ibeos(struct gpib_board *board, int eos, int eosflags)
-{
- int retval;
-
- if (eosflags & ~EOS_MASK)
- return -EINVAL;
- if (eosflags & REOS) {
- retval = board->interface->enable_eos(board, eos, eosflags & BIN);
- } else {
- board->interface->disable_eos(board);
- retval = 0;
- }
- return retval;
-}
-
-int ibstatus(struct gpib_board *board)
-{
- return general_ibstatus(board, NULL, 0, 0, NULL);
-}
-
-int general_ibstatus(struct gpib_board *board, const struct gpib_status_queue *device,
- int clear_mask, int set_mask, struct gpib_descriptor *desc)
-{
- int status = 0;
- short line_status;
-
- if (board->private_data) {
- status = board->interface->update_status(board, clear_mask);
- /*
- * XXX should probably stop having drivers use TIMO bit in
- * board->status to avoid confusion
- */
- status &= ~TIMO;
- /* get real SRQI status if we can */
- if (iblines(board, &line_status) == 0) {
- if ((line_status & VALID_SRQ)) {
- if ((line_status & BUS_SRQ))
- status |= SRQI;
- else
- status &= ~SRQI;
- }
- }
- }
- if (device)
- if (num_status_bytes(device))
- status |= RQS;
-
- if (desc) {
- if (set_mask & CMPL)
- atomic_set(&desc->io_in_progress, 0);
- else if (clear_mask & CMPL)
- atomic_set(&desc->io_in_progress, 1);
-
- if (atomic_read(&desc->io_in_progress))
- status &= ~CMPL;
- else
- status |= CMPL;
- }
- if (num_gpib_events(&board->event_queue))
- status |= EVENT;
- else
- status &= ~EVENT;
-
- return status;
-}
-
-struct wait_info {
- struct gpib_board *board;
- struct timer_list timer;
- int timed_out;
- unsigned long usec_timeout;
-};
-
-static void wait_timeout(struct timer_list *t)
-{
- struct wait_info *winfo = timer_container_of(winfo, t, timer);
-
- winfo->timed_out = 1;
- wake_up_interruptible(&winfo->board->wait);
-}
-
-static void init_wait_info(struct wait_info *winfo)
-{
- winfo->board = NULL;
- winfo->timed_out = 0;
- timer_setup_on_stack(&winfo->timer, wait_timeout, 0);
-}
-
-static int wait_satisfied(struct wait_info *winfo, struct gpib_status_queue *status_queue,
- int wait_mask, int *status, struct gpib_descriptor *desc)
-{
- struct gpib_board *board = winfo->board;
- int temp_status;
-
- if (mutex_lock_interruptible(&board->big_gpib_mutex))
- return -ERESTARTSYS;
-
- temp_status = general_ibstatus(board, status_queue, 0, 0, desc);
-
- mutex_unlock(&board->big_gpib_mutex);
-
- if (winfo->timed_out)
- temp_status |= TIMO;
- else
- temp_status &= ~TIMO;
- if (wait_mask & temp_status) {
- *status = temp_status;
- return 1;
- }
-// XXX does wait for END work?
- return 0;
-}
-
-/* install timer interrupt handler */
-static void start_wait_timer(struct wait_info *winfo)
-/* Starts the timeout task */
-{
- winfo->timed_out = 0;
-
- if (winfo->usec_timeout > 0)
- mod_timer(&winfo->timer, jiffies + usec_to_jiffies(winfo->usec_timeout));
-}
-
-static void remove_wait_timer(struct wait_info *winfo)
-{
- timer_delete_sync(&winfo->timer);
- timer_destroy_on_stack(&winfo->timer);
-}
-
-/*
- * IBWAIT
- * Check or wait for a GPIB event to occur. The mask argument
- * is a bit vector corresponding to the status bit vector. It
- * has a bit set for each condition which can terminate the wait
- * If the mask is 0 then
- * no condition is waited for.
- */
-int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask,
- int *status, unsigned long usec_timeout, struct gpib_descriptor *desc)
-{
- int retval = 0;
- struct gpib_status_queue *status_queue;
- struct wait_info winfo;
-
- if (desc->is_board)
- status_queue = NULL;
- else
- status_queue = get_gpib_status_queue(board, desc->pad, desc->sad);
-
- if (wait_mask == 0) {
- *status = general_ibstatus(board, status_queue, clear_mask, set_mask, desc);
- return 0;
- }
-
- mutex_unlock(&board->big_gpib_mutex);
-
- init_wait_info(&winfo);
- winfo.board = board;
- winfo.usec_timeout = usec_timeout;
- start_wait_timer(&winfo);
-
- if (wait_event_interruptible(board->wait, wait_satisfied(&winfo, status_queue,
- wait_mask, status, desc))) {
- dev_dbg(board->gpib_dev, "wait interrupted\n");
- retval = -ERESTARTSYS;
- }
- remove_wait_timer(&winfo);
-
- if (retval)
- return retval;
- if (mutex_lock_interruptible(&board->big_gpib_mutex))
- return -ERESTARTSYS;
-
- /* make sure we only clear status bits that we are reporting */
- if (*status & clear_mask || set_mask)
- general_ibstatus(board, status_queue, *status & clear_mask, set_mask, NULL);
-
- return 0;
-}
-
-/*
- * IBWRT
- * Write cnt bytes of data from buf to the GPIB. The write
- * operation terminates only on I/O complete.
- *
- * NOTE:
- * 1. Prior to beginning the write, the interface is
- * placed in the controller standby state.
- * 2. Prior to calling ibwrt, the intended devices as
- * well as the interface board itself must be
- * addressed by calling ibcmd.
- */
-int ibwrt(struct gpib_board *board, u8 *buf, size_t cnt, int send_eoi, size_t *bytes_written)
-{
- int ret = 0;
- int retval;
-
- if (cnt == 0)
- return 0;
-
- if (board->master) {
- retval = ibgts(board);
- if (retval < 0)
- return retval;
- }
- os_start_timer(board, board->usec_timeout);
- ret = board->interface->write(board, buf, cnt, send_eoi, bytes_written);
-
- if (io_timed_out(board))
- ret = -ETIMEDOUT;
-
- os_remove_timer(board);
-
- return ret;
-}
-
diff --git a/drivers/staging/gpib/common/ibsys.h b/drivers/staging/gpib/common/ibsys.h
deleted file mode 100644
index e5a148f513a8..000000000000
--- a/drivers/staging/gpib/common/ibsys.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#include "gpibP.h"
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-
-#define MAX_GPIB_PRIMARY_ADDRESS 30
-#define MAX_GPIB_SECONDARY_ADDRESS 31
-
-int gpib_allocate_board(struct gpib_board *board);
-void gpib_deallocate_board(struct gpib_board *board);
-
-unsigned int num_status_bytes(const struct gpib_status_queue *dev);
-int push_status_byte(struct gpib_board *board, struct gpib_status_queue *device,
- u8 poll_byte);
-int pop_status_byte(struct gpib_board *board, struct gpib_status_queue *device,
- u8 *poll_byte);
-struct gpib_status_queue *get_gpib_status_queue(struct gpib_board *board,
- unsigned int pad, int sad);
-int get_serial_poll_byte(struct gpib_board *board, unsigned int pad, int sad,
- unsigned int usec_timeout, u8 *poll_byte);
-int autopoll_all_devices(struct gpib_board *board);
diff --git a/drivers/staging/gpib/eastwood/Makefile b/drivers/staging/gpib/eastwood/Makefile
deleted file mode 100644
index 384825195f77..000000000000
--- a/drivers/staging/gpib/eastwood/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-
-obj-$(CONFIG_GPIB_FLUKE) += fluke_gpib.o
-
diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.c b/drivers/staging/gpib/eastwood/fluke_gpib.c
deleted file mode 100644
index 3ae848e3f738..000000000000
--- a/drivers/staging/gpib/eastwood/fluke_gpib.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * GPIB Driver for Fluke cda devices. Basically, its a driver for a (bugfixed)
- * cb7210 connected to channel 0 of a pl330 dma controller.
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * copyright: (C) 2006, 2010, 2015 Fluke Corporation
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "fluke_gpib.h"
-
-#include "gpibP.h"
-#include <linux/dma-mapping.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB Driver for Fluke cda devices");
-
-static int fluke_attach_holdoff_all(struct gpib_board *board,
- const struct gpib_board_config *config);
-static int fluke_attach_holdoff_end(struct gpib_board *board,
- const struct gpib_board_config *config);
-static void fluke_detach(struct gpib_board *board);
-static int fluke_config_dma(struct gpib_board *board, int output);
-static irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board);
-
-static struct platform_device *fluke_gpib_pdev;
-
-static u8 fluke_locking_read_byte(struct nec7210_priv *nec_priv, unsigned int register_number)
-{
- u8 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- retval = fluke_read_byte_nolock(nec_priv, register_number);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
- return retval;
-}
-
-static void fluke_locking_write_byte(struct nec7210_priv *nec_priv, u8 byte,
- unsigned int register_number)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- fluke_write_byte_nolock(nec_priv, byte, register_number);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
-}
-
-// wrappers for interface functions
-static int fluke_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-}
-
-static int fluke_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int fluke_command(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int fluke_take_control(struct gpib_board *board, int synchronous)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int fluke_go_to_standby(struct gpib_board *board)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int fluke_request_system_control(struct gpib_board *board, int request_control)
-{
- struct fluke_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- return nec7210_request_system_control(board, nec_priv, request_control);
-}
-
-static void fluke_interface_clear(struct gpib_board *board, int assert)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void fluke_remote_enable(struct gpib_board *board, int enable)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int fluke_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void fluke_disable_eos(struct gpib_board *board)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int fluke_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int fluke_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int fluke_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int fluke_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void fluke_parallel_poll_configure(struct gpib_board *board, u8 configuration)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
-}
-
-static void fluke_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void fluke_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct fluke_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static u8 fluke_serial_poll_status(struct gpib_board *board)
-{
- struct fluke_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static void fluke_return_to_local(struct gpib_board *board)
-{
- struct fluke_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- write_byte(nec_priv, AUX_RTL2, AUXMR);
- udelay(1);
- write_byte(nec_priv, AUX_RTL, AUXMR);
-}
-
-static int fluke_line_status(const struct gpib_board *board)
-{
- int status = VALID_ALL;
- int bsr_bits;
- struct fluke_priv *e_priv;
-
- e_priv = board->private_data;
-
- bsr_bits = fluke_paged_read_byte(e_priv, BUS_STATUS, BUS_STATUS_PAGE);
-
- if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BUS_REN;
- if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BUS_IFC;
- if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BUS_SRQ;
- if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BUS_EOI;
- if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BUS_NRFD;
- if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BUS_NDAC;
- if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BUS_DAV;
- if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BUS_ATN;
-
- return status;
-}
-
-static int fluke_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned int retval;
-
- retval = nec7210_t1_delay(board, nec_priv, nano_sec);
-
- if (nano_sec <= 350) {
- write_byte(nec_priv, AUX_HI_SPEED, AUXMR);
- retval = 350;
- } else {
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- }
- return retval;
-}
-
-static int lacs_or_read_ready(struct gpib_board *board)
-{
- const struct fluke_priv *e_priv = board->private_data;
- const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = test_bit(LACS_NUM, &board->status) || test_bit(READ_READY_BN, &nec_priv->state);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-/*
- * Wait until it is possible for a read to do something useful. This
- * is not essential, it only exists to prevent RFD holdoff from being released pointlessly.
- */
-static int wait_for_read(struct gpib_board *board)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- lacs_or_read_ready(board) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- return retval;
-}
-
-/*
- * Check if the SH state machine is in SGNS. We check twice since there is a very small chance
- * we could be blowing through SGNS from SIDS to SDYS if there is already a
- * byte available in the handshake state machine. We are interested
- * in the case where the handshake is stuck in SGNS due to no byte being
- * available to the chip (and thus we can be confident a dma transfer will
- * result in at least one byte making it into the chip). This matters
- * because we want to be confident before sending a "send eoi" auxilary
- * command that we will be able to also put the associated data byte
- * in the chip before any potential timeout.
- */
-static int source_handshake_is_sgns(struct fluke_priv *e_priv)
-{
- int i;
-
- for (i = 0; i < 2; ++i) {
- if ((fluke_paged_read_byte(e_priv, STATE1_REG, STATE1_PAGE) &
- SOURCE_HANDSHAKE_MASK) != SOURCE_HANDSHAKE_SGNS_BITS) {
- return 0;
- }
- }
- return 1;
-}
-
-static int source_handshake_is_sids_or_sgns(struct fluke_priv *e_priv)
-{
- unsigned int source_handshake_bits;
-
- source_handshake_bits = fluke_paged_read_byte(e_priv, STATE1_REG, STATE1_PAGE) &
- SOURCE_HANDSHAKE_MASK;
-
- return (source_handshake_bits == SOURCE_HANDSHAKE_SGNS_BITS) ||
- (source_handshake_bits == SOURCE_HANDSHAKE_SIDS_BITS);
-}
-
-/*
- * Wait until the gpib chip is ready to accept a data out byte.
- * If the chip is SGNS it is probably waiting for a a byte to
- * be written to it.
- */
-static int wait_for_data_out_ready(struct gpib_board *board)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- (test_bit(TACS_NUM, &board->status) &&
- source_handshake_is_sgns(e_priv)) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- return retval;
-}
-
-static int wait_for_sids_or_sgns(struct gpib_board *board)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- source_handshake_is_sids_or_sgns(e_priv) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- return retval;
-}
-
-static void fluke_dma_callback(void *arg)
-{
- struct gpib_board *board = arg;
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE);
- wake_up_interruptible(&board->wait);
-
- fluke_gpib_internal_interrupt(board);
- clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
- clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static int fluke_dma_write(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
- int retval = 0;
- dma_addr_t address;
- struct dma_async_tx_descriptor *tx_desc;
-
- *bytes_written = 0;
-
- if (WARN_ON_ONCE(length > e_priv->dma_buffer_size))
- return -EFAULT;
- dmaengine_terminate_all(e_priv->dma_channel);
- // write-clear counter
- writel(0x0, e_priv->write_transfer_counter);
-
- memcpy(e_priv->dma_buffer, buffer, length);
- address = dma_map_single(board->dev, e_priv->dma_buffer,
- length, DMA_TO_DEVICE);
- /* program dma controller */
- retval = fluke_config_dma(board, 1);
- if (retval)
- goto cleanup;
-
- tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!tx_desc) {
- dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
- retval = -ENOMEM;
- goto cleanup;
- }
- tx_desc->callback = fluke_dma_callback;
- tx_desc->callback_param = board;
-
- spin_lock_irqsave(&board->spinlock, flags);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO);
- dmaengine_submit(tx_desc);
- dma_async_issue_pending(e_priv->dma_channel);
-
- clear_bit(WRITE_READY_BN, &nec_priv->state);
- set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- // suspend until message is sent
- if (wait_event_interruptible(board->wait,
- ((readl(e_priv->write_transfer_counter) &
- write_transfer_counter_mask) == length) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state))
- retval = -EIO;
- // disable board's dma
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0);
-
- dmaengine_terminate_all(e_priv->dma_channel);
- // make sure fluke_dma_callback got called
- if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state))
- fluke_dma_callback(board);
-
- /*
- * if everything went fine, try to wait until last byte is actually
- * transmitted across gpib (but don't try _too_ hard)
- */
- if (retval == 0)
- retval = wait_for_sids_or_sgns(board);
-
- *bytes_written = readl(e_priv->write_transfer_counter) & write_transfer_counter_mask;
- if (WARN_ON_ONCE(*bytes_written > length))
- return -EFAULT;
-
-cleanup:
- dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE);
- return retval;
-}
-
-static int fluke_accel_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remainder = length;
- size_t transfer_size;
- ssize_t retval = 0;
- size_t dma_remainder = remainder;
-
- if (!e_priv->dma_channel) {
- dev_err(board->gpib_dev, "No dma channel available, cannot do accel write.");
- return -ENXIO;
- }
-
- *bytes_written = 0;
- if (length < 1)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
-
- if (send_eoi)
- --dma_remainder;
-
- while (dma_remainder > 0) {
- size_t num_bytes;
-
- retval = wait_for_data_out_ready(board);
- if (retval < 0)
- break;
-
- transfer_size = (e_priv->dma_buffer_size < dma_remainder) ?
- e_priv->dma_buffer_size : dma_remainder;
- retval = fluke_dma_write(board, buffer, transfer_size, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- break;
- dma_remainder -= num_bytes;
- remainder -= num_bytes;
- buffer += num_bytes;
- if (need_resched())
- schedule();
- }
- if (retval < 0)
- return retval;
- // handle sending of last byte with eoi
- if (send_eoi) {
- size_t num_bytes;
-
- if (WARN_ON_ONCE(remainder != 1))
- return -EFAULT;
-
- /*
- * wait until we are sure we will be able to write the data byte
- * into the chip before we send AUX_SEOI. This prevents a timeout
- * scenerio where we send AUX_SEOI but then timeout without getting
- * any bytes into the gpib chip. This will result in the first byte
- * of the next write having a spurious EOI set on the first byte.
- */
- retval = wait_for_data_out_ready(board);
- if (retval < 0)
- return retval;
-
- write_byte(nec_priv, AUX_SEOI, AUXMR);
- retval = fluke_dma_write(board, buffer, remainder, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- remainder -= num_bytes;
- }
- return 0;
-}
-
-static int fluke_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
-{
- struct dma_tx_state state;
- int result;
-
- result = dmaengine_pause(chan);
- if (result < 0) {
- pr_err("dma pause failed?\n");
- return result;
- }
- dmaengine_tx_status(chan, cookie, &state);
- /*
- * hardware doesn't support resume, so dont call this
- * method unless the dma transfer is done.
- */
- return state.residue;
-}
-
-static int fluke_dma_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
- unsigned long flags;
- int residue;
- dma_addr_t bus_address;
- struct dma_async_tx_descriptor *tx_desc;
- dma_cookie_t dma_cookie;
- int i;
- static const int timeout = 10;
-
- *bytes_read = 0;
- *end = 0;
- if (length == 0)
- return 0;
-
- bus_address = dma_map_single(board->dev, e_priv->dma_buffer,
- length, DMA_FROM_DEVICE);
-
- /* program dma controller */
- retval = fluke_config_dma(board, 0);
- if (retval) {
- dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
- return retval;
- }
- tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel,
- bus_address, length, DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!tx_desc) {
- dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
- dma_unmap_single(NULL, bus_address, length, DMA_FROM_DEVICE);
- return -EIO;
- }
- tx_desc->callback = fluke_dma_callback;
- tx_desc->callback_param = board;
-
- spin_lock_irqsave(&board->spinlock, flags);
- // enable nec7210 dma
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI);
-
- dma_cookie = dmaengine_submit(tx_desc);
- dma_async_issue_pending(e_priv->dma_channel);
-
- set_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
- clear_bit(READ_READY_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
- // wait for data to transfer
- if (wait_event_interruptible(board->wait,
- test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) == 0 ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
-
- /*
- * If we woke up because of end, wait until the dma transfer has pulled
- * the data byte associated with the end before we cancel the dma transfer.
- */
- if (test_bit(RECEIVED_END_BN, &nec_priv->state)) {
- for (i = 0; i < timeout; ++i) {
- if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state) == 0)
- break;
- if ((read_byte(nec_priv, ADR0) & DATA_IN_STATUS) == 0)
- break;
- usleep_range(10, 15);
- }
- if (i == timeout)
- pr_warn("fluke_gpib: timeout waiting for dma to transfer end data byte.\n");
- }
-
- // stop the dma transfer
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- /*
- * delay a little just to make sure any bytes in dma controller's fifo get
- * written to memory before we disable it
- */
- usleep_range(10, 15);
- residue = fluke_get_dma_residue(e_priv->dma_channel, dma_cookie);
- if (WARN_ON_ONCE(residue > length || residue < 0))
- return -EFAULT;
- *bytes_read += length - residue;
- dmaengine_terminate_all(e_priv->dma_channel);
- // make sure fluke_dma_callback got called
- if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state))
- fluke_dma_callback(board);
-
- dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
- memcpy(buffer, e_priv->dma_buffer, *bytes_read);
-
- /*
- * If we got an end interrupt, figure out if it was
- * associated with the last byte we dma'd or with a
- * byte still sitting on the cb7210.
- */
- spin_lock_irqsave(&board->spinlock, flags);
- if (test_bit(READ_READY_BN, &nec_priv->state) == 0) {
- /*
- * There is no byte sitting on the cb7210. If we
- * saw an end interrupt, we need to deal with it now
- */
- if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state))
- *end = 1;
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-
-static int fluke_accel_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remain = length;
- size_t transfer_size;
- int retval = 0;
- size_t dma_nbytes;
-
- *end = 0;
- *bytes_read = 0;
-
- smp_mb__before_atomic();
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
- smp_mb__after_atomic();
-
- retval = wait_for_read(board);
- if (retval < 0)
- return retval;
-
- nec7210_release_rfd_holdoff(board, nec_priv);
-
- while (remain > 0) {
- transfer_size = (e_priv->dma_buffer_size < remain) ?
- e_priv->dma_buffer_size : remain;
- retval = fluke_dma_read(board, buffer, transfer_size, end, &dma_nbytes);
- remain -= dma_nbytes;
- buffer += dma_nbytes;
- *bytes_read += dma_nbytes;
- if (*end)
- break;
- if (retval < 0)
- return retval;
- if (need_resched())
- schedule();
- }
-
- return retval;
-}
-
-static struct gpib_interface fluke_unaccel_interface = {
- .name = "fluke_unaccel",
- .attach = fluke_attach_holdoff_all,
- .detach = fluke_detach,
- .read = fluke_read,
- .write = fluke_write,
- .command = fluke_command,
- .take_control = fluke_take_control,
- .go_to_standby = fluke_go_to_standby,
- .request_system_control = fluke_request_system_control,
- .interface_clear = fluke_interface_clear,
- .remote_enable = fluke_remote_enable,
- .enable_eos = fluke_enable_eos,
- .disable_eos = fluke_disable_eos,
- .parallel_poll = fluke_parallel_poll,
- .parallel_poll_configure = fluke_parallel_poll_configure,
- .parallel_poll_response = fluke_parallel_poll_response,
- .line_status = fluke_line_status,
- .update_status = fluke_update_status,
- .primary_address = fluke_primary_address,
- .secondary_address = fluke_secondary_address,
- .serial_poll_response = fluke_serial_poll_response,
- .serial_poll_status = fluke_serial_poll_status,
- .t1_delay = fluke_t1_delay,
- .return_to_local = fluke_return_to_local,
-};
-
-/*
- * fluke_hybrid uses dma for writes but not for reads. Added
- * to deal with occasional corruption of bytes seen when doing dma
- * reads. From looking at the cb7210 vhdl, I believe the corruption
- * is due to a hardware bug triggered by the cpu reading a cb7210
- * }
- * register just as the dma controller is also doing a read.
- */
-
-static struct gpib_interface fluke_hybrid_interface = {
- .name = "fluke_hybrid",
- .attach = fluke_attach_holdoff_all,
- .detach = fluke_detach,
- .read = fluke_read,
- .write = fluke_accel_write,
- .command = fluke_command,
- .take_control = fluke_take_control,
- .go_to_standby = fluke_go_to_standby,
- .request_system_control = fluke_request_system_control,
- .interface_clear = fluke_interface_clear,
- .remote_enable = fluke_remote_enable,
- .enable_eos = fluke_enable_eos,
- .disable_eos = fluke_disable_eos,
- .parallel_poll = fluke_parallel_poll,
- .parallel_poll_configure = fluke_parallel_poll_configure,
- .parallel_poll_response = fluke_parallel_poll_response,
- .line_status = fluke_line_status,
- .update_status = fluke_update_status,
- .primary_address = fluke_primary_address,
- .secondary_address = fluke_secondary_address,
- .serial_poll_response = fluke_serial_poll_response,
- .serial_poll_status = fluke_serial_poll_status,
- .t1_delay = fluke_t1_delay,
- .return_to_local = fluke_return_to_local,
-};
-
-static struct gpib_interface fluke_interface = {
- .name = "fluke",
- .attach = fluke_attach_holdoff_end,
- .detach = fluke_detach,
- .read = fluke_accel_read,
- .write = fluke_accel_write,
- .command = fluke_command,
- .take_control = fluke_take_control,
- .go_to_standby = fluke_go_to_standby,
- .request_system_control = fluke_request_system_control,
- .interface_clear = fluke_interface_clear,
- .remote_enable = fluke_remote_enable,
- .enable_eos = fluke_enable_eos,
- .disable_eos = fluke_disable_eos,
- .parallel_poll = fluke_parallel_poll,
- .parallel_poll_configure = fluke_parallel_poll_configure,
- .parallel_poll_response = fluke_parallel_poll_response,
- .line_status = fluke_line_status,
- .update_status = fluke_update_status,
- .primary_address = fluke_primary_address,
- .secondary_address = fluke_secondary_address,
- .serial_poll_response = fluke_serial_poll_response,
- .serial_poll_status = fluke_serial_poll_status,
- .t1_delay = fluke_t1_delay,
- .return_to_local = fluke_return_to_local,
-};
-
-irqreturn_t fluke_gpib_internal_interrupt(struct gpib_board *board)
-{
- int status0, status1, status2;
- struct fluke_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- int retval = IRQ_NONE;
-
- if (read_byte(nec_priv, ADR0) & DATA_IN_STATUS)
- set_bit(READ_READY_BN, &nec_priv->state);
-
- status0 = fluke_paged_read_byte(priv, ISR0_IMR0, ISR0_IMR0_PAGE);
- status1 = read_byte(nec_priv, ISR1);
- status2 = read_byte(nec_priv, ISR2);
-
- if (status0 & FLUKE_IFCI_BIT) {
- push_gpib_event(board, EVENT_IFC);
- retval = IRQ_HANDLED;
- }
-
- if (nec7210_interrupt_have_status(board, nec_priv, status1, status2) == IRQ_HANDLED)
- retval = IRQ_HANDLED;
-
- if (read_byte(nec_priv, ADR0) & DATA_IN_STATUS) {
- if (test_bit(RFD_HOLDOFF_BN, &nec_priv->state))
- set_bit(READ_READY_BN, &nec_priv->state);
- else
- clear_bit(READ_READY_BN, &nec_priv->state);
- }
-
- if (retval == IRQ_HANDLED)
- wake_up_interruptible(&board->wait);
-
- return retval;
-}
-
-static irqreturn_t fluke_gpib_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = fluke_gpib_internal_interrupt(board);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-static int fluke_allocate_private(struct gpib_board *board)
-{
- struct fluke_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct fluke_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct fluke_priv));
- init_nec7210_private(&priv->nec7210_priv);
- priv->dma_buffer_size = 0x7ff;
- priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL);
- if (!priv->dma_buffer)
- return -ENOMEM;
- return 0;
-}
-
-static void fluke_generic_detach(struct gpib_board *board)
-{
- if (board->private_data) {
- struct fluke_priv *e_priv = board->private_data;
-
- kfree(e_priv->dma_buffer);
- kfree(board->private_data);
- board->private_data = NULL;
- }
-}
-
-// generic part of attach functions shared by all cb7210 boards
-static int fluke_generic_attach(struct gpib_board *board)
-{
- struct fluke_priv *e_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- board->status = 0;
-
- retval = fluke_allocate_private(board);
- if (retval < 0)
- return retval;
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
- nec_priv->read_byte = fluke_locking_read_byte;
- nec_priv->write_byte = fluke_locking_write_byte;
- nec_priv->offset = fluke_reg_offset;
- nec_priv->type = CB7210;
- return 0;
-}
-
-static int fluke_config_dma(struct gpib_board *board, int output)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct dma_slave_config config;
-
- config.src_maxburst = 1;
- config.dst_maxburst = 1;
- config.device_fc = true;
-
- if (output) {
- config.direction = DMA_MEM_TO_DEV;
- config.src_addr = 0;
- config.dst_addr = e_priv->dma_port_res->start;
- config.src_addr_width = 1;
- config.dst_addr_width = 1;
- } else {
- config.direction = DMA_DEV_TO_MEM;
- config.src_addr = e_priv->dma_port_res->start;
- config.dst_addr = 0;
- config.src_addr_width = 1;
- config.dst_addr_width = 1;
- }
- return dmaengine_slave_config(e_priv->dma_channel, &config);
-}
-
-static int fluke_init(struct fluke_priv *e_priv, struct gpib_board *board, int handshake_mode)
-{
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
-
- nec7210_board_reset(nec_priv, board);
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- /*
- * set clock register for driving frequency
- * ICR should be set to clock in megahertz (1-15) and to zero
- * for clocks faster than 15 MHz (max 20MHz)
- */
- write_byte(nec_priv, ICR | 10, AUXMR);
- nec7210_set_handshake_mode(board, nec_priv, handshake_mode);
-
- nec7210_board_online(nec_priv, board);
-
- /* poll so we can detect ATN changes */
- if (gpib_request_pseudo_irq(board, fluke_gpib_interrupt)) {
- dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
- return -EINVAL;
- }
-
- fluke_paged_write_byte(e_priv, FLUKE_IFCIE_BIT, ISR0_IMR0, ISR0_IMR0_PAGE);
- return 0;
-}
-
-/*
- * This function is passed to dma_request_channel() in order to
- * select the pl330 dma channel which has been hardwired to
- * the gpib controller.
- */
-static bool gpib_dma_channel_filter(struct dma_chan *chan, void *filter_param)
-{
- // select the channel which is wired to the gpib chip
- return chan->chan_id == 0;
-}
-
-static int fluke_attach_impl(struct gpib_board *board, const struct gpib_board_config *config,
- unsigned int handshake_mode)
-{
- struct fluke_priv *e_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- int retval;
- int irq;
- struct resource *res;
- dma_cap_mask_t dma_cap;
-
- if (!fluke_gpib_pdev) {
- dev_err(board->gpib_dev, "No fluke device was found, attach failed.\n");
- return -ENODEV;
- }
-
- retval = fluke_generic_attach(board);
- if (retval)
- return retval;
-
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
- nec_priv->offset = fluke_reg_offset;
- board->dev = &fluke_gpib_pdev->dev;
-
- res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource\n");
- return -ENODEV;
- }
-
- if (request_mem_region(res->start,
- resource_size(res),
- fluke_gpib_pdev->name) == NULL) {
- dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n");
- return -ENXIO;
- }
- e_priv->gpib_iomem_res = res;
-
- nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
- if (!nec_priv->mmiobase) {
- dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n");
- return -ENOMEM;
- }
-
- res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for gpib dma port\n");
- return -ENODEV;
- }
- if (request_mem_region(res->start,
- resource_size(res),
- fluke_gpib_pdev->name) == NULL) {
- dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n");
- return -ENXIO;
- }
- e_priv->dma_port_res = res;
-
- res = platform_get_resource(fluke_gpib_pdev, IORESOURCE_MEM, 2);
- if (!res) {
- dev_err(&fluke_gpib_pdev->dev, "Unable to locate mmio resource for write transfer counter\n");
- return -ENODEV;
- }
-
- if (request_mem_region(res->start,
- resource_size(res),
- fluke_gpib_pdev->name) == NULL) {
- dev_err(&fluke_gpib_pdev->dev, "cannot claim registers\n");
- return -ENXIO;
- }
- e_priv->write_transfer_counter_res = res;
-
- e_priv->write_transfer_counter = ioremap(e_priv->write_transfer_counter_res->start,
- resource_size(e_priv->write_transfer_counter_res));
- if (!e_priv->write_transfer_counter) {
- dev_err(&fluke_gpib_pdev->dev, "Could not map I/O memory\n");
- return -ENOMEM;
- }
-
- irq = platform_get_irq(fluke_gpib_pdev, 0);
- if (irq < 0)
- return -EBUSY;
- retval = request_irq(irq, fluke_gpib_interrupt, isr_flags, fluke_gpib_pdev->name, board);
- if (retval) {
- dev_err(&fluke_gpib_pdev->dev,
- "cannot register interrupt handler err=%d\n",
- retval);
- return retval;
- }
- e_priv->irq = irq;
-
- dma_cap_zero(dma_cap);
- dma_cap_set(DMA_SLAVE, dma_cap);
- e_priv->dma_channel = dma_request_channel(dma_cap, gpib_dma_channel_filter, NULL);
- if (!e_priv->dma_channel) {
- dev_err(board->gpib_dev, "failed to allocate a dma channel.\n");
- /*
- * we don't error out here because unaccel interface will still
- * work without dma
- */
- }
-
- return fluke_init(e_priv, board, handshake_mode);
-}
-
-int fluke_attach_holdoff_all(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return fluke_attach_impl(board, config, HR_HLDA);
-}
-
-int fluke_attach_holdoff_end(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return fluke_attach_impl(board, config, HR_HLDE);
-}
-
-void fluke_detach(struct gpib_board *board)
-{
- struct fluke_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (e_priv) {
- if (e_priv->dma_channel)
- dma_release_channel(e_priv->dma_channel);
- gpib_free_pseudo_irq(board);
- nec_priv = &e_priv->nec7210_priv;
-
- if (nec_priv->mmiobase) {
- fluke_paged_write_byte(e_priv, 0, ISR0_IMR0, ISR0_IMR0_PAGE);
- nec7210_board_reset(nec_priv, board);
- }
- if (e_priv->irq)
- free_irq(e_priv->irq, board);
- if (e_priv->write_transfer_counter_res) {
- release_mem_region(e_priv->write_transfer_counter_res->start,
- resource_size(e_priv->write_transfer_counter_res));
- }
- if (e_priv->dma_port_res) {
- release_mem_region(e_priv->dma_port_res->start,
- resource_size(e_priv->dma_port_res));
- }
- if (e_priv->gpib_iomem_res)
- release_mem_region(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
- }
- fluke_generic_detach(board);
-}
-
-static int fluke_gpib_probe(struct platform_device *pdev)
-{
- fluke_gpib_pdev = pdev;
- return 0;
-}
-
-static const struct of_device_id fluke_gpib_of_match[] = {
- { .compatible = "flk,fgpib-4.0"},
- { {0} }
-};
-MODULE_DEVICE_TABLE(of, fluke_gpib_of_match);
-
-static struct platform_driver fluke_gpib_platform_driver = {
- .driver = {
- .name = DRV_NAME,
- .of_match_table = fluke_gpib_of_match,
- },
- .probe = &fluke_gpib_probe
-};
-
-static int __init fluke_init_module(void)
-{
- int result;
-
- result = platform_driver_register(&fluke_gpib_platform_driver);
- if (result) {
- pr_err("platform_driver_register failed: error = %d\n", result);
- return result;
- }
-
- result = gpib_register_driver(&fluke_unaccel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_unaccel;
- }
-
- result = gpib_register_driver(&fluke_hybrid_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_hybrid;
- }
-
- result = gpib_register_driver(&fluke_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_interface;
- }
-
- return 0;
-
-err_interface:
- gpib_unregister_driver(&fluke_hybrid_interface);
-err_hybrid:
- gpib_unregister_driver(&fluke_unaccel_interface);
-err_unaccel:
- platform_driver_unregister(&fluke_gpib_platform_driver);
-
- return result;
-}
-
-static void __exit fluke_exit_module(void)
-{
- gpib_unregister_driver(&fluke_unaccel_interface);
- gpib_unregister_driver(&fluke_hybrid_interface);
- gpib_unregister_driver(&fluke_interface);
- platform_driver_unregister(&fluke_gpib_platform_driver);
-}
-
-module_init(fluke_init_module);
-module_exit(fluke_exit_module);
diff --git a/drivers/staging/gpib/eastwood/fluke_gpib.h b/drivers/staging/gpib/eastwood/fluke_gpib.h
deleted file mode 100644
index 493c200d0bbf..000000000000
--- a/drivers/staging/gpib/eastwood/fluke_gpib.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * copyright: (C) 2006, 2010, 2015 Fluke Corporation
- ***************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/dmaengine.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include "nec7210.h"
-
-struct fluke_priv {
- struct nec7210_priv nec7210_priv;
- struct resource *gpib_iomem_res;
- struct resource *write_transfer_counter_res;
- struct resource *dma_port_res;
- int irq;
- struct dma_chan *dma_channel;
- u8 *dma_buffer;
- int dma_buffer_size;
- void __iomem *write_transfer_counter;
-};
-
-// cb7210 specific registers and bits
-enum cb7210_regs {
- STATE1_REG = 0x4,
- ISR0_IMR0 = 0x6,
- BUS_STATUS = 0x7
-};
-
-enum cb7210_page_in {
- ISR0_IMR0_PAGE = 1,
- BUS_STATUS_PAGE = 1,
- STATE1_PAGE = 1
-};
-
-/* IMR0 -- Interrupt Mode Register 0 */
-enum imr0_bits {
- FLUKE_IFCIE_BIT = 0x8, /* interface clear interrupt */
-};
-
-/* ISR0 -- Interrupt Status Register 0 */
-enum isr0_bits {
- FLUKE_IFCI_BIT = 0x8, /* interface clear interrupt */
-};
-
-enum state1_bits {
- SOURCE_HANDSHAKE_SIDS_BITS = 0x0, /* source idle state */
- SOURCE_HANDSHAKE_SGNS_BITS = 0x1, /* source generate state */
- SOURCE_HANDSHAKE_SDYS_BITS = 0x2, /* source delay state */
- SOURCE_HANDSHAKE_STRS_BITS = 0x5, /* source transfer state */
- SOURCE_HANDSHAKE_MASK = 0x7
-};
-
-/*
- * we customized the cb7210 vhdl to give the "data in" status
- * on the unused bit 7 of the address0 register.
- */
-enum cb7210_address0 {
- DATA_IN_STATUS = 0x80
-};
-
-static inline int cb7210_page_in_bits(unsigned int page)
-{
- return 0x50 | (page & 0xf);
-}
-
-// don't use without locking nec_priv->register_page_lock
-static inline u8 fluke_read_byte_nolock(struct nec7210_priv *nec_priv,
- int register_num)
-{
- u8 retval;
-
- retval = readl(nec_priv->mmiobase + register_num * nec_priv->offset);
- return retval;
-}
-
-// don't use without locking nec_priv->register_page_lock
-static inline void fluke_write_byte_nolock(struct nec7210_priv *nec_priv, u8 data,
- int register_num)
-{
- writel(data, nec_priv->mmiobase + register_num * nec_priv->offset);
-}
-
-static inline u8 fluke_paged_read_byte(struct fluke_priv *e_priv,
- unsigned int register_num, unsigned int page)
-{
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- u8 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR);
- udelay(1);
- /* chip auto clears the page after a read */
- retval = fluke_read_byte_nolock(nec_priv, register_num);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
- return retval;
-}
-
-static inline void fluke_paged_write_byte(struct fluke_priv *e_priv, u8 data,
- unsigned int register_num, unsigned int page)
-{
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&nec_priv->register_page_lock, flags);
- fluke_write_byte_nolock(nec_priv, cb7210_page_in_bits(page), AUXMR);
- udelay(1);
- fluke_write_byte_nolock(nec_priv, data, register_num);
- spin_unlock_irqrestore(&nec_priv->register_page_lock, flags);
-}
-
-enum bus_status_bits {
- BSR_ATN_BIT = 0x1,
- BSR_EOI_BIT = 0x2,
- BSR_SRQ_BIT = 0x4,
- BSR_IFC_BIT = 0x8,
- BSR_REN_BIT = 0x10,
- BSR_DAV_BIT = 0x20,
- BSR_NRFD_BIT = 0x40,
- BSR_NDAC_BIT = 0x80,
-};
-
-enum cb7210_aux_cmds {
-/*
- * AUX_RTL2 is an undocumented aux command which causes cb7210 to assert
- * (and keep asserted) local rtl message. This is used in conjunction
- * with the (stupid) cb7210 implementation
- * of the normal nec7210 AUX_RTL aux command, which
- * causes the rtl message to toggle between on and off.
- */
- AUX_RTL2 = 0xd,
- AUX_NBAF = 0xe, // new byte available false (also clears seoi)
- AUX_LO_SPEED = 0x40,
- AUX_HI_SPEED = 0x41,
-};
-
-enum {
- fluke_reg_offset = 4,
- fluke_num_regs = 8,
- write_transfer_counter_mask = 0x7ff,
-};
diff --git a/drivers/staging/gpib/fmh_gpib/Makefile b/drivers/staging/gpib/fmh_gpib/Makefile
deleted file mode 100644
index cc4d9e7cd5cd..000000000000
--- a/drivers/staging/gpib/fmh_gpib/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_GPIB_FMH) += fmh_gpib.o
diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c b/drivers/staging/gpib/fmh_gpib/fmh_gpib.c
deleted file mode 100644
index f7bfb4a8e553..000000000000
--- a/drivers/staging/gpib/fmh_gpib/fmh_gpib.c
+++ /dev/null
@@ -1,1754 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * GPIB Driver for fmh_gpib_core, see
- * https://github.com/fmhess/fmh_gpib_core
- *
- * More specifically, it is a driver for the hardware arrangement described by
- * src/examples/fmh_gpib_top.vhd in the fmh_gpib_core repository.
- *
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * Copyright: (C) 2006, 2010, 2015 Fluke Corporation
- * (C) 2017 Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "fmh_gpib.h"
-
-#include "gpibP.h"
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB Driver for fmh_gpib_core");
-MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>");
-
-static irqreturn_t fmh_gpib_interrupt(int irq, void *arg);
-static int fmh_gpib_attach_holdoff_all(struct gpib_board *board,
- const struct gpib_board_config *config);
-static int fmh_gpib_attach_holdoff_end(struct gpib_board *board,
- const struct gpib_board_config *config);
-static void fmh_gpib_detach(struct gpib_board *board);
-static int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board,
- const struct gpib_board_config *config);
-static int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board,
- const struct gpib_board_config *config);
-static void fmh_gpib_pci_detach(struct gpib_board *board);
-static int fmh_gpib_config_dma(struct gpib_board *board, int output);
-static irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board);
-static struct platform_driver fmh_gpib_platform_driver;
-static struct pci_driver fmh_gpib_pci_driver;
-
-// wrappers for interface functions
-static int fmh_gpib_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-}
-
-static int fmh_gpib_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int fmh_gpib_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int fmh_gpib_take_control(struct gpib_board *board, int synchronous)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int fmh_gpib_go_to_standby(struct gpib_board *board)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int fmh_gpib_request_system_control(struct gpib_board *board, int request_control)
-{
- struct fmh_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- return nec7210_request_system_control(board, nec_priv, request_control);
-}
-
-static void fmh_gpib_interface_clear(struct gpib_board *board, int assert)
-{
- struct fmh_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void fmh_gpib_remote_enable(struct gpib_board *board, int enable)
-{
- struct fmh_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int fmh_gpib_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void fmh_gpib_disable_eos(struct gpib_board *board)
-{
- struct fmh_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int fmh_gpib_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int fmh_gpib_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int fmh_gpib_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int fmh_gpib_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void fmh_gpib_parallel_poll_configure(struct gpib_board *board, u8 configuration)
-{
- struct fmh_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, configuration);
-}
-
-static void fmh_gpib_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct fmh_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void fmh_gpib_local_parallel_poll_mode(struct gpib_board *board, int local)
-{
- struct fmh_priv *priv = board->private_data;
-
- if (local) {
- write_byte(&priv->nec7210_priv, AUX_I_REG | LOCAL_PPOLL_MODE_BIT, AUXMR);
- } else {
- /*
- * For fmh_gpib_core, remote parallel poll config mode is unaffected by the
- * state of the disable bit of the parallel poll register (unlike the tnt4882).
- * So, we don't need to worry about that.
- */
- write_byte(&priv->nec7210_priv, AUX_I_REG | 0x0, AUXMR);
- }
-}
-
-static void fmh_gpib_serial_poll_response2(struct gpib_board *board, u8 status,
- int new_reason_for_service)
-{
- struct fmh_priv *priv = board->private_data;
- unsigned long flags;
- const int MSS = status & request_service_bit;
- const int reqt = MSS && new_reason_for_service;
- const int reqf = MSS == 0;
-
- spin_lock_irqsave(&board->spinlock, flags);
- if (reqt) {
- priv->nec7210_priv.srq_pending = 1;
- clear_bit(SPOLL_NUM, &board->status);
- } else if (reqf) {
- priv->nec7210_priv.srq_pending = 0;
- }
-
- if (reqt) {
- /*
- * It may seem like a race to issue reqt before updating
- * the status byte, but it is not. The chip does not
- * issue the reqt until the SPMR is written to at
- * a later time.
- */
- write_byte(&priv->nec7210_priv, AUX_REQT, AUXMR);
- } else if (reqf) {
- write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR);
- }
- /*
- * We need to always zero bit 6 of the status byte before writing it to
- * the SPMR to insure we are using
- * serial poll mode SP1, and not accidentally triggering mode SP3.
- */
- write_byte(&priv->nec7210_priv, status & ~request_service_bit, SPMR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static u8 fmh_gpib_serial_poll_status(struct gpib_board *board)
-{
- struct fmh_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static void fmh_gpib_return_to_local(struct gpib_board *board)
-{
- struct fmh_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- write_byte(nec_priv, AUX_RTL2, AUXMR);
- udelay(1);
- write_byte(nec_priv, AUX_RTL, AUXMR);
-}
-
-static int fmh_gpib_line_status(const struct gpib_board *board)
-{
- int status = VALID_ALL;
- int bsr_bits;
- struct fmh_priv *e_priv;
- struct nec7210_priv *nec_priv;
-
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
-
- bsr_bits = read_byte(nec_priv, BUS_STATUS_REG);
-
- if ((bsr_bits & BSR_REN_BIT) == 0)
- status |= BUS_REN;
- if ((bsr_bits & BSR_IFC_BIT) == 0)
- status |= BUS_IFC;
- if ((bsr_bits & BSR_SRQ_BIT) == 0)
- status |= BUS_SRQ;
- if ((bsr_bits & BSR_EOI_BIT) == 0)
- status |= BUS_EOI;
- if ((bsr_bits & BSR_NRFD_BIT) == 0)
- status |= BUS_NRFD;
- if ((bsr_bits & BSR_NDAC_BIT) == 0)
- status |= BUS_NDAC;
- if ((bsr_bits & BSR_DAV_BIT) == 0)
- status |= BUS_DAV;
- if ((bsr_bits & BSR_ATN_BIT) == 0)
- status |= BUS_ATN;
-
- return status;
-}
-
-static int fmh_gpib_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned int retval;
-
- retval = nec7210_t1_delay(board, nec_priv, nano_sec);
-
- if (nano_sec <= 350) {
- write_byte(nec_priv, AUX_HI_SPEED, AUXMR);
- retval = 350;
- } else {
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- }
- return retval;
-}
-
-static int lacs_or_read_ready(struct gpib_board *board)
-{
- const struct fmh_priv *e_priv = board->private_data;
- const struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = test_bit(LACS_NUM, &board->status) ||
- test_bit(READ_READY_BN, &nec_priv->state);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-
-static int wait_for_read(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- lacs_or_read_ready(board) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- return retval;
-}
-
-static int wait_for_rx_fifo_half_full_or_end(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- (fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) &
- RX_FIFO_HALF_FULL) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- return retval;
-}
-
-/*
- * Wait until the gpib chip is ready to accept a data out byte.
- */
-static int wait_for_data_out_ready(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- (test_bit(TACS_NUM, &board->status) &&
- (read_byte(nec_priv, EXT_STATUS_1_REG) &
- DATA_OUT_STATUS_BIT)) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
-
- return retval;
-}
-
-static void fmh_gpib_dma_callback(void *arg)
-{
- struct gpib_board *board = arg;
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, HR_DOIE | HR_DIIE);
- wake_up_interruptible(&board->wait);
-
- fmh_gpib_internal_interrupt(board);
-
- clear_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
- clear_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-/*
- * returns true when all the bytes of a write have been transferred to
- * the chip and successfully transferred out over the gpib bus.
- */
-static int fmh_gpib_all_bytes_are_sent(struct fmh_priv *e_priv)
-{
- if (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) & fifo_xfer_counter_mask)
- return 0;
-
- if ((read_byte(&e_priv->nec7210_priv, EXT_STATUS_1_REG) & DATA_OUT_STATUS_BIT) == 0)
- return 0;
-
- return 1;
-}
-
-static int fmh_gpib_dma_write(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
- int retval = 0;
- dma_addr_t address;
- struct dma_async_tx_descriptor *tx_desc;
-
- *bytes_written = 0;
- if (WARN_ON_ONCE(length > e_priv->dma_buffer_size))
- return -EFAULT;
- dmaengine_terminate_all(e_priv->dma_channel);
- memcpy(e_priv->dma_buffer, buffer, length);
- address = dma_map_single(board->dev, e_priv->dma_buffer, length, DMA_TO_DEVICE);
- if (dma_mapping_error(board->dev, address))
- dev_err(board->gpib_dev, "dma mapping error in dma write!\n");
- /* program dma controller */
- retval = fmh_gpib_config_dma(board, 1);
- if (retval)
- goto cleanup;
-
- tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, address, length, DMA_MEM_TO_DEV,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!tx_desc) {
- dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
- retval = -ENOMEM;
- goto cleanup;
- }
- tx_desc->callback = fmh_gpib_dma_callback;
- tx_desc->callback_param = board;
-
- spin_lock_irqsave(&board->spinlock, flags);
- fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG);
- fifos_write(e_priv, TX_FIFO_DMA_REQUEST_ENABLE | TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO);
-
- dmaengine_submit(tx_desc);
- dma_async_issue_pending(e_priv->dma_channel);
- clear_bit(WRITE_READY_BN, &nec_priv->state);
- set_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- // suspend until message is sent
- if (wait_event_interruptible(board->wait,
- fmh_gpib_all_bytes_are_sent(e_priv) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state))
- retval = -EIO;
- // disable board's dma
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0);
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
-
- dmaengine_terminate_all(e_priv->dma_channel);
- // make sure fmh_gpib_dma_callback got called
- if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &nec_priv->state))
- fmh_gpib_dma_callback(board);
-
- *bytes_written = length - (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) &
- fifo_xfer_counter_mask);
- if (WARN_ON_ONCE(*bytes_written > length))
- return -EFAULT;
-cleanup:
- dma_unmap_single(board->dev, address, length, DMA_TO_DEVICE);
- return retval;
-}
-
-static int fmh_gpib_accel_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remainder = length;
- size_t transfer_size;
- ssize_t retval = 0;
- size_t dma_remainder = remainder;
-
- if (!e_priv->dma_channel) {
- dev_err(board->gpib_dev, "No dma channel available, cannot do accel write.");
- return -ENXIO;
- }
-
- *bytes_written = 0;
- if (length < 1)
- return 0;
-
- smp_mb__before_atomic();
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
- smp_mb__after_atomic();
-
- if (send_eoi)
- --dma_remainder;
-
- while (dma_remainder > 0) {
- size_t num_bytes;
-
- retval = wait_for_data_out_ready(board);
- if (retval < 0)
- break;
-
- transfer_size = (e_priv->dma_buffer_size < dma_remainder) ?
- e_priv->dma_buffer_size : dma_remainder;
- retval = fmh_gpib_dma_write(board, buffer, transfer_size, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- break;
- dma_remainder -= num_bytes;
- remainder -= num_bytes;
- buffer += num_bytes;
- if (need_resched())
- schedule();
- }
- if (retval < 0)
- return retval;
- // handle sending of last byte with eoi
- if (send_eoi) {
- size_t num_bytes;
-
- if (WARN_ON_ONCE(remainder != 1))
- return -EFAULT;
-
- /*
- * wait until we are sure we will be able to write the data byte
- * into the chip before we send AUX_SEOI. This prevents a timeout
- * scenario where we send AUX_SEOI but then timeout without getting
- * any bytes into the gpib chip. This will result in the first byte
- * of the next write having a spurious EOI set on the first byte.
- */
- retval = wait_for_data_out_ready(board);
- if (retval < 0)
- return retval;
-
- write_byte(nec_priv, AUX_SEOI, AUXMR);
- retval = fmh_gpib_dma_write(board, buffer, remainder, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- remainder -= num_bytes;
- }
- return 0;
-}
-
-static int fmh_gpib_get_dma_residue(struct dma_chan *chan, dma_cookie_t cookie)
-{
- struct dma_tx_state state;
- int result;
-
- result = dmaengine_pause(chan);
- if (result < 0) {
- pr_err("dma pause failed?\n");
- return result;
- }
- dmaengine_tx_status(chan, cookie, &state);
- /*
- * dma330 hardware doesn't support resume, so dont call this
- * method unless the dma transfer is done.
- */
- return state.residue;
-}
-
-static int wait_for_tx_fifo_half_empty(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- if (wait_event_interruptible(board->wait,
- (test_bit(TACS_NUM, &board->status) &&
- (fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) &
- TX_FIFO_HALF_EMPTY)) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
-
- return retval;
-}
-
-/*
- * supports writing a chunk of data whose length must fit into the hardware'd xfer counter,
- * called in a loop by fmh_gpib_fifo_write()
- */
-static int fmh_gpib_fifo_write_countable(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
- unsigned int remainder;
-
- *bytes_written = 0;
- if (WARN_ON_ONCE(length > fifo_xfer_counter_mask))
- return -EFAULT;
-
- fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG);
- fifos_write(e_priv, TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO);
-
- remainder = length;
- while (remainder > 0) {
- int i;
-
- fifos_write(e_priv, TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE, FIFO_CONTROL_STATUS_REG);
- retval = wait_for_tx_fifo_half_empty(board);
- if (retval < 0)
- goto cleanup;
-
- for (i = 0; i < fmh_gpib_half_fifo_size(e_priv) && remainder > 0; ++i) {
- unsigned int data_value = *buffer;
-
- if (send_eoi && remainder == 1)
- data_value |= FIFO_DATA_EOI_FLAG;
- fifos_write(e_priv, data_value, FIFO_DATA_REG);
- ++buffer;
- --remainder;
- }
- }
-
- // suspend until last byte is sent
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, HR_DOIE);
- if (wait_event_interruptible(board->wait,
- fmh_gpib_all_bytes_are_sent(e_priv) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state))
- retval = -EIO;
-
-cleanup:
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0);
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
-
- *bytes_written = length - (fifos_read(e_priv, FIFO_XFER_COUNTER_REG) &
- fifo_xfer_counter_mask);
- if (WARN_ON_ONCE(*bytes_written > length))
- return -EFAULT;
-
- return retval;
-}
-
-static int fmh_gpib_fifo_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remainder = length;
- size_t transfer_size;
- ssize_t retval = 0;
-
- *bytes_written = 0;
- if (length < 1)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
-
- while (remainder > 0) {
- size_t num_bytes;
- int last_pass;
-
- retval = wait_for_data_out_ready(board);
- if (retval < 0)
- break;
-
- if (fifo_xfer_counter_mask < remainder) {
- // round transfer size to a multiple of half fifo size
- transfer_size = (fifo_xfer_counter_mask /
- fmh_gpib_half_fifo_size(e_priv)) *
- fmh_gpib_half_fifo_size(e_priv);
- last_pass = 0;
- } else {
- transfer_size = remainder;
- last_pass = 1;
- }
- retval = fmh_gpib_fifo_write_countable(board, buffer, transfer_size,
- last_pass && send_eoi, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- break;
- remainder -= num_bytes;
- buffer += num_bytes;
- if (need_resched())
- schedule();
- }
-
- return retval;
-}
-
-static int fmh_gpib_dma_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
- unsigned long flags;
- int residue;
- int wait_retval;
- dma_addr_t bus_address;
- struct dma_async_tx_descriptor *tx_desc;
- dma_cookie_t dma_cookie;
-
- *bytes_read = 0;
- *end = 0;
- if (length == 0)
- return 0;
-
- bus_address = dma_map_single(board->dev, e_priv->dma_buffer,
- length, DMA_FROM_DEVICE);
- if (dma_mapping_error(board->dev, bus_address))
- dev_err(board->gpib_dev, "dma mapping error in dma read!");
-
- /* program dma controller */
- retval = fmh_gpib_config_dma(board, 0);
- if (retval) {
- dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
- return retval;
- }
- tx_desc = dmaengine_prep_slave_single(e_priv->dma_channel, bus_address,
- length, DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (!tx_desc) {
- dev_err(board->gpib_dev, "failed to allocate dma transmit descriptor\n");
- dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
- return -EIO;
- }
- tx_desc->callback = fmh_gpib_dma_callback;
- tx_desc->callback_param = board;
-
- spin_lock_irqsave(&board->spinlock, flags);
- // enable nec7210 dma
- fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG);
- fifos_write(e_priv, RX_FIFO_DMA_REQUEST_ENABLE | RX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI);
-
- dma_cookie = dmaengine_submit(tx_desc);
- dma_async_issue_pending(e_priv->dma_channel);
-
- set_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- // wait for data to transfer
- wait_retval = wait_event_interruptible(board->wait,
- test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state)
- == 0 ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- if (wait_retval)
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- // stop the dma transfer
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
- /*
- * give time for pl330 to transfer any in-flight data, since
- * pl330 will throw it away when dmaengine_pause is called.
- */
- usleep_range(10, 15);
- residue = fmh_gpib_get_dma_residue(e_priv->dma_channel, dma_cookie);
- if (WARN_ON_ONCE(residue > length || residue < 0))
- return -EFAULT;
- *bytes_read += length - residue;
- dmaengine_terminate_all(e_priv->dma_channel);
- // make sure fmh_gpib_dma_callback got called
- if (test_bit(DMA_READ_IN_PROGRESS_BN, &nec_priv->state))
- fmh_gpib_dma_callback(board);
-
- dma_unmap_single(board->dev, bus_address, length, DMA_FROM_DEVICE);
- memcpy(buffer, e_priv->dma_buffer, *bytes_read);
-
- /* Manually read any dregs out of fifo. */
- while ((fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & RX_FIFO_EMPTY) == 0) {
- if ((*bytes_read) >= length) {
- dev_err(board->dev, "unexpected extra bytes in rx fifo, discarding! bytes_read=%d length=%d residue=%d\n",
- (int)(*bytes_read), (int)length, (int)residue);
- break;
- }
- buffer[(*bytes_read)++] = fifos_read(e_priv, FIFO_DATA_REG) & fifo_data_mask;
- }
-
- /*
- * If we got an end interrupt, figure out if it was
- * associated with the last byte we dma'd or with a
- * byte still sitting on the cb7210.
- */
- spin_lock_irqsave(&board->spinlock, flags);
- if (*bytes_read > 0 && test_bit(READ_READY_BN, &nec_priv->state) == 0) {
- /*
- * If there is no byte sitting on the cb7210 and we
- * saw an end, we need to deal with it now
- */
- if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state))
- *end = 1;
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-
-static void fmh_gpib_release_rfd_holdoff(struct gpib_board *board, struct fmh_priv *e_priv)
-{
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned int ext_status_1;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- ext_status_1 = read_byte(nec_priv, EXT_STATUS_1_REG);
-
- /*
- * if there is an end byte sitting on the chip, don't release
- * holdoff. We want it left set after we read out the end
- * byte.
- */
- if ((ext_status_1 & (DATA_IN_STATUS_BIT | END_STATUS_BIT)) !=
- (DATA_IN_STATUS_BIT | END_STATUS_BIT)) {
- if (ext_status_1 & RFD_HOLDOFF_STATUS_BIT)
- write_byte(nec_priv, AUX_FH, AUXMR);
-
- /*
- * Check if an end byte raced in before we executed the AUX_FH command.
- * If it did, we want to make sure the rfd holdoff is in effect. The end
- * byte can arrive since
- * AUX_RFD_HOLDOFF_ASAP doesn't immediately force the acceptor handshake
- * to leave ACRS.
- */
- if ((read_byte(nec_priv, EXT_STATUS_1_REG) &
- (RFD_HOLDOFF_STATUS_BIT | DATA_IN_STATUS_BIT | END_STATUS_BIT)) ==
- (DATA_IN_STATUS_BIT | END_STATUS_BIT)) {
- write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR);
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- } else {
- clear_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- }
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static int fmh_gpib_accel_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remain = length;
- size_t transfer_size;
- int retval = 0;
- size_t dma_nbytes;
- unsigned long flags;
-
- smp_mb__before_atomic();
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
- smp_mb__after_atomic();
- *end = 0;
- *bytes_read = 0;
-
- retval = wait_for_read(board);
- if (retval < 0)
- return retval;
-
- fmh_gpib_release_rfd_holdoff(board, e_priv);
- while (remain > 0) {
- transfer_size = (e_priv->dma_buffer_size < remain) ?
- e_priv->dma_buffer_size : remain;
- retval = fmh_gpib_dma_read(board, buffer, transfer_size, end, &dma_nbytes);
- remain -= dma_nbytes;
- buffer += dma_nbytes;
- *bytes_read += dma_nbytes;
- if (*end)
- break;
- if (retval < 0)
- break;
- if (need_resched())
- schedule();
- }
-
- spin_lock_irqsave(&board->spinlock, flags);
- if (test_bit(RFD_HOLDOFF_BN, &nec_priv->state) == 0) {
- write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR);
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-
-/*
- * Read a chunk of data whose length is within the limits of the hardware's
- * xfer counter. Called in a loop from fmh_gpib_fifo_read().
- */
-static int fmh_gpib_fifo_read_countable(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- int retval = 0;
-
- *bytes_read = 0;
- *end = 0;
- if (length == 0)
- return 0;
-
- fifos_write(e_priv, length & fifo_xfer_counter_mask, FIFO_XFER_COUNTER_REG);
- fifos_write(e_priv, RX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG);
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI);
-
- while (*bytes_read < length && *end == 0) {
- int i;
-
- fifos_write(e_priv, RX_FIFO_HALF_FULL_INTERRUPT_ENABLE, FIFO_CONTROL_STATUS_REG);
- retval = wait_for_rx_fifo_half_full_or_end(board);
- if (retval < 0)
- goto cleanup;
-
- for (i = 0; i < fmh_gpib_half_fifo_size(e_priv) && *end == 0; ++i) {
- unsigned int data_value;
-
- data_value = fifos_read(e_priv, FIFO_DATA_REG);
- buffer[(*bytes_read)++] = data_value & fifo_data_mask;
- if (data_value & FIFO_DATA_EOI_FLAG)
- *end = 1;
- }
- }
-
-cleanup:
- // stop the transfer
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
-
- /* Manually read any dregs out of fifo. */
- while ((fifos_read(e_priv, FIFO_CONTROL_STATUS_REG) & RX_FIFO_EMPTY) == 0) {
- unsigned int data_value;
-
- if ((*bytes_read) >= length) {
- dev_err(board->dev, "unexpected extra bytes in rx fifo, discarding! bytes_read=%d length=%d\n",
- (int)(*bytes_read), (int)length);
- break;
- }
- data_value = fifos_read(e_priv, FIFO_DATA_REG);
- buffer[(*bytes_read)++] = data_value & fifo_data_mask;
- if (data_value & FIFO_DATA_EOI_FLAG)
- *end = 1;
- }
-
- return retval;
-}
-
-static int fmh_gpib_fifo_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- size_t remain = length;
- size_t transfer_size;
- int retval = 0;
- size_t nbytes;
- unsigned long flags;
-
- clear_bit(DEV_CLEAR_BN, &nec_priv->state); // XXX FIXME
- *end = 0;
- *bytes_read = 0;
-
- /*
- * Do a little prep with data in interrupt so that following wait_for_read()
- * will wake up if a data byte is received.
- */
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DIIE, HR_DIIE);
- fmh_gpib_interrupt(0, board);
-
- retval = wait_for_read(board);
- if (retval < 0)
- return retval;
-
- fmh_gpib_release_rfd_holdoff(board, e_priv);
- while (remain > 0) {
- if (fifo_xfer_counter_mask < remain) {
- // round transfer size to a multiple of half fifo size
- transfer_size = (fifo_xfer_counter_mask /
- fmh_gpib_half_fifo_size(e_priv)) *
- fmh_gpib_half_fifo_size(e_priv);
- } else {
- transfer_size = remain;
- }
- retval = fmh_gpib_fifo_read_countable(board, buffer, transfer_size, end, &nbytes);
- remain -= nbytes;
- buffer += nbytes;
- *bytes_read += nbytes;
- if (*end)
- break;
- if (retval < 0)
- break;
- if (need_resched())
- schedule();
- }
-
- if (*end == 0) {
- spin_lock_irqsave(&board->spinlock, flags);
- write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR);
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- spin_unlock_irqrestore(&board->spinlock, flags);
- }
-
- return retval;
-}
-
-static struct gpib_interface fmh_gpib_unaccel_interface = {
- .name = "fmh_gpib_unaccel",
- .attach = fmh_gpib_attach_holdoff_all,
- .detach = fmh_gpib_detach,
- .read = fmh_gpib_read,
- .write = fmh_gpib_write,
- .command = fmh_gpib_command,
- .take_control = fmh_gpib_take_control,
- .go_to_standby = fmh_gpib_go_to_standby,
- .request_system_control = fmh_gpib_request_system_control,
- .interface_clear = fmh_gpib_interface_clear,
- .remote_enable = fmh_gpib_remote_enable,
- .enable_eos = fmh_gpib_enable_eos,
- .disable_eos = fmh_gpib_disable_eos,
- .parallel_poll = fmh_gpib_parallel_poll,
- .parallel_poll_configure = fmh_gpib_parallel_poll_configure,
- .parallel_poll_response = fmh_gpib_parallel_poll_response,
- .local_parallel_poll_mode = fmh_gpib_local_parallel_poll_mode,
- .line_status = fmh_gpib_line_status,
- .update_status = fmh_gpib_update_status,
- .primary_address = fmh_gpib_primary_address,
- .secondary_address = fmh_gpib_secondary_address,
- .serial_poll_response2 = fmh_gpib_serial_poll_response2,
- .serial_poll_status = fmh_gpib_serial_poll_status,
- .t1_delay = fmh_gpib_t1_delay,
- .return_to_local = fmh_gpib_return_to_local,
-};
-
-static struct gpib_interface fmh_gpib_interface = {
- .name = "fmh_gpib",
- .attach = fmh_gpib_attach_holdoff_end,
- .detach = fmh_gpib_detach,
- .read = fmh_gpib_accel_read,
- .write = fmh_gpib_accel_write,
- .command = fmh_gpib_command,
- .take_control = fmh_gpib_take_control,
- .go_to_standby = fmh_gpib_go_to_standby,
- .request_system_control = fmh_gpib_request_system_control,
- .interface_clear = fmh_gpib_interface_clear,
- .remote_enable = fmh_gpib_remote_enable,
- .enable_eos = fmh_gpib_enable_eos,
- .disable_eos = fmh_gpib_disable_eos,
- .parallel_poll = fmh_gpib_parallel_poll,
- .parallel_poll_configure = fmh_gpib_parallel_poll_configure,
- .parallel_poll_response = fmh_gpib_parallel_poll_response,
- .local_parallel_poll_mode = fmh_gpib_local_parallel_poll_mode,
- .line_status = fmh_gpib_line_status,
- .update_status = fmh_gpib_update_status,
- .primary_address = fmh_gpib_primary_address,
- .secondary_address = fmh_gpib_secondary_address,
- .serial_poll_response2 = fmh_gpib_serial_poll_response2,
- .serial_poll_status = fmh_gpib_serial_poll_status,
- .t1_delay = fmh_gpib_t1_delay,
- .return_to_local = fmh_gpib_return_to_local,
-};
-
-static struct gpib_interface fmh_gpib_pci_interface = {
- .name = "fmh_gpib_pci",
- .attach = fmh_gpib_pci_attach_holdoff_end,
- .detach = fmh_gpib_pci_detach,
- .read = fmh_gpib_fifo_read,
- .write = fmh_gpib_fifo_write,
- .command = fmh_gpib_command,
- .take_control = fmh_gpib_take_control,
- .go_to_standby = fmh_gpib_go_to_standby,
- .request_system_control = fmh_gpib_request_system_control,
- .interface_clear = fmh_gpib_interface_clear,
- .remote_enable = fmh_gpib_remote_enable,
- .enable_eos = fmh_gpib_enable_eos,
- .disable_eos = fmh_gpib_disable_eos,
- .parallel_poll = fmh_gpib_parallel_poll,
- .parallel_poll_configure = fmh_gpib_parallel_poll_configure,
- .parallel_poll_response = fmh_gpib_parallel_poll_response,
- .local_parallel_poll_mode = fmh_gpib_local_parallel_poll_mode,
- .line_status = fmh_gpib_line_status,
- .update_status = fmh_gpib_update_status,
- .primary_address = fmh_gpib_primary_address,
- .secondary_address = fmh_gpib_secondary_address,
- .serial_poll_response2 = fmh_gpib_serial_poll_response2,
- .serial_poll_status = fmh_gpib_serial_poll_status,
- .t1_delay = fmh_gpib_t1_delay,
- .return_to_local = fmh_gpib_return_to_local,
-};
-
-static struct gpib_interface fmh_gpib_pci_unaccel_interface = {
- .name = "fmh_gpib_pci_unaccel",
- .attach = fmh_gpib_pci_attach_holdoff_all,
- .detach = fmh_gpib_pci_detach,
- .read = fmh_gpib_read,
- .write = fmh_gpib_write,
- .command = fmh_gpib_command,
- .take_control = fmh_gpib_take_control,
- .go_to_standby = fmh_gpib_go_to_standby,
- .request_system_control = fmh_gpib_request_system_control,
- .interface_clear = fmh_gpib_interface_clear,
- .remote_enable = fmh_gpib_remote_enable,
- .enable_eos = fmh_gpib_enable_eos,
- .disable_eos = fmh_gpib_disable_eos,
- .parallel_poll = fmh_gpib_parallel_poll,
- .parallel_poll_configure = fmh_gpib_parallel_poll_configure,
- .parallel_poll_response = fmh_gpib_parallel_poll_response,
- .local_parallel_poll_mode = fmh_gpib_local_parallel_poll_mode,
- .line_status = fmh_gpib_line_status,
- .update_status = fmh_gpib_update_status,
- .primary_address = fmh_gpib_primary_address,
- .secondary_address = fmh_gpib_secondary_address,
- .serial_poll_response2 = fmh_gpib_serial_poll_response2,
- .serial_poll_status = fmh_gpib_serial_poll_status,
- .t1_delay = fmh_gpib_t1_delay,
- .return_to_local = fmh_gpib_return_to_local,
-};
-
-irqreturn_t fmh_gpib_internal_interrupt(struct gpib_board *board)
-{
- unsigned int status0, status1, status2, ext_status_1, fifo_status;
- struct fmh_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- int retval = IRQ_NONE;
-
- status0 = read_byte(nec_priv, ISR0_IMR0_REG);
- status1 = read_byte(nec_priv, ISR1);
- status2 = read_byte(nec_priv, ISR2);
- fifo_status = fifos_read(priv, FIFO_CONTROL_STATUS_REG);
-
- if (status0 & IFC_INTERRUPT_BIT) {
- push_gpib_event(board, EVENT_IFC);
- retval = IRQ_HANDLED;
- }
-
- if (nec7210_interrupt_have_status(board, nec_priv, status1, status2) == IRQ_HANDLED)
- retval = IRQ_HANDLED;
-
- ext_status_1 = read_byte(nec_priv, EXT_STATUS_1_REG);
-
- if (ext_status_1 & DATA_IN_STATUS_BIT)
- set_bit(READ_READY_BN, &nec_priv->state);
- else
- clear_bit(READ_READY_BN, &nec_priv->state);
-
- if (ext_status_1 & DATA_OUT_STATUS_BIT)
- set_bit(WRITE_READY_BN, &nec_priv->state);
- else
- clear_bit(WRITE_READY_BN, &nec_priv->state);
-
- if (ext_status_1 & COMMAND_OUT_STATUS_BIT)
- set_bit(COMMAND_READY_BN, &nec_priv->state);
- else
- clear_bit(COMMAND_READY_BN, &nec_priv->state);
-
- if (ext_status_1 & RFD_HOLDOFF_STATUS_BIT)
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- else
- clear_bit(RFD_HOLDOFF_BN, &nec_priv->state);
-
- if (ext_status_1 & END_STATUS_BIT) {
- /*
- * only set RECEIVED_END while there is still a data
- * byte sitting in the chip, to avoid spuriously
- * setting it multiple times after it has been cleared
- * during a read.
- */
- if (ext_status_1 & DATA_IN_STATUS_BIT)
- set_bit(RECEIVED_END_BN, &nec_priv->state);
- } else {
- clear_bit(RECEIVED_END_BN, &nec_priv->state);
- }
-
- if ((fifo_status & TX_FIFO_HALF_EMPTY_INTERRUPT_IS_ENABLED) &&
- (fifo_status & TX_FIFO_HALF_EMPTY)) {
- /*
- * We really only want to clear the
- * TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE bit in the
- * FIFO_CONTROL_STATUS_REG. Since we are not being
- * careful, this also has a side effect of disabling
- * DMA requests and the RX fifo interrupt. That is
- * fine though, since they should never be in use at
- * the same time as the TX fifo interrupt.
- */
- fifos_write(priv, 0x0, FIFO_CONTROL_STATUS_REG);
- retval = IRQ_HANDLED;
- }
-
- if ((fifo_status & RX_FIFO_HALF_FULL_INTERRUPT_IS_ENABLED) &&
- (fifo_status & RX_FIFO_HALF_FULL)) {
- /*
- * We really only want to clear the
- * RX_FIFO_HALF_FULL_INTERRUPT_ENABLE bit in the
- * FIFO_CONTROL_STATUS_REG. Since we are not being
- * careful, this also has a side effect of disabling
- * DMA requests and the TX fifo interrupt. That is
- * fine though, since they should never be in use at
- * the same time as the RX fifo interrupt.
- */
- fifos_write(priv, 0x0, FIFO_CONTROL_STATUS_REG);
- retval = IRQ_HANDLED;
- }
-
- if (retval == IRQ_HANDLED)
- wake_up_interruptible(&board->wait);
-
- return retval;
-}
-
-irqreturn_t fmh_gpib_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = fmh_gpib_internal_interrupt(board);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-static int fmh_gpib_allocate_private(struct gpib_board *board)
-{
- struct fmh_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct fmh_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct fmh_priv));
- init_nec7210_private(&priv->nec7210_priv);
- priv->dma_buffer_size = 0x800;
- priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL);
- if (!priv->dma_buffer)
- return -ENOMEM;
- return 0;
-}
-
-static void fmh_gpib_generic_detach(struct gpib_board *board)
-{
- if (board->private_data) {
- struct fmh_priv *e_priv = board->private_data;
-
- kfree(e_priv->dma_buffer);
- kfree(board->private_data);
- board->private_data = NULL;
- }
- if (board->dev)
- dev_set_drvdata(board->dev, NULL);
-}
-
-// generic part of attach functions
-static int fmh_gpib_generic_attach(struct gpib_board *board)
-{
- struct fmh_priv *e_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- board->status = 0;
-
- retval = fmh_gpib_allocate_private(board);
- if (retval < 0)
- return retval;
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
- nec_priv->read_byte = gpib_cs_read_byte;
- nec_priv->write_byte = gpib_cs_write_byte;
- nec_priv->offset = 1;
- nec_priv->type = CB7210;
- return 0;
-}
-
-static int fmh_gpib_config_dma(struct gpib_board *board, int output)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct dma_slave_config config;
-
- config.device_fc = true;
-
- if (e_priv->dma_burst_length < 1) {
- config.src_maxburst = 1;
- config.dst_maxburst = 1;
- } else {
- config.src_maxburst = e_priv->dma_burst_length;
- config.dst_maxburst = e_priv->dma_burst_length;
- }
-
- config.src_addr_width = 1;
- config.dst_addr_width = 1;
-
- if (output) {
- config.direction = DMA_MEM_TO_DEV;
- config.src_addr = 0;
- config.dst_addr = e_priv->dma_port_res->start + FIFO_DATA_REG * fifo_reg_offset;
- } else {
- config.direction = DMA_DEV_TO_MEM;
- config.src_addr = e_priv->dma_port_res->start + FIFO_DATA_REG * fifo_reg_offset;
- config.dst_addr = 0;
- }
- return dmaengine_slave_config(e_priv->dma_channel, &config);
-}
-
-static int fmh_gpib_init(struct fmh_priv *e_priv, struct gpib_board *board, int handshake_mode)
-{
- struct nec7210_priv *nec_priv = &e_priv->nec7210_priv;
- unsigned long flags;
- unsigned int fifo_status_bits;
-
- fifos_write(e_priv, RX_FIFO_CLEAR | TX_FIFO_CLEAR, FIFO_CONTROL_STATUS_REG);
-
- nec7210_board_reset(nec_priv, board);
- write_byte(nec_priv, AUX_LO_SPEED, AUXMR);
- nec7210_set_handshake_mode(board, nec_priv, handshake_mode);
-
- /* Hueristically check if hardware supports fifo half full/empty interrupts */
- fifo_status_bits = fifos_read(e_priv, FIFO_CONTROL_STATUS_REG);
- e_priv->supports_fifo_interrupts = (fifo_status_bits & TX_FIFO_EMPTY) &&
- (fifo_status_bits & TX_FIFO_HALF_EMPTY);
-
- nec7210_board_online(nec_priv, board);
-
- write_byte(nec_priv, IFC_INTERRUPT_ENABLE_BIT | ATN_INTERRUPT_ENABLE_BIT, ISR0_IMR0_REG);
-
- spin_lock_irqsave(&board->spinlock, flags);
- write_byte(nec_priv, AUX_RFD_HOLDOFF_ASAP, AUXMR);
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return 0;
-}
-
-/* Match callback for driver_find_device */
-static int fmh_gpib_device_match(struct device *dev, const void *data)
-{
- const struct gpib_board_config *config = data;
-
- if (dev_get_drvdata(dev))
- return 0;
-
- if (gpib_match_device_path(dev, config->device_path) == 0)
- return 0;
-
- // driver doesn't support selection by serial number
- if (config->serial_number)
- return 0;
-
- dev_dbg(dev, "matched: %s\n", of_node_full_name(dev_of_node((dev))));
- return 1;
-}
-
-static int fmh_gpib_attach_impl(struct gpib_board *board, const struct gpib_board_config *config,
- unsigned int handshake_mode, int acquire_dma)
-{
- struct fmh_priv *e_priv;
- struct nec7210_priv *nec_priv;
- int retval;
- int irq;
- struct resource *res;
- struct platform_device *pdev;
-
- board->dev = driver_find_device(&fmh_gpib_platform_driver.driver,
- NULL, (const void *)config, &fmh_gpib_device_match);
- if (!board->dev) {
- dev_err(board->gpib_dev, "No matching fmh_gpib_core device was found, attach failed.");
- return -ENODEV;
- }
- // currently only used to mark the device as already attached
- dev_set_drvdata(board->dev, board);
- pdev = to_platform_device(board->dev);
-
- retval = fmh_gpib_generic_attach(board);
- if (retval)
- return retval;
-
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpib_control_status");
- if (!res) {
- dev_err(board->dev, "Unable to locate mmio resource\n");
- return -ENODEV;
- }
-
- if (request_mem_region(res->start,
- resource_size(res),
- pdev->name) == NULL) {
- dev_err(board->dev, "cannot claim registers\n");
- return -ENXIO;
- }
- e_priv->gpib_iomem_res = res;
-
- nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
- if (!nec_priv->mmiobase) {
- dev_err(board->dev, "Could not map I/O memory\n");
- return -ENOMEM;
- }
- dev_dbg(board->dev, "iobase %pr remapped to %p\n",
- e_priv->gpib_iomem_res, nec_priv->mmiobase);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma_fifos");
- if (!res) {
- dev_err(board->dev, "Unable to locate mmio resource for gpib dma port\n");
- return -ENODEV;
- }
- if (request_mem_region(res->start,
- resource_size(res),
- pdev->name) == NULL) {
- dev_err(board->dev, "cannot claim registers\n");
- return -ENXIO;
- }
- e_priv->dma_port_res = res;
- e_priv->fifo_base = ioremap(e_priv->dma_port_res->start,
- resource_size(e_priv->dma_port_res));
- if (!e_priv->fifo_base) {
- dev_err(board->dev, "Could not map I/O memory for fifos\n");
- return -ENOMEM;
- }
- dev_dbg(board->dev, "dma fifos 0x%lx remapped to %p, length=%ld\n",
- (unsigned long)e_priv->dma_port_res->start, e_priv->fifo_base,
- (unsigned long)resource_size(e_priv->dma_port_res));
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -EBUSY;
- retval = request_irq(irq, fmh_gpib_interrupt, IRQF_SHARED, pdev->name, board);
- if (retval) {
- dev_err(board->dev,
- "cannot register interrupt handler err=%d\n",
- retval);
- return retval;
- }
- e_priv->irq = irq;
-
- if (acquire_dma) {
- e_priv->dma_channel = dma_request_slave_channel(board->dev, "rxtx");
- if (!e_priv->dma_channel) {
- dev_err(board->dev, "failed to acquire dma channel \"rxtx\".\n");
- return -EIO;
- }
- }
- /*
- * in the future we might want to know the half-fifo size
- * (dma_burst_length) even when not using dma, so go ahead an
- * initialize it unconditionally.
- */
- e_priv->dma_burst_length = fifos_read(e_priv, FIFO_MAX_BURST_LENGTH_REG) &
- fifo_max_burst_length_mask;
-
- return fmh_gpib_init(e_priv, board, handshake_mode);
-}
-
-int fmh_gpib_attach_holdoff_all(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return fmh_gpib_attach_impl(board, config, HR_HLDA, 0);
-}
-
-int fmh_gpib_attach_holdoff_end(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return fmh_gpib_attach_impl(board, config, HR_HLDE, 1);
-}
-
-void fmh_gpib_detach(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (e_priv) {
- if (e_priv->dma_channel)
- dma_release_channel(e_priv->dma_channel);
- nec_priv = &e_priv->nec7210_priv;
-
- if (e_priv->irq)
- free_irq(e_priv->irq, board);
- if (e_priv->fifo_base)
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
- if (nec_priv->mmiobase) {
- write_byte(nec_priv, 0, ISR0_IMR0_REG);
- nec7210_board_reset(nec_priv, board);
- }
- if (e_priv->fifo_base)
- iounmap(e_priv->fifo_base);
- if (nec_priv->mmiobase)
- iounmap(nec_priv->mmiobase);
- if (e_priv->dma_port_res) {
- release_mem_region(e_priv->dma_port_res->start,
- resource_size(e_priv->dma_port_res));
- }
- if (e_priv->gpib_iomem_res)
- release_mem_region(e_priv->gpib_iomem_res->start,
- resource_size(e_priv->gpib_iomem_res));
- }
- fmh_gpib_generic_detach(board);
-
- if (board->dev) {
- put_device(board->dev);
- board->dev = NULL;
- }
-}
-
-static int fmh_gpib_pci_attach_impl(struct gpib_board *board,
- const struct gpib_board_config *config,
- unsigned int handshake_mode)
-{
- struct fmh_priv *e_priv;
- struct nec7210_priv *nec_priv;
- int retval;
- struct pci_dev *pci_device;
-
- retval = fmh_gpib_generic_attach(board);
- if (retval)
- return retval;
-
- e_priv = board->private_data;
- nec_priv = &e_priv->nec7210_priv;
-
- // find board
- pci_device = gpib_pci_get_device(config, BOGUS_PCI_VENDOR_ID_FLUKE,
- BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER, NULL);
- if (!pci_device) {
- dev_err(board->gpib_dev, "No matching fmh_gpib_core pci device was found, attach failed.");
- return -ENODEV;
- }
- board->dev = &pci_device->dev;
-
- // bladerunner prototype has offset of 4 between gpib control/status registers
- nec_priv->offset = 4;
-
- if (pci_enable_device(pci_device)) {
- dev_err(board->dev, "error enabling pci device\n");
- return -EIO;
- }
- if (pci_request_regions(pci_device, KBUILD_MODNAME)) {
- dev_err(board->dev, "pci_request_regions failed\n");
- return -EIO;
- }
- e_priv->gpib_iomem_res = &pci_device->resource[gpib_control_status_pci_resource_index];
- e_priv->dma_port_res = &pci_device->resource[gpib_fifo_pci_resource_index];
-
- nec_priv->mmiobase = ioremap(pci_resource_start(pci_device,
- gpib_control_status_pci_resource_index),
- pci_resource_len(pci_device,
- gpib_control_status_pci_resource_index));
- dev_dbg(board->dev, "base address for gpib control/status registers remapped to 0x%p\n",
- nec_priv->mmiobase);
-
- if (e_priv->dma_port_res->flags & IORESOURCE_MEM) {
- e_priv->fifo_base = ioremap(pci_resource_start(pci_device,
- gpib_fifo_pci_resource_index),
- pci_resource_len(pci_device,
- gpib_fifo_pci_resource_index));
- dev_dbg(board->dev, "base address for gpib fifo registers remapped to 0x%p\n",
- e_priv->fifo_base);
- } else {
- e_priv->fifo_base = NULL;
- dev_dbg(board->dev, "hardware has no gpib fifo registers.\n");
- }
-
- if (pci_device->irq) {
- retval = request_irq(pci_device->irq, fmh_gpib_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, board);
- if (retval) {
- dev_err(board->dev, "cannot register interrupt handler err=%d\n", retval);
- return retval;
- }
- }
- e_priv->irq = pci_device->irq;
-
- e_priv->dma_burst_length = fifos_read(e_priv, FIFO_MAX_BURST_LENGTH_REG) &
- fifo_max_burst_length_mask;
-
- return fmh_gpib_init(e_priv, board, handshake_mode);
-}
-
-int fmh_gpib_pci_attach_holdoff_all(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- return fmh_gpib_pci_attach_impl(board, config, HR_HLDA);
-}
-
-int fmh_gpib_pci_attach_holdoff_end(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- int retval;
- struct fmh_priv *e_priv;
-
- retval = fmh_gpib_pci_attach_impl(board, config, HR_HLDE);
- e_priv = board->private_data;
- if (retval == 0 && e_priv && e_priv->supports_fifo_interrupts == 0) {
- dev_err(board->gpib_dev, "your fmh_gpib_core does not appear to support fifo interrupts. Try the fmh_gpib_pci_unaccel board type instead.");
- return -EIO;
- }
- return retval;
-}
-
-void fmh_gpib_pci_detach(struct gpib_board *board)
-{
- struct fmh_priv *e_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (e_priv) {
- nec_priv = &e_priv->nec7210_priv;
-
- if (e_priv->irq)
- free_irq(e_priv->irq, board);
- if (e_priv->fifo_base)
- fifos_write(e_priv, 0, FIFO_CONTROL_STATUS_REG);
- if (nec_priv->mmiobase) {
- write_byte(nec_priv, 0, ISR0_IMR0_REG);
- nec7210_board_reset(nec_priv, board);
- }
- if (e_priv->fifo_base)
- iounmap(e_priv->fifo_base);
- if (nec_priv->mmiobase)
- iounmap(nec_priv->mmiobase);
- if (e_priv->dma_port_res || e_priv->gpib_iomem_res)
- pci_release_regions(to_pci_dev(board->dev));
- if (board->dev)
- pci_dev_put(to_pci_dev(board->dev));
- }
- fmh_gpib_generic_detach(board);
-}
-
-static int fmh_gpib_platform_probe(struct platform_device *pdev)
-{
- return 0;
-}
-
-static const struct of_device_id fmh_gpib_of_match[] = {
- { .compatible = "fmhess,fmh_gpib_core"},
- { {0} }
-};
-MODULE_DEVICE_TABLE(of, fmh_gpib_of_match);
-
-static struct platform_driver fmh_gpib_platform_driver = {
- .driver = {
- .name = DRV_NAME,
- .of_match_table = fmh_gpib_of_match,
- },
- .probe = &fmh_gpib_platform_probe
-};
-
-static int fmh_gpib_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return 0;
-}
-
-static const struct pci_device_id fmh_gpib_pci_match[] = {
- { BOGUS_PCI_VENDOR_ID_FLUKE, BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER, 0, 0, 0 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, fmh_gpib_pci_match);
-
-static struct pci_driver fmh_gpib_pci_driver = {
- .name = DRV_NAME,
- .id_table = fmh_gpib_pci_match,
- .probe = &fmh_gpib_pci_probe
-};
-
-static int __init fmh_gpib_init_module(void)
-{
- int result;
-
- result = platform_driver_register(&fmh_gpib_platform_driver);
- if (result) {
- pr_err("platform_driver_register failed: error = %d\n", result);
- return result;
- }
-
- result = pci_register_driver(&fmh_gpib_pci_driver);
- if (result) {
- pr_err("pci_register_driver failed: error = %d\n", result);
- goto err_pci_driver;
- }
-
- result = gpib_register_driver(&fmh_gpib_unaccel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_unaccel;
- }
-
- result = gpib_register_driver(&fmh_gpib_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_interface;
- }
-
- result = gpib_register_driver(&fmh_gpib_pci_unaccel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pci_unaccel;
- }
-
- result = gpib_register_driver(&fmh_gpib_pci_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pci;
- }
-
- return 0;
-
-err_pci:
- gpib_unregister_driver(&fmh_gpib_pci_unaccel_interface);
-err_pci_unaccel:
- gpib_unregister_driver(&fmh_gpib_interface);
-err_interface:
- gpib_unregister_driver(&fmh_gpib_unaccel_interface);
-err_unaccel:
- pci_unregister_driver(&fmh_gpib_pci_driver);
-err_pci_driver:
- platform_driver_unregister(&fmh_gpib_platform_driver);
-
- return result;
-}
-
-static void __exit fmh_gpib_exit_module(void)
-{
- gpib_unregister_driver(&fmh_gpib_pci_interface);
- gpib_unregister_driver(&fmh_gpib_pci_unaccel_interface);
- gpib_unregister_driver(&fmh_gpib_unaccel_interface);
- gpib_unregister_driver(&fmh_gpib_interface);
-
- pci_unregister_driver(&fmh_gpib_pci_driver);
- platform_driver_unregister(&fmh_gpib_platform_driver);
-}
-
-module_init(fmh_gpib_init_module);
-module_exit(fmh_gpib_exit_module);
diff --git a/drivers/staging/gpib/fmh_gpib/fmh_gpib.h b/drivers/staging/gpib/fmh_gpib/fmh_gpib.h
deleted file mode 100644
index e7602d7e1401..000000000000
--- a/drivers/staging/gpib/fmh_gpib/fmh_gpib.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * Copyright: (C) 2006, 2010, 2015 Fluke Corporation
- * (C) 2017 Frank Mori Hess
- ***************************************************************************/
-
-#include <linux/dmaengine.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include "nec7210.h"
-
-static const int fifo_reg_offset = 2;
-
-static const int gpib_control_status_pci_resource_index;
-static const int gpib_fifo_pci_resource_index = 1;
-
-/* We don't have a real pci vendor/device id, the following will need to be
- * patched to match prototype hardware.
- */
-#define BOGUS_PCI_VENDOR_ID_FLUKE 0xffff
-#define BOGUS_PCI_DEVICE_ID_FLUKE_BLADERUNNER 0x0
-
-struct fmh_priv {
- struct nec7210_priv nec7210_priv;
- struct resource *gpib_iomem_res;
- struct resource *write_transfer_counter_res;
- struct resource *dma_port_res;
- int irq;
- struct dma_chan *dma_channel;
- u8 *dma_buffer;
- int dma_buffer_size;
- int dma_burst_length;
- void __iomem *fifo_base;
- unsigned supports_fifo_interrupts : 1;
-};
-
-static inline int fmh_gpib_half_fifo_size(struct fmh_priv *priv)
-{
- return priv->dma_burst_length;
-}
-
-// registers beyond the nec7210 register set
-enum fmh_gpib_regs {
- EXT_STATUS_1_REG = 0x9,
- STATE1_REG = 0xc,
- ISR0_IMR0_REG = 0xe,
- BUS_STATUS_REG = 0xf
-};
-
-/* IMR0 -- Interrupt Mode Register 0 */
-enum imr0_bits {
- ATN_INTERRUPT_ENABLE_BIT = 0x4,
- IFC_INTERRUPT_ENABLE_BIT = 0x8
-};
-
-/* ISR0 -- Interrupt Status Register 0 */
-enum isr0_bits {
- ATN_INTERRUPT_BIT = 0x4,
- IFC_INTERRUPT_BIT = 0x8
-};
-
-enum state1_bits {
- SOURCE_HANDSHAKE_SIDS_BITS = 0x0, /* source idle state */
- SOURCE_HANDSHAKE_SGNS_BITS = 0x1, /* source generate state */
- SOURCE_HANDSHAKE_SDYS_BITS = 0x2, /* source delay state */
- SOURCE_HANDSHAKE_STRS_BITS = 0x5, /* source transfer state */
- SOURCE_HANDSHAKE_MASK = 0x7
-};
-
-enum fmh_gpib_auxmr_bits {
- AUX_I_REG = 0xe0,
-};
-
-enum aux_reg_i_bits {
- LOCAL_PPOLL_MODE_BIT = 0x4
-};
-
-enum ext_status_1_bits {
- DATA_IN_STATUS_BIT = 0x01,
- DATA_OUT_STATUS_BIT = 0x02,
- COMMAND_OUT_STATUS_BIT = 0x04,
- RFD_HOLDOFF_STATUS_BIT = 0x08,
- END_STATUS_BIT = 0x10
-};
-
-/* dma fifo reg and bits */
-enum dma_fifo_regs {
- FIFO_DATA_REG = 0x0,
- FIFO_CONTROL_STATUS_REG = 0x1,
- FIFO_XFER_COUNTER_REG = 0x2,
- FIFO_MAX_BURST_LENGTH_REG = 0x3
-};
-
-enum fifo_data_bits {
- FIFO_DATA_EOI_FLAG = 0x100
-};
-
-enum fifo_control_bits {
- TX_FIFO_DMA_REQUEST_ENABLE = 0x0001,
- TX_FIFO_CLEAR = 0x0002,
- TX_FIFO_HALF_EMPTY_INTERRUPT_ENABLE = 0x0008,
- RX_FIFO_DMA_REQUEST_ENABLE = 0x0100,
- RX_FIFO_CLEAR = 0x0200,
- RX_FIFO_HALF_FULL_INTERRUPT_ENABLE = 0x0800
-};
-
-enum fifo_status_bits {
- TX_FIFO_EMPTY = 0x0001,
- TX_FIFO_FULL = 0x0002,
- TX_FIFO_HALF_EMPTY = 0x0004,
- TX_FIFO_HALF_EMPTY_INTERRUPT_IS_ENABLED = 0x0008,
- TX_FIFO_DMA_REQUEST_IS_ENABLED = 0x0010,
- RX_FIFO_EMPTY = 0x0100,
- RX_FIFO_FULL = 0x0200,
- RX_FIFO_HALF_FULL = 0x0400,
- RX_FIFO_HALF_FULL_INTERRUPT_IS_ENABLED = 0x0800,
- RX_FIFO_DMA_REQUEST_IS_ENABLED = 0x1000
-};
-
-static const unsigned int fifo_data_mask = 0x00ff;
-static const unsigned int fifo_xfer_counter_mask = 0x0fff;
-static const unsigned int fifo_max_burst_length_mask = 0x00ff;
-
-static inline u8 gpib_cs_read_byte(struct nec7210_priv *nec_priv,
- unsigned int register_num)
-{
- return readb(nec_priv->mmiobase + register_num * nec_priv->offset);
-}
-
-static inline void gpib_cs_write_byte(struct nec7210_priv *nec_priv, u8 data,
- unsigned int register_num)
-{
- writeb(data, nec_priv->mmiobase + register_num * nec_priv->offset);
-}
-
-static inline uint16_t fifos_read(struct fmh_priv *fmh_priv, int register_num)
-{
- if (!fmh_priv->fifo_base)
- return 0;
- return readw(fmh_priv->fifo_base + register_num * fifo_reg_offset);
-}
-
-static inline void fifos_write(struct fmh_priv *fmh_priv, uint16_t data, int register_num)
-{
- if (!fmh_priv->fifo_base)
- return;
- writew(data, fmh_priv->fifo_base + register_num * fifo_reg_offset);
-}
-
-enum bus_status_bits {
- BSR_ATN_BIT = 0x01,
- BSR_EOI_BIT = 0x02,
- BSR_SRQ_BIT = 0x04,
- BSR_IFC_BIT = 0x08,
- BSR_REN_BIT = 0x10,
- BSR_DAV_BIT = 0x20,
- BSR_NRFD_BIT = 0x40,
- BSR_NDAC_BIT = 0x80,
-};
-
-enum fmh_gpib_aux_cmds {
- /* AUX_RTL2 is an auxiliary command which causes the cb7210 to assert
- * (and keep asserted) the local rtl message. This is used in conjunction
- * with the normal nec7210 AUX_RTL command, which
- * pulses the rtl message, having the effect of clearing rtl if it was left
- * asserted by AUX_RTL2.
- */
- AUX_RTL2 = 0x0d,
- AUX_RFD_HOLDOFF_ASAP = 0x15,
- AUX_REQT = 0x18,
- AUX_REQF = 0x19,
- AUX_LO_SPEED = 0x40,
- AUX_HI_SPEED = 0x41
-};
diff --git a/drivers/staging/gpib/gpio/Makefile b/drivers/staging/gpib/gpio/Makefile
deleted file mode 100644
index 00ea52abdda7..000000000000
--- a/drivers/staging/gpib/gpio/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-obj-$(CONFIG_GPIB_GPIO) += gpib_bitbang.o
-
-
diff --git a/drivers/staging/gpib/gpio/gpib_bitbang.c b/drivers/staging/gpib/gpio/gpib_bitbang.c
deleted file mode 100644
index 374cd61355e9..000000000000
--- a/drivers/staging/gpib/gpio/gpib_bitbang.c
+++ /dev/null
@@ -1,1469 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/*************************************************************************
- * This code has been developed at the Institute of Sensor and Actuator *
- * Systems (Technical University of Vienna, Austria) to enable the GPIO *
- * lines (e.g. of a raspberry pi) to function as a GPIO master device *
- * *
- * authors : Thomas Klima *
- * Marcello Carla' *
- * Dave Penkler *
- * *
- * copyright : (C) 2016 Thomas Klima *
- * *
- *************************************************************************/
-
-/*
- * limitations:
- * works only on RPi
- * cannot function as non-CIC system controller with SN7516x because
- * SN75161B cannot simultaneously make ATN input with IFC and REN as
- * outputs.
- * not implemented:
- * parallel poll
- * return2local
- * device support (non master operation)
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define NAME KBUILD_MODNAME
-
-#define ENABLE_IRQ(IRQ, TYPE) irq_set_irq_type(IRQ, TYPE)
-#define DISABLE_IRQ(IRQ) irq_set_irq_type(IRQ, IRQ_TYPE_NONE)
-
-/*
- * Debug print levels:
- * 0 = load/unload info and errors that make the driver fail;
- * 1 = + warnings for unforeseen events that may break the current
- * operation and lead to a timeout, but do not affect the
- * driver integrity (mainly unexpected interrupts);
- * 2 = + trace of function calls;
- * 3 = + trace of protocol codes;
- * 4 = + trace of interrupt operation.
- */
-#define dbg_printk(level, frm, ...) \
- do { if (debug >= (level)) \
- dev_dbg(board->gpib_dev, frm, ## __VA_ARGS__); } \
- while (0)
-
-#define LINVAL gpiod_get_value(DAV), \
- gpiod_get_value(NRFD), \
- gpiod_get_value(NDAC), \
- gpiod_get_value(SRQ)
-#define LINFMT "DAV: %d NRFD:%d NDAC: %d SRQ: %d"
-
-#include "gpibP.h"
-#include "gpib_state_machines.h"
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
-#include <linux/gpio/machine.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-
-static int sn7516x_used = 1, sn7516x;
-module_param(sn7516x_used, int, 0660);
-
-#define PINMAP_0 "elektronomikon"
-#define PINMAP_1 "gpib4pi-1.1"
-#define PINMAP_2 "yoga"
-static char *pin_map = PINMAP_0;
-module_param(pin_map, charp, 0660);
-MODULE_PARM_DESC(pin_map, " valid values: " PINMAP_0 " " PINMAP_1 " " PINMAP_2);
-
-/**********************************************
- * Signal pairing and pin wiring between the *
- * Raspberry-Pi connector and the GPIB bus *
- * *
- * signal pin wiring *
- * GPIB Pi-gpio GPIB -> RPi *
- **********************************************
- */
-enum lines_t {
- D01_pin_nr = 20, /* 1 -> 38 */
- D02_pin_nr = 26, /* 2 -> 37 */
- D03_pin_nr = 16, /* 3 -> 36 */
- D04_pin_nr = 19, /* 4 -> 35 */
- D05_pin_nr = 13, /* 13 -> 33 */
- D06_pin_nr = 12, /* 14 -> 32 */
- D07_pin_nr = 6, /* 15 -> 31 */
- D08_pin_nr = 5, /* 16 -> 29 */
- EOI_pin_nr = 9, /* 5 -> 21 */
- DAV_pin_nr = 10, /* 6 -> 19 */
- NRFD_pin_nr = 24, /* 7 -> 18 */
- NDAC_pin_nr = 23, /* 8 -> 16 */
- IFC_pin_nr = 22, /* 9 -> 15 */
- SRQ_pin_nr = 11, /* 10 -> 23 */
- _ATN_pin_nr = 25, /* 11 -> 22 */
- REN_pin_nr = 27, /* 17 -> 13 */
-/*
- * GROUND PINS
- * 12,18,19,20,21,22,23,24 => 14,20,25,30,34,39
- */
-
-/*
- * These lines are used to control the external
- * SN75160/161 driver chips when used.
- * When not used there is reduced fan out;
- * currently tested with up to 4 devices.
- */
-
-/* Pi GPIO RPI 75161B 75160B Description */
- PE_pin_nr = 7, /* 26 -> nc 11 Pullup Enable */
- DC_pin_nr = 8, /* 24 -> 12 nc Direction control */
- TE_pin_nr = 18, /* 12 -> 2 1 Talk Enable */
- ACT_LED_pin_nr = 4, /* 7 -> LED */
-
-/* YOGA adapter uses different pinout to ease layout */
- YOGA_D03_pin_nr = 13,
- YOGA_D04_pin_nr = 12,
- YOGA_D05_pin_nr = 21,
- YOGA_D06_pin_nr = 19,
-};
-
-/*
- * GPIO descriptors and pins - WARNING: STRICTLY KEEP ITEMS ORDER
- */
-
-#define GPIB_PINS 16
-#define SN7516X_PINS 4
-#define NUM_PINS (GPIB_PINS + SN7516X_PINS)
-
-#define ACT_LED_ON do { \
- if (ACT_LED) \
- gpiod_direction_output(ACT_LED, 1); \
- } while (0)
-#define ACT_LED_OFF do { \
- if (ACT_LED) \
- gpiod_direction_output(ACT_LED, 0); \
- } while (0)
-
-static struct gpio_desc *all_descriptors[GPIB_PINS + SN7516X_PINS];
-
-#define D01 all_descriptors[0]
-#define D02 all_descriptors[1]
-#define D03 all_descriptors[2]
-#define D04 all_descriptors[3]
-#define D05 all_descriptors[4]
-#define D06 all_descriptors[5]
-#define D07 all_descriptors[6]
-#define D08 all_descriptors[7]
-
-#define EOI all_descriptors[8]
-#define NRFD all_descriptors[9]
-#define IFC all_descriptors[10]
-#define _ATN all_descriptors[11]
-#define REN all_descriptors[12]
-#define DAV all_descriptors[13]
-#define NDAC all_descriptors[14]
-#define SRQ all_descriptors[15]
-
-#define PE all_descriptors[16]
-#define DC all_descriptors[17]
-#define TE all_descriptors[18]
-#define ACT_LED all_descriptors[19]
-
-/* YOGA adapter uses a global enable for the buffer chips, re-using the TE pin */
-#define YOGA_ENABLE TE
-
-static int gpios_vector[] = {
- D01_pin_nr,
- D02_pin_nr,
- D03_pin_nr,
- D04_pin_nr,
- D05_pin_nr,
- D06_pin_nr,
- D07_pin_nr,
- D08_pin_nr,
-
- EOI_pin_nr,
- NRFD_pin_nr,
- IFC_pin_nr,
- _ATN_pin_nr,
- REN_pin_nr,
- DAV_pin_nr,
- NDAC_pin_nr,
- SRQ_pin_nr,
-
- PE_pin_nr,
- DC_pin_nr,
- TE_pin_nr,
- ACT_LED_pin_nr
-};
-
-/* Lookup table for general GPIOs */
-
-static struct gpiod_lookup_table gpib_gpio_table_1 = {
- // for bcm2835/6
- .dev_id = "", // device id of board device
- .table = {
- GPIO_LOOKUP_IDX("GPIO_GCLK", U16_MAX, NULL, 4, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO5", U16_MAX, NULL, 5, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO6", U16_MAX, NULL, 6, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("SPI_CE1_N", U16_MAX, NULL, 7, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("SPI_CE0_N", U16_MAX, NULL, 8, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("SPI_MISO", U16_MAX, NULL, 9, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("SPI_MOSI", U16_MAX, NULL, 10, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("SPI_SCLK", U16_MAX, NULL, 11, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO12", U16_MAX, NULL, 12, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO13", U16_MAX, NULL, 13, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO16", U16_MAX, NULL, 16, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO17", U16_MAX, NULL, 17, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO18", U16_MAX, NULL, 18, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO19", U16_MAX, NULL, 19, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO20", U16_MAX, NULL, 20, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO21", U16_MAX, NULL, 21, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO22", U16_MAX, NULL, 22, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO23", U16_MAX, NULL, 23, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO24", U16_MAX, NULL, 24, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO25", U16_MAX, NULL, 25, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO26", U16_MAX, NULL, 26, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO27", U16_MAX, NULL, 27, GPIO_ACTIVE_HIGH),
- { }
- },
-};
-
-static struct gpiod_lookup_table gpib_gpio_table_0 = {
- .dev_id = "", // device id of board device
- .table = {
- // for bcm27xx based pis (b b+ 2b 3b 3b+ 4 5)
- GPIO_LOOKUP_IDX("GPIO4", U16_MAX, NULL, 4, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO5", U16_MAX, NULL, 5, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO6", U16_MAX, NULL, 6, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO7", U16_MAX, NULL, 7, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO8", U16_MAX, NULL, 8, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO9", U16_MAX, NULL, 9, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO10", U16_MAX, NULL, 10, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO11", U16_MAX, NULL, 11, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO12", U16_MAX, NULL, 12, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO13", U16_MAX, NULL, 13, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO16", U16_MAX, NULL, 16, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO17", U16_MAX, NULL, 17, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO18", U16_MAX, NULL, 18, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO19", U16_MAX, NULL, 19, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO20", U16_MAX, NULL, 20, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO21", U16_MAX, NULL, 21, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO22", U16_MAX, NULL, 22, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO23", U16_MAX, NULL, 23, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO24", U16_MAX, NULL, 24, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO25", U16_MAX, NULL, 25, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO26", U16_MAX, NULL, 26, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX("GPIO27", U16_MAX, NULL, 27, GPIO_ACTIVE_HIGH),
- { }
- },
-};
-
-static struct gpiod_lookup_table *lookup_tables[] = {
- &gpib_gpio_table_0,
- &gpib_gpio_table_1,
- NULL
-};
-
-/* struct which defines private_data for gpio driver */
-
-struct bb_priv {
- int irq_NRFD;
- int irq_NDAC;
- int irq_DAV;
- int irq_SRQ;
- int dav_mode; /* dav interrupt mode 0/1 -> edge/levels */
- int nrfd_mode; /* nrfd interrupt mode 0/1 -> edge/levels */
- int ndac_mode; /* nrfd interrupt mode 0/1 -> edge/levels */
- int dav_tx; /* keep trace of DAV status while sending */
- int dav_rx; /* keep trace of DAV status while receiving */
- u8 eos; /* eos character */
- short eos_flags; /* eos mode */
- short eos_check; /* eos check required in current operation ... */
- short eos_check_8; /* ... with byte comparison */
- short eos_mask_7; /* ... with 7 bit masked character */
- short int end;
- int request;
- int count;
- int direction;
- int t1_delay;
- u8 *rbuf;
- u8 *wbuf;
- int end_flag;
- int r_busy; /* 0==idle 1==busy */
- int w_busy;
- int write_done;
- int cmd; /* 1 = cmd write in progress */
- size_t w_cnt;
- size_t length;
- u8 *w_buf;
- spinlock_t rw_lock; /* protect mods to rw_lock */
- int phase;
- int ndac_idle;
- int ndac_seq;
- int nrfd_idle;
- int nrfd_seq;
- int dav_seq;
- long all_irqs;
- int dav_idle;
-
- enum talker_function_state talker_state;
- enum listener_function_state listener_state;
-};
-
-static inline long usec_diff(struct timespec64 *a, struct timespec64 *b);
-static void bb_buffer_print(struct gpib_board *board, unsigned char *buffer, size_t length,
- int cmd, int eoi);
-static void set_data_lines(u8 byte);
-static u8 get_data_lines(void);
-static void set_data_lines_input(void);
-static void set_data_lines_output(void);
-static inline int check_for_eos(struct bb_priv *priv, u8 byte);
-static void set_atn(struct gpib_board *board, int atn_asserted);
-
-static inline void SET_DIR_WRITE(struct bb_priv *priv);
-static inline void SET_DIR_READ(struct bb_priv *priv);
-
-#define DIR_READ 0
-#define DIR_WRITE 1
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB helper functions for bitbanging I/O");
-
-/**** global variables ****/
-static int debug;
-module_param(debug, int, 0644);
-
-static char printable(char x)
-{
- if (x < 32 || x > 126)
- return ' ';
- return x;
-}
-
-/***************************************************************************
- * *
- * READ *
- * *
- ***************************************************************************/
-
-static int bb_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct bb_priv *priv = board->private_data;
- unsigned long flags;
- int retval = 0;
-
- ACT_LED_ON;
- SET_DIR_READ(priv);
-
- dbg_printk(2, "board: %p lock %d length: %zu\n",
- board, mutex_is_locked(&board->user_mutex), length);
-
- priv->end = 0;
- priv->count = 0;
- priv->rbuf = buffer;
- if (length == 0)
- goto read_end;
- priv->request = length;
- priv->eos_check = (priv->eos_flags & REOS) == 0; /* do eos check */
- priv->eos_check_8 = priv->eos_flags & BIN; /* over 8 bits */
- priv->eos_mask_7 = priv->eos & 0x7f; /* with this 7 bit eos */
-
- dbg_printk(3, ".........." LINFMT "\n", LINVAL);
-
- spin_lock_irqsave(&priv->rw_lock, flags);
- priv->dav_mode = 1;
- priv->dav_rx = 1;
- ENABLE_IRQ(priv->irq_DAV, IRQ_TYPE_LEVEL_LOW);
- priv->end_flag = 0;
- gpiod_set_value(NRFD, 1); // ready for data
- priv->r_busy = 1;
- priv->phase = 100;
- spin_unlock_irqrestore(&priv->rw_lock, flags);
-
- /* wait for the interrupt routines finish their work */
-
- retval = wait_event_interruptible(board->wait,
- (priv->end_flag || board->status & TIMO));
-
- dbg_printk(3, "awake from wait queue: %d\n", retval);
-
- if (retval == 0 && board->status & TIMO) {
- retval = -ETIMEDOUT;
- dbg_printk(1, "timeout\n");
- } else if (retval) {
- retval = -ERESTARTSYS;
- }
-
- DISABLE_IRQ(priv->irq_DAV);
- spin_lock_irqsave(&priv->rw_lock, flags);
- gpiod_set_value(NRFD, 0); // DIR_READ line state
- priv->r_busy = 0;
- spin_unlock_irqrestore(&priv->rw_lock, flags);
-
-read_end:
- ACT_LED_OFF;
- *bytes_read = priv->count;
- *end = priv->end;
- priv->r_busy = 0;
- dbg_printk(2, "return: %d eoi|eos: %d count: %d\n\n", retval, priv->end, priv->count);
- return retval;
-}
-
-/***************************************************************************
- * *
- * READ interrupt routine (DAV line) *
- * *
- ***************************************************************************/
-
-static irqreturn_t bb_DAV_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct bb_priv *priv = board->private_data;
- int val;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->rw_lock, flags);
-
- priv->all_irqs++;
-
- if (priv->dav_mode) {
- ENABLE_IRQ(priv->irq_DAV, IRQ_TYPE_EDGE_BOTH);
- priv->dav_mode = 0;
- }
-
- if (priv->r_busy == 0) {
- dbg_printk(1, "interrupt while idle after %d at %d\n",
- priv->count, priv->phase);
- priv->dav_idle++;
- priv->phase = 200;
- goto dav_exit; /* idle */
- }
-
- val = gpiod_get_value(DAV);
- if (val == priv->dav_rx) {
- dbg_printk(1, "out of order DAV interrupt %d/%d after %zu/%zu at %d cmd %d "
- LINFMT ".\n", val, priv->dav_rx, priv->w_cnt, priv->length,
- priv->phase, priv->cmd, LINVAL);
- priv->dav_seq++;
- }
- priv->dav_rx = val;
-
- dbg_printk(3, "> irq: %d DAV: %d st: %4lx dir: %d busy: %d:%d\n",
- irq, val, board->status, priv->direction, priv->r_busy, priv->w_busy);
-
- if (val == 0) {
- gpiod_set_value(NRFD, 0); // not ready for data
- priv->rbuf[priv->count++] = get_data_lines();
- priv->end = !gpiod_get_value(EOI);
- gpiod_set_value(NDAC, 1); // data accepted
- priv->end |= check_for_eos(priv, priv->rbuf[priv->count - 1]);
- priv->end_flag = ((priv->count >= priv->request) || priv->end);
- priv->phase = 210;
- } else {
- gpiod_set_value(NDAC, 0); // data not accepted
- if (priv->end_flag) {
- priv->r_busy = 0;
- wake_up_interruptible(&board->wait);
- priv->phase = 220;
- } else {
- gpiod_set_value(NRFD, 1); // ready for data
- priv->phase = 230;
- }
- }
-
-dav_exit:
- spin_unlock_irqrestore(&priv->rw_lock, flags);
- dbg_printk(3, "< irq: %d count %d\n", irq, priv->count);
- return IRQ_HANDLED;
-}
-
-/***************************************************************************
- * *
- * WRITE *
- * *
- ***************************************************************************/
-
-static int bb_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- unsigned long flags;
- int retval = 0;
-
- struct bb_priv *priv = board->private_data;
-
- ACT_LED_ON;
-
- priv->w_cnt = 0;
- priv->w_buf = buffer;
- dbg_printk(2, "board %p lock %d length: %zu\n",
- board, mutex_is_locked(&board->user_mutex), length);
-
- if (debug > 1)
- bb_buffer_print(board, buffer, length, priv->cmd, send_eoi);
- priv->count = 0;
- priv->phase = 300;
-
- if (length == 0)
- goto write_end;
- priv->end = send_eoi;
- priv->length = length;
-
- SET_DIR_WRITE(priv);
-
- dbg_printk(2, "Enabling interrupts - NRFD: %d NDAC: %d\n",
- gpiod_get_value(NRFD), gpiod_get_value(NDAC));
-
- if (gpiod_get_value(NRFD) && gpiod_get_value(NDAC)) { /* check for listener */
- retval = -ENOTCONN;
- goto write_end;
- }
-
- spin_lock_irqsave(&priv->rw_lock, flags);
- priv->w_busy = 1; /* make the interrupt routines active */
- priv->write_done = 0;
- priv->nrfd_mode = 1;
- priv->ndac_mode = 1;
- priv->dav_tx = 1;
- ENABLE_IRQ(priv->irq_NDAC, IRQ_TYPE_LEVEL_HIGH);
- ENABLE_IRQ(priv->irq_NRFD, IRQ_TYPE_LEVEL_HIGH);
- spin_unlock_irqrestore(&priv->rw_lock, flags);
-
- /* wait for the interrupt routines finish their work */
-
- retval = wait_event_interruptible(board->wait,
- priv->write_done || (board->status & TIMO));
-
- dbg_printk(3, "awake from wait queue: %d\n", retval);
-
- if (retval == 0) {
- if (board->status & TIMO) {
- retval = -ETIMEDOUT;
- dbg_printk(1, "timeout after %zu/%zu at %d " LINFMT " eoi: %d\n",
- priv->w_cnt, length, priv->phase, LINVAL, send_eoi);
- } else {
- retval = priv->w_cnt;
- }
- } else {
- retval = -ERESTARTSYS;
- }
-
- DISABLE_IRQ(priv->irq_NRFD);
- DISABLE_IRQ(priv->irq_NDAC);
-
- spin_lock_irqsave(&priv->rw_lock, flags);
- priv->w_busy = 0;
- gpiod_set_value(DAV, 1); // DIR_WRITE line state
- gpiod_set_value(EOI, 1); // De-assert EOI (in case)
- spin_unlock_irqrestore(&priv->rw_lock, flags);
-
-write_end:
- *bytes_written = priv->w_cnt;
- ACT_LED_OFF;
- dbg_printk(2, "sent %zu bytes\r\n\r\n", *bytes_written);
- priv->phase = 310;
- return retval;
-}
-
-/***************************************************************************
- * *
- * WRITE interrupt routine (NRFD line) *
- * *
- ***************************************************************************/
-
-static irqreturn_t bb_NRFD_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct bb_priv *priv = board->private_data;
- unsigned long flags;
- int nrfd;
-
- spin_lock_irqsave(&priv->rw_lock, flags);
-
- nrfd = gpiod_get_value(NRFD);
- priv->all_irqs++;
-
- dbg_printk(3, "> irq: %d NRFD: %d NDAC: %d st: %4lx dir: %d busy: %d:%d\n",
- irq, nrfd, gpiod_get_value(NDAC), board->status, priv->direction,
- priv->w_busy, priv->r_busy);
-
- if (priv->nrfd_mode) {
- ENABLE_IRQ(priv->irq_NRFD, IRQ_TYPE_EDGE_RISING);
- priv->nrfd_mode = 0;
- }
-
- if (priv->w_busy == 0) {
- dbg_printk(1, "interrupt while idle after %zu/%zu at %d\n",
- priv->w_cnt, priv->length, priv->phase);
- priv->nrfd_idle++;
- goto nrfd_exit; /* idle */
- }
- if (nrfd == 0) {
- dbg_printk(1, "out of order interrupt after %zu/%zu at %d cmd %d " LINFMT ".\n",
- priv->w_cnt, priv->length, priv->phase, priv->cmd, LINVAL);
- priv->phase = 400;
- priv->nrfd_seq++;
- goto nrfd_exit;
- }
- if (!priv->dav_tx) {
- dbg_printk(1, "DAV low after %zu/%zu cmd %d " LINFMT ". No action.\n",
- priv->w_cnt, priv->length, priv->cmd, LINVAL);
- priv->dav_seq++;
- goto nrfd_exit;
- }
-
- if (priv->w_cnt >= priv->length) { // test for missed NDAC end of transfer
- dev_err(board->gpib_dev, "Unexpected NRFD exit\n");
- priv->write_done = 1;
- priv->w_busy = 0;
- wake_up_interruptible(&board->wait);
- goto nrfd_exit;
- }
-
- dbg_printk(3, "sending %zu\n", priv->w_cnt);
-
- set_data_lines(priv->w_buf[priv->w_cnt++]); // put the data on the lines
-
- if (priv->w_cnt == priv->length && priv->end) {
- dbg_printk(3, "Asserting EOI\n");
- gpiod_set_value(EOI, 0); // Assert EOI
- }
-
- gpiod_set_value(DAV, 0); // Data available
- priv->dav_tx = 0;
- priv->phase = 410;
-
-nrfd_exit:
- spin_unlock_irqrestore(&priv->rw_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-/***************************************************************************
- * *
- * WRITE interrupt routine (NDAC line) *
- * *
- ***************************************************************************/
-
-static irqreturn_t bb_NDAC_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct bb_priv *priv = board->private_data;
- unsigned long flags;
- int ndac;
-
- spin_lock_irqsave(&priv->rw_lock, flags);
-
- ndac = gpiod_get_value(NDAC);
- priv->all_irqs++;
- dbg_printk(3, "> irq: %d NRFD: %d NDAC: %d st: %4lx dir: %d busy: %d:%d\n",
- irq, gpiod_get_value(NRFD), ndac, board->status, priv->direction,
- priv->w_busy, priv->r_busy);
-
- if (priv->ndac_mode) {
- ENABLE_IRQ(priv->irq_NDAC, IRQ_TYPE_EDGE_RISING);
- priv->ndac_mode = 0;
- }
-
- if (priv->w_busy == 0) {
- dbg_printk(1, "interrupt while idle.\n");
- priv->ndac_idle++;
- goto ndac_exit;
- }
- if (ndac == 0) {
- dbg_printk(1, "out of order interrupt at %zu:%d.\n", priv->w_cnt, priv->phase);
- priv->phase = 500;
- priv->ndac_seq++;
- goto ndac_exit;
- }
- if (priv->dav_tx) {
- dbg_printk(1, "DAV high after %zu/%zu cmd %d " LINFMT ". No action.\n",
- priv->w_cnt, priv->length, priv->cmd, LINVAL);
- priv->dav_seq++;
- goto ndac_exit;
- }
-
- dbg_printk(3, "accepted %zu\n", priv->w_cnt - 1);
-
- gpiod_set_value(DAV, 1); // Data not available
- priv->dav_tx = 1;
- priv->phase = 510;
-
- if (priv->w_cnt >= priv->length) { // test for end of transfer
- priv->write_done = 1;
- priv->w_busy = 0;
- wake_up_interruptible(&board->wait);
- }
-
-ndac_exit:
- spin_unlock_irqrestore(&priv->rw_lock, flags);
- return IRQ_HANDLED;
-}
-
-/***************************************************************************
- * *
- * interrupt routine for SRQ line *
- * *
- ***************************************************************************/
-
-static irqreturn_t bb_SRQ_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
-
- int val = gpiod_get_value(SRQ);
-
- dbg_printk(3, "> %d st: %4lx\n", val, board->status);
-
- if (!val)
- set_bit(SRQI_NUM, &board->status); /* set_bit() is atomic */
-
- wake_up_interruptible(&board->wait);
-
- return IRQ_HANDLED;
-}
-
-static int bb_command(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- int ret;
- struct bb_priv *priv = board->private_data;
- int i;
-
- dbg_printk(2, "%p %p\n", buffer, board->buffer);
-
- /* the _ATN line has already been asserted by bb_take_control() */
-
- priv->cmd = 1;
-
- ret = bb_write(board, buffer, length, 0, bytes_written); // no eoi
-
- for (i = 0; i < length; i++) {
- if (buffer[i] == UNT) {
- priv->talker_state = talker_idle;
- } else {
- if (buffer[i] == UNL) {
- priv->listener_state = listener_idle;
- } else {
- if (buffer[i] == (MTA(board->pad))) {
- priv->talker_state = talker_addressed;
- priv->listener_state = listener_idle;
- } else if (buffer[i] == (MLA(board->pad))) {
- priv->listener_state = listener_addressed;
- priv->talker_state = talker_idle;
- }
- }
- }
- }
-
- /* the _ATN line will be released by bb_go_to_stby */
-
- priv->cmd = 0;
-
- return ret;
-}
-
-/***************************************************************************
- * *
- * Buffer print with decode for debug/trace *
- * *
- ***************************************************************************/
-
-static char *cmd_string[32] = {
- "", // 0x00
- "GTL", // 0x01
- "", // 0x02
- "", // 0x03
- "SDC", // 0x04
- "PPC", // 0x05
- "", // 0x06
- "", // 0x07
- "GET", // 0x08
- "TCT", // 0x09
- "", // 0x0a
- "", // 0x0b
- "", // 0x0c
- "", // 0x0d
- "", // 0x0e
- "", // 0x0f
- "", // 0x10
- "LLO", // 0x11
- "", // 0x12
- "", // 0x13
- "DCL", // 0x14
- "PPU", // 0x15
- "", // 0x16
- "", // 0x17
- "SPE", // 0x18
- "SPD", // 0x19
- "", // 0x1a
- "", // 0x1b
- "", // 0x1c
- "", // 0x1d
- "", // 0x1e
- "CFE" // 0x1f
-};
-
-static void bb_buffer_print(struct gpib_board *board, unsigned char *buffer, size_t length,
- int cmd, int eoi)
-{
- int i;
-
- if (cmd) {
- dbg_printk(2, "<cmd len %zu>\n", length);
- for (i = 0; i < length; i++) {
- if (buffer[i] < 0x20) {
- dbg_printk(3, "0x%x=%s\n", buffer[i], cmd_string[buffer[i]]);
- } else if (buffer[i] == 0x3f) {
- dbg_printk(3, "0x%x=%s\n", buffer[i], "UNL");
- } else if (buffer[i] == 0x5f) {
- dbg_printk(3, "0x%x=%s\n", buffer[i], "UNT");
- } else if (buffer[i] < 0x60) {
- dbg_printk(3, "0x%x=%s%d\n", buffer[i],
- (buffer[i] & 0x40) ? "TLK" : "LSN", buffer[i] & 0x1F);
- } else {
- dbg_printk(3, "0x%x\n", buffer[i]);
- }
- }
- } else {
- dbg_printk(2, "<data len %zu %s>\n", length, (eoi) ? "w.EOI" : " ");
- for (i = 0; i < length; i++)
- dbg_printk(2, "%3d 0x%x->%c\n", i, buffer[i], printable(buffer[i]));
- }
-}
-
-/***************************************************************************
- * *
- * STATUS Management *
- * *
- ***************************************************************************/
-static void set_atn(struct gpib_board *board, int atn_asserted)
-{
- struct bb_priv *priv = board->private_data;
-
- if (priv->listener_state != listener_idle &&
- priv->talker_state != talker_idle) {
- dev_err(board->gpib_dev, "listener/talker state machine conflict\n");
- }
- if (atn_asserted) {
- if (priv->listener_state == listener_active)
- priv->listener_state = listener_addressed;
- if (priv->talker_state == talker_active)
- priv->talker_state = talker_addressed;
- SET_DIR_WRITE(priv); // need to be able to read bus NRFD/NDAC
- } else {
- if (priv->listener_state == listener_addressed) {
- priv->listener_state = listener_active;
- SET_DIR_READ(priv); // make sure holdoff is active when we unassert ATN
- }
- if (priv->talker_state == talker_addressed)
- priv->talker_state = talker_active;
- }
- gpiod_direction_output(_ATN, !atn_asserted);
-}
-
-static int bb_take_control(struct gpib_board *board, int synchronous)
-{
- dbg_printk(2, "%d\n", synchronous);
- set_atn(board, 1);
- return 0;
-}
-
-static int bb_go_to_standby(struct gpib_board *board)
-{
- dbg_printk(2, "\n");
- set_atn(board, 0);
- return 0;
-}
-
-static int bb_request_system_control(struct gpib_board *board, int request_control)
-{
- struct bb_priv *priv = board->private_data;
-
- dbg_printk(2, "%d\n", request_control);
- if (!request_control)
- return -EINVAL;
-
- gpiod_direction_output(REN, 1); /* user space must enable REN if needed */
- gpiod_direction_output(IFC, 1); /* user space must toggle IFC if needed */
- if (sn7516x)
- gpiod_direction_output(DC, 0); /* enable ATN as output on SN75161/2 */
-
- gpiod_direction_input(SRQ);
-
- ENABLE_IRQ(priv->irq_SRQ, IRQ_TYPE_EDGE_FALLING);
-
- return 0;
-}
-
-static void bb_interface_clear(struct gpib_board *board, int assert)
-{
- struct bb_priv *priv = board->private_data;
-
- dbg_printk(2, "%d\n", assert);
- if (assert) {
- gpiod_direction_output(IFC, 0);
- priv->talker_state = talker_idle;
- priv->listener_state = listener_idle;
- set_bit(CIC_NUM, &board->status);
- } else {
- gpiod_direction_output(IFC, 1);
- }
-}
-
-static void bb_remote_enable(struct gpib_board *board, int enable)
-{
- dbg_printk(2, "%d\n", enable);
- if (enable) {
- set_bit(REM_NUM, &board->status);
- gpiod_direction_output(REN, 0);
- } else {
- clear_bit(REM_NUM, &board->status);
- gpiod_direction_output(REN, 1);
- }
-}
-
-static int bb_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct bb_priv *priv = board->private_data;
-
- dbg_printk(2, "%s\n", "EOS_en");
- priv->eos = eos_byte;
- priv->eos_flags = REOS;
- if (compare_8_bits)
- priv->eos_flags |= BIN;
-
- return 0;
-}
-
-static void bb_disable_eos(struct gpib_board *board)
-{
- struct bb_priv *priv = board->private_data;
-
- dbg_printk(2, "\n");
- priv->eos_flags &= ~REOS;
-}
-
-static unsigned int bb_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct bb_priv *priv = board->private_data;
-
- board->status &= ~clear_mask;
-
- if (gpiod_get_value(SRQ)) /* SRQ asserted low */
- clear_bit(SRQI_NUM, &board->status);
- else
- set_bit(SRQI_NUM, &board->status);
- if (gpiod_get_value(_ATN)) /* ATN asserted low */
- clear_bit(ATN_NUM, &board->status);
- else
- set_bit(ATN_NUM, &board->status);
- if (priv->talker_state == talker_active ||
- priv->talker_state == talker_addressed)
- set_bit(TACS_NUM, &board->status);
- else
- clear_bit(TACS_NUM, &board->status);
-
- if (priv->listener_state == listener_active ||
- priv->listener_state == listener_addressed)
- set_bit(LACS_NUM, &board->status);
- else
- clear_bit(LACS_NUM, &board->status);
-
- dbg_printk(2, "0x%lx mask 0x%x\n", board->status, clear_mask);
-
- return board->status;
-}
-
-static int bb_primary_address(struct gpib_board *board, unsigned int address)
-{
- dbg_printk(2, "%d\n", address);
- board->pad = address;
- return 0;
-}
-
-static int bb_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- dbg_printk(2, "%d %d\n", address, enable);
- if (enable)
- board->sad = address;
- return 0;
-}
-
-static int bb_parallel_poll(struct gpib_board *board, u8 *result)
-{
- return -ENOENT;
-}
-
-static void bb_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
-}
-
-static void bb_parallel_poll_response(struct gpib_board *board, int ist)
-{
-}
-
-static void bb_serial_poll_response(struct gpib_board *board, u8 status)
-{
-}
-
-static u8 bb_serial_poll_status(struct gpib_board *board)
-{
- return 0; // -ENOENT;
-}
-
-static int bb_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct bb_priv *priv = board->private_data;
-
- if (nano_sec <= 350)
- priv->t1_delay = 350;
- else if (nano_sec <= 1100)
- priv->t1_delay = 1100;
- else
- priv->t1_delay = 2000;
-
- dbg_printk(2, "t1 delay set to %d nanosec\n", priv->t1_delay);
-
- return priv->t1_delay;
-}
-
-static void bb_return_to_local(struct gpib_board *board)
-{
-}
-
-static int bb_line_status(const struct gpib_board *board)
-{
- int line_status = VALID_ALL;
-
- if (gpiod_get_value(REN) == 0)
- line_status |= BUS_REN;
- if (gpiod_get_value(IFC) == 0)
- line_status |= BUS_IFC;
- if (gpiod_get_value(NDAC) == 0)
- line_status |= BUS_NDAC;
- if (gpiod_get_value(NRFD) == 0)
- line_status |= BUS_NRFD;
- if (gpiod_get_value(DAV) == 0)
- line_status |= BUS_DAV;
- if (gpiod_get_value(EOI) == 0)
- line_status |= BUS_EOI;
- if (gpiod_get_value(_ATN) == 0)
- line_status |= BUS_ATN;
- if (gpiod_get_value(SRQ) == 0)
- line_status |= BUS_SRQ;
-
- dbg_printk(2, "status lines: %4x\n", line_status);
-
- return line_status;
-}
-
-/***************************************************************************
- * *
- * Module Management *
- * *
- ***************************************************************************/
-
-static int allocate_private(struct gpib_board *board)
-{
- board->private_data = kzalloc(sizeof(struct bb_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- return 0;
-}
-
-static void free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static int bb_get_irq(struct gpib_board *board, char *name,
- struct gpio_desc *gpio, int *irq,
- irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags)
-{
- if (!gpio)
- return -1;
- gpiod_direction_input(gpio);
- *irq = gpiod_to_irq(gpio);
- dbg_printk(2, "IRQ %s: %d\n", name, *irq);
- if (*irq < 0) {
- dev_err(board->gpib_dev, "can't get IRQ for %s\n", name);
- return -1;
- }
- if (request_threaded_irq(*irq, handler, thread_fn, flags, name, board)) {
- dev_err(board->gpib_dev, "can't request IRQ for %s %d\n", name, *irq);
- *irq = 0;
- return -1;
- }
- DISABLE_IRQ(*irq);
- return 0;
-}
-
-static void bb_free_irq(struct gpib_board *board, int *irq, char *name)
-{
- if (*irq) {
- free_irq(*irq, board);
- dbg_printk(2, "IRQ %d(%s) freed\n", *irq, name);
- *irq = 0;
- }
-}
-
-static void release_gpios(void)
-{
- int j;
-
- for (j = 0 ; j < NUM_PINS ; j++) {
- if (all_descriptors[j]) {
- gpiod_put(all_descriptors[j]);
- all_descriptors[j] = NULL;
- }
- }
-}
-
-static int allocate_gpios(struct gpib_board *board)
-{
- int j;
- int table_index = 0;
- char name[256];
- struct gpio_desc *desc;
- struct gpiod_lookup_table *lookup_table;
-
- if (!board->gpib_dev) {
- pr_err("NULL gpib dev for board\n");
- return -ENOENT;
- }
-
- lookup_table = lookup_tables[table_index];
- lookup_table->dev_id = dev_name(board->gpib_dev);
- gpiod_add_lookup_table(lookup_table);
- dbg_printk(1, "Allocating gpios using table index %d\n", table_index);
-
- for (j = 0 ; j < NUM_PINS ; j++) {
- if (gpios_vector[j] < 0)
- continue;
- /* name not really used in gpiod_get_index() */
- sprintf(name, "GPIO%d", gpios_vector[j]);
-try_again:
- dbg_printk(1, "Allocating gpio %s pin no %d\n", name, gpios_vector[j]);
- desc = gpiod_get_index(board->gpib_dev, name, gpios_vector[j], GPIOD_IN);
-
- if (IS_ERR(desc)) {
- gpiod_remove_lookup_table(lookup_table);
- table_index++;
- lookup_table = lookup_tables[table_index];
- if (!lookup_table) {
- dev_err(board->gpib_dev, "Unable to obtain gpio descriptor for pin %d error %ld\n",
- gpios_vector[j], PTR_ERR(desc));
- goto alloc_gpios_fail;
- }
- dbg_printk(1, "Allocation failed, now using table_index %d\n", table_index);
- lookup_table->dev_id = dev_name(board->gpib_dev);
- gpiod_add_lookup_table(lookup_table);
- goto try_again;
- }
- all_descriptors[j] = desc;
- }
-
- gpiod_remove_lookup_table(lookup_table);
-
- return 0;
-
-alloc_gpios_fail:
- release_gpios();
- return -1;
-}
-
-static void bb_detach(struct gpib_board *board)
-{
- struct bb_priv *priv = board->private_data;
-
- dbg_printk(2, "Enter with data %p\n", board->private_data);
- if (!board->private_data)
- return;
-
- bb_free_irq(board, &priv->irq_DAV, NAME "_DAV");
- bb_free_irq(board, &priv->irq_NRFD, NAME "_NRFD");
- bb_free_irq(board, &priv->irq_NDAC, NAME "_NDAC");
- bb_free_irq(board, &priv->irq_SRQ, NAME "_SRQ");
-
- if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA */
- gpiod_set_value(YOGA_ENABLE, 0);
- }
-
- release_gpios();
-
- dbg_printk(2, "detached board: %d\n", board->minor);
- dbg_printk(0, "NRFD: idle %d, seq %d, NDAC: idle %d, seq %d DAV: idle %d seq: %d all: %ld",
- priv->nrfd_idle, priv->nrfd_seq,
- priv->ndac_idle, priv->ndac_seq,
- priv->dav_idle, priv->dav_seq, priv->all_irqs);
-
- free_private(board);
-}
-
-static int bb_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct bb_priv *priv;
- int retval = 0;
-
- dbg_printk(2, "%s\n", "Enter ...");
-
- board->status = 0;
-
- if (allocate_private(board))
- return -ENOMEM;
- priv = board->private_data;
- priv->direction = -1;
- priv->t1_delay = 2000;
- priv->listener_state = listener_idle;
- priv->talker_state = talker_idle;
-
- sn7516x = sn7516x_used;
- if (strcmp(PINMAP_0, pin_map) == 0) {
- if (!sn7516x) {
- gpios_vector[&(PE) - &all_descriptors[0]] = -1;
- gpios_vector[&(DC) - &all_descriptors[0]] = -1;
- gpios_vector[&(TE) - &all_descriptors[0]] = -1;
- }
- } else if (strcmp(PINMAP_1, pin_map) == 0) {
- if (!sn7516x) {
- gpios_vector[&(PE) - &all_descriptors[0]] = -1;
- gpios_vector[&(DC) - &all_descriptors[0]] = -1;
- gpios_vector[&(TE) - &all_descriptors[0]] = -1;
- }
- gpios_vector[&(REN) - &all_descriptors[0]] = 0; /* 27 -> 0 REN on GPIB pin 0 */
- } else if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA */
- sn7516x = 0;
- gpios_vector[&(D03) - &all_descriptors[0]] = YOGA_D03_pin_nr;
- gpios_vector[&(D04) - &all_descriptors[0]] = YOGA_D04_pin_nr;
- gpios_vector[&(D05) - &all_descriptors[0]] = YOGA_D05_pin_nr;
- gpios_vector[&(D06) - &all_descriptors[0]] = YOGA_D06_pin_nr;
- gpios_vector[&(PE) - &all_descriptors[0]] = -1;
- gpios_vector[&(DC) - &all_descriptors[0]] = -1;
- } else {
- dev_err(board->gpib_dev, "Unrecognized pin map %s\n", pin_map);
- goto bb_attach_fail;
- }
- dbg_printk(0, "Using pin map \"%s\" %s\n", pin_map, (sn7516x) ?
- " with SN7516x driver support" : "");
-
- if (allocate_gpios(board))
- goto bb_attach_fail;
-
-/*
- * Configure SN7516X control lines.
- * drive ATN, IFC and REN as outputs only when master
- * i.e. system controller. In this mode can only be the CIC
- * When not master then enable device mode ATN, IFC & REN as inputs
- */
- if (sn7516x) {
- gpiod_direction_output(DC, 0);
- gpiod_direction_output(TE, 1);
- gpiod_direction_output(PE, 1);
- }
-/* Set main control lines to a known state */
- gpiod_direction_output(IFC, 1);
- gpiod_direction_output(REN, 1);
- gpiod_direction_output(_ATN, 1);
-
- if (strcmp(PINMAP_2, pin_map) == 0) { /* YOGA: enable level shifters */
- gpiod_direction_output(YOGA_ENABLE, 1);
- }
-
- spin_lock_init(&priv->rw_lock);
-
- /* request DAV interrupt for read */
- if (bb_get_irq(board, NAME "_DAV", DAV, &priv->irq_DAV, bb_DAV_interrupt, NULL,
- IRQF_TRIGGER_NONE))
- goto bb_attach_fail_r;
-
- /* request NRFD interrupt for write */
- if (bb_get_irq(board, NAME "_NRFD", NRFD, &priv->irq_NRFD, bb_NRFD_interrupt, NULL,
- IRQF_TRIGGER_NONE))
- goto bb_attach_fail_r;
-
- /* request NDAC interrupt for write */
- if (bb_get_irq(board, NAME "_NDAC", NDAC, &priv->irq_NDAC, bb_NDAC_interrupt, NULL,
- IRQF_TRIGGER_NONE))
- goto bb_attach_fail_r;
-
- /* request SRQ interrupt for Service Request */
- if (bb_get_irq(board, NAME "_SRQ", SRQ, &priv->irq_SRQ, bb_SRQ_interrupt, NULL,
- IRQF_TRIGGER_NONE))
- goto bb_attach_fail_r;
-
- dbg_printk(0, "attached board %d\n", board->minor);
- goto bb_attach_out;
-
-bb_attach_fail_r:
- release_gpios();
-bb_attach_fail:
- retval = -1;
-bb_attach_out:
- return retval;
-}
-
-static struct gpib_interface bb_interface = {
- .name = NAME,
- .attach = bb_attach,
- .detach = bb_detach,
- .read = bb_read,
- .write = bb_write,
- .command = bb_command,
- .take_control = bb_take_control,
- .go_to_standby = bb_go_to_standby,
- .request_system_control = bb_request_system_control,
- .interface_clear = bb_interface_clear,
- .remote_enable = bb_remote_enable,
- .enable_eos = bb_enable_eos,
- .disable_eos = bb_disable_eos,
- .parallel_poll = bb_parallel_poll,
- .parallel_poll_configure = bb_parallel_poll_configure,
- .parallel_poll_response = bb_parallel_poll_response,
- .line_status = bb_line_status,
- .update_status = bb_update_status,
- .primary_address = bb_primary_address,
- .secondary_address = bb_secondary_address,
- .serial_poll_response = bb_serial_poll_response,
- .serial_poll_status = bb_serial_poll_status,
- .t1_delay = bb_t1_delay,
- .return_to_local = bb_return_to_local,
-};
-
-static int __init bb_init_module(void)
-{
- int result = gpib_register_driver(&bb_interface, THIS_MODULE);
-
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- return result;
- }
-
- return 0;
-}
-
-static void __exit bb_exit_module(void)
-{
- gpib_unregister_driver(&bb_interface);
-}
-
-module_init(bb_init_module);
-module_exit(bb_exit_module);
-
-/***************************************************************************
- * *
- * UTILITY Functions *
- * *
- ***************************************************************************/
-inline long usec_diff(struct timespec64 *a, struct timespec64 *b)
-{
- return ((a->tv_sec - b->tv_sec) * 1000000 +
- (a->tv_nsec - b->tv_nsec) / 1000);
-}
-
-static inline int check_for_eos(struct bb_priv *priv, u8 byte)
-{
- if (priv->eos_check)
- return 0;
-
- if (priv->eos_check_8) {
- if (priv->eos == byte)
- return 1;
- } else {
- if (priv->eos_mask_7 == (byte & 0x7f))
- return 1;
- }
- return 0;
-}
-
-static void set_data_lines_output(void)
-{
- gpiod_direction_output(D01, 1);
- gpiod_direction_output(D02, 1);
- gpiod_direction_output(D03, 1);
- gpiod_direction_output(D04, 1);
- gpiod_direction_output(D05, 1);
- gpiod_direction_output(D06, 1);
- gpiod_direction_output(D07, 1);
- gpiod_direction_output(D08, 1);
-}
-
-static void set_data_lines(u8 byte)
-{
- gpiod_set_value(D01, !(byte & 0x01));
- gpiod_set_value(D02, !(byte & 0x02));
- gpiod_set_value(D03, !(byte & 0x04));
- gpiod_set_value(D04, !(byte & 0x08));
- gpiod_set_value(D05, !(byte & 0x10));
- gpiod_set_value(D06, !(byte & 0x20));
- gpiod_set_value(D07, !(byte & 0x40));
- gpiod_set_value(D08, !(byte & 0x80));
-}
-
-static u8 get_data_lines(void)
-{
- u8 ret;
-
- ret = gpiod_get_value(D01);
- ret |= gpiod_get_value(D02) << 1;
- ret |= gpiod_get_value(D03) << 2;
- ret |= gpiod_get_value(D04) << 3;
- ret |= gpiod_get_value(D05) << 4;
- ret |= gpiod_get_value(D06) << 5;
- ret |= gpiod_get_value(D07) << 6;
- ret |= gpiod_get_value(D08) << 7;
- return ~ret;
-}
-
-static void set_data_lines_input(void)
-{
- gpiod_direction_input(D01);
- gpiod_direction_input(D02);
- gpiod_direction_input(D03);
- gpiod_direction_input(D04);
- gpiod_direction_input(D05);
- gpiod_direction_input(D06);
- gpiod_direction_input(D07);
- gpiod_direction_input(D08);
-}
-
-static inline void SET_DIR_WRITE(struct bb_priv *priv)
-{
- if (priv->direction == DIR_WRITE)
- return;
-
- gpiod_direction_input(NRFD);
- gpiod_direction_input(NDAC);
- set_data_lines_output();
- gpiod_direction_output(DAV, 1);
- gpiod_direction_output(EOI, 1);
-
- if (sn7516x) {
- gpiod_set_value(PE, 1); /* set data lines to transmit on sn75160b */
- gpiod_set_value(TE, 1); /* set NDAC and NRFD to receive and DAV to transmit */
- }
-
- priv->direction = DIR_WRITE;
-}
-
-static inline void SET_DIR_READ(struct bb_priv *priv)
-{
- if (priv->direction == DIR_READ)
- return;
-
- gpiod_direction_input(DAV);
- gpiod_direction_input(EOI);
-
- set_data_lines_input();
-
- if (sn7516x) {
- gpiod_set_value(PE, 0); /* set data lines to receive on sn75160b */
- gpiod_set_value(TE, 0); /* set NDAC and NRFD to transmit and DAV to receive */
- }
-
- gpiod_direction_output(NRFD, 0); /* hold off the talker */
- gpiod_direction_output(NDAC, 0); /* data not accepted */
-
- priv->direction = DIR_READ;
-}
diff --git a/drivers/staging/gpib/hp_82335/Makefile b/drivers/staging/gpib/hp_82335/Makefile
deleted file mode 100644
index 305ce44ee48a..000000000000
--- a/drivers/staging/gpib/hp_82335/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-obj-$(CONFIG_GPIB_HP82335) += hp82335.o
-
-
diff --git a/drivers/staging/gpib/hp_82335/hp82335.c b/drivers/staging/gpib/hp_82335/hp82335.c
deleted file mode 100644
index d0e47ef77c87..000000000000
--- a/drivers/staging/gpib/hp_82335/hp82335.c
+++ /dev/null
@@ -1,371 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess *
- ***************************************************************************/
-
-/*
- * should enable ATN interrupts (and update board->status on occurrence),
- * implement recovery from bus errors (if necessary)
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "hp82335.h"
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards");
-
-static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static void hp82335_detach(struct gpib_board *board);
-static irqreturn_t hp82335_interrupt(int irq, void *arg);
-
-// wrappers for interface functions
-static int hp82335_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
-}
-
-static int hp82335_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int hp82335_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
-}
-
-static int hp82335_take_control(struct gpib_board *board, int synchronous)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
-}
-
-static int hp82335_go_to_standby(struct gpib_board *board)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_go_to_standby(board, &priv->tms9914_priv);
-}
-
-static int hp82335_request_system_control(struct gpib_board *board, int request_control)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
-}
-
-static void hp82335_interface_clear(struct gpib_board *board, int assert)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_interface_clear(board, &priv->tms9914_priv, assert);
-}
-
-static void hp82335_remote_enable(struct gpib_board *board, int enable)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_remote_enable(board, &priv->tms9914_priv, enable);
-}
-
-static int hp82335_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
-}
-
-static void hp82335_disable_eos(struct gpib_board *board)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_disable_eos(board, &priv->tms9914_priv);
-}
-
-static unsigned int hp82335_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
-}
-
-static int hp82335_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_primary_address(board, &priv->tms9914_priv, address);
-}
-
-static int hp82335_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
-}
-
-static int hp82335_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
-}
-
-static void hp82335_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
-}
-
-static void hp82335_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
-}
-
-static void hp82335_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
-}
-
-static u8 hp82335_serial_poll_status(struct gpib_board *board)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_serial_poll_status(board, &priv->tms9914_priv);
-}
-
-static int hp82335_line_status(const struct gpib_board *board)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_line_status(board, &priv->tms9914_priv);
-}
-
-static int hp82335_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct hp82335_priv *priv = board->private_data;
-
- return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
-}
-
-static void hp82335_return_to_local(struct gpib_board *board)
-{
- struct hp82335_priv *priv = board->private_data;
-
- tms9914_return_to_local(board, &priv->tms9914_priv);
-}
-
-static struct gpib_interface hp82335_interface = {
- .name = "hp82335",
- .attach = hp82335_attach,
- .detach = hp82335_detach,
- .read = hp82335_read,
- .write = hp82335_write,
- .command = hp82335_command,
- .request_system_control = hp82335_request_system_control,
- .take_control = hp82335_take_control,
- .go_to_standby = hp82335_go_to_standby,
- .interface_clear = hp82335_interface_clear,
- .remote_enable = hp82335_remote_enable,
- .enable_eos = hp82335_enable_eos,
- .disable_eos = hp82335_disable_eos,
- .parallel_poll = hp82335_parallel_poll,
- .parallel_poll_configure = hp82335_parallel_poll_configure,
- .parallel_poll_response = hp82335_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = hp82335_line_status,
- .update_status = hp82335_update_status,
- .primary_address = hp82335_primary_address,
- .secondary_address = hp82335_secondary_address,
- .serial_poll_response = hp82335_serial_poll_response,
- .serial_poll_status = hp82335_serial_poll_status,
- .t1_delay = hp82335_t1_delay,
- .return_to_local = hp82335_return_to_local,
-};
-
-static int hp82335_allocate_private(struct gpib_board *board)
-{
- board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- return 0;
-}
-
-static void hp82335_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static inline unsigned int tms9914_to_hp82335_offset(unsigned int register_num)
-{
- return 0x1ff8 + register_num;
-}
-
-static u8 hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num)
-{
- return tms9914_iomem_read_byte(priv, tms9914_to_hp82335_offset(register_num));
-}
-
-static void hp82335_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
-{
- tms9914_iomem_write_byte(priv, data, tms9914_to_hp82335_offset(register_num));
-}
-
-static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv)
-{
- struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
-
- writeb(0, tms_priv->mmiobase + HPREG_INTR_CLEAR);
-}
-
-static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct hp82335_priv *hp_priv;
- struct tms9914_priv *tms_priv;
- int retval;
- const unsigned long upper_iomem_base = config->ibbase + hp82335_rom_size;
-
- board->status = 0;
-
- if (hp82335_allocate_private(board))
- return -ENOMEM;
- hp_priv = board->private_data;
- tms_priv = &hp_priv->tms9914_priv;
- tms_priv->read_byte = hp82335_read_byte;
- tms_priv->write_byte = hp82335_write_byte;
- tms_priv->offset = 1;
-
- switch (config->ibbase) {
- case 0xc4000:
- case 0xc8000:
- case 0xcc000:
- case 0xd0000:
- case 0xd4000:
- case 0xd8000:
- case 0xdc000:
- case 0xe0000:
- case 0xe4000:
- case 0xe8000:
- case 0xec000:
- case 0xf0000:
- case 0xf4000:
- case 0xf8000:
- case 0xfc000:
- break;
- default:
- dev_err(board->gpib_dev, "invalid base io address 0x%x\n", config->ibbase);
- return -EINVAL;
- }
- if (!request_mem_region(upper_iomem_base, hp82335_upper_iomem_size, "hp82335")) {
- dev_err(board->gpib_dev, "failed to allocate io memory region 0x%lx-0x%lx\n",
- upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1);
- return -EBUSY;
- }
- hp_priv->raw_iobase = upper_iomem_base;
- tms_priv->mmiobase = ioremap(upper_iomem_base, hp82335_upper_iomem_size);
-
- retval = request_irq(config->ibirq, hp82335_interrupt, 0, DRV_NAME, board);
- if (retval) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
- return retval;
- }
- hp_priv->irq = config->ibirq;
-
- tms9914_board_reset(tms_priv);
-
- hp82335_clear_interrupt(hp_priv);
-
- writeb(INTR_ENABLE, tms_priv->mmiobase + HPREG_CCR);
-
- tms9914_online(board, tms_priv);
-
- return 0;
-}
-
-static void hp82335_detach(struct gpib_board *board)
-{
- struct hp82335_priv *hp_priv = board->private_data;
- struct tms9914_priv *tms_priv;
-
- if (hp_priv) {
- tms_priv = &hp_priv->tms9914_priv;
- if (hp_priv->irq)
- free_irq(hp_priv->irq, board);
- if (tms_priv->mmiobase) {
- writeb(0, tms_priv->mmiobase + HPREG_CCR);
- tms9914_board_reset(tms_priv);
- iounmap(tms_priv->mmiobase);
- }
- if (hp_priv->raw_iobase)
- release_mem_region(hp_priv->raw_iobase, hp82335_upper_iomem_size);
- }
- hp82335_free_private(board);
-}
-
-static int __init hp82335_init_module(void)
-{
- int result = gpib_register_driver(&hp82335_interface, THIS_MODULE);
-
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- return result;
- }
-
- return 0;
-}
-
-static void __exit hp82335_exit_module(void)
-{
- gpib_unregister_driver(&hp82335_interface);
-}
-
-module_init(hp82335_init_module);
-module_exit(hp82335_exit_module);
-
-/*
- * GPIB interrupt service routines
- */
-
-static irqreturn_t hp82335_interrupt(int irq, void *arg)
-{
- int status1, status2;
- struct gpib_board *board = arg;
- struct hp82335_priv *priv = board->private_data;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- status1 = read_byte(&priv->tms9914_priv, ISR0);
- status2 = read_byte(&priv->tms9914_priv, ISR1);
- hp82335_clear_interrupt(priv);
- retval = tms9914_interrupt_have_status(board, &priv->tms9914_priv, status1, status2);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
diff --git a/drivers/staging/gpib/hp_82335/hp82335.h b/drivers/staging/gpib/hp_82335/hp82335.h
deleted file mode 100644
index 0c252a712ec9..000000000000
--- a/drivers/staging/gpib/hp_82335/hp82335.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess *
- ***************************************************************************/
-
-#ifndef _HP82335_H
-#define _HP82335_H
-
-#include "tms9914.h"
-#include "gpibP.h"
-
-// struct which defines private_data for board
-struct hp82335_priv {
- struct tms9914_priv tms9914_priv;
- unsigned int irq;
- unsigned long raw_iobase;
-};
-
-// size of io memory region used
-static const int hp82335_rom_size = 0x2000;
-static const int hp82335_upper_iomem_size = 0x2000;
-
-// hp82335 register offsets
-enum hp_read_regs {
- HPREG_CSR = 0x17f8,
- HPREG_STATUS = 0x1ffc,
-};
-
-enum hp_write_regs {
- HPREG_INTR_CLEAR = 0x17f7,
- HPREG_CCR = HPREG_CSR,
-};
-
-enum ccr_bits {
- DMA_ENABLE = (1 << 0), /* DMA enable */
- DMA_CHAN_SELECT = (1 << 1), /* DMA channel select O=3,1=2 */
- INTR_ENABLE = (1 << 2), /* interrupt enable */
- SYS_DISABLE = (1 << 3), /* system controller disable */
-};
-
-enum csr_bits {
- SWITCH6 = (1 << 0), /* switch 6 position */
- SWITCH5 = (1 << 1), /* switch 5 position */
- SYS_CONTROLLER = (1 << 2), /* system controller bit */
- DMA_ENABLE_STATUS = (1 << 4), /* DMA enabled */
- DMA_CHAN_STATUS = (1 << 5), /* DMA channel 0=3,1=2 */
- INTR_ENABLE_STATUS = (1 << 6), /* Interrupt enable */
- INTR_PENDING = (1 << 7), /* Interrupt Pending */
-};
-
-#endif // _HP82335_H
diff --git a/drivers/staging/gpib/hp_82341/Makefile b/drivers/staging/gpib/hp_82341/Makefile
deleted file mode 100644
index 21367310a17e..000000000000
--- a/drivers/staging/gpib/hp_82341/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-
-obj-$(CONFIG_GPIB_HP82341) += hp_82341.o
diff --git a/drivers/staging/gpib/hp_82341/hp_82341.c b/drivers/staging/gpib/hp_82341/hp_82341.c
deleted file mode 100644
index 1a2ad0560e14..000000000000
--- a/drivers/staging/gpib/hp_82341/hp_82341.c
+++ /dev/null
@@ -1,907 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * Driver for hp 82341a/b/c/d boards. *
- * Might be worth merging with Agilent 82350b driver. *
- * copyright : (C) 2002, 2005 by Frank Mori Hess *
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "hp_82341.h"
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/isapnp.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for hp 82341a/b/c/d boards");
-
-static unsigned short read_and_clear_event_status(struct gpib_board *board);
-static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count);
-static int read_transfer_counter(struct hp_82341_priv *hp_priv);
-static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
-static irqreturn_t hp_82341_interrupt(int irq, void *arg);
-
-static int hp_82341_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct hp_82341_priv *hp_priv = board->private_data;
- struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
- int retval = 0;
- unsigned short event_status;
- int i;
- int num_fifo_bytes;
- // hardware doesn't support checking for end-of-string character when using fifo
- if (tms_priv->eos_flags & REOS)
- return tms9914_read(board, tms_priv, buffer, length, end, bytes_read);
-
- clear_bit(DEV_CLEAR_BN, &tms_priv->state);
-
- read_and_clear_event_status(board);
- *end = 0;
- *bytes_read = 0;
- if (length == 0)
- return 0;
- // disable fifo for the moment
- outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
- /*
- * Handle corner case of board not in holdoff and one byte has slipped in already.
- * Also, board sometimes has problems (spurious 1 byte reads) when read fifo is
- * started up with board in TACS under certain data holdoff conditions.
- * Doing a 1 byte tms9914-style read avoids these problems.
- */
- if (/*tms_priv->holdoff_active == 0 && */length > 1) {
- size_t num_bytes;
-
- retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- dev_err(board->gpib_dev, "tms9914_read failed retval=%i\n", retval);
- if (retval < 0 || *end)
- return retval;
- ++buffer;
- --length;
- }
- tms9914_set_holdoff_mode(tms_priv, TMS9914_HOLDOFF_EOI);
- tms9914_release_holdoff(tms_priv);
- outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG);
- i = 0;
- num_fifo_bytes = length - 1;
- while (i < num_fifo_bytes && *end == 0) {
- int block_size;
- int j;
- int count;
-
- block_size = min(num_fifo_bytes - i, hp_82341_fifo_size);
- set_transfer_counter(hp_priv, block_size);
- outb(ENABLE_TI_BUFFER_BIT | DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] +
- BUFFER_CONTROL_REG);
- if (inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT)
- outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG);
-
- clear_bit(READ_READY_BN, &tms_priv->state);
-
- retval = wait_event_interruptible(board->wait,
- ((event_status =
- read_and_clear_event_status(board)) &
- (TERMINAL_COUNT_EVENT_BIT |
- BUFFER_END_EVENT_BIT)) ||
- test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- if (retval) {
- retval = -ERESTARTSYS;
- break;
- }
- // have to disable buffer before we can read from buffer port
- outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
- count = block_size - read_transfer_counter(hp_priv);
- j = 0;
- while (j < count && i < num_fifo_bytes) {
- unsigned short data_word = inw(hp_priv->iobase[3] + BUFFER_PORT_LOW_REG);
-
- buffer[i++] = data_word & 0xff;
- ++j;
- if (j < count && i < num_fifo_bytes) {
- buffer[i++] = (data_word >> 8) & 0xff;
- ++j;
- }
- }
- if (event_status & BUFFER_END_EVENT_BIT) {
- clear_bit(RECEIVED_END_BN, &tms_priv->state);
-
- *end = 1;
- tms_priv->holdoff_active = 1;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- retval = -EINTR;
- break;
- }
- }
- *bytes_read += i;
- buffer += i;
- length -= i;
- if (retval < 0)
- return retval;
- // read last byte if we havn't received an END yet
- if (*end == 0) {
- size_t num_bytes;
- // try to make sure we holdoff after last byte read
- retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static int restart_write_fifo(struct gpib_board *board, struct hp_82341_priv *hp_priv)
-{
- struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
-
- if ((inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT) == 0)
- return 0;
- while (1) {
- int status;
-
- // restart doesn't work if data holdoff is in effect
- status = tms9914_line_status(board, tms_priv);
- if ((status & BUS_NRFD) == 0) {
- outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG);
- return 0;
- }
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state))
- return -EINTR;
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (msleep_interruptible(1))
- return -EINTR;
- }
- return 0;
-}
-
-static int hp_82341_accel_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- struct hp_82341_priv *hp_priv = board->private_data;
- struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
- int i, j;
- unsigned short event_status;
- int retval = 0;
- int fifo_xfer_len = length;
-
- *bytes_written = 0;
- if (send_eoi)
- --fifo_xfer_len;
-
- clear_bit(DEV_CLEAR_BN, &tms_priv->state);
-
- read_and_clear_event_status(board);
- outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
- outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG);
- for (i = 0; i < fifo_xfer_len;) {
- int block_size;
-
- block_size = min(fifo_xfer_len - i, hp_82341_fifo_size);
- set_transfer_counter(hp_priv, block_size);
- // load data into board's fifo
- for (j = 0; j < block_size;) {
- unsigned short data_word = buffer[i++];
- ++j;
- if (j < block_size) {
- data_word |= buffer[i++] << 8;
- ++j;
- }
- outw(data_word, hp_priv->iobase[3] + BUFFER_PORT_LOW_REG);
- }
- clear_bit(WRITE_READY_BN, &tms_priv->state);
- outb(ENABLE_TI_BUFFER_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
- retval = restart_write_fifo(board, hp_priv);
- if (retval < 0) {
- dev_err(board->gpib_dev, "failed to restart write stream\n");
- break;
- }
- retval = wait_event_interruptible(board->wait,
- ((event_status =
- read_and_clear_event_status(board)) &
- TERMINAL_COUNT_EVENT_BIT) ||
- test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
- test_bit(TIMO_NUM, &board->status));
- outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
- *bytes_written += block_size - read_transfer_counter(hp_priv);
- if (retval) {
- retval = -ERESTARTSYS;
- break;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
- retval = -EINTR;
- break;
- }
- }
- if (retval)
- return retval;
- if (send_eoi) {
- size_t num_bytes;
-
- retval = hp_82341_write(board, buffer + fifo_xfer_len, 1, 1, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config);
-
-static void hp_82341_detach(struct gpib_board *board);
-
-// wrappers for interface functions
-static int hp_82341_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
-}
-
-static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int hp_82341_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
-}
-
-static int hp_82341_take_control(struct gpib_board *board, int synchronous)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
-}
-
-static int hp_82341_go_to_standby(struct gpib_board *board)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_go_to_standby(board, &priv->tms9914_priv);
-}
-
-static int hp_82341_request_system_control(struct gpib_board *board, int request_control)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- if (request_control)
- priv->mode_control_bits |= SYSTEM_CONTROLLER_BIT;
- else
- priv->mode_control_bits &= ~SYSTEM_CONTROLLER_BIT;
- outb(priv->mode_control_bits, priv->iobase[0] + MODE_CONTROL_STATUS_REG);
- return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
-}
-
-static void hp_82341_interface_clear(struct gpib_board *board, int assert)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_interface_clear(board, &priv->tms9914_priv, assert);
-}
-
-static void hp_82341_remote_enable(struct gpib_board *board, int enable)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_remote_enable(board, &priv->tms9914_priv, enable);
-}
-
-static int hp_82341_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
-}
-
-static void hp_82341_disable_eos(struct gpib_board *board)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_disable_eos(board, &priv->tms9914_priv);
-}
-
-static unsigned int hp_82341_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
-}
-
-static int hp_82341_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_primary_address(board, &priv->tms9914_priv, address);
-}
-
-static int hp_82341_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
-}
-
-static int hp_82341_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
-}
-
-static void hp_82341_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
-}
-
-static void hp_82341_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
-}
-
-static void hp_82341_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
-}
-
-static u8 hp_82341_serial_poll_status(struct gpib_board *board)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_serial_poll_status(board, &priv->tms9914_priv);
-}
-
-static int hp_82341_line_status(const struct gpib_board *board)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_line_status(board, &priv->tms9914_priv);
-}
-
-static int hp_82341_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
-}
-
-static void hp_82341_return_to_local(struct gpib_board *board)
-{
- struct hp_82341_priv *priv = board->private_data;
-
- tms9914_return_to_local(board, &priv->tms9914_priv);
-}
-
-static struct gpib_interface hp_82341_unaccel_interface = {
- .name = "hp_82341_unaccel",
- .attach = hp_82341_attach,
- .detach = hp_82341_detach,
- .read = hp_82341_read,
- .write = hp_82341_write,
- .command = hp_82341_command,
- .request_system_control = hp_82341_request_system_control,
- .take_control = hp_82341_take_control,
- .go_to_standby = hp_82341_go_to_standby,
- .interface_clear = hp_82341_interface_clear,
- .remote_enable = hp_82341_remote_enable,
- .enable_eos = hp_82341_enable_eos,
- .disable_eos = hp_82341_disable_eos,
- .parallel_poll = hp_82341_parallel_poll,
- .parallel_poll_configure = hp_82341_parallel_poll_configure,
- .parallel_poll_response = hp_82341_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = hp_82341_line_status,
- .update_status = hp_82341_update_status,
- .primary_address = hp_82341_primary_address,
- .secondary_address = hp_82341_secondary_address,
- .serial_poll_response = hp_82341_serial_poll_response,
- .serial_poll_status = hp_82341_serial_poll_status,
- .t1_delay = hp_82341_t1_delay,
- .return_to_local = hp_82341_return_to_local,
-};
-
-static struct gpib_interface hp_82341_interface = {
- .name = "hp_82341",
- .attach = hp_82341_attach,
- .detach = hp_82341_detach,
- .read = hp_82341_accel_read,
- .write = hp_82341_accel_write,
- .command = hp_82341_command,
- .request_system_control = hp_82341_request_system_control,
- .take_control = hp_82341_take_control,
- .go_to_standby = hp_82341_go_to_standby,
- .interface_clear = hp_82341_interface_clear,
- .remote_enable = hp_82341_remote_enable,
- .enable_eos = hp_82341_enable_eos,
- .disable_eos = hp_82341_disable_eos,
- .parallel_poll = hp_82341_parallel_poll,
- .parallel_poll_configure = hp_82341_parallel_poll_configure,
- .parallel_poll_response = hp_82341_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = hp_82341_line_status,
- .update_status = hp_82341_update_status,
- .primary_address = hp_82341_primary_address,
- .secondary_address = hp_82341_secondary_address,
- .serial_poll_response = hp_82341_serial_poll_response,
- .t1_delay = hp_82341_t1_delay,
- .return_to_local = hp_82341_return_to_local,
-};
-
-static int hp_82341_allocate_private(struct gpib_board *board)
-{
- board->private_data = kzalloc(sizeof(struct hp_82341_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- return 0;
-}
-
-static void hp_82341_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static u8 hp_82341_read_byte(struct tms9914_priv *priv, unsigned int register_num)
-{
- return inb(priv->iobase + register_num);
-}
-
-static void hp_82341_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
-{
- outb(data, priv->iobase + register_num);
-}
-
-static int hp_82341_find_isapnp_board(struct pnp_dev **dev)
-{
- *dev = pnp_find_dev(NULL, ISAPNP_VENDOR('H', 'W', 'P'),
- ISAPNP_FUNCTION(0x1411), NULL);
- if (!*dev || !(*dev)->card) {
- pr_err("failed to find isapnp board\n");
- return -ENODEV;
- }
- if (pnp_device_attach(*dev) < 0) {
- pr_err("board already active, skipping\n");
- return -EBUSY;
- }
- if (pnp_activate_dev(*dev) < 0) {
- pnp_device_detach(*dev);
- pr_err("failed to activate(), aborting\n");
- return -EAGAIN;
- }
- if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) {
- pnp_device_detach(*dev);
- pr_err("invalid port or irq, aborting\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-static int xilinx_ready(struct hp_82341_priv *hp_priv)
-{
- switch (hp_priv->hw_version) {
- case HW_VERSION_82341C:
- if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & XILINX_READY_BIT)
- return 1;
- else
- return 0;
- break;
- case HW_VERSION_82341D:
- if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_READY_BIT)
- return 1;
- else
- return 0;
- default:
- pr_err("bug! unknown hw_version\n");
- break;
- }
- return 0;
-}
-
-static int xilinx_done(struct hp_82341_priv *hp_priv)
-{
- switch (hp_priv->hw_version) {
- case HW_VERSION_82341C:
- if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & DONE_PGL_BIT)
- return 1;
- else
- return 0;
- case HW_VERSION_82341D:
- if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_DONE_BIT)
- return 1;
- else
- return 0;
- default:
- pr_err("bug! unknown hw_version\n");
- break;
- }
- return 0;
-}
-
-static int irq_valid(struct hp_82341_priv *hp_priv, int irq)
-{
- switch (hp_priv->hw_version) {
- case HW_VERSION_82341C:
- switch (irq) {
- case 3:
- case 5:
- case 7:
- case 9:
- case 10:
- case 11:
- case 12:
- case 15:
- return 1;
- default:
- pr_err("invalid irq=%i for 82341C, irq must be 3, 5, 7, 9, 10, 11, 12, or 15.\n",
- irq);
- return 0;
- }
- break;
- case HW_VERSION_82341D:
- return 1;
- default:
- pr_err("bug! unknown hw_version\n");
- break;
- }
- return 0;
-}
-
-static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv,
- const unsigned char *firmware_data,
- unsigned int firmware_length)
-{
- int i, j;
- static const int timeout = 100;
-
- for (i = 0; i < firmware_length; ++i) {
- for (j = 0; j < timeout; ++j) {
- if (need_resched())
- schedule();
- if (xilinx_ready(hp_priv))
- break;
- usleep_range(10, 15);
- }
- if (j == timeout) {
- pr_err("timed out waiting for Xilinx ready.\n");
- return -ETIMEDOUT;
- }
- outb(firmware_data[i], hp_priv->iobase[0] + XILINX_DATA_REG);
- }
- for (j = 0; j < timeout; ++j) {
- if (xilinx_done(hp_priv))
- break;
- if (need_resched())
- schedule();
- usleep_range(10, 15);
- }
- if (j == timeout) {
- pr_err("timed out waiting for Xilinx done.\n");
- return -ETIMEDOUT;
- }
- return 0;
-}
-
-static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv,
- const struct gpib_board_config *config)
-{
- if (config->init_data_length == 0) {
- if (xilinx_done(hp_priv))
- return 0;
- pr_err("board needs be initialized with firmware upload.\n"
- "\tUse the --init-data option of gpib_config.\n");
- return -EINVAL;
- }
- switch (hp_priv->hw_version) {
- case HW_VERSION_82341C:
- if (config->init_data_length != hp_82341c_firmware_length) {
- pr_err("bad firmware length=%i for 82341c (expected %i).\n",
- config->init_data_length, hp_82341c_firmware_length);
- return -EINVAL;
- }
- break;
- case HW_VERSION_82341D:
- if (config->init_data_length != hp_82341d_firmware_length) {
- pr_err("bad firmware length=%i for 82341d (expected %i).\n",
- config->init_data_length, hp_82341d_firmware_length);
- return -EINVAL;
- }
- break;
- default:
- pr_err("bug! unknown hw_version\n");
- break;
- }
- return hp_82341_load_firmware_array(hp_priv, config->init_data, config->init_data_length);
-}
-
-static void set_xilinx_not_prog(struct hp_82341_priv *hp_priv, int assert)
-{
- switch (hp_priv->hw_version) {
- case HW_VERSION_82341C:
- if (assert)
- hp_priv->config_control_bits |= DONE_PGL_BIT;
- else
- hp_priv->config_control_bits &= ~DONE_PGL_BIT;
- outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG);
- break;
- case HW_VERSION_82341D:
- if (assert)
- isapnp_write_byte(PIO_DATA_REG, HP_82341D_NOT_PROG_BIT);
- else
- isapnp_write_byte(PIO_DATA_REG, 0x0);
- break;
- default:
- break;
- }
-}
-
-// clear xilinx firmware
-static int clear_xilinx(struct hp_82341_priv *hp_priv)
-{
- set_xilinx_not_prog(hp_priv, 1);
- if (msleep_interruptible(1))
- return -EINTR;
- set_xilinx_not_prog(hp_priv, 0);
- if (msleep_interruptible(1))
- return -EINTR;
- set_xilinx_not_prog(hp_priv, 1);
- if (msleep_interruptible(1))
- return -EINTR;
- return 0;
-}
-
-static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct hp_82341_priv *hp_priv;
- struct tms9914_priv *tms_priv;
- u32 start_addr;
- u32 iobase;
- int irq;
- int i;
- int retval;
-
- board->status = 0;
- if (hp_82341_allocate_private(board))
- return -ENOMEM;
- hp_priv = board->private_data;
- tms_priv = &hp_priv->tms9914_priv;
- tms_priv->read_byte = hp_82341_read_byte;
- tms_priv->write_byte = hp_82341_write_byte;
- tms_priv->offset = 1;
-
- if (config->ibbase == 0) {
- struct pnp_dev *dev;
- int retval = hp_82341_find_isapnp_board(&dev);
-
- if (retval < 0)
- return retval;
- hp_priv->pnp_dev = dev;
- iobase = pnp_port_start(dev, 0);
- irq = pnp_irq(dev, 0);
- hp_priv->hw_version = HW_VERSION_82341D;
- hp_priv->io_region_offset = 0x8;
- } else {
- iobase = config->ibbase;
- irq = config->ibirq;
- hp_priv->hw_version = HW_VERSION_82341C;
- hp_priv->io_region_offset = 0x400;
- }
- for (i = 0; i < hp_82341_num_io_regions; ++i) {
- start_addr = iobase + i * hp_priv->io_region_offset;
- if (!request_region(start_addr, hp_82341_region_iosize, DRV_NAME)) {
- dev_err(board->gpib_dev, "failed to allocate io ports 0x%x-0x%x\n",
- start_addr,
- start_addr + hp_82341_region_iosize - 1);
- return -EIO;
- }
- hp_priv->iobase[i] = start_addr;
- }
- tms_priv->iobase = hp_priv->iobase[2];
- if (hp_priv->hw_version == HW_VERSION_82341D) {
- retval = isapnp_cfg_begin(hp_priv->pnp_dev->card->number,
- hp_priv->pnp_dev->number);
- if (retval < 0) {
- dev_err(board->gpib_dev, "isapnp_cfg_begin returned error\n");
- return retval;
- }
- isapnp_write_byte(PIO_DIRECTION_REG, HP_82341D_XILINX_READY_BIT |
- HP_82341D_XILINX_DONE_BIT);
- }
- retval = clear_xilinx(hp_priv);
- if (retval < 0)
- return retval;
- retval = hp_82341_load_firmware(hp_priv, config);
- if (hp_priv->hw_version == HW_VERSION_82341D)
- isapnp_cfg_end();
- if (retval < 0)
- return retval;
- if (irq_valid(hp_priv, irq) == 0)
- return -EINVAL;
- if (request_irq(irq, hp_82341_interrupt, 0, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to allocate IRQ %d\n", irq);
- return -EIO;
- }
- hp_priv->irq = irq;
- hp_priv->config_control_bits &= ~IRQ_SELECT_MASK;
- hp_priv->config_control_bits |= IRQ_SELECT_BITS(irq);
- outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG);
- hp_priv->mode_control_bits |= ENABLE_IRQ_CONFIG_BIT;
- outb(hp_priv->mode_control_bits, hp_priv->iobase[0] + MODE_CONTROL_STATUS_REG);
- tms9914_board_reset(tms_priv);
- outb(ENABLE_BUFFER_END_EVENT_BIT | ENABLE_TERMINAL_COUNT_EVENT_BIT |
- ENABLE_TI_INTERRUPT_EVENT_BIT, hp_priv->iobase[0] + EVENT_ENABLE_REG);
- outb(ENABLE_BUFFER_END_INTERRUPT_BIT | ENABLE_TERMINAL_COUNT_INTERRUPT_BIT |
- ENABLE_TI_INTERRUPT_BIT, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG);
- // write clear event register
- outb((TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
- BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT),
- hp_priv->iobase[0] + EVENT_STATUS_REG);
-
- tms9914_online(board, tms_priv);
-
- return 0;
-}
-
-static void hp_82341_detach(struct gpib_board *board)
-{
- struct hp_82341_priv *hp_priv = board->private_data;
- struct tms9914_priv *tms_priv;
- int i;
-
- if (hp_priv) {
- tms_priv = &hp_priv->tms9914_priv;
- if (hp_priv->iobase[0]) {
- outb(0, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG);
- if (tms_priv->iobase)
- tms9914_board_reset(tms_priv);
- if (hp_priv->irq)
- free_irq(hp_priv->irq, board);
- }
- for (i = 0; i < hp_82341_num_io_regions; ++i) {
- if (hp_priv->iobase[i])
- release_region(hp_priv->iobase[i], hp_82341_region_iosize);
- }
- if (hp_priv->pnp_dev)
- pnp_device_detach(hp_priv->pnp_dev);
- }
- hp_82341_free_private(board);
-}
-
-#if 0
-/* unused, will be needed when the driver is turned into a pnp_driver */
-static const struct pnp_device_id hp_82341_pnp_table[] = {
- {.id = "HWP1411"},
- {.id = ""}
-};
-MODULE_DEVICE_TABLE(pnp, hp_82341_pnp_table);
-#endif
-
-static int __init hp_82341_init_module(void)
-{
- int ret;
-
- ret = gpib_register_driver(&hp_82341_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&hp_82341_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- gpib_unregister_driver(&hp_82341_unaccel_interface);
- return ret;
- }
-
- return 0;
-}
-
-static void __exit hp_82341_exit_module(void)
-{
- gpib_unregister_driver(&hp_82341_interface);
- gpib_unregister_driver(&hp_82341_unaccel_interface);
-}
-
-module_init(hp_82341_init_module);
-module_exit(hp_82341_exit_module);
-
-/*
- * GPIB interrupt service routines
- */
-static unsigned short read_and_clear_event_status(struct gpib_board *board)
-{
- struct hp_82341_priv *hp_priv = board->private_data;
- unsigned long flags;
- unsigned short status;
-
- spin_lock_irqsave(&board->spinlock, flags);
- status = hp_priv->event_status_bits;
- hp_priv->event_status_bits = 0;
- spin_unlock_irqrestore(&board->spinlock, flags);
- return status;
-}
-
-static irqreturn_t hp_82341_interrupt(int irq, void *arg)
-{
- int status1, status2;
- struct gpib_board *board = arg;
- struct hp_82341_priv *hp_priv = board->private_data;
- struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
- unsigned long flags;
- irqreturn_t retval = IRQ_NONE;
- int event_status;
-
- spin_lock_irqsave(&board->spinlock, flags);
- event_status = inb(hp_priv->iobase[0] + EVENT_STATUS_REG);
- if (event_status & INTERRUPT_PENDING_EVENT_BIT)
- retval = IRQ_HANDLED;
- // write-clear status bits
- if (event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
- BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT)) {
- outb(event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
- BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT),
- hp_priv->iobase[0] + EVENT_STATUS_REG);
- hp_priv->event_status_bits |= event_status;
- }
- if (event_status & TI_INTERRUPT_EVENT_BIT) {
- status1 = read_byte(tms_priv, ISR0);
- status2 = read_byte(tms_priv, ISR1);
- tms9914_interrupt_have_status(board, tms_priv, status1, status2);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-static int read_transfer_counter(struct hp_82341_priv *hp_priv)
-{
- int lo, mid, value;
-
- lo = inb(hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG);
- mid = inb(hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG);
- value = (lo & 0xff) | ((mid << 8) & 0x7f00);
- value = ~(value - 1) & 0x7fff;
- return value;
-}
-
-static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count)
-{
- int complement = -count;
-
- outb(complement & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG);
- outb((complement >> 8) & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG);
- // I don't think the hi count reg is even used, but oh well
- outb((complement >> 16) & 0xf, hp_priv->iobase[1] + TRANSFER_COUNT_HIGH_REG);
-}
-
diff --git a/drivers/staging/gpib/hp_82341/hp_82341.h b/drivers/staging/gpib/hp_82341/hp_82341.h
deleted file mode 100644
index 859ef2899acb..000000000000
--- a/drivers/staging/gpib/hp_82341/hp_82341.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002, 2005 by Frank Mori Hess *
- ***************************************************************************/
-
-#include "tms9914.h"
-#include "gpibP.h"
-
-enum hp_82341_hardware_version {
- HW_VERSION_UNKNOWN,
- HW_VERSION_82341C,
- HW_VERSION_82341D,
-};
-
-// struct which defines private_data for board
-struct hp_82341_priv {
- struct tms9914_priv tms9914_priv;
- unsigned int irq;
- unsigned short config_control_bits;
- unsigned short mode_control_bits;
- unsigned short event_status_bits;
- struct pnp_dev *pnp_dev;
- unsigned long iobase[4];
- unsigned long io_region_offset;
- enum hp_82341_hardware_version hw_version;
-};
-
-static const int hp_82341_region_iosize = 0x8;
-static const int hp_82341_num_io_regions = 4;
-static const int hp_82341_fifo_size = 0xffe;
-static const int hp_82341c_firmware_length = 5764;
-static const int hp_82341d_firmware_length = 5302;
-
-// hp 82341 register offsets
-enum hp_82341_region_0_registers {
- CONFIG_CONTROL_STATUS_REG = 0x0,
- MODE_CONTROL_STATUS_REG = 0x1,
- MONITOR_REG = 0x2, // after initialization
- XILINX_DATA_REG = 0x2, // before initialization, write only
- INTERRUPT_ENABLE_REG = 0x3,
- EVENT_STATUS_REG = 0x4,
- EVENT_ENABLE_REG = 0x5,
- STREAM_STATUS_REG = 0x7,
-};
-
-enum hp_82341_region_1_registers {
- ID0_REG = 0x2,
- ID1_REG = 0x3,
- TRANSFER_COUNT_LOW_REG = 0x4,
- TRANSFER_COUNT_MID_REG = 0x5,
- TRANSFER_COUNT_HIGH_REG = 0x6,
-};
-
-enum hp_82341_region_3_registers {
- BUFFER_PORT_LOW_REG = 0x0,
- BUFFER_PORT_HIGH_REG = 0x1,
- ID2_REG = 0x2,
- ID3_REG = 0x3,
- BUFFER_FLUSH_REG = 0x4,
- BUFFER_CONTROL_REG = 0x7
-};
-
-enum config_control_status_bits {
- IRQ_SELECT_MASK = 0x7,
- DMA_CONFIG_MASK = 0x18,
- ENABLE_DMA_CONFIG_BIT = 0x20,
- XILINX_READY_BIT = 0x40, // read only
- DONE_PGL_BIT = 0x80
-};
-
-static inline unsigned int IRQ_SELECT_BITS(int irq)
-{
- switch (irq) {
- case 3:
- return 0x3;
- case 5:
- return 0x2;
- case 7:
- return 0x1;
- case 9:
- return 0x0;
- case 10:
- return 0x7;
- case 11:
- return 0x6;
- case 12:
- return 0x5;
- case 15:
- return 0x4;
- default:
- return 0x0;
- }
-};
-
-enum mode_control_status_bits {
- SLOT8_BIT = 0x1, // read only
- ACTIVE_CONTROLLER_BIT = 0x2, // read only
- ENABLE_DMA_BIT = 0x4,
- SYSTEM_CONTROLLER_BIT = 0x8,
- MONITOR_BIT = 0x10,
- ENABLE_IRQ_CONFIG_BIT = 0x20,
- ENABLE_TI_STREAM_BIT = 0x40
-};
-
-enum monitor_bits {
- MONITOR_INTERRUPT_PENDING_BIT = 0x1, // read only
- MONITOR_CLEAR_HOLDOFF_BIT = 0x2, // write only
- MONITOR_PPOLL_BIT = 0x4, // write clear
- MONITOR_SRQ_BIT = 0x8, // write clear
- MONITOR_IFC_BIT = 0x10, // write clear
- MONITOR_REN_BIT = 0x20, // write clear
- MONITOR_END_BIT = 0x40, // write clear
- MONITOR_DAV_BIT = 0x80 // write clear
-};
-
-enum interrupt_enable_bits {
- ENABLE_TI_INTERRUPT_BIT = 0x1,
- ENABLE_POINTERS_EQUAL_INTERRUPT_BIT = 0x4,
- ENABLE_BUFFER_END_INTERRUPT_BIT = 0x10,
- ENABLE_TERMINAL_COUNT_INTERRUPT_BIT = 0x20,
- ENABLE_DMA_TERMINAL_COUNT_INTERRUPT_BIT = 0x80,
-};
-
-enum event_status_bits {
- TI_INTERRUPT_EVENT_BIT = 0x1, // write clear
- INTERRUPT_PENDING_EVENT_BIT = 0x2, // read only
- POINTERS_EQUAL_EVENT_BIT = 0x4, // write clear
- BUFFER_END_EVENT_BIT = 0x10, // write clear
- TERMINAL_COUNT_EVENT_BIT = 0x20, // write clear
- DMA_TERMINAL_COUNT_EVENT_BIT = 0x80, // write clear
-};
-
-enum event_enable_bits {
- ENABLE_TI_INTERRUPT_EVENT_BIT = 0x1, // write clear
- ENABLE_POINTERS_EQUAL_EVENT_BIT = 0x4, // write clear
- ENABLE_BUFFER_END_EVENT_BIT = 0x10, // write clear
- ENABLE_TERMINAL_COUNT_EVENT_BIT = 0x20, // write clear
- ENABLE_DMA_TERMINAL_COUNT_EVENT_BIT = 0x80, // write clear
-};
-
-enum stream_status_bits {
- HALTED_STATUS_BIT = 0x1, // read
- RESTART_STREAM_BIT = 0x1 // write
-};
-
-enum buffer_control_bits {
- DIRECTION_GPIB_TO_HOST_BIT = 0x20, // transfer direction (set for gpib to host)
- ENABLE_TI_BUFFER_BIT = 0x40, // enable fifo
- FAST_WR_EN_BIT = 0x80, // 350 ns t1 delay?
-};
-
-// registers accessible through isapnp chip on 82341d
-enum hp_82341d_pnp_registers {
- PIO_DATA_REG = 0x20, // read/write pio data lines
- PIO_DIRECTION_REG = 0x21, // set pio data line directions (set for input)
-};
-
-enum hp_82341d_pnp_pio_bits {
- HP_82341D_XILINX_READY_BIT = 0x1,
- HP_82341D_XILINX_DONE_BIT = 0x2,
- // use register layout compatible with C and older versions instead of 32 contiguous ioports
- HP_82341D_LEGACY_MODE_BIT = 0x4,
- HP_82341D_NOT_PROG_BIT = 0x8, // clear to reinitialize xilinx
-};
diff --git a/drivers/staging/gpib/include/amcc5920.h b/drivers/staging/gpib/include/amcc5920.h
deleted file mode 100644
index 7a88bd282feb..000000000000
--- a/drivers/staging/gpib/include/amcc5920.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Header for amcc5920 pci chip
- *
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-// plx pci chip registers and bits
-enum amcc_registers {
- AMCC_INTCS_REG = 0x38,
- AMCC_PASS_THRU_REG = 0x60,
-};
-
-enum amcc_incsr_bits {
- AMCC_ADDON_INTR_ENABLE_BIT = 0x2000,
- AMCC_ADDON_INTR_ACTIVE_BIT = 0x400000,
- AMCC_INTR_ACTIVE_BIT = 0x800000,
-};
-
-static const int bits_per_region = 8;
-
-static inline uint32_t amcc_wait_state_bits(unsigned int region, unsigned int num_wait_states)
-{
- return (num_wait_states & 0x7) << (--region * bits_per_region);
-};
-
-enum amcc_prefetch_bits {
- PREFETCH_DISABLED = 0x0,
- PREFETCH_SMALL = 0x8,
- PREFETCH_MEDIUM = 0x10,
- PREFETCH_LARGE = 0x18,
-};
-
-static inline uint32_t amcc_prefetch_bits(unsigned int region, enum amcc_prefetch_bits prefetch)
-{
- return prefetch << (--region * bits_per_region);
-};
-
-static inline uint32_t amcc_PTADR_mode_bit(unsigned int region)
-{
- return 0x80 << (--region * bits_per_region);
-};
-
-static inline uint32_t amcc_disable_write_fifo_bit(unsigned int region)
-{
- return 0x20 << (--region * bits_per_region);
-};
-
diff --git a/drivers/staging/gpib/include/amccs5933.h b/drivers/staging/gpib/include/amccs5933.h
deleted file mode 100644
index d7f63c795096..000000000000
--- a/drivers/staging/gpib/include/amccs5933.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Registers and bits for amccs5933 pci chip
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-// register offsets
-enum {
- MBEF_REG = 0x34, // mailbux empty/full
- INTCSR_REG = 0x38, // interrupt control and status
- BMCSR_REG = 0x3c, // bus master control and status
-};
-
-// incoming mailbox 0-3 register offsets
-extern inline int INCOMING_MAILBOX_REG(unsigned int mailbox)
-{
- return (0x10 + 4 * mailbox);
-};
-
-// bit definitions
-
-// INTCSR bits
-enum {
- OUTBOX_EMPTY_INTR_BIT = 0x10, // enable outbox empty interrupt
- INBOX_FULL_INTR_BIT = 0x1000, // enable inbox full interrupt
- INBOX_INTR_CS_BIT = 0x20000, // read, or write clear inbox full interrupt
- INTR_ASSERTED_BIT = 0x800000, // read only, interrupt asserted
-};
-
-// select byte 0 to 3 of incoming mailbox
-extern inline int INBOX_BYTE_BITS(unsigned int byte)
-{
- return (byte & 0x3) << 8;
-};
-
-// select incoming mailbox 0 to 3
-extern inline int INBOX_SELECT_BITS(unsigned int mailbox)
-{
- return (mailbox & 0x3) << 10;
-};
-
-// select byte 0 to 3 of outgoing mailbox
-extern inline int OUTBOX_BYTE_BITS(unsigned int byte)
-{
- return (byte & 0x3);
-};
-
-// select outgoing mailbox 0 to 3
-extern inline int OUTBOX_SELECT_BITS(unsigned int mailbox)
-{
- return (mailbox & 0x3) << 2;
-};
-
-// BMCSR bits
-enum {
- MBOX_FLAGS_RESET_BIT = 0x08000000, // resets mailbox empty/full flags
-};
-
diff --git a/drivers/staging/gpib/include/gpibP.h b/drivers/staging/gpib/include/gpibP.h
deleted file mode 100644
index 1b27f37e0ba0..000000000000
--- a/drivers/staging/gpib/include/gpibP.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002,2003 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_P_H
-#define _GPIB_P_H
-
-#include <linux/types.h>
-
-#include "gpib_types.h"
-#include "gpib_proto.h"
-#include "gpib_cmd.h"
-#include "gpib.h"
-#include "gpib_ioctl.h"
-
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-int gpib_register_driver(struct gpib_interface *interface, struct module *mod);
-void gpib_unregister_driver(struct gpib_interface *interface);
-struct pci_dev *gpib_pci_get_device(const struct gpib_board_config *config, unsigned int vendor_id,
- unsigned int device_id, struct pci_dev *from);
-struct pci_dev *gpib_pci_get_subsys(const struct gpib_board_config *config, unsigned int vendor_id,
- unsigned int device_id, unsigned int ss_vendor,
- unsigned int ss_device, struct pci_dev *from);
-unsigned int num_gpib_events(const struct gpib_event_queue *queue);
-int push_gpib_event(struct gpib_board *board, short event_type);
-int pop_gpib_event(struct gpib_board *board, struct gpib_event_queue *queue, short *event_type);
-int gpib_request_pseudo_irq(struct gpib_board *board, irqreturn_t (*handler)(int, void *));
-void gpib_free_pseudo_irq(struct gpib_board *board);
-int gpib_match_device_path(struct device *dev, const char *device_path_in);
-
-extern struct gpib_board board_array[GPIB_MAX_NUM_BOARDS];
-
-extern struct list_head registered_drivers;
-
-#endif // _GPIB_P_H
-
diff --git a/drivers/staging/gpib/include/gpib_cmd.h b/drivers/staging/gpib/include/gpib_cmd.h
deleted file mode 100644
index 9e96a3bfa22d..000000000000
--- a/drivers/staging/gpib/include/gpib_cmd.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _GPIB_CMD_H
-#define _GPIB_CMD_H
-
-#include <linux/types.h>
-
-/* Command byte definitions tests and functions */
-
-/* mask of bits that actually matter in a command byte */
-enum {
- gpib_command_mask = 0x7f,
-};
-
-/* Possible GPIB command messages */
-
-enum cmd_byte {
- GTL = 0x1, /* go to local */
- SDC = 0x4, /* selected device clear */
- PP_CONFIG = 0x5,
- GET = 0x8, /* group execute trigger */
- TCT = 0x9, /* take control */
- LLO = 0x11, /* local lockout */
- DCL = 0x14, /* device clear */
- PPU = 0x15, /* parallel poll unconfigure */
- SPE = 0x18, /* serial poll enable */
- SPD = 0x19, /* serial poll disable */
- CFE = 0x1f, /* configure enable */
- LAD = 0x20, /* value to be 'ored' in to obtain listen address */
- UNL = 0x3F, /* unlisten */
- TAD = 0x40, /* value to be 'ored' in to obtain talk address */
- UNT = 0x5F, /* untalk */
- SAD = 0x60, /* my secondary address (base) */
- PPE = 0x60, /* parallel poll enable (base) */
- PPD = 0x70 /* parallel poll disable */
-};
-
-/* confine address to range 0 to 30. */
-static inline unsigned int gpib_address_restrict(u32 addr)
-{
- addr &= 0x1f;
- if (addr == 0x1f)
- addr = 0;
- return addr;
-}
-
-static inline u8 MLA(u32 addr)
-{
- return gpib_address_restrict(addr) | LAD;
-}
-
-static inline u8 MTA(u32 addr)
-{
- return gpib_address_restrict(addr) | TAD;
-}
-
-static inline u8 MSA(u32 addr)
-{
- return (addr & 0x1f) | SAD;
-}
-
-static inline s32 gpib_address_equal(u32 pad1, s32 sad1, u32 pad2, s32 sad2)
-{
- if (pad1 == pad2) {
- if (sad1 == sad2)
- return 1;
- if (sad1 < 0 && sad2 < 0)
- return 1;
- }
-
- return 0;
-}
-
-static inline s32 is_PPE(u8 command)
-{
- return (command & 0x70) == 0x60;
-}
-
-static inline s32 is_PPD(u8 command)
-{
- return (command & 0x70) == 0x70;
-}
-
-static inline s32 in_addressed_command_group(u8 command)
-{
- return (command & 0x70) == 0x0;
-}
-
-static inline s32 in_universal_command_group(u8 command)
-{
- return (command & 0x70) == 0x10;
-}
-
-static inline s32 in_listen_address_group(u8 command)
-{
- return (command & 0x60) == 0x20;
-}
-
-static inline s32 in_talk_address_group(u8 command)
-{
- return (command & 0x60) == 0x40;
-}
-
-static inline s32 in_primary_command_group(u8 command)
-{
- return in_addressed_command_group(command) ||
- in_universal_command_group(command) ||
- in_listen_address_group(command) ||
- in_talk_address_group(command);
-}
-
-#endif /* _GPIB_CMD_H */
diff --git a/drivers/staging/gpib/include/gpib_pci_ids.h b/drivers/staging/gpib/include/gpib_pci_ids.h
deleted file mode 100644
index 52dcab07a7d1..000000000000
--- a/drivers/staging/gpib/include/gpib_pci_ids.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef __GPIB_PCI_IDS_H
-#define __GPIB_PCI_IDS_H
-
-#ifndef PCI_VENDOR_ID_AMCC
-#define PCI_VENDOR_ID_AMCC 0x10e8
-#endif
-
-#ifndef PCI_VENDOR_ID_CBOARDS
-#define PCI_VENDOR_ID_CBOARDS 0x1307
-#endif
-
-#ifndef PCI_VENDOR_ID_QUANCOM
-#define PCI_VENDOR_ID_QUANCOM 0x8008
-#endif
-
-#ifndef PCI_DEVICE_ID_QUANCOM_GPIB
-#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302
-#endif
-
-#endif // __GPIB_PCI_IDS_H
-
diff --git a/drivers/staging/gpib/include/gpib_proto.h b/drivers/staging/gpib/include/gpib_proto.h
deleted file mode 100644
index 42e736e3b7cd..000000000000
--- a/drivers/staging/gpib/include/gpib_proto.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef GPIB_PROTO_INCLUDED
-#define GPIB_PROTO_INCLUDED
-
-#include <linux/fs.h>
-
-int ibopen(struct inode *inode, struct file *filep);
-int ibclose(struct inode *inode, struct file *file);
-long ibioctl(struct file *filep, unsigned int cmd, unsigned long arg);
-void os_start_timer(struct gpib_board *board, unsigned int usec_timeout);
-void os_remove_timer(struct gpib_board *board);
-void init_gpib_board(struct gpib_board *board);
-static inline unsigned long usec_to_jiffies(unsigned int usec)
-{
- unsigned long usec_per_jiffy = 1000000 / HZ;
-
- return 1 + (usec + usec_per_jiffy - 1) / usec_per_jiffy;
-};
-
-int serial_poll_all(struct gpib_board *board, unsigned int usec_timeout);
-void init_gpib_descriptor(struct gpib_descriptor *desc);
-int dvrsp(struct gpib_board *board, unsigned int pad, int sad,
- unsigned int usec_timeout, u8 *result);
-int ibcac(struct gpib_board *board, int sync, int fallback_to_async);
-int ibcmd(struct gpib_board *board, u8 *buf, size_t length, size_t *bytes_written);
-int ibgts(struct gpib_board *board);
-int ibonline(struct gpib_board *board);
-int iboffline(struct gpib_board *board);
-int iblines(const struct gpib_board *board, short *lines);
-int ibrd(struct gpib_board *board, u8 *buf, size_t length, int *end_flag, size_t *bytes_read);
-int ibrpp(struct gpib_board *board, u8 *buf);
-int ibrsv2(struct gpib_board *board, u8 status_byte, int new_reason_for_service);
-int ibrsc(struct gpib_board *board, int request_control);
-int ibsic(struct gpib_board *board, unsigned int usec_duration);
-int ibsre(struct gpib_board *board, int enable);
-int ibpad(struct gpib_board *board, unsigned int addr);
-int ibsad(struct gpib_board *board, int addr);
-int ibeos(struct gpib_board *board, int eos, int eosflags);
-int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask,
- int *status, unsigned long usec_timeout, struct gpib_descriptor *desc);
-int ibwrt(struct gpib_board *board, u8 *buf, size_t cnt, int send_eoi, size_t *bytes_written);
-int ibstatus(struct gpib_board *board);
-int general_ibstatus(struct gpib_board *board, const struct gpib_status_queue *device,
- int clear_mask, int set_mask, struct gpib_descriptor *desc);
-int io_timed_out(struct gpib_board *board);
-int ibppc(struct gpib_board *board, u8 configuration);
-
-#endif /* GPIB_PROTO_INCLUDED */
diff --git a/drivers/staging/gpib/include/gpib_state_machines.h b/drivers/staging/gpib/include/gpib_state_machines.h
deleted file mode 100644
index 7488c00f191e..000000000000
--- a/drivers/staging/gpib/include/gpib_state_machines.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2006 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_STATE_MACHINES_H
-#define _GPIB_STATE_MACHINES_H
-
-enum talker_function_state {
- talker_idle,
- talker_addressed,
- talker_active,
- serial_poll_active
-};
-
-enum listener_function_state {
- listener_idle,
- listener_addressed,
- listener_active
-};
-
-#endif // _GPIB_STATE_MACHINES_H
diff --git a/drivers/staging/gpib/include/gpib_types.h b/drivers/staging/gpib/include/gpib_types.h
deleted file mode 100644
index 998abb379749..000000000000
--- a/drivers/staging/gpib/include/gpib_types.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_TYPES_H
-#define _GPIB_TYPES_H
-
-#ifdef __KERNEL__
-#include "gpib.h"
-#include <linux/atomic.h>
-#include <linux/device.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-
-struct gpib_board;
-
-/* config parameters that are only used by driver attach functions */
-struct gpib_board_config {
- /* firmware blob */
- void *init_data;
- int init_data_length;
- /* IO base address to use for non-pnp cards (set by core, driver should make local copy) */
- u32 ibbase;
- void __iomem *mmibbase;
- /* IRQ to use for non-pnp cards (set by core, driver should make local copy) */
- unsigned int ibirq;
- /* dma channel to use for non-pnp cards (set by core, driver should make local copy) */
- unsigned int ibdma;
- /*
- * pci bus of card, useful for distinguishing multiple identical pci cards
- * (negative means don't care)
- */
- int pci_bus;
- /*
- * pci slot of card, useful for distinguishing multiple identical pci cards
- * (negative means don't care)
- */
- int pci_slot;
- /* sysfs device path of hardware to attach */
- char *device_path;
- /* serial number of hardware to attach */
- char *serial_number;
-};
-
-/*
- * struct gpib_interface defines the interface
- * between the board-specific details dealt with in the drivers
- * and generic interface provided by gpib-common.
- * This really should be in a different header file.
- */
-struct gpib_interface {
- /* name of board */
- char *name;
- /* attach() initializes board and allocates resources */
- int (*attach)(struct gpib_board *board, const struct gpib_board_config *config);
- /* detach() shuts down board and frees resources */
- void (*detach)(struct gpib_board *board);
- /*
- * read() should read at most 'length' bytes from the bus into
- * 'buffer'. It should return when it fills the buffer or
- * encounters an END (EOI and or EOS if appropriate). It should set 'end'
- * to be nonzero if the read was terminated by an END, otherwise 'end'
- * should be zero.
- * Ultimately, this will be changed into or replaced by an asynchronous
- * read. Zero return value for success, negative
- * return indicates error.
- * nbytes returns number of bytes read
- */
- int (*read)(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read);
- /*
- * write() should write 'length' bytes from buffer to the bus.
- * If the boolean value send_eoi is nonzero, then EOI should
- * be sent along with the last byte. Returns number of bytes
- * written or negative value on error.
- */
- int (*write)(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written);
- /*
- * command() writes the command bytes in 'buffer' to the bus
- * Returns zero on success or negative value on error.
- */
- int (*command)(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written);
- /*
- * Take control (assert ATN). If 'asyncronous' is nonzero, take
- * control asyncronously (assert ATN immediately without waiting
- * for other processes to complete first). Should not return
- * until board becomes controller in charge. Returns zero no success,
- * nonzero on error.
- */
- int (*take_control)(struct gpib_board *board, int asyncronous);
- /*
- * De-assert ATN. Returns zero on success, nonzer on error.
- */
- int (*go_to_standby)(struct gpib_board *board);
- /* request/release control of the IFC and REN lines (system controller) */
- int (*request_system_control)(struct gpib_board *board, int request_control);
- /*
- * Asserts or de-asserts 'interface clear' (IFC) depending on
- * boolean value of 'assert'
- */
- void (*interface_clear)(struct gpib_board *board, int assert);
- /*
- * Sends remote enable command if 'enable' is nonzero, disables remote mode
- * if 'enable' is zero
- */
- void (*remote_enable)(struct gpib_board *board, int enable);
- /*
- * enable END for reads, when byte 'eos' is received. If
- * 'compare_8_bits' is nonzero, then all 8 bits are compared
- * with the eos bytes. Otherwise only the 7 least significant
- * bits are compared.
- */
- int (*enable_eos)(struct gpib_board *board, u8 eos, int compare_8_bits);
- /* disable END on eos byte (END on EOI only)*/
- void (*disable_eos)(struct gpib_board *board);
- /* configure parallel poll */
- void (*parallel_poll_configure)(struct gpib_board *board, u8 configuration);
- /* conduct parallel poll */
- int (*parallel_poll)(struct gpib_board *board, u8 *result);
- /* set/clear ist (individual status bit) */
- void (*parallel_poll_response)(struct gpib_board *board, int ist);
- /* select local parallel poll configuration mode PP2 versus remote PP1 */
- void (*local_parallel_poll_mode)(struct gpib_board *board, int local);
- /*
- * Returns current status of the bus lines. Should be set to
- * NULL if your board does not have the ability to query the
- * state of the bus lines.
- */
- int (*line_status)(const struct gpib_board *board);
- /*
- * updates and returns the board's current status.
- * The meaning of the bits are specified in gpib_user.h
- * in the IBSTA section. The driver does not need to
- * worry about setting the CMPL, END, TIMO, or ERR bits.
- */
- unsigned int (*update_status)(struct gpib_board *board, unsigned int clear_mask);
- /*
- * Sets primary address 0-30 for gpib interface card.
- */
- int (*primary_address)(struct gpib_board *board, unsigned int address);
- /*
- * Sets and enables, or disables secondary address 0-30
- * for gpib interface card.
- */
- int (*secondary_address)(struct gpib_board *board, unsigned int address,
- int enable);
- /*
- * Sets the byte the board should send in response to a serial poll.
- * This function should also start or stop requests for service via
- * IEEE 488.2 reqt/reqf, based on MSS (bit 6 of the status_byte).
- * If the more flexible serial_poll_response2 is implemented by the
- * driver, then this method should be left NULL since it will not
- * be used. This method can generate spurious service requests
- * which are allowed by IEEE 488.2, but not ideal.
- *
- * This method should implement the serial poll response method described
- * by IEEE 488.2 section 11.3.3.4.3 "Allowed Coupled Control of
- * STB, reqt, and reqf".
- */
- void (*serial_poll_response)(struct gpib_board *board, u8 status_byte);
- /*
- * Sets the byte the board should send in response to a serial poll.
- * This function should also request service via IEEE 488.2 reqt/reqf
- * based on MSS (bit 6 of the status_byte) and new_reason_for_service.
- * reqt should be set true if new_reason_for_service is true,
- * and reqf should be set true if MSS is false. This function
- * will never be called with MSS false and new_reason_for_service
- * true simultaneously, so don't worry about that case.
- *
- * This method implements the serial poll response method described
- * by IEEE 488.2 section 11.3.3.4.1 "Preferred Implementation".
- *
- * If this method is left NULL by the driver, then the user library
- * function ibrsv2 will not work.
- */
- void (*serial_poll_response2)(struct gpib_board *board, u8 status_byte,
- int new_reason_for_service);
- /*
- * returns the byte the board will send in response to a serial poll.
- */
- u8 (*serial_poll_status)(struct gpib_board *board);
- /* adjust T1 delay */
- int (*t1_delay)(struct gpib_board *board, unsigned int nano_sec);
- /* go to local mode */
- void (*return_to_local)(struct gpib_board *board);
- /* board does not support 7 bit eos comparisons */
- unsigned no_7_bit_eos : 1;
- /* skip check for listeners before trying to send command bytes */
- unsigned skip_check_for_command_acceptors : 1;
-};
-
-struct gpib_event_queue {
- struct list_head event_head;
- spinlock_t lock; // for access to event list
- unsigned int num_events;
- unsigned dropped_event : 1;
-};
-
-static inline void init_event_queue(struct gpib_event_queue *queue)
-{
- INIT_LIST_HEAD(&queue->event_head);
- queue->num_events = 0;
- queue->dropped_event = 0;
- spin_lock_init(&queue->lock);
-}
-
-/* struct for supporting polling operation when irq is not available */
-struct gpib_pseudo_irq {
- struct timer_list timer;
- irqreturn_t (*handler)(int irq, void *arg);
- struct gpib_board *board;
- atomic_t active;
-};
-
-static inline void init_gpib_pseudo_irq(struct gpib_pseudo_irq *pseudo_irq)
-{
- pseudo_irq->handler = NULL;
- timer_setup(&pseudo_irq->timer, NULL, 0);
- atomic_set(&pseudo_irq->active, 0);
-}
-
-/* list so we can make a linked list of drivers */
-struct gpib_interface_list {
- struct list_head list;
- struct gpib_interface *interface;
- struct module *module;
-};
-
-/*
- * One struct gpib_board is allocated for each physical board in the computer.
- * It provides storage for variables local to each board, and interface
- * functions for performing operations on the board
- */
-struct gpib_board {
- /* functions used by this board */
- struct gpib_interface *interface;
- /*
- * Pointer to module whose use count we should increment when
- * interface is in use
- */
- struct module *provider_module;
- /* buffer used to store read/write data for this board */
- u8 *buffer;
- /* length of buffer */
- unsigned int buffer_length;
- /*
- * Used to hold the board's current status (see update_status() above)
- */
- unsigned long status;
- /*
- * Driver should only sleep on this wait queue. It is special in that the
- * core will wake this queue and set the TIMO bit in 'status' when the
- * watchdog timer times out.
- */
- wait_queue_head_t wait;
- /*
- * Lock that only allows one process to access this board at a time.
- * Has to be first in any locking order, since it can be locked over
- * multiple ioctls.
- */
- struct mutex user_mutex;
- /*
- * Mutex which compensates for removal of "big kernel lock" from kernel.
- * Should not be held for extended waits.
- */
- struct mutex big_gpib_mutex;
- /* pid of last process to lock the board mutex */
- pid_t locking_pid;
- /* lock for setting locking pid */
- spinlock_t locking_pid_spinlock;
- /* Spin lock for dealing with races with the interrupt handler */
- spinlock_t spinlock;
- /* Watchdog timer to enable timeouts */
- struct timer_list timer;
- /* device of attached driver if any */
- struct device *dev;
- /* gpib_common device gpibN */
- struct device *gpib_dev;
- /*
- * 'private_data' can be used as seen fit by the driver to
- * store additional variables for this board
- */
- void *private_data;
- /* Number of open file descriptors using this board */
- unsigned int use_count;
- /* list of open devices connected to this board */
- struct list_head device_list;
- /* primary address */
- unsigned int pad;
- /* secondary address */
- int sad;
- /* timeout for io operations, in microseconds */
- unsigned int usec_timeout;
- /* board's parallel poll configuration byte */
- u8 parallel_poll_configuration;
- /* t1 delay we are using */
- unsigned int t1_nano_sec;
- /* Count that keeps track of whether board is up and running or not */
- unsigned int online;
- /* number of processes trying to autopoll */
- int autospollers;
- /* autospoll kernel thread */
- struct task_struct *autospoll_task;
- /* queue for recording received trigger/clear/ifc events */
- struct gpib_event_queue event_queue;
- /* minor number for this board's device file */
- int minor;
- /* struct to deal with polling mode*/
- struct gpib_pseudo_irq pseudo_irq;
- /* error dong autopoll */
- atomic_t stuck_srq;
- struct gpib_board_config config;
- /* Flag that indicates whether board is system controller of the bus */
- unsigned master : 1;
- /* individual status bit */
- unsigned ist : 1;
- /*
- * one means local parallel poll mode ieee 488.1 PP2 (or no parallel poll PP0),
- * zero means remote parallel poll configuration mode ieee 488.1 PP1
- */
- unsigned local_ppoll_mode : 1;
-};
-
-/* element of event queue */
-struct gpib_event {
- struct list_head list;
- short event_type;
-};
-
-/*
- * Each board has a list of gpib_status_queue to keep track of all open devices
- * on the bus, so we know what address to poll when we get a service request
- */
-struct gpib_status_queue {
- /* list_head so we can make a linked list of devices */
- struct list_head list;
- unsigned int pad; /* primary gpib address */
- int sad; /* secondary gpib address (negative means disabled) */
- /* stores serial poll bytes for this device */
- struct list_head status_bytes;
- unsigned int num_status_bytes;
- /* number of times this address is opened */
- unsigned int reference_count;
- /* flags loss of status byte error due to limit on size of queue */
- unsigned dropped_byte : 1;
-};
-
-struct gpib_status_byte {
- struct list_head list;
- u8 poll_byte;
-};
-
-void init_gpib_status_queue(struct gpib_status_queue *device);
-
-/* Used to store device-descriptor-specific information */
-struct gpib_descriptor {
- unsigned int pad; /* primary gpib address */
- int sad; /* secondary gpib address (negative means disabled) */
- atomic_t io_in_progress;
- unsigned is_board : 1;
- unsigned autopoll_enabled : 1;
-};
-
-struct gpib_file_private {
- atomic_t holding_mutex;
- struct gpib_descriptor *descriptors[GPIB_MAX_NUM_DESCRIPTORS];
- /* locked while descriptors are being allocated/deallocated */
- struct mutex descriptors_mutex;
- unsigned got_module : 1;
-};
-
-#endif /* __KERNEL__ */
-
-#endif /* _GPIB_TYPES_H */
diff --git a/drivers/staging/gpib/include/nec7210.h b/drivers/staging/gpib/include/nec7210.h
deleted file mode 100644
index 9835aa5ef4ff..000000000000
--- a/drivers/staging/gpib/include/nec7210.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _NEC7210_H
-#define _NEC7210_H
-
-#include "gpib_state_machines.h"
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-
-#include "gpib_types.h"
-#include "nec7210_registers.h"
-
-/* struct used to provide variables local to a nec7210 chip */
-struct nec7210_priv {
-#ifdef CONFIG_HAS_IOPORT
- u32 iobase;
-#endif
- void __iomem *mmiobase;
- unsigned int offset; // offset between successive nec7210 io addresses
- unsigned int dma_channel;
- u8 *dma_buffer;
- unsigned int dma_buffer_length; // length of dma buffer
- dma_addr_t dma_buffer_addr; // bus address of board->buffer for use with dma
- // software copy of bits written to registers
- u8 reg_bits[8];
- u8 auxa_bits; // bits written to auxiliary register A
- u8 auxb_bits; // bits written to auxiliary register B
- // used to keep track of board's state, bit definitions given below
- unsigned long state;
- // lock for chips that extend the nec7210 registers by paging in alternate regs
- spinlock_t register_page_lock;
- // wrappers for outb, inb, readb, or writeb
- u8 (*read_byte)(struct nec7210_priv *priv, unsigned int register_number);
- void (*write_byte)(struct nec7210_priv *priv, u8 byte, unsigned int register_number);
- enum nec7210_chipset type;
- enum talker_function_state talker_state;
- enum listener_function_state listener_state;
- void *private;
- unsigned srq_pending : 1;
-};
-
-static inline void init_nec7210_private(struct nec7210_priv *priv)
-{
- memset(priv, 0, sizeof(struct nec7210_priv));
- spin_lock_init(&priv->register_page_lock);
-}
-
-// slightly shorter way to access read_byte and write_byte
-static inline u8 read_byte(struct nec7210_priv *priv, unsigned int register_number)
-{
- return priv->read_byte(priv, register_number);
-}
-
-static inline void write_byte(struct nec7210_priv *priv, u8 byte, unsigned int register_number)
-{
- priv->write_byte(priv, byte, register_number);
-}
-
-// struct nec7210_priv.state bit numbers
-enum {
- PIO_IN_PROGRESS_BN, // pio transfer in progress
- DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress
- DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress
- READ_READY_BN, // board has data byte available to read
- WRITE_READY_BN, // board is ready to send a data byte
- COMMAND_READY_BN, // board is ready to send a command byte
- RECEIVED_END_BN, // received END
- BUS_ERROR_BN, // output error has occurred
- RFD_HOLDOFF_BN, // rfd holdoff in effect
- DEV_CLEAR_BN, // device clear received
- ADR_CHANGE_BN, // address state change occurred
-};
-
-// interface functions
-int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read);
-int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written);
-int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, size_t *bytes_written);
-int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous);
-int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv);
-int nec7210_request_system_control(struct gpib_board *board,
- struct nec7210_priv *priv, int request_control);
-void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert);
-void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable);
-int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, u8 eos_bytes,
- int compare_8_bits);
-void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv);
-unsigned int nec7210_update_status(struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int clear_mask);
-unsigned int nec7210_update_status_nolock(struct gpib_board *board, struct nec7210_priv *priv);
-int nec7210_primary_address(const struct gpib_board *board,
- struct nec7210_priv *priv, unsigned int address);
-int nec7210_secondary_address(const struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int address, int enable);
-int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, u8 *result);
-void nec7210_serial_poll_response(struct gpib_board *board,
- struct nec7210_priv *priv, u8 status);
-void nec7210_parallel_poll_configure(struct gpib_board *board,
- struct nec7210_priv *priv, unsigned int configuration);
-void nec7210_parallel_poll_response(struct gpib_board *board,
- struct nec7210_priv *priv, int ist);
-u8 nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv);
-int nec7210_t1_delay(struct gpib_board *board,
- struct nec7210_priv *priv, unsigned int nano_sec);
-void nec7210_return_to_local(const struct gpib_board *board, struct nec7210_priv *priv);
-
-// utility functions
-void nec7210_board_reset(struct nec7210_priv *priv, const struct gpib_board *board);
-void nec7210_board_online(struct nec7210_priv *priv, const struct gpib_board *board);
-unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg,
- unsigned int mask, unsigned int bits);
-void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *priv, int mode);
-void nec7210_release_rfd_holdoff(struct gpib_board *board, struct nec7210_priv *priv);
-u8 nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end);
-
-// wrappers for io functions
-u8 nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num);
-void nec7210_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num);
-u8 nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num);
-void nec7210_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num);
-u8 nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num);
-void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, u8 data,
- unsigned int register_num);
-u8 nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num);
-void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, u8 data,
- unsigned int register_num);
-
-// interrupt service routine
-irqreturn_t nec7210_interrupt(struct gpib_board *board, struct nec7210_priv *priv);
-irqreturn_t nec7210_interrupt_have_status(struct gpib_board *board,
- struct nec7210_priv *priv, int status1, int status2);
-
-#endif //_NEC7210_H
diff --git a/drivers/staging/gpib/include/nec7210_registers.h b/drivers/staging/gpib/include/nec7210_registers.h
deleted file mode 100644
index 067983d7a07f..000000000000
--- a/drivers/staging/gpib/include/nec7210_registers.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _NEC7210_REGISTERS_H
-#define _NEC7210_REGISTERS_H
-
-enum nec7210_chipset {
- NEC7210, // The original
- TNT4882, // NI
- NAT4882, // NI
- CB7210, // measurement computing
- IOT7210, // iotech
- IGPIB7210, // Ines
- TNT5004, // NI (minor differences to TNT4882)
-};
-
-/*
- * nec7210 register numbers (might need to be multiplied by
- * a board-dependent offset to get actually io address offset)
- */
-// write registers
-enum nec7210_write_regs {
- CDOR, // command/data out
- IMR1, // interrupt mask 1
- IMR2, // interrupt mask 2
- SPMR, // serial poll mode
- ADMR, // address mode
- AUXMR, // auxiliary mode
- ADR, // address
- EOSR, // end-of-string
-
- // nec7210 has 8 registers
- nec7210_num_registers = 8,
-};
-
-// read registers
-enum nec7210_read_regs {
- DIR, // data in
- ISR1, // interrupt status 1
- ISR2, // interrupt status 2
- SPSR, // serial poll status
- ADSR, // address status
- CPTR, // command pass though
- ADR0, // address 1
- ADR1, // address 2
-};
-
-// bit definitions common to nec-7210 compatible registers
-
-// ISR1: interrupt status register 1
-enum isr1_bits {
- HR_DI = (1 << 0),
- HR_DO = (1 << 1),
- HR_ERR = (1 << 2),
- HR_DEC = (1 << 3),
- HR_END = (1 << 4),
- HR_DET = (1 << 5),
- HR_APT = (1 << 6),
- HR_CPT = (1 << 7),
-};
-
-// IMR1: interrupt mask register 1
-enum imr1_bits {
- HR_DIIE = (1 << 0),
- HR_DOIE = (1 << 1),
- HR_ERRIE = (1 << 2),
- HR_DECIE = (1 << 3),
- HR_ENDIE = (1 << 4),
- HR_DETIE = (1 << 5),
- HR_APTIE = (1 << 6),
- HR_CPTIE = (1 << 7),
-};
-
-// ISR2, interrupt status register 2
-enum isr2_bits {
- HR_ADSC = (1 << 0),
- HR_REMC = (1 << 1),
- HR_LOKC = (1 << 2),
- HR_CO = (1 << 3),
- HR_REM = (1 << 4),
- HR_LOK = (1 << 5),
- HR_SRQI = (1 << 6),
- HR_INT = (1 << 7),
-};
-
-// IMR2, interrupt mask register 2
-enum imr2_bits {
- // all the bits in this register that enable interrupts
- IMR2_ENABLE_INTR_MASK = 0x4f,
- HR_ACIE = (1 << 0),
- HR_REMIE = (1 << 1),
- HR_LOKIE = (1 << 2),
- HR_COIE = (1 << 3),
- HR_DMAI = (1 << 4),
- HR_DMAO = (1 << 5),
- HR_SRQIE = (1 << 6),
-};
-
-// SPSR, serial poll status register
-enum spsr_bits {
- HR_PEND = (1 << 6),
-};
-
-// SPMR, serial poll mode register
-enum spmr_bits {
- HR_RSV = (1 << 6),
-};
-
-// ADSR, address status register
-enum adsr_bits {
- HR_MJMN = (1 << 0),
- HR_TA = (1 << 1),
- HR_LA = (1 << 2),
- HR_TPAS = (1 << 3),
- HR_LPAS = (1 << 4),
- HR_SPMS = (1 << 5),
- HR_NATN = (1 << 6),
- HR_CIC = (1 << 7),
-};
-
-// ADMR, address mode register
-enum admr_bits {
- HR_ADM0 = (1 << 0),
- HR_ADM1 = (1 << 1),
- HR_TRM0 = (1 << 4),
- HR_TRM1 = (1 << 5),
- HR_TRM_EOIOE_TRIG = 0,
- HR_TRM_CIC_TRIG = HR_TRM0,
- HR_TRM_CIC_EOIOE = HR_TRM1,
- HR_TRM_CIC_PE = HR_TRM0 | HR_TRM1,
- HR_LON = (1 << 6),
- HR_TON = (1 << 7),
-};
-
-// ADR, bits used in address0, address1 and address0/1 registers
-enum adr_bits {
- ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits */
- HR_DL = (1 << 5),
- HR_DT = (1 << 6),
- HR_ARS = (1 << 7),
-};
-
-// ADR1, address1 register
-enum adr1_bits {
- HR_EOI = (1 << 7),
-};
-
-// AUXMR, auxiliary mode register
-enum auxmr_bits {
- ICR = 0x20,
- PPR = 0x60,
- AUXRA = 0x80,
- AUXRB = 0xa0,
- AUXRE = 0xc0,
-};
-
-// auxra, auxiliary register A
-enum auxra_bits {
- HR_HANDSHAKE_MASK = 0x3,
- HR_HLDA = 0x1,
- HR_HLDE = 0x2,
- HR_LCM = 0x3, /* auxra listen continuous */
- HR_REOS = 0x4,
- HR_XEOS = 0x8,
- HR_BIN = 0x10,
-};
-
-// auxrb, auxiliary register B
-enum auxrb_bits {
- HR_CPTE = (1 << 0),
- HR_SPEOI = (1 << 1),
- HR_TRI = (1 << 2),
- HR_INV = (1 << 3),
- HR_ISS = (1 << 4),
-};
-
-enum auxre_bits {
- HR_DAC_HLD_DCAS = 0x1, /* perform DAC holdoff on receiving clear */
- HR_DAC_HLD_DTAS = 0x2, /* perform DAC holdoff on receiving trigger */
-};
-
-// parallel poll register
-enum ppr_bits {
- HR_PPS = (1 << 3),
- HR_PPU = (1 << 4),
-};
-
-/* 7210 Auxiliary Commands */
-enum aux_cmds {
- AUX_PON = 0x0, /* Immediate Execute pon */
- AUX_CPPF = 0x1, /* Clear Parallel Poll Flag */
- AUX_CR = 0x2, /* Chip Reset */
- AUX_FH = 0x3, /* Finish Handshake */
- AUX_TRIG = 0x4, /* Trigger */
- AUX_RTL = 0x5, /* Return to local */
- AUX_SEOI = 0x6, /* Send EOI */
- AUX_NVAL = 0x7, /* Non-Valid Secondary Command or Address */
- AUX_SPPF = 0x9, /* Set Parallel Poll Flag */
- AUX_VAL = 0xf, /* Valid Secondary Command or Address */
- AUX_GTS = 0x10, /* Go To Standby */
- AUX_TCA = 0x11, /* Take Control Asynchronously */
- AUX_TCS = 0x12, /* Take Control Synchronously */
- AUX_LTN = 0x13, /* Listen */
- AUX_DSC = 0x14, /* Disable System Control */
- AUX_CIFC = 0x16, /* Clear IFC */
- AUX_CREN = 0x17, /* Clear REN */
- AUX_TCSE = 0x1a, /* Take Control Synchronously on End */
- AUX_LTNC = 0x1b, /* Listen in Continuous Mode */
- AUX_LUN = 0x1c, /* Local Unlisten */
- AUX_EPP = 0x1d, /* Execute Parallel Poll */
- AUX_SIFC = 0x1e, /* Set IFC */
- AUX_SREN = 0x1f, /* Set REN */
-};
-
-#endif //_NEC7210_REGISTERS_H
diff --git a/drivers/staging/gpib/include/plx9050.h b/drivers/staging/gpib/include/plx9050.h
deleted file mode 100644
index c911b285a0ca..000000000000
--- a/drivers/staging/gpib/include/plx9050.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Header for plx9050 pci chip
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _PLX9050_GPIB_H
-#define _PLX9050_GPIB_H
-
-// plx pci chip registers and bits
-enum {
- PLX9050_INTCSR_REG = 0x4c,
- PLX9050_CNTRL_REG = 0x50
-};
-
-enum plx9050_intcsr_bits {
- PLX9050_LINTR1_EN_BIT = 0x1,
- PLX9050_LINTR1_POLARITY_BIT = 0x2,
- PLX9050_LINTR1_STATUS_BIT = 0x4,
- PLX9050_LINTR2_EN_BIT = 0x8,
- PLX9050_LINTR2_POLARITY_BIT = 0x10,
- PLX9050_LINTR2_STATUS_BIT = 0x20,
- PLX9050_PCI_INTR_EN_BIT = 0x40,
- PLX9050_SOFT_INTR_BIT = 0x80,
- PLX9050_LINTR1_SELECT_ENABLE_BIT = 0x100, // 9052 extension
- PLX9050_LINTR2_SELECT_ENABLE_BIT = 0x200, // 9052 extension
- PLX9050_LINTR1_EDGE_CLEAR_BIT = 0x400, // 9052 extension
- PLX9050_LINTR2_EDGE_CLEAR_BIT = 0x800, // 9052 extension
-};
-
-enum plx9050_cntrl_bits {
- PLX9050_WAITO_NOT_USER0_SELECT_BIT = 0x1,
- PLX9050_USER0_OUTPUT_BIT = 0x2,
- PLX9050_USER0_DATA_BIT = 0x4,
- PLX9050_LLOCK_NOT_USER1_SELECT_BIT = 0x8,
- PLX9050_USER1_OUTPUT_BIT = 0x10,
- PLX9050_USER1_DATA_BIT = 0x20,
- PLX9050_CS2_NOT_USER2_SELECT_BIT = 0x40,
- PLX9050_USER2_OUTPUT_BIT = 0x80,
- PLX9050_USER2_DATA_BIT = 0x100,
- PLX9050_CS3_NOT_USER3_SELECT_BIT = 0x200,
- PLX9050_USER3_OUTPUT_BIT = 0x400,
- PLX9050_USER3_DATA_BIT = 0x800,
- PLX9050_PCIBAR_ENABLE_MASK = 0x3000,
- PLX9050_PCIBAR_MEMORY_AND_IO_ENABLE_BITS = 0x0,
- PLX9050_PCIBAR_MEMORY_NO_IO_ENABLE_BITS = 0x1000,
- PLX9050_PCIBAR_IO_NO_MEMORY_ENABLE_BITS = 0x2000,
- PLX9050_PCIBAR_MEMORY_AND_IO_TOO_ENABLE_BITS = 0x3000,
- PLX9050_PCI_READ_MODE_BIT = 0x4000,
- PLX9050_PCI_READ_WITH_WRITE_FLUSH_MODE_BIT = 0x8000,
- PLX9050_PCI_READ_NO_FLUSH_MODE_BIT = 0x10000,
- PLX9050_PCI_READ_NO_WRITE_MODE_BIT = 0x20000,
- PLX9050_PCI_WRITE_MODE_BIT = 0x40000,
- PLX9050_PCI_RETRY_DELAY_MASK = 0x780000,
- PLX9050_DIRECT_SLAVE_LOCK_ENABLE_BIT = 0x800000,
- PLX9050_EEPROM_CLOCK_BIT = 0x1000000,
- PLX9050_EEPROM_CHIP_SELECT_BIT = 0x2000000,
- PLX9050_WRITE_TO_EEPROM_BIT = 0x4000000,
- PLX9050_READ_EEPROM_DATA_BIT = 0x8000000,
- PLX9050_EEPROM_VALID_BIT = 0x10000000,
- PLX9050_RELOAD_CONFIG_REGISTERS_BIT = 0x20000000,
- PLX9050_PCI_SOFTWARE_RESET_BIT = 0x40000000,
- PLX9050_MASK_REVISION_BIT = 0x80000000
-};
-
-static inline unsigned int PLX9050_PCI_RETRY_DELAY_BITS(unsigned int clocks)
-{
- return ((clocks / 8) << 19) & PLX9050_PCI_RETRY_DELAY_MASK;
-}
-
-#endif // _PLX9050_GPIB_H
diff --git a/drivers/staging/gpib/include/quancom_pci.h b/drivers/staging/gpib/include/quancom_pci.h
deleted file mode 100644
index cdaf0d056be9..000000000000
--- a/drivers/staging/gpib/include/quancom_pci.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Quancom pci stuff
- * copyright (C) 2005 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _QUANCOM_PCI_H
-#define _QUANCOM_PCI_H
-
-/* quancom registers */
-enum quancom_regs {
- QUANCOM_IRQ_CONTROL_STATUS_REG = 0xfc,
-};
-
-enum quancom_irq_control_status_bits {
- QUANCOM_IRQ_ASSERTED_BIT = 0x1, /* readable */
- /* (any write to the register clears the interrupt)*/
- QUANCOM_IRQ_ENABLE_BIT = 0x4, /* writeable */
-};
-
-#endif // _QUANCOM_PCI_H
diff --git a/drivers/staging/gpib/include/tms9914.h b/drivers/staging/gpib/include/tms9914.h
deleted file mode 100644
index e66b75e0fda8..000000000000
--- a/drivers/staging/gpib/include/tms9914.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _TMS9914_H
-#define _TMS9914_H
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include "gpib_state_machines.h"
-#include "gpib_types.h"
-
-enum tms9914_holdoff_mode {
- TMS9914_HOLDOFF_NONE,
- TMS9914_HOLDOFF_EOI,
- TMS9914_HOLDOFF_ALL,
-};
-
-/* struct used to provide variables local to a tms9914 chip */
-struct tms9914_priv {
-#ifdef CONFIG_HAS_IOPORT
- u32 iobase;
-#endif
- void __iomem *mmiobase;
- unsigned int offset; // offset between successive tms9914 io addresses
- unsigned int dma_channel;
- // software copy of bits written to interrupt mask registers
- u8 imr0_bits, imr1_bits;
- // bits written to address mode register
- u8 admr_bits;
- u8 auxa_bits; // bits written to auxiliary register A
- // used to keep track of board's state, bit definitions given below
- unsigned long state;
- u8 eos; // eos character
- short eos_flags;
- u8 spoll_status;
- enum tms9914_holdoff_mode holdoff_mode;
- unsigned int ppoll_line;
- enum talker_function_state talker_state;
- enum listener_function_state listener_state;
- unsigned ppoll_sense : 1;
- unsigned ppoll_enable : 1;
- unsigned ppoll_configure_state : 1;
- unsigned primary_listen_addressed : 1;
- unsigned primary_talk_addressed : 1;
- unsigned holdoff_on_end : 1;
- unsigned holdoff_on_all : 1;
- unsigned holdoff_active : 1;
- // wrappers for outb, inb, readb, or writeb
- u8 (*read_byte)(struct tms9914_priv *priv, unsigned int register_number);
- void (*write_byte)(struct tms9914_priv *priv, u8 byte, unsigned int
- register_number);
-};
-
-// slightly shorter way to access read_byte and write_byte
-static inline u8 read_byte(struct tms9914_priv *priv, unsigned int register_number)
-{
- return priv->read_byte(priv, register_number);
-}
-
-static inline void write_byte(struct tms9914_priv *priv, u8 byte, unsigned int register_number)
-{
- priv->write_byte(priv, byte, register_number);
-}
-
-// struct tms9914_priv.state bit numbers
-enum {
- PIO_IN_PROGRESS_BN, // pio transfer in progress
- DMA_READ_IN_PROGRESS_BN, // dma read transfer in progress
- DMA_WRITE_IN_PROGRESS_BN, // dma write transfer in progress
- READ_READY_BN, // board has data byte available to read
- WRITE_READY_BN, // board is ready to send a data byte
- COMMAND_READY_BN, // board is ready to send a command byte
- RECEIVED_END_BN, // received END
- BUS_ERROR_BN, // bus error
- DEV_CLEAR_BN, // device clear received
-};
-
-// interface functions
-int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read);
-int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written);
-int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, size_t *bytes_written);
-int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int syncronous);
-/*
- * alternate version of tms9914_take_control which works around buggy tcs
- * implementation.
- */
-int tms9914_take_control_workaround(struct gpib_board *board, struct tms9914_priv *priv,
- int syncronous);
-int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv);
-int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
- int request_control);
-void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert);
-void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable);
-int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_bytes,
- int compare_8_bits);
-void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv);
-unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int clear_mask);
-int tms9914_primary_address(struct gpib_board *board,
- struct tms9914_priv *priv, unsigned int address);
-int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int address, int enable);
-int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result);
-void tms9914_parallel_poll_configure(struct gpib_board *board,
- struct tms9914_priv *priv, u8 config);
-void tms9914_parallel_poll_response(struct gpib_board *board,
- struct tms9914_priv *priv, int ist);
-void tms9914_serial_poll_response(struct gpib_board *board,
- struct tms9914_priv *priv, u8 status);
-u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv);
-int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv);
-unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int nano_sec);
-void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv);
-
-// utility functions
-void tms9914_board_reset(struct tms9914_priv *priv);
-void tms9914_online(struct gpib_board *board, struct tms9914_priv *priv);
-void tms9914_release_holdoff(struct tms9914_priv *priv);
-void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode);
-
-// wrappers for io functions
-u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num);
-void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num);
-u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num);
-void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num);
-
-// interrupt service routine
-irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv);
-irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
- int status1, int status2);
-
-// tms9914 has 8 registers
-enum {
- ms9914_num_registers = 8,
-};
-
-/*
- * tms9914 register numbers (might need to be multiplied by
- * a board-dependent offset to get actually io address offset)
- */
-// write registers
-enum {
- IMR0 = 0, /* interrupt mask 0 */
- IMR1 = 1, /* interrupt mask 1 */
- AUXCR = 3, /* auxiliary command */
- ADR = 4, /* address register */
- SPMR = 5, /* serial poll mode register */
- PPR = 6, /* parallel poll */
- CDOR = 7, /* data out register */
-};
-
-// read registers
-enum {
- ISR0 = 0, /* interrupt status 0 */
- ISR1 = 1, /* interrupt status 1 */
- ADSR = 2, /* address status */
- BSR = 3, /* bus status */
- CPTR = 6, /* command pass thru */
- DIR = 7, /* data in register */
-};
-
-// bit definitions common to tms9914 compatible registers
-
-/* ISR0 - Register bits */
-enum isr0_bits {
- HR_MAC = (1 << 0), /* My Address Change */
- HR_RLC = (1 << 1), /* Remote/Local change */
- HR_SPAS = (1 << 2), /* Serial Poll active State */
- HR_END = (1 << 3), /* END (EOI or EOS) */
- HR_BO = (1 << 4), /* Byte Out */
- HR_BI = (1 << 5), /* Byte In */
-};
-
-/* IMR0 - Register bits */
-enum imr0_bits {
- HR_MACIE = (1 << 0), /* */
- HR_RLCIE = (1 << 1), /* */
- HR_SPASIE = (1 << 2), /* */
- HR_ENDIE = (1 << 3), /* */
- HR_BOIE = (1 << 4), /* */
- HR_BIIE = (1 << 5), /* */
-};
-
-/* ISR1 - Register bits */
-enum isr1_bits {
- HR_IFC = (1 << 0), /* IFC asserted */
- HR_SRQ = (1 << 1), /* SRQ asserted */
- HR_MA = (1 << 2), /* My Address */
- HR_DCAS = (1 << 3), /* Device Clear active State */
- HR_APT = (1 << 4), /* Address pass Through */
- HR_UNC = (1 << 5), /* Unrecognized Command */
- HR_ERR = (1 << 6), /* Data Transmission Error */
- HR_GET = (1 << 7), /* Group execute Trigger */
-};
-
-/* IMR1 - Register bits */
-enum imr1_bits {
- HR_IFCIE = (1 << 0), /* */
- HR_SRQIE = (1 << 1), /* */
- HR_MAIE = (1 << 2), /* */
- HR_DCASIE = (1 << 3), /* */
- HR_APTIE = (1 << 4), /* */
- HR_UNCIE = (1 << 5), /* */
- HR_ERRIE = (1 << 6), /* */
- HR_GETIE = (1 << 7), /* */
-};
-
-/* ADSR - Register bits */
-enum adsr_bits {
- HR_ULPA = (1 << 0), /* Store last address LSB */
- HR_TA = (1 << 1), /* Talker Adressed */
- HR_LA = (1 << 2), /* Listener adressed */
- HR_TPAS = (1 << 3), /* talker primary address state */
- HR_LPAS = (1 << 4), /* listener " */
- HR_ATN = (1 << 5), /* ATN active */
- HR_LLO = (1 << 6), /* LLO active */
- HR_REM = (1 << 7), /* REM active */
-};
-
-/* ADR - Register bits */
-enum adr_bits {
- ADDRESS_MASK = 0x1f, /* mask to specify lower 5 bits for ADR */
- HR_DAT = (1 << 5), /* disable talker */
- HR_DAL = (1 << 6), /* disable listener */
- HR_EDPA = (1 << 7), /* enable dual primary addressing */
-};
-
-enum bus_status_bits {
- BSR_REN_BIT = 0x1,
- BSR_IFC_BIT = 0x2,
- BSR_SRQ_BIT = 0x4,
- BSR_EOI_BIT = 0x8,
- BSR_NRFD_BIT = 0x10,
- BSR_NDAC_BIT = 0x20,
- BSR_DAV_BIT = 0x40,
- BSR_ATN_BIT = 0x80,
-};
-
-/*---------------------------------------------------------*/
-/* TMS 9914 Auxiliary Commands */
-/*---------------------------------------------------------*/
-
-enum aux_cmd_bits {
- AUX_CS = 0x80, /* set bit instead of clearing it, used with commands marked 'd' below */
- AUX_CHIP_RESET = 0x0, /* d Chip reset */
- AUX_INVAL = 0x1, /* release dac holdoff, invalid command byte */
- AUX_VAL = (AUX_INVAL | AUX_CS), /* release dac holdoff, valid command byte */
- AUX_RHDF = 0x2, /* X Release RFD holdoff */
- AUX_HLDA = 0x3, /* d holdoff on all data */
- AUX_HLDE = 0x4, /* d holdoff on EOI only */
- AUX_NBAF = 0x5, /* X Set new byte available false */
- AUX_FGET = 0x6, /* d force GET */
- AUX_RTL = 0x7, /* d return to local */
- AUX_SEOI = 0x8, /* X send EOI with next byte */
- AUX_LON = 0x9, /* d Listen only */
- AUX_TON = 0xa, /* d Talk only */
- AUX_GTS = 0xb, /* X goto standby */
- AUX_TCA = 0xc, /* X take control asynchronously */
- AUX_TCS = 0xd, /* X take " synchronously */
- AUX_RPP = 0xe, /* d Request parallel poll */
- AUX_SIC = 0xf, /* d send interface clear */
- AUX_SRE = 0x10, /* d send remote enable */
- AUX_RQC = 0x11, /* X request control */
- AUX_RLC = 0x12, /* X release control */
- AUX_DAI = 0x13, /* d disable all interrupts */
- AUX_PTS = 0x14, /* X pass through next secondary */
- AUX_STDL = 0x15, /* d short T1 delay */
- AUX_SHDW = 0x16, /* d shadow handshake */
- AUX_VSTDL = 0x17, /* d very short T1 delay (smj9914 extension) */
- AUX_RSV2 = 0x18, /* d request service bit 2 (smj9914 extension) */
-};
-
-#endif //_TMS9914_H
diff --git a/drivers/staging/gpib/include/tnt4882_registers.h b/drivers/staging/gpib/include/tnt4882_registers.h
deleted file mode 100644
index d54c4cc61168..000000000000
--- a/drivers/staging/gpib/include/tnt4882_registers.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002, 2004 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _TNT4882_REGISTERS_H
-#define _TNT4882_REGISTERS_H
-
-// tnt4882 register offsets
-enum {
- ACCWR = 0x5,
- // offset of auxiliary command register in 9914 mode
- AUXCR = 0x6,
- INTRT = 0x7,
- // register number for auxiliary command register when swap bit is set (9914 mode)
- SWAPPED_AUXCR = 0xa,
- HSSEL = 0xd, // handshake select register
- CNT2 = 0x9,
- CNT3 = 0xb,
- CFG = 0x10,
- SASR = 0x1b,
- IMR0 = 0x1d,
- IMR3 = 0x12,
- CNT0 = 0x14,
- CNT1 = 0x16,
- KEYREG = 0x17, // key control register (7210 mode only)
- CSR = KEYREG,
- FIFOB = 0x18,
- FIFOA = 0x19,
- CCR = 0x1a, // carry cycle register
- CMDR = 0x1c, // command register
- TIMER = 0x1e, // timer register
-
- STS1 = 0x10, // T488 Status Register 1
- STS2 = 0x1c, // T488 Status Register 2
- ISR0 = IMR0,
- ISR3 = 0x1a, // T488 Interrupt Status Register 3
- BCR = 0x1f, // bus control/status register
- BSR = BCR,
-};
-
-enum {
- tnt_pagein_offset = 0x11,
-};
-
-/*============================================================*/
-
-/* TURBO-488 registers bit definitions */
-
-enum bus_control_status_bits {
- BCSR_REN_BIT = 0x1,
- BCSR_IFC_BIT = 0x2,
- BCSR_SRQ_BIT = 0x4,
- BCSR_EOI_BIT = 0x8,
- BCSR_NRFD_BIT = 0x10,
- BCSR_NDAC_BIT = 0x20,
- BCSR_DAV_BIT = 0x40,
- BCSR_ATN_BIT = 0x80,
-};
-
-/* CFG -- Configuration Register (write only) */
-enum cfg_bits {
- TNT_COMMAND = 0x80, /* bytes are command bytes instead of data bytes
- * (tnt4882 one-chip and newer only?)
- */
- TNT_TLCHE = (1 << 6), /* halt transfer on imr0, imr1, or imr2 interrupt */
- TNT_IN = (1 << 5), /* transfer is GPIB read */
- TNT_A_B = (1 << 4), /* order to use fifos 1=fifo A first(big endian),
- * 0=fifo b first(little endian)
- */
- TNT_CCEN = (1 << 3), /* enable carry cycle */
- TNT_TMOE = (1 << 2), /* enable CPU bus time limit */
- TNT_TIM_BYTN = (1 << 1), /* tmot reg is: 1=125ns clocks, 0=num bytes */
- TNT_B_16BIT = (1 << 0), /* 1=FIFO is 16-bit register, 0=8-bit */
-};
-
-/* CMDR -- Command Register */
-enum cmdr_bits {
- CLRSC = 0x2, /* clear the system controller bit */
- SETSC = 0x3, /* set the system controller bit */
- GO = 0x4, /* start fifos */
- STOP = 0x8, /* stop fifos */
- RESET_FIFO = 0x10, /* reset the FIFOs */
- SOFT_RESET = 0x22, /* issue a software reset */
- HARD_RESET = 0x40 /* 500x only? */
-};
-
-/* HSSEL -- handshake select register (write only) */
-enum hssel_bits {
- TNT_ONE_CHIP_BIT = 0x1,
- NODMA = 0x10,
- TNT_GO2SIDS_BIT = 0x20,
-};
-
-/* IMR0 -- Interrupt Mode Register 0 */
-enum imr0_bits {
- TNT_SYNCIE_BIT = 0x1, /* handshake sync */
- TNT_TOIE_BIT = 0x2, /* timeout */
- TNT_ATNIE_BIT = 0x4, /* ATN interrupt */
- TNT_IFCIE_BIT = 0x8, /* interface clear interrupt */
- TNT_BTO_BIT = 0x10, /* byte timeout */
- TNT_NLEN_BIT = 0x20, /* treat new line as EOS char */
- TNT_STBOIE_BIT = 0x40, /* status byte out */
- TNT_IMR0_ALWAYS_BITS = 0x80, /* always set this bit on write */
-};
-
-/* ISR0 -- Interrupt Status Register 0 */
-enum isr0_bits {
- TNT_SYNC_BIT = 0x1, /* handshake sync */
- TNT_TO_BIT = 0x2, /* timeout */
- TNT_ATNI_BIT = 0x4, /* ATN interrupt */
- TNT_IFCI_BIT = 0x8, /* interface clear interrupt */
- TNT_EOS_BIT = 0x10, /* end of string */
- TNT_NL_BIT = 0x20, /* new line receive */
- TNT_STBO_BIT = 0x40, /* status byte out */
- TNT_NBA_BIT = 0x80, /* new byte available */
-};
-
-/* ISR3 -- Interrupt Status Register 3 (read only) */
-enum isr3_bits {
- HR_DONE = (1 << 0), /* transfer done */
- HR_TLCI = (1 << 1), /* isr0, isr1, or isr2 interrupt asserted */
- HR_NEF = (1 << 2), /* NOT empty fifo */
- HR_NFF = (1 << 3), /* NOT full fifo */
- HR_STOP = (1 << 4), /* fifo empty or STOP command issued */
- HR_SRQI_CIC = (1 << 5), /* SRQ asserted and we are CIC (500x only?)*/
- HR_INTR = (1 << 7), /* isr3 interrupt active */
-};
-
-enum keyreg_bits {
- MSTD = 0x20, /* enable 350ns T1 delay */
-};
-
-/* STS1 -- Status Register 1 (read only) */
-enum sts1_bits {
- S_DONE = 0x80, /* DMA done */
- S_SC = 0x40, /* is system controller */
- S_IN = 0x20, /* DMA in (to memory) */
- S_DRQ = 0x10, /* DRQ line (for diagnostics) */
- S_STOP = 0x08, /* DMA stopped */
- S_NDAV = 0x04, /* inverse of DAV */
- S_HALT = 0x02, /* status of transfer machine */
- S_GSYNC = 0x01, /* indicates if GPIB is in sync w I/O */
-};
-
-/* STS2 -- Status Register 2 */
-enum sts2_bits {
- AFFN = (1 << 3), /* "A full FIFO NOT" (0=FIFO full) */
- AEFN = (1 << 2), /* "A empty FIFO NOT" (0=FIFO empty) */
- BFFN = (1 << 1), /* "B full FIFO NOT" (0=FIFO full) */
- BEFN = (1 << 0), /* "B empty FIFO NOT" (0=FIFO empty) */
-};
-
-// Auxiliary commands
-enum tnt4882_aux_cmds {
- AUX_9914 = 0x15, // switch to 9914 mode
- AUX_REQT = 0x18,
- AUX_REQF = 0x19,
- AUX_PAGEIN = 0x50, // page in alternate registers
- AUX_HLDI = 0x51, // rfd holdoff immediately
- AUX_CLEAR_END = 0x55,
- AUX_7210 = 0x99, // switch to 7210 mode
-};
-
-enum tnt4882_aux_regs {
- AUXRG = 0x40,
- AUXRI = 0xe0,
-};
-
-enum auxg_bits {
- /* no talking when no listeners bit (prevents bus errors when data written at wrong time) */
- NTNL_BIT = 0x8,
- RPP2_BIT = 0x4, /* set/clear local rpp message */
- CHES_BIT = 0x1, /*clear holdoff on end select bit*/
-};
-
-enum auxi_bits {
- SISB = 0x1, // static interrupt bits (don't clear isr1, isr2 on read)
- PP2 = 0x4, // ignore remote parallel poll configuration
- USTD = 0x8, // ultra short (1100 nanosec) T1 delay
-};
-
-enum sasr_bits {
- ACRDY_BIT = 0x4, /* acceptor ready state */
- ADHS_BIT = 0x8, /* acceptor data holdoff state */
- ANHS2_BIT = 0x10, /* acceptor not ready holdoff immediately state */
- ANHS1_BIT = 0x20, /* acceptor not ready holdoff state */
- AEHS_BIT = 0x40, /* acceptor end holdoff state */
-};
-
-#endif // _TNT4882_REGISTERS_H
diff --git a/drivers/staging/gpib/ines/Makefile b/drivers/staging/gpib/ines/Makefile
deleted file mode 100644
index 88241f15ecea..000000000000
--- a/drivers/staging/gpib/ines/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_GPIB_INES) += ines_gpib.o
-
-
diff --git a/drivers/staging/gpib/ines/ines.h b/drivers/staging/gpib/ines/ines.h
deleted file mode 100644
index 6ad57e9a1216..000000000000
--- a/drivers/staging/gpib/ines/ines.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * Header for ines GPIB boards
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _INES_GPIB_H
-#define _INES_GPIB_H
-
-#include "nec7210.h"
-#include "gpibP.h"
-#include "plx9050.h"
-#include "amcc5920.h"
-#include "quancom_pci.h"
-#include <linux/interrupt.h>
-
-enum ines_pci_chip {
- PCI_CHIP_NONE,
- PCI_CHIP_PLX9050,
- PCI_CHIP_AMCC5920,
- PCI_CHIP_QUANCOM,
- PCI_CHIP_QUICKLOGIC5030,
-};
-
-struct ines_priv {
- struct nec7210_priv nec7210_priv;
- struct pci_dev *pci_device;
- // base address for plx9052 pci chip
- unsigned long plx_iobase;
- // base address for amcc5920 pci chip
- unsigned long amcc_iobase;
- unsigned int irq;
- enum ines_pci_chip pci_chip_type;
- u8 extend_mode_bits;
-};
-
-/* inb/outb wrappers */
-static inline unsigned int ines_inb(struct ines_priv *priv, unsigned int register_number)
-{
- return inb(priv->nec7210_priv.iobase +
- register_number * priv->nec7210_priv.offset);
-}
-
-static inline void ines_outb(struct ines_priv *priv, unsigned int value,
- unsigned int register_number)
-{
- outb(value, priv->nec7210_priv.iobase +
- register_number * priv->nec7210_priv.offset);
-}
-
-enum ines_regs {
- // read
- FIFO_STATUS = 0x8,
- ISR3 = 0x9,
- ISR4 = 0xa,
- IN_FIFO_COUNT = 0x10,
- OUT_FIFO_COUNT = 0x11,
- EXTEND_STATUS = 0xf,
-
- // write
- XDMA_CONTROL = 0x8,
- IMR3 = ISR3,
- IMR4 = ISR4,
- IN_FIFO_WATERMARK = IN_FIFO_COUNT,
- OUT_FIFO_WATERMARK = OUT_FIFO_COUNT,
- EXTEND_MODE = 0xf,
-
- // read-write
- XFER_COUNT_LOWER = 0xb,
- XFER_COUNT_UPPER = 0xc,
- BUS_CONTROL_MONITOR = 0x13,
-};
-
-enum isr3_imr3_bits {
- HW_TIMEOUT_BIT = 0x1,
- XFER_COUNT_BIT = 0x2,
- CMD_RECEIVED_BIT = 0x4,
- TCT_RECEIVED_BIT = 0x8,
- IFC_ACTIVE_BIT = 0x10,
- ATN_ACTIVE_BIT = 0x20,
- FIFO_ERROR_BIT = 0x40,
-};
-
-enum isr4_imr4_bits {
- IN_FIFO_WATERMARK_BIT = 0x1,
- OUT_FIFO_WATERMARK_BIT = 0x2,
- IN_FIFO_FULL_BIT = 0x4,
- OUT_FIFO_EMPTY_BIT = 0x8,
- IN_FIFO_READY_BIT = 0x10,
- OUT_FIFO_READY_BIT = 0x20,
- IN_FIFO_EXIT_WATERMARK_BIT = 0x40,
- OUT_FIFO_EXIT_WATERMARK_BIT = 0x80,
-};
-
-enum extend_mode_bits {
- TR3_TRIG_ENABLE_BIT = 0x1, // enable generation of trigger pulse T/R3 pin
- // clear message available status bit when chip writes byte with EOI true
- MAV_ENABLE_BIT = 0x2,
- EOS1_ENABLE_BIT = 0x4, // enable eos register 1
- EOS2_ENABLE_BIT = 0x8, // enable eos register 2
- EOIDIS_BIT = 0x10, // disable EOI interrupt when doing rfd holdoff on end?
- XFER_COUNTER_ENABLE_BIT = 0x20,
- XFER_COUNTER_OUTPUT_BIT = 0x40, // use counter for output, clear for input
- // when xfer counter hits 0, assert EOI on write or RFD holdoff on read
- LAST_BYTE_HANDLING_BIT = 0x80,
-};
-
-enum extend_status_bits {
- OUTPUT_MESSAGE_IN_PROGRESS_BIT = 0x1,
- SCSEL_BIT = 0x2, // statue of SCSEL pin
- LISTEN_DISABLED = 0x4,
- IN_FIFO_EMPTY_BIT = 0x8,
- OUT_FIFO_FULL_BIT = 0x10,
-};
-
-// ines adds fifo enable bits to address mode register
-enum ines_admr_bits {
- IN_FIFO_ENABLE_BIT = 0x8,
- OUT_FIFO_ENABLE_BIT = 0x4,
-};
-
-enum xdma_control_bits {
- DMA_OUTPUT_BIT = 0x1, // use dma for output, clear for input
- ENABLE_SYNC_DMA_BIT = 0x2,
- DMA_ACCESS_EVERY_CYCLE = 0x4, // dma accesses fifo every cycle, clear for every other cycle
- DMA_16BIT = 0x8, // clear for 8 bit transfers
-};
-
-enum bus_control_monitor_bits {
- BCM_DAV_BIT = 0x1,
- BCM_NRFD_BIT = 0x2,
- BCM_NDAC_BIT = 0x4,
- BCM_IFC_BIT = 0x8,
- BCM_ATN_BIT = 0x10,
- BCM_SRQ_BIT = 0x20,
- BCM_REN_BIT = 0x40,
- BCM_EOI_BIT = 0x80,
-};
-
-enum ines_aux_reg_bits {
- INES_AUXD = 0x40,
-};
-
-enum ines_aux_cmds {
- INES_RFD_HLD_IMMEDIATE = 0x4,
- INES_AUX_CLR_OUT_FIFO = 0x5,
- INES_AUX_CLR_IN_FIFO = 0x6,
- INES_AUX_XMODE = 0xa,
-};
-
-enum ines_auxd_bits {
- INES_FOLLOWING_T1_MASK = 0x3,
- INES_FOLLOWING_T1_500ns = 0x0,
- INES_FOLLOWING_T1_350ns = 0x1,
- INES_FOLLOWING_T1_250ns = 0x2,
- INES_INITIAL_TI_MASK = 0xc,
- INES_INITIAL_T1_2000ns = 0x0,
- INES_INITIAL_T1_1100ns = 0x4,
- INES_INITIAL_T1_700ns = 0x8,
- INES_T6_2us = 0x0,
- INES_T6_50us = 0x10,
-};
-
-#endif // _INES_GPIB_H
diff --git a/drivers/staging/gpib/ines/ines_gpib.c b/drivers/staging/gpib/ines/ines_gpib.c
deleted file mode 100644
index a3cf846fd0f9..000000000000
--- a/drivers/staging/gpib/ines/ines_gpib.c
+++ /dev/null
@@ -1,1500 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 1999 Axel Dziemba (axel.dziemba@ines.de)
- * (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include "ines.h"
-
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/bitops.h>
-#include <asm/dma.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "gpib_pci_ids.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for Ines iGPIB 72010");
-
-static irqreturn_t ines_interrupt(struct gpib_board *board);
-
-static int ines_line_status(const struct gpib_board *board)
-{
- int status = VALID_ALL;
- int bcm_bits;
- struct ines_priv *ines_priv;
-
- ines_priv = board->private_data;
-
- bcm_bits = ines_inb(ines_priv, BUS_CONTROL_MONITOR);
-
- if (bcm_bits & BCM_REN_BIT)
- status |= BUS_REN;
- if (bcm_bits & BCM_IFC_BIT)
- status |= BUS_IFC;
- if (bcm_bits & BCM_SRQ_BIT)
- status |= BUS_SRQ;
- if (bcm_bits & BCM_EOI_BIT)
- status |= BUS_EOI;
- if (bcm_bits & BCM_NRFD_BIT)
- status |= BUS_NRFD;
- if (bcm_bits & BCM_NDAC_BIT)
- status |= BUS_NDAC;
- if (bcm_bits & BCM_DAV_BIT)
- status |= BUS_DAV;
- if (bcm_bits & BCM_ATN_BIT)
- status |= BUS_ATN;
-
- return status;
-}
-
-static void ines_set_xfer_counter(struct ines_priv *priv, unsigned int count)
-{
- if (count > 0xffff) {
- pr_err("bug! tried to set xfer counter > 0xffff\n");
- return;
- }
- ines_outb(priv, (count >> 8) & 0xff, XFER_COUNT_UPPER);
- ines_outb(priv, count & 0xff, XFER_COUNT_LOWER);
-}
-
-static int ines_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
- unsigned int retval;
-
- retval = nec7210_t1_delay(board, nec_priv, nano_sec);
-
- if (nano_sec <= 250) {
- write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_250ns |
- INES_INITIAL_T1_2000ns, AUXMR);
- retval = 250;
- } else if (nano_sec <= 350) {
- write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_350ns |
- INES_INITIAL_T1_2000ns, AUXMR);
- retval = 350;
- } else {
- write_byte(nec_priv, INES_AUXD | INES_FOLLOWING_T1_500ns |
- INES_INITIAL_T1_2000ns, AUXMR);
- retval = 500;
- }
-
- return retval;
-}
-
-static inline unsigned short num_in_fifo_bytes(struct ines_priv *ines_priv)
-{
- return ines_inb(ines_priv, IN_FIFO_COUNT);
-}
-
-static ssize_t pio_read(struct gpib_board *board, struct ines_priv *ines_priv, u8 *buffer,
- size_t length, size_t *nbytes)
-{
- ssize_t retval = 0;
- unsigned int num_fifo_bytes, i;
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
-
- *nbytes = 0;
- while (*nbytes < length) {
- if (wait_event_interruptible(board->wait,
- num_in_fifo_bytes(ines_priv) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- return -EINTR;
-
- num_fifo_bytes = num_in_fifo_bytes(ines_priv);
- if (num_fifo_bytes + *nbytes > length)
- num_fifo_bytes = length - *nbytes;
-
- for (i = 0; i < num_fifo_bytes; i++)
- buffer[(*nbytes)++] = read_byte(nec_priv, DIR);
- if (test_bit(RECEIVED_END_BN, &nec_priv->state) &&
- num_in_fifo_bytes(ines_priv) == 0)
- break;
- if (need_resched())
- schedule();
- }
- /* make sure RECEIVED_END is in sync */
- ines_interrupt(board);
- return retval;
-}
-
-static int ines_accel_read(struct gpib_board *board, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
- int counter_setting;
-
- *end = 0;
- *bytes_read = 0;
- if (length == 0)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &nec_priv->state);
-
- write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR);
-
- // clear in fifo
- nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT, 0);
- nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT, IN_FIFO_ENABLE_BIT);
-
- ines_priv->extend_mode_bits |= LAST_BYTE_HANDLING_BIT;
- ines_priv->extend_mode_bits &= ~XFER_COUNTER_OUTPUT_BIT & ~XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
-
- counter_setting = length - num_in_fifo_bytes(ines_priv);
- if (counter_setting > 0) {
- ines_set_xfer_counter(ines_priv, length);
- ines_priv->extend_mode_bits |= XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
-
- // holdoff on END
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
- /* release rfd holdoff */
- write_byte(nec_priv, AUX_FH, AUXMR);
- }
-
- retval = pio_read(board, ines_priv, buffer, length, bytes_read);
- ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
- if (retval < 0) {
- write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR);
- return retval;
- }
- if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state))
- *end = 1;
-
- return retval;
-}
-
-static const int out_fifo_size = 0xff;
-
-static inline unsigned short num_out_fifo_bytes(struct ines_priv *ines_priv)
-{
- return ines_inb(ines_priv, OUT_FIFO_COUNT);
-}
-
-static int ines_write_wait(struct gpib_board *board, struct ines_priv *ines_priv,
- unsigned int fifo_threshold)
-{
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
-
- // wait until byte is ready to be sent
- if (wait_event_interruptible(board->wait,
- num_out_fifo_bytes(ines_priv) < fifo_threshold ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(BUS_ERROR_BN, &nec_priv->state))
- return -EIO;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- return -EINTR;
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int ines_accel_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- size_t count = 0;
- ssize_t retval = 0;
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
- unsigned int num_bytes, i;
-
- *bytes_written = 0;
- // clear out fifo
- nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, 0);
- nec7210_set_reg_bits(nec_priv, ADMR, OUT_FIFO_ENABLE_BIT, OUT_FIFO_ENABLE_BIT);
-
- ines_priv->extend_mode_bits |= XFER_COUNTER_OUTPUT_BIT;
- ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
- ines_priv->extend_mode_bits &= ~LAST_BYTE_HANDLING_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
-
- ines_set_xfer_counter(ines_priv, length);
- if (send_eoi)
- ines_priv->extend_mode_bits |= LAST_BYTE_HANDLING_BIT;
- ines_priv->extend_mode_bits |= XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
-
- while (count < length) {
- retval = ines_write_wait(board, ines_priv, out_fifo_size);
- if (retval < 0)
- break;
-
- num_bytes = out_fifo_size - num_out_fifo_bytes(ines_priv);
- if (num_bytes + count > length)
- num_bytes = length - count;
- for (i = 0; i < num_bytes; i++)
- write_byte(nec_priv, buffer[count++], CDOR);
- }
- if (retval < 0) {
- ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
- *bytes_written = length - num_out_fifo_bytes(ines_priv);
- return retval;
- }
- // wait last byte has been sent
- retval = ines_write_wait(board, ines_priv, 1);
- ines_priv->extend_mode_bits &= ~XFER_COUNTER_ENABLE_BIT;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
- *bytes_written = length - num_out_fifo_bytes(ines_priv);
-
- return retval;
-}
-
-static irqreturn_t ines_pci_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct ines_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
-
- if (priv->pci_chip_type == PCI_CHIP_QUANCOM) {
- if ((inb(nec_priv->iobase +
- QUANCOM_IRQ_CONTROL_STATUS_REG) &
- QUANCOM_IRQ_ASSERTED_BIT))
- outb(QUANCOM_IRQ_ENABLE_BIT, nec_priv->iobase +
- QUANCOM_IRQ_CONTROL_STATUS_REG);
- }
-
- return ines_interrupt(board);
-}
-
-static irqreturn_t ines_interrupt(struct gpib_board *board)
-{
- struct ines_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- unsigned int isr3_bits, isr4_bits;
- unsigned long flags;
- int wake = 0;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- nec7210_interrupt(board, nec_priv);
- isr3_bits = ines_inb(priv, ISR3);
- isr4_bits = ines_inb(priv, ISR4);
- if (isr3_bits & IFC_ACTIVE_BIT) {
- push_gpib_event(board, EVENT_IFC);
- wake++;
- }
- if (isr3_bits & FIFO_ERROR_BIT)
- dev_err(board->gpib_dev, "fifo error\n");
- if (isr3_bits & XFER_COUNT_BIT)
- wake++;
-
- if (isr4_bits & (IN_FIFO_WATERMARK_BIT | IN_FIFO_FULL_BIT | OUT_FIFO_WATERMARK_BIT |
- OUT_FIFO_EMPTY_BIT))
- wake++;
-
- if (wake)
- wake_up_interruptible(&board->wait);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return IRQ_HANDLED;
-}
-
-static int ines_pci_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static int ines_pci_accel_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static int ines_isa_attach(struct gpib_board *board, const struct gpib_board_config *config);
-
-static void ines_pci_detach(struct gpib_board *board);
-static void ines_isa_detach(struct gpib_board *board);
-
-enum ines_pci_vendor_ids {
- PCI_VENDOR_ID_INES_QUICKLOGIC = 0x16da
-};
-
-enum ines_pci_device_ids {
- PCI_DEVICE_ID_INES_GPIB_AMCC = 0x8507,
- PCI_DEVICE_ID_INES_GPIB_QL5030 = 0x11,
-};
-
-enum ines_pci_subdevice_ids {
- PCI_SUBDEVICE_ID_INES_GPIB = 0x1072
-};
-
-static struct pci_device_id ines_pci_table[] = {
- {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
- PCI_SUBDEVICE_ID_INES_GPIB, 0, 0, 0},
- {PCI_VENDOR_ID_AMCC, PCI_DEVICE_ID_INES_GPIB_AMCC, PCI_VENDOR_ID_AMCC,
- PCI_SUBDEVICE_ID_INES_GPIB, 0, 0, 0},
- {PCI_VENDOR_ID_INES_QUICKLOGIC, PCI_DEVICE_ID_INES_GPIB_QL5030,
- PCI_VENDOR_ID_INES_QUICKLOGIC, PCI_DEVICE_ID_INES_GPIB_QL5030, 0, 0, 0},
- {PCI_DEVICE(PCI_VENDOR_ID_QUANCOM, PCI_DEVICE_ID_QUANCOM_GPIB)},
- {0}
-};
-MODULE_DEVICE_TABLE(pci, ines_pci_table);
-
-struct ines_pci_id {
- unsigned int vendor_id;
- unsigned int device_id;
- int subsystem_vendor_id;
- int subsystem_device_id;
- unsigned int gpib_region;
- unsigned int io_offset;
- enum ines_pci_chip pci_chip_type;
-};
-
-static struct ines_pci_id pci_ids[] = {
- {.vendor_id = PCI_VENDOR_ID_PLX,
- .device_id = PCI_DEVICE_ID_PLX_9050,
- .subsystem_vendor_id = PCI_VENDOR_ID_PLX,
- .subsystem_device_id = PCI_SUBDEVICE_ID_INES_GPIB,
- .gpib_region = 2,
- .io_offset = 1,
- .pci_chip_type = PCI_CHIP_PLX9050,
- },
- {.vendor_id = PCI_VENDOR_ID_AMCC,
- .device_id = PCI_DEVICE_ID_INES_GPIB_AMCC,
- .subsystem_vendor_id = PCI_VENDOR_ID_AMCC,
- .subsystem_device_id = PCI_SUBDEVICE_ID_INES_GPIB,
- .gpib_region = 1,
- .io_offset = 1,
- .pci_chip_type = PCI_CHIP_AMCC5920,
- },
- {.vendor_id = PCI_VENDOR_ID_INES_QUICKLOGIC,
- .device_id = PCI_DEVICE_ID_INES_GPIB_QL5030,
- .subsystem_vendor_id = PCI_VENDOR_ID_INES_QUICKLOGIC,
- .subsystem_device_id = PCI_DEVICE_ID_INES_GPIB_QL5030,
- .gpib_region = 1,
- .io_offset = 1,
- .pci_chip_type = PCI_CHIP_QUICKLOGIC5030,
- },
- {.vendor_id = PCI_VENDOR_ID_QUANCOM,
- .device_id = PCI_DEVICE_ID_QUANCOM_GPIB,
- .subsystem_vendor_id = -1,
- .subsystem_device_id = -1,
- .gpib_region = 0,
- .io_offset = 4,
- .pci_chip_type = PCI_CHIP_QUANCOM,
- },
-};
-
-static const int num_pci_chips = ARRAY_SIZE(pci_ids);
-
-// wrappers for interface functions
-static int ines_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- struct ines_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- ssize_t retval;
- int dummy;
-
- retval = nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
- if (retval < 0) {
- write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR);
-
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
-
- nec7210_read_data_in(board, nec_priv, &dummy);
- }
- return retval;
-}
-
-static int ines_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int ines_command(struct gpib_board *board, u8 *buffer, size_t length, size_t *bytes_written)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int ines_take_control(struct gpib_board *board, int synchronous)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int ines_go_to_standby(struct gpib_board *board)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int ines_request_system_control(struct gpib_board *board, int request_control)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
-}
-
-static void ines_interface_clear(struct gpib_board *board, int assert)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void ines_remote_enable(struct gpib_board *board, int enable)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int ines_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void ines_disable_eos(struct gpib_board *board)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int ines_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int ines_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int ines_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int ines_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void ines_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
-}
-
-static void ines_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void ines_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static u8 ines_serial_poll_status(struct gpib_board *board)
-{
- struct ines_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static void ines_return_to_local(struct gpib_board *board)
-{
- struct ines_priv *priv = board->private_data;
-
- nec7210_return_to_local(board, &priv->nec7210_priv);
-}
-
-static struct gpib_interface ines_pci_unaccel_interface = {
- .name = "ines_pci_unaccel",
- .attach = ines_pci_attach,
- .detach = ines_pci_detach,
- .read = ines_read,
- .write = ines_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static struct gpib_interface ines_pci_interface = {
- .name = "ines_pci",
- .attach = ines_pci_accel_attach,
- .detach = ines_pci_detach,
- .read = ines_accel_read,
- .write = ines_accel_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static struct gpib_interface ines_pci_accel_interface = {
- .name = "ines_pci_accel",
- .attach = ines_pci_accel_attach,
- .detach = ines_pci_detach,
- .read = ines_accel_read,
- .write = ines_accel_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static struct gpib_interface ines_isa_interface = {
- .name = "ines_isa",
- .attach = ines_isa_attach,
- .detach = ines_isa_detach,
- .read = ines_accel_read,
- .write = ines_accel_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static int ines_allocate_private(struct gpib_board *board)
-{
- struct ines_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct ines_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct ines_priv));
- init_nec7210_private(&priv->nec7210_priv);
- return 0;
-}
-
-static void ines_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static int ines_generic_attach(struct gpib_board *board)
-{
- struct ines_priv *ines_priv;
- struct nec7210_priv *nec_priv;
-
- board->status = 0;
-
- if (ines_allocate_private(board))
- return -ENOMEM;
- ines_priv = board->private_data;
- nec_priv = &ines_priv->nec7210_priv;
- nec_priv->read_byte = nec7210_ioport_read_byte;
- nec_priv->write_byte = nec7210_ioport_write_byte;
- nec_priv->offset = 1;
- nec_priv->type = IGPIB7210;
- ines_priv->pci_chip_type = PCI_CHIP_NONE;
-
- return 0;
-}
-
-static void ines_online(struct ines_priv *ines_priv, const struct gpib_board *board, int use_accel)
-{
- struct nec7210_priv *nec_priv = &ines_priv->nec7210_priv;
-
- /* ines doesn't seem to use internal count register */
- write_byte(nec_priv, ICR | 0, AUXMR);
-
- write_byte(nec_priv, INES_AUX_XMODE, AUXMR);
- write_byte(nec_priv, INES_RFD_HLD_IMMEDIATE, AUXMR);
-
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
-
- write_byte(nec_priv, INES_AUXD | 0, AUXMR);
- ines_outb(ines_priv, 0, XDMA_CONTROL);
- ines_priv->extend_mode_bits = 0;
- ines_outb(ines_priv, ines_priv->extend_mode_bits, EXTEND_MODE);
- if (use_accel) {
- ines_outb(ines_priv, 0x80, OUT_FIFO_WATERMARK);
- ines_outb(ines_priv, 0x80, IN_FIFO_WATERMARK);
- ines_outb(ines_priv, IFC_ACTIVE_BIT | ATN_ACTIVE_BIT |
- FIFO_ERROR_BIT | XFER_COUNT_BIT, IMR3);
- ines_outb(ines_priv, IN_FIFO_WATERMARK_BIT | IN_FIFO_FULL_BIT |
- OUT_FIFO_WATERMARK_BIT | OUT_FIFO_EMPTY_BIT, IMR4);
- } else {
- nec7210_set_reg_bits(nec_priv, ADMR, IN_FIFO_ENABLE_BIT | OUT_FIFO_ENABLE_BIT, 0);
- ines_outb(ines_priv, IFC_ACTIVE_BIT | FIFO_ERROR_BIT, IMR3);
- ines_outb(ines_priv, 0, IMR4);
- }
-
- nec7210_board_online(nec_priv, board);
- if (use_accel)
- nec7210_set_reg_bits(nec_priv, IMR1, HR_DOIE | HR_DIIE, 0);
-}
-
-static int ines_common_pci_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- int retval;
- struct ines_pci_id found_id;
- unsigned int i;
- struct pci_dev *pdev;
-
- memset(&found_id, 0, sizeof(found_id));
-
- retval = ines_generic_attach(board);
- if (retval)
- return retval;
-
- ines_priv = board->private_data;
- nec_priv = &ines_priv->nec7210_priv;
-
- // find board
- ines_priv->pci_device = NULL;
- for (i = 0; i < num_pci_chips && !ines_priv->pci_device; i++) {
- pdev = NULL;
- do {
- if (pci_ids[i].subsystem_vendor_id >= 0 &&
- pci_ids[i].subsystem_device_id >= 0)
- pdev = pci_get_subsys(pci_ids[i].vendor_id, pci_ids[i].device_id,
- pci_ids[i].subsystem_vendor_id,
- pci_ids[i].subsystem_device_id, pdev);
- else
- pdev = pci_get_device(pci_ids[i].vendor_id, pci_ids[i].device_id,
- pdev);
- if (!pdev)
- break;
- if (config->pci_bus >= 0 && config->pci_bus != pdev->bus->number)
- continue;
- if (config->pci_slot >= 0 && config->pci_slot != PCI_SLOT(pdev->devfn))
- continue;
- found_id = pci_ids[i];
- ines_priv->pci_device = pdev;
- break;
- } while (1);
- }
- if (!ines_priv->pci_device) {
- dev_err(board->gpib_dev, "could not find ines PCI board\n");
- return -1;
- }
-
- if (pci_enable_device(ines_priv->pci_device)) {
- dev_err(board->gpib_dev, "error enabling pci device\n");
- return -1;
- }
-
- if (pci_request_regions(ines_priv->pci_device, DRV_NAME))
- return -1;
- nec_priv->iobase = pci_resource_start(ines_priv->pci_device,
- found_id.gpib_region);
-
- ines_priv->pci_chip_type = found_id.pci_chip_type;
- nec_priv->offset = found_id.io_offset;
- switch (ines_priv->pci_chip_type) {
- case PCI_CHIP_PLX9050:
- ines_priv->plx_iobase = pci_resource_start(ines_priv->pci_device, 1);
- break;
- case PCI_CHIP_AMCC5920:
- ines_priv->amcc_iobase = pci_resource_start(ines_priv->pci_device, 0);
- break;
- case PCI_CHIP_QUANCOM:
- break;
- case PCI_CHIP_QUICKLOGIC5030:
- break;
- default:
- dev_err(board->gpib_dev, "unspecified chip type? (bug)\n");
- nec_priv->iobase = 0;
- pci_release_regions(ines_priv->pci_device);
- return -1;
- }
-
- nec7210_board_reset(nec_priv, board);
-#ifdef QUANCOM_PCI
- if (ines_priv->pci_chip_type == PCI_CHIP_QUANCOM) {
- /* change interrupt polarity */
- nec_priv->auxb_bits |= HR_INV;
- ines_outb(ines_priv, nec_priv->auxb_bits, AUXMR);
- }
-#endif
- isr_flags |= IRQF_SHARED;
- if (request_irq(ines_priv->pci_device->irq, ines_pci_interrupt, isr_flags,
- DRV_NAME, board)) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n", ines_priv->pci_device->irq);
- return -1;
- }
- ines_priv->irq = ines_priv->pci_device->irq;
-
- // enable interrupts on pci chip
- switch (ines_priv->pci_chip_type) {
- case PCI_CHIP_PLX9050:
- outl(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR1_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT,
- ines_priv->plx_iobase + PLX9050_INTCSR_REG);
- break;
- case PCI_CHIP_AMCC5920:
- {
- static const int region = 1;
- static const int num_wait_states = 7;
- u32 bits;
-
- bits = amcc_prefetch_bits(region, PREFETCH_DISABLED);
- bits |= amcc_PTADR_mode_bit(region);
- bits |= amcc_disable_write_fifo_bit(region);
- bits |= amcc_wait_state_bits(region, num_wait_states);
- outl(bits, ines_priv->amcc_iobase + AMCC_PASS_THRU_REG);
- outl(AMCC_ADDON_INTR_ENABLE_BIT, ines_priv->amcc_iobase + AMCC_INTCS_REG);
- }
- break;
- case PCI_CHIP_QUANCOM:
- outb(QUANCOM_IRQ_ENABLE_BIT, nec_priv->iobase +
- QUANCOM_IRQ_CONTROL_STATUS_REG);
- break;
- case PCI_CHIP_QUICKLOGIC5030:
- break;
- default:
- dev_err(board->gpib_dev, "unspecified chip type? (bug)\n");
- return -1;
- }
-
- return 0;
-}
-
-static int ines_pci_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- int retval;
-
- retval = ines_common_pci_attach(board, config);
- if (retval < 0)
- return retval;
-
- ines_priv = board->private_data;
- ines_online(ines_priv, board, 0);
-
- return 0;
-}
-
-static int ines_pci_accel_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- int retval;
-
- retval = ines_common_pci_attach(board, config);
- if (retval < 0)
- return retval;
-
- ines_priv = board->private_data;
- ines_online(ines_priv, board, 1);
-
- return 0;
-}
-
-static const int ines_isa_iosize = 0x20;
-
-static int ines_isa_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- int retval;
-
- retval = ines_generic_attach(board);
- if (retval)
- return retval;
-
- ines_priv = board->private_data;
- nec_priv = &ines_priv->nec7210_priv;
-
- if (!request_region(config->ibbase, ines_isa_iosize, DRV_NAME)) {
- dev_err(board->gpib_dev, "ioports at 0x%x already in use\n",
- config->ibbase);
- return -EBUSY;
- }
- nec_priv->iobase = config->ibbase;
- nec_priv->offset = 1;
- nec7210_board_reset(nec_priv, board);
- if (request_irq(config->ibirq, ines_pci_interrupt, isr_flags, DRV_NAME, board)) {
- dev_err(board->gpib_dev, "failed to allocate IRQ %d\n", config->ibirq);
- return -1;
- }
- ines_priv->irq = config->ibirq;
- ines_online(ines_priv, board, 1);
- return 0;
-}
-
-static void ines_pci_detach(struct gpib_board *board)
-{
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (ines_priv) {
- nec_priv = &ines_priv->nec7210_priv;
- if (ines_priv->irq) {
- // disable interrupts
- switch (ines_priv->pci_chip_type) {
- case PCI_CHIP_AMCC5920:
- if (ines_priv->plx_iobase)
- outl(0, ines_priv->plx_iobase + PLX9050_INTCSR_REG);
- break;
- case PCI_CHIP_QUANCOM:
- if (nec_priv->iobase)
- outb(0, nec_priv->iobase +
- QUANCOM_IRQ_CONTROL_STATUS_REG);
- break;
- default:
- break;
- }
- free_irq(ines_priv->irq, board);
- }
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- pci_release_regions(ines_priv->pci_device);
- }
- if (ines_priv->pci_device)
- pci_dev_put(ines_priv->pci_device);
- }
- ines_free_private(board);
-}
-
-static void ines_isa_detach(struct gpib_board *board)
-{
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (ines_priv) {
- nec_priv = &ines_priv->nec7210_priv;
- if (ines_priv->irq)
- free_irq(ines_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- release_region(nec_priv->iobase, ines_isa_iosize);
- }
- }
- ines_free_private(board);
-}
-
-static int ines_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return 0;
-}
-
-static struct pci_driver ines_pci_driver = {
- .name = "ines_gpib",
- .id_table = ines_pci_table,
- .probe = &ines_pci_probe
-};
-
-#ifdef CONFIG_GPIB_PCMCIA
-
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-static const int ines_pcmcia_iosize = 0x20;
-
-/*
- * The event() function is this driver's Card Services event handler.
- * It will be called by Card Services when an appropriate card status
- * event is received. The config() and release() entry points are
- * used to configure or release a socket, in response to card insertion
- * and ejection events. They are invoked from the gpib event
- * handler.
- */
-
-static int ines_gpib_config(struct pcmcia_device *link);
-static void ines_gpib_release(struct pcmcia_device *link);
-static int ines_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config);
-static int ines_pcmcia_accel_attach(struct gpib_board *board,
- const struct gpib_board_config *config);
-static void ines_pcmcia_detach(struct gpib_board *board);
-static int ines_common_pcmcia_attach(struct gpib_board *board);
-/*
- * A linked list of "instances" of the gpib device. Each actual
- * PCMCIA card corresponds to one device instance, and is described
- * by one dev_link_t structure (defined in ds.h).
- *
- * You may not want to use a linked list for this -- for example, the
- * memory card driver uses an array of dev_link_t pointers, where minor
- * device numbers are used to derive the corresponding array index.
- */
-
-static struct pcmcia_device *curr_dev;
-
-/*
- * A dev_link_t structure has fields for most things that are needed
- * to keep track of a socket, but there will usually be some device
- * specific information that also needs to be kept track of. The
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
- * A driver needs to provide a dev_node_t structure for each device
- * on a card. In some cases, there is only one device per card (for
- * example, ethernet cards, modems). In other cases, there may be
- * many actual or logical devices (SCSI adapters, memory cards with
- * multiple partitions). The dev_node_t structures need to be kept
- * in a linked list starting at the 'dev' field of a dev_link_t
- * structure. We allocate them in the card's private data structure,
- * because they generally can't be allocated dynamically.
- */
-
-struct local_info {
- struct pcmcia_device *p_dev;
- struct gpib_board *dev;
- u_short manfid;
- u_short cardid;
-};
-
-/*
- * gpib_attach() creates an "instance" of the driver, allocating
- * local data structures for one device. The device is registered
- * with Card Services.
- *
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a
- * card insertion event.
- */
-static int ines_gpib_probe(struct pcmcia_device *link)
-{
- struct local_info *info;
-
-// int ret, i;
-
- /* Allocate space for private device-specific data */
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- /* The io structure describes IO port mapping */
- link->resource[0]->end = 32;
- link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- link->io_lines = 5;
-
- /* General socket configuration */
- link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
- /* Register with Card Services */
- curr_dev = link;
- return ines_gpib_config(link);
-}
-
-/*
- * This deletes a driver "instance". The device is de-registered
- * with Card Services. If it has been released, all local data
- * structures are freed. Otherwise, the structures will be freed
- * when the device is released.
- */
-static void ines_gpib_remove(struct pcmcia_device *link)
-{
- struct local_info *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (info->dev)
- ines_pcmcia_detach(info->dev);
- ines_gpib_release(link);
-
- //free_netdev(dev);
- kfree(info);
-}
-
-static int ines_gpib_config_iteration(struct pcmcia_device *link, void *priv_data)
-{
- return pcmcia_request_io(link);
-}
-
-/*
- * gpib_config() is scheduled to run after a CARD_INSERTION event
- * is received, to configure the PCMCIA socket, and to make the
- * device available to the system.
- */
-static int ines_gpib_config(struct pcmcia_device *link)
-{
- int retval;
- void __iomem *virt;
-
- retval = pcmcia_loop_config(link, &ines_gpib_config_iteration, NULL);
- if (retval) {
- dev_warn(&link->dev, "no configuration found\n");
- ines_gpib_release(link);
- return -ENODEV;
- }
-
- dev_dbg(&link->dev, "ines_cs: manufacturer: 0x%x card: 0x%x\n",
- link->manf_id, link->card_id);
-
- /*
- * for the ines card we have to setup the configuration registers in
- * attribute memory here
- */
- link->resource[2]->flags |= WIN_MEMORY_TYPE_AM | WIN_DATA_WIDTH_8 | WIN_ENABLE;
- link->resource[2]->end = 0x1000;
- retval = pcmcia_request_window(link, link->resource[2], 250);
- if (retval) {
- dev_warn(&link->dev, "pcmcia_request_window failed\n");
- ines_gpib_release(link);
- return -ENODEV;
- }
- retval = pcmcia_map_mem_page(link, link->resource[2], 0);
- if (retval) {
- dev_warn(&link->dev, "pcmcia_map_mem_page failed\n");
- ines_gpib_release(link);
- return -ENODEV;
- }
- virt = ioremap(link->resource[2]->start, resource_size(link->resource[2]));
- writeb((link->resource[2]->start >> 2) & 0xff, virt + 0xf0); // IOWindow base
- iounmap(virt);
-
- /*
- * This actually configures the PCMCIA socket -- setting up
- * the I/O windows and the interrupt mapping.
- */
- retval = pcmcia_enable_device(link);
- if (retval) {
- ines_gpib_release(link);
- return -ENODEV;
- }
- return 0;
-} /* gpib_config */
-
-/*
- * After a card is removed, gpib_release() will unregister the net
- * device, and release the PCMCIA configuration. If the device is
- * still open, this will be postponed until it is closed.
- */
-
-static void ines_gpib_release(struct pcmcia_device *link)
-{
- pcmcia_disable_device(link);
-} /* gpib_release */
-
-static int ines_gpib_suspend(struct pcmcia_device *link)
-{
- //struct local_info *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (link->open)
- dev_err(&link->dev, "Device still open\n");
- //netif_device_detach(dev);
-
- return 0;
-}
-
-static int ines_gpib_resume(struct pcmcia_device *link)
-{
- //struct local_info_t *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- /*if (link->open) {
- * ni_gpib_probe(dev); / really?
- * //netif_device_attach(dev);
- *}
- */
- return ines_gpib_config(link);
-}
-
-static struct pcmcia_device_id ines_pcmcia_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x01b4, 0x4730),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, ines_pcmcia_ids);
-
-static struct pcmcia_driver ines_gpib_cs_driver = {
- .owner = THIS_MODULE,
- .name = "ines_gpib_cs",
- .id_table = ines_pcmcia_ids,
- .probe = ines_gpib_probe,
- .remove = ines_gpib_remove,
- .suspend = ines_gpib_suspend,
- .resume = ines_gpib_resume,
-};
-
-static void ines_pcmcia_cleanup_module(void)
-{
- pcmcia_unregister_driver(&ines_gpib_cs_driver);
-}
-
-static struct gpib_interface ines_pcmcia_unaccel_interface = {
- .name = "ines_pcmcia_unaccel",
- .attach = ines_pcmcia_attach,
- .detach = ines_pcmcia_detach,
- .read = ines_read,
- .write = ines_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static struct gpib_interface ines_pcmcia_accel_interface = {
- .name = "ines_pcmcia_accel",
- .attach = ines_pcmcia_accel_attach,
- .detach = ines_pcmcia_detach,
- .read = ines_accel_read,
- .write = ines_accel_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static struct gpib_interface ines_pcmcia_interface = {
- .name = "ines_pcmcia",
- .attach = ines_pcmcia_accel_attach,
- .detach = ines_pcmcia_detach,
- .read = ines_accel_read,
- .write = ines_accel_write,
- .command = ines_command,
- .take_control = ines_take_control,
- .go_to_standby = ines_go_to_standby,
- .request_system_control = ines_request_system_control,
- .interface_clear = ines_interface_clear,
- .remote_enable = ines_remote_enable,
- .enable_eos = ines_enable_eos,
- .disable_eos = ines_disable_eos,
- .parallel_poll = ines_parallel_poll,
- .parallel_poll_configure = ines_parallel_poll_configure,
- .parallel_poll_response = ines_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ines_line_status,
- .update_status = ines_update_status,
- .primary_address = ines_primary_address,
- .secondary_address = ines_secondary_address,
- .serial_poll_response = ines_serial_poll_response,
- .serial_poll_status = ines_serial_poll_status,
- .t1_delay = ines_t1_delay,
- .return_to_local = ines_return_to_local,
-};
-
-static irqreturn_t ines_pcmcia_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
-
- return ines_interrupt(board);
-}
-
-static int ines_common_pcmcia_attach(struct gpib_board *board)
-{
- struct ines_priv *ines_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- if (!curr_dev) {
- dev_err(board->gpib_dev, "no ines pcmcia cards found\n");
- return -1;
- }
-
- retval = ines_generic_attach(board);
- if (retval)
- return retval;
-
- ines_priv = board->private_data;
- nec_priv = &ines_priv->nec7210_priv;
-
- if (!request_region(curr_dev->resource[0]->start,
- resource_size(curr_dev->resource[0]), DRV_NAME)) {
- dev_err(board->gpib_dev, "ioports at 0x%lx already in use\n",
- (unsigned long)(curr_dev->resource[0]->start));
- return -1;
- }
-
- nec_priv->iobase = curr_dev->resource[0]->start;
-
- nec7210_board_reset(nec_priv, board);
-
- if (request_irq(curr_dev->irq, ines_pcmcia_interrupt, IRQF_SHARED,
- "pcmcia-gpib", board)) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n", curr_dev->irq);
- return -1;
- }
- ines_priv->irq = curr_dev->irq;
-
- return 0;
-}
-
-static int ines_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- int retval;
-
- retval = ines_common_pcmcia_attach(board);
- if (retval < 0)
- return retval;
-
- ines_priv = board->private_data;
- ines_online(ines_priv, board, 0);
-
- return 0;
-}
-
-static int ines_pcmcia_accel_attach(struct gpib_board *board,
- const struct gpib_board_config *config)
-{
- struct ines_priv *ines_priv;
- int retval;
-
- retval = ines_common_pcmcia_attach(board);
- if (retval < 0)
- return retval;
-
- ines_priv = board->private_data;
- ines_online(ines_priv, board, 1);
-
- return 0;
-}
-
-static void ines_pcmcia_detach(struct gpib_board *board)
-{
- struct ines_priv *ines_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (ines_priv) {
- nec_priv = &ines_priv->nec7210_priv;
- if (ines_priv->irq)
- free_irq(ines_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- release_region(nec_priv->iobase, ines_pcmcia_iosize);
- }
- }
- ines_free_private(board);
-}
-
-#endif /* CONFIG_GPIB_PCMCIA */
-
-static int __init ines_init_module(void)
-{
- int ret;
-
- ret = pci_register_driver(&ines_pci_driver);
- if (ret) {
- pr_err("pci_register_driver failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&ines_pci_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci;
- }
-
- ret = gpib_register_driver(&ines_pci_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci_unaccel;
- }
-
- ret = gpib_register_driver(&ines_pci_accel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pci_accel;
- }
-
- ret = gpib_register_driver(&ines_isa_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_isa;
- }
-
-#ifdef CONFIG_GPIB_PCMCIA
- ret = gpib_register_driver(&ines_pcmcia_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia;
- }
-
- ret = gpib_register_driver(&ines_pcmcia_unaccel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_unaccel;
- }
-
- ret = gpib_register_driver(&ines_pcmcia_accel_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_accel;
- }
-
- ret = pcmcia_register_driver(&ines_gpib_cs_driver);
- if (ret) {
- pr_err("pcmcia_register_driver failed: error = %d\n", ret);
- goto err_pcmcia_driver;
- }
-#endif
-
- return 0;
-
-#ifdef CONFIG_GPIB_PCMCIA
-err_pcmcia_driver:
- gpib_unregister_driver(&ines_pcmcia_accel_interface);
-err_pcmcia_accel:
- gpib_unregister_driver(&ines_pcmcia_unaccel_interface);
-err_pcmcia_unaccel:
- gpib_unregister_driver(&ines_pcmcia_interface);
-err_pcmcia:
-#endif
- gpib_unregister_driver(&ines_isa_interface);
-err_isa:
- gpib_unregister_driver(&ines_pci_accel_interface);
-err_pci_accel:
- gpib_unregister_driver(&ines_pci_unaccel_interface);
-err_pci_unaccel:
- gpib_unregister_driver(&ines_pci_interface);
-err_pci:
- pci_unregister_driver(&ines_pci_driver);
-
- return ret;
-}
-
-static void __exit ines_exit_module(void)
-{
- gpib_unregister_driver(&ines_pci_interface);
- gpib_unregister_driver(&ines_pci_unaccel_interface);
- gpib_unregister_driver(&ines_pci_accel_interface);
- gpib_unregister_driver(&ines_isa_interface);
-#ifdef CONFIG_GPIB_PCMCIA
- gpib_unregister_driver(&ines_pcmcia_interface);
- gpib_unregister_driver(&ines_pcmcia_unaccel_interface);
- gpib_unregister_driver(&ines_pcmcia_accel_interface);
- ines_pcmcia_cleanup_module();
-#endif
-
- pci_unregister_driver(&ines_pci_driver);
-}
-
-module_init(ines_init_module);
-module_exit(ines_exit_module);
diff --git a/drivers/staging/gpib/lpvo_usb_gpib/Makefile b/drivers/staging/gpib/lpvo_usb_gpib/Makefile
deleted file mode 100644
index 360553488e6d..000000000000
--- a/drivers/staging/gpib/lpvo_usb_gpib/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-
-obj-$(CONFIG_GPIB_LPVO) += lpvo_usb_gpib.o
-
diff --git a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c b/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c
deleted file mode 100644
index dd68c4843490..000000000000
--- a/drivers/staging/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c
+++ /dev/null
@@ -1,2025 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * This code has been developed at the Department of Physics (University *
- * of Florence, Italy) to support in linux-gpib the open usb-gpib adapter *
- * implemented at the University of Ljubljana (lpvo.fe.uni-lj.si/gpib) *
- * *
- * copyright : (C) 2011 Marcello Carla' *
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define NAME KBUILD_MODNAME
-
-/* base module includes */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/spinlock.h>
-#include <linux/file.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/sched/signal.h>
-#include <linux/usb.h>
-
-#include "gpibP.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for LPVO usb devices");
-
-/*
- * Table of devices that work with this driver.
- *
- * Currently, only one device is known to be used in the
- * lpvo_usb_gpib adapter (FTDI 0403:6001).
- * If your adapter uses a different chip, insert a line
- * in the following table with proper <Vendor-id>, <Product-id>.
- *
- * To have your chip automatically handled by the driver,
- * update files "/usr/local/etc/modprobe.d/lpvo_usb_gpib.conf"
- * and /usr/local/etc/udev/rules.d/99-lpvo_usb_gpib.rules.
- *
- */
-
-static const struct usb_device_id skel_table[] = {
- { USB_DEVICE(0x0403, 0x6001) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, skel_table);
-
-/*
- * *** Diagnostics and Debug ***
- * To enable the diagnostic and debug messages either compile with DEBUG set
- * or control via the dynamic debug mechanisms.
- * The module parameter "debug" controls the sending of debug messages to
- * syslog. By default it is set to 0
- * debug = 0: only attach/detach messages are sent
- * 1: every action is logged
- * 2: extended logging; each single exchanged byte is documented
- * (about twice the log volume of [1])
- * To switch debug level:
- * At module loading: modprobe lpvo_usb_gpib debug={0,1,2}
- * On the fly: echo {0,1,2} > /sys/modules/lpvo_usb_gpib/parameters/debug
- */
-
-static int debug;
-module_param(debug, int, 0644);
-
-#define DIA_LOG(level, format, ...) \
- do { if (debug >= (level)) \
- dev_dbg(board->gpib_dev, format, ## __VA_ARGS__); } \
- while (0)
-
-#define WQT wait_queue_entry_t
-#define WQH head
-#define WQE entry
-
-/* standard and extended command sets of the usb-gpib adapter */
-
-#define USB_GPIB_ON "\nIB\n"
-#define USB_GPIB_OFF "\nIBO\n"
-#define USB_GPIB_IBm0 "\nIBm0\n" /* do not assert REN with IFC */
-#define USB_GPIB_IBm1 "\nIBm1\n" /* assert REN with IFC */
-#define USB_GPIB_IBCL "\nIBZ\n"
-#define USB_GPIB_STATUS "\nIBS\n"
-#define USB_GPIB_READ "\nIB?\n"
-#define USB_GPIB_READ_1 "\nIBB\n"
-#define USB_GPIB_EOI "\nIBe0\n"
-#define USB_GPIB_FTMO "\nIBf0\n" /* disable first byte timeout */
-#define USB_GPIB_TTMOZ "\nIBt0\n" /* disable byte timeout */
-
-/* incomplete commands */
-
-#define USB_GPIB_BTMO "\nIBt" /* set byte timeout */
-#define USB_GPIB_TTMO "\nIBT" /* set total timeout */
-
-#define USB_GPIB_DEBUG_ON "\nIBDE\xAA\n"
-#define USB_GPIB_SET_LISTEN "\nIBDT0\n"
-#define USB_GPIB_SET_TALK "\nIBDT1\n"
-#define USB_GPIB_SET_LINES "\nIBDC.\n"
-#define USB_GPIB_SET_DATA "\nIBDM.\n"
-#define USB_GPIB_READ_LINES "\nIBD?C\n"
-#define USB_GPIB_READ_DATA "\nIBD?M\n"
-#define USB_GPIB_READ_BUS "\nIBD??\n"
-
-/* command sequences */
-
-#define USB_GPIB_UNTALK "\nIBC_\n"
-#define USB_GPIB_UNLISTEN "\nIBC?\n"
-
-/* special characters used by the adapter */
-
-#define DLE ('\020')
-#define STX ('\02')
-#define ETX ('\03')
-#define ACK ('\06')
-#define NODATA ('\03')
-#define NODAV ('\011')
-
-#define IB_BUS_REN 0x01
-#define IB_BUS_IFC 0x02
-#define IB_BUS_NDAC 0x04
-#define IB_BUS_NRFD 0x08
-#define IB_BUS_DAV 0x10
-#define IB_BUS_EOI 0x20
-#define IB_BUS_ATN 0x40
-#define IB_BUS_SRQ 0x80
-
-#define INBUF_SIZE 128
-
-struct char_buf { /* used by one_char() routine */
- char *inbuf;
- int last;
- int nchar;
-};
-
-struct usb_gpib_priv { /* private data to the device */
- u8 eos; /* eos character */
- short eos_flags; /* eos mode */
- int timeout; /* current value for timeout */
- void *dev; /* the usb device private data structure */
-};
-
-#define GPIB_DEV (((struct usb_gpib_priv *)board->private_data)->dev)
-
-static void show_status(struct gpib_board *board)
-{
- DIA_LOG(2, "# - buffer_length %d\n", board->buffer_length);
- DIA_LOG(2, "# - status %lx\n", board->status);
- DIA_LOG(2, "# - use_count %d\n", board->use_count);
- DIA_LOG(2, "# - pad %x\n", board->pad);
- DIA_LOG(2, "# - sad %x\n", board->sad);
- DIA_LOG(2, "# - timeout %d\n", board->usec_timeout);
- DIA_LOG(2, "# - ppc %d\n", board->parallel_poll_configuration);
- DIA_LOG(2, "# - t1delay %d\n", board->t1_nano_sec);
- DIA_LOG(2, "# - online %d\n", board->online);
- DIA_LOG(2, "# - autopoll %d\n", board->autospollers);
- DIA_LOG(2, "# - autopoll task %p\n", board->autospoll_task);
- DIA_LOG(2, "# - minor %d\n", board->minor);
- DIA_LOG(2, "# - master %d\n", board->master);
- DIA_LOG(2, "# - list %d\n", board->ist);
-}
-
-/*
- * GLOBAL VARIABLES: required for
- * pairing among gpib minor and usb minor.
- * MAX_DEV is the max number of usb-gpib adapters; free
- * to change as you like, but no more than 32
- */
-
-#define MAX_DEV 8
-static struct usb_interface *lpvo_usb_interfaces[MAX_DEV]; /* registered interfaces */
-static int usb_minors[MAX_DEV]; /* usb minors */
-static int assigned_usb_minors; /* mask of filled slots */
-static struct mutex minors_lock; /* operations on usb_minors are to be protected */
-
-/*
- * usb-skeleton prototypes
- */
-
-struct usb_skel;
-static ssize_t skel_do_write(struct usb_skel *, const char *, size_t);
-static ssize_t skel_do_read(struct usb_skel *, char *, size_t);
-static int skel_do_open(struct gpib_board *, int);
-static int skel_do_release(struct gpib_board *);
-
-/*
- * usec_diff : take difference in MICROsec between two 'timespec'
- * (unix time in sec and NANOsec)
- */
-
-static inline int usec_diff(struct timespec64 *a, struct timespec64 *b)
-{
- return ((a->tv_sec - b->tv_sec) * 1000000 +
- (a->tv_nsec - b->tv_nsec) / 1000);
-}
-
-/*
- * *** these routines are specific to the usb-gpib adapter ***
- */
-
-/**
- * write_loop() - Send a byte sequence to the adapter
- *
- * @dev: the private device structure
- * @msg: the byte sequence.
- * @leng: the byte sequence length.
- *
- */
-
-static int write_loop(void *dev, char *msg, int leng)
-{
- return skel_do_write(dev, msg, leng);
-}
-
-/**
- * send_command() - Send a byte sequence and return a single byte reply.
- *
- * @board: the gpib_board_struct data area for this gpib interface
- * @msg: the byte sequence.
- * @leng: the byte sequence length; can be given as zero and is
- * computed automatically, but if 'msg' contains a zero byte,
- * it has to be given explicitly.
- */
-
-static int send_command(struct gpib_board *board, char *msg, int leng)
-{
- char buffer[64];
- int nchar;
- int retval;
- struct timespec64 before, after;
-
- ktime_get_real_ts64 (&before);
-
- if (!leng)
- leng = strlen(msg);
- retval = write_loop(GPIB_DEV, msg, leng);
- if (retval < 0)
- return retval;
-
- nchar = skel_do_read(GPIB_DEV, buffer, 64);
-
- if (nchar < 0) {
- dev_err(board->gpib_dev, " return from read: %d\n", nchar);
- return nchar;
- } else if (nchar != 1) {
- dev_err(board->gpib_dev, " Irregular reply to command: %s\n", msg);
- return -EIO;
- }
- ktime_get_real_ts64 (&after);
-
- DIA_LOG(1, "Sent %d - done %d us.\n", leng, usec_diff(&after, &before));
-
- return buffer[0] & 0xff;
-}
-
-/*
- * set_control_line() - Set the value of a single gpib control line
- *
- * @board: the gpib_board_struct data area for this gpib interface
- * @line: line mask
- * @value: line new value (0/1)
- */
-
-static int set_control_line(struct gpib_board *board, int line, int value)
-{
- char msg[] = USB_GPIB_SET_LINES;
- int retval;
- int leng = strlen(msg);
-
- DIA_LOG(1, "setting line %x to %x\n", line, value);
-
- retval = send_command(board, USB_GPIB_READ_LINES, 0);
-
- DIA_LOG(1, "old line values: %x\n", retval);
-
- if (retval == -EIO)
- return retval;
-
- msg[leng - 2] = value ? (retval & ~line) : retval | line;
-
- retval = send_command(board, msg, 0);
-
- DIA_LOG(1, "operation result: %x\n", retval);
-
- return retval;
-}
-
-/*
- * one_char() - read one single byte from input buffer
- *
- * @board: the gpib_board_struct data area for this gpib interface
- * @char_buf: the routine private data structure
- */
-
-static int one_char(struct gpib_board *board, struct char_buf *b)
-{
- struct timespec64 before, after;
-
- if (b->nchar) {
- DIA_LOG(2, "-> %x\n", b->inbuf[b->last - b->nchar]);
- return b->inbuf[b->last - b->nchar--];
- }
- ktime_get_real_ts64 (&before);
- b->nchar = skel_do_read(GPIB_DEV, b->inbuf, INBUF_SIZE);
- b->last = b->nchar;
- ktime_get_real_ts64 (&after);
-
- DIA_LOG(2, "read %d bytes in %d usec\n",
- b->nchar, usec_diff(&after, &before));
-
- if (b->nchar > 0) {
- DIA_LOG(2, "--> %x\n", b->inbuf[b->last - b->nchar]);
- return b->inbuf[b->last - b->nchar--];
- }
- return -EIO;
-}
-
-/**
- * set_timeout() - set single byte / total timeouts on the adapter
- *
- * @board: the gpib_board_struct data area for this gpib interface
- *
- * For sake of speed, the operation is performed only if it
- * modifies the current (saved) value. Minimum allowed timeout
- * is 30 ms (T30ms -> 8); timeout disable (TNONE -> 0) currently
- * not supported.
- */
-
-static void set_timeout(struct gpib_board *board)
-{
- int n, val;
- char command[sizeof(USB_GPIB_TTMO) + 6];
- struct usb_gpib_priv *data = board->private_data;
-
- if (data->timeout == board->usec_timeout)
- return;
-
- n = (board->usec_timeout + 32767) / 32768;
- if (n < 2)
- n = 2;
-
- DIA_LOG(1, "Set timeout to %d us -> %d\n", board->usec_timeout, n);
-
- sprintf(command, "%s%d\n", USB_GPIB_BTMO, n > 255 ? 255 : n);
- val = send_command(board, command, 0);
-
- if (val == ACK) {
- if (n > 65535)
- n = 65535;
- sprintf(command, "%s%d\n", USB_GPIB_TTMO, n);
- val = send_command(board, command, 0);
- }
-
- if (val != ACK)
- dev_err(board->gpib_dev, "error in timeout set: <%s>\n", command);
- else
- data->timeout = board->usec_timeout;
-}
-
-/*
- * now the standard interface functions - attach and detach
- */
-
-/**
- * usb_gpib_attach() - activate the usb-gpib converter board
- *
- * @board: the gpib_board_struct data area for this gpib interface
- * @config: firmware data, if any (from gpib_config -I <file>)
- *
- * The channel name is ttyUSBn, with n=0 by default. Other values for n
- * passed with gpib_config -b <n>.
- *
- * In this routine I trust that when an error code is returned
- * detach() will be called. Always.
- */
-
-static int usb_gpib_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- int retval, j;
- u32 base = config->ibbase;
- char *device_path;
- int match;
- struct usb_device *udev;
-
- DIA_LOG(0, "Board %p -t %s -m %d -a %p -u %d -l %d -b %d\n",
- board, board->interface->name, board->minor, config->device_path,
- config->pci_bus, config->pci_slot, base);
-
- board->private_data = NULL; /* to be sure - we can detach before setting */
-
- /* identify device to be attached */
-
- mutex_lock(&minors_lock);
-
- if (config->device_path) {
- /* if config->device_path given, try that first */
- for (j = 0 ; j < MAX_DEV ; j++) {
- if ((assigned_usb_minors & 1 << j) == 0)
- continue;
- udev = usb_get_dev(interface_to_usbdev(lpvo_usb_interfaces[j]));
- device_path = kobject_get_path(&udev->dev.kobj, GFP_KERNEL);
- match = gpib_match_device_path(&lpvo_usb_interfaces[j]->dev,
- config->device_path);
- DIA_LOG(1, "dev. %d: minor %d path: %s --> %d\n", j,
- lpvo_usb_interfaces[j]->minor, device_path, match);
- kfree(device_path);
- if (match)
- break;
- }
- } else if (config->pci_bus != -1 && config->pci_slot != -1) {
- /* second: look for bus and slot */
- for (j = 0 ; j < MAX_DEV ; j++) {
- if ((assigned_usb_minors & 1 << j) == 0)
- continue;
- udev = usb_get_dev(interface_to_usbdev(lpvo_usb_interfaces[j]));
- DIA_LOG(1, "dev. %d: bus %d -> %d dev: %d -> %d\n", j,
- udev->bus->busnum, config->pci_bus, udev->devnum, config->pci_slot);
- if (config->pci_bus == udev->bus->busnum &&
- config->pci_slot == udev->devnum)
- break;
- }
- } else { /* last chance: usb_minor, given as ibbase */
- for (j = 0 ; j < MAX_DEV ; j++) {
- if (usb_minors[j] == base && assigned_usb_minors & 1 << j)
- break;
- }
- }
- mutex_unlock(&minors_lock);
-
- if (j == MAX_DEV) {
- dev_err(board->gpib_dev, "Requested device is not registered.\n");
- return -EIO;
- }
-
- board->private_data = kzalloc(sizeof(struct usb_gpib_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
-
- retval = skel_do_open(board, usb_minors[j]);
-
- DIA_LOG(1, "Skel open: %d\n", retval);
-
- if (retval) {
- dev_err(board->gpib_dev, "skel open failed.\n");
- kfree(board->private_data);
- board->private_data = NULL;
- return -ENODEV;
- }
-
- show_status(board);
-
- retval = send_command(board, USB_GPIB_ON, 0);
- DIA_LOG(1, "USB_GPIB_ON returns %x\n", retval);
- if (retval != ACK)
- return -EIO;
-
- /*
- * We must setup debug mode because we need the extended instruction
- * set to cope with the Core (gpib_common) point of view
- */
-
- retval = send_command(board, USB_GPIB_DEBUG_ON, 0);
- DIA_LOG(1, "USB_GPIB_DEBUG_ON returns %x\n", retval);
- if (retval != ACK)
- return -EIO;
-
- /*
- * We must keep REN off after an IFC because so it is
- * assumed by the Core
- */
-
- retval = send_command(board, USB_GPIB_IBm0, 0);
- DIA_LOG(1, "USB_GPIB_IBm0 returns %x\n", retval);
- if (retval != ACK)
- return -EIO;
-
- retval = set_control_line(board, IB_BUS_REN, 0);
- if (retval != ACK)
- return -EIO;
-
- retval = send_command(board, USB_GPIB_FTMO, 0);
- DIA_LOG(1, "USB_GPIB_FTMO returns %x\n", retval);
- if (retval != ACK)
- return -EIO;
-
- show_status(board);
- DIA_LOG(0, "attached\n");
- return 0;
-}
-
-/**
- * usb_gpib_detach() - deactivate the usb-gpib converter board
- *
- * @board: the gpib_board data area for this gpib interface
- *
- */
-
-static void usb_gpib_detach(struct gpib_board *board)
-{
- int retval;
-
- show_status(board);
-
- DIA_LOG(0, "detaching\n");
-
- if (board->private_data) {
- if (GPIB_DEV) {
- write_loop(GPIB_DEV, USB_GPIB_OFF, strlen(USB_GPIB_OFF));
- msleep(100);
- DIA_LOG(1, "%s", "GPIB off\n");
- retval = skel_do_release(board);
- DIA_LOG(1, "skel release -> %d\n", retval);
- }
- kfree(board->private_data);
- board->private_data = NULL;
- }
-
- DIA_LOG(0, "detached\n");
-}
-
-/*
- * Other functions follow in alphabetical order
- */
-/* command */
-static int usb_gpib_command(struct gpib_board *board,
- u8 *buffer,
- size_t length,
- size_t *bytes_written)
-{
- int i, retval;
- char command[6] = "IBc.\n";
-
- DIA_LOG(1, "enter %p\n", board);
-
- set_timeout(board);
-
- *bytes_written = 0;
- for (i = 0 ; i < length ; i++) {
- command[3] = buffer[i];
- retval = send_command(board, command, 5);
- DIA_LOG(2, "%d ==> %x %x\n", i, buffer[i], retval);
- if (retval != 0x06)
- return retval;
- ++(*bytes_written);
- }
- return 0;
-}
-
-/**
- * usb_gpib_disable_eos() - Disable END on eos byte (END on EOI only)
- *
- * @board: the gpib_board data area for this gpib interface
- *
- * With the lpvo adapter eos can only be handled via software.
- * Cannot do nothing here, but remember for future use.
- */
-
-static void usb_gpib_disable_eos(struct gpib_board *board)
-{
- ((struct usb_gpib_priv *)board->private_data)->eos_flags &= ~REOS;
- DIA_LOG(1, "done: %x\n",
- ((struct usb_gpib_priv *)board->private_data)->eos_flags);
-}
-
-/**
- * usb_gpib_enable_eos() - Enable END for reads when eos byte is received.
- *
- * @board: the gpib_board data area for this gpib interface
- * @eos_byte: the 'eos' byte
- * @compare_8_bits: if zero ignore eigthth bit when comparing
- *
- */
-
-static int usb_gpib_enable_eos(struct gpib_board *board,
- u8 eos_byte,
- int compare_8_bits)
-{
- struct usb_gpib_priv *pd = (struct usb_gpib_priv *)board->private_data;
-
- DIA_LOG(1, "enter with %x\n", eos_byte);
- pd->eos = eos_byte;
- pd->eos_flags = REOS;
- if (compare_8_bits)
- pd->eos_flags |= BIN;
- return 0;
-}
-
-/**
- * usb_gpib_go_to_standby() - De-assert ATN
- *
- * @board: the gpib_board data area for this gpib interface
- */
-
-static int usb_gpib_go_to_standby(struct gpib_board *board)
-{
- int retval = set_control_line(board, IB_BUS_ATN, 0);
-
- DIA_LOG(1, "done with %x\n", retval);
-
- if (retval == ACK)
- return 0;
- return -EIO;
-}
-
-/**
- * usb_gpib_interface_clear() - Assert or de-assert IFC
- *
- * @board: the gpib_board data area for this gpib interface
- * @assert: 1: assert IFC; 0: de-assert IFC
- *
- * Currently on the assert request we issue the lpvo IBZ
- * command that cycles IFC low for 100 usec, then we ignore
- * the de-assert request.
- */
-
-static void usb_gpib_interface_clear(struct gpib_board *board, int assert)
-{
- int retval = 0;
-
- DIA_LOG(1, "enter with %d\n", assert);
-
- if (assert) {
- retval = send_command(board, USB_GPIB_IBCL, 0);
-
- set_bit(CIC_NUM, &board->status);
- }
-
- DIA_LOG(1, "done with %d %d\n", assert, retval);
-}
-
-/**
- * usb_gpib_line_status() - Read the status of the bus lines.
- *
- * @board: the gpib_board data area for this gpib interface
- *
- * We can read all lines.
- */
-static int usb_gpib_line_status(const struct gpib_board *board)
-{
- int buffer;
- int line_status = VALID_ALL; /* all lines will be read */
- struct list_head *p, *q;
- WQT *item;
- unsigned long flags;
- int sleep = 0;
-
- DIA_LOG(1, "%s\n", "request");
-
- /*
- * if we are on the wait queue (board->wait), do not hurry
- * reading status line; instead, pause a little
- */
-
- spin_lock_irqsave((spinlock_t *)&board->wait.lock, flags);
- q = (struct list_head *)&board->wait.WQH;
- list_for_each(p, q) {
- item = container_of(p, WQT, WQE);
- if (item->private == current) {
- sleep = 20;
- break;
- }
- /* pid is: ((struct task_struct *) item->private)->pid); */
- }
- spin_unlock_irqrestore((spinlock_t *)&board->wait.lock, flags);
- if (sleep) {
- DIA_LOG(1, "we are on the wait queue - sleep %d ms\n", sleep);
- msleep(sleep);
- }
-
- buffer = send_command((struct gpib_board *)board, USB_GPIB_STATUS, 0);
-
- if (buffer < 0) {
- dev_err(board->gpib_dev, "line status read failed with %d\n", buffer);
- return -1;
- }
-
- if ((buffer & 0x01) == 0)
- line_status |= BUS_REN;
- if ((buffer & 0x02) == 0)
- line_status |= BUS_IFC;
- if ((buffer & 0x04) == 0)
- line_status |= BUS_NDAC;
- if ((buffer & 0x08) == 0)
- line_status |= BUS_NRFD;
- if ((buffer & 0x10) == 0)
- line_status |= BUS_DAV;
- if ((buffer & 0x20) == 0)
- line_status |= BUS_EOI;
- if ((buffer & 0x40) == 0)
- line_status |= BUS_ATN;
- if ((buffer & 0x80) == 0)
- line_status |= BUS_SRQ;
-
- DIA_LOG(1, "done with %x %x\n", buffer, line_status);
-
- return line_status;
-}
-
-/* parallel_poll */
-
-static int usb_gpib_parallel_poll(struct gpib_board *board, u8 *result)
-{
- /*
- * request parallel poll asserting ATN | EOI;
- * we suppose ATN already asserted
- */
-
- int retval;
-
- DIA_LOG(1, "enter %p\n", board);
-
- retval = set_control_line(board, IB_BUS_EOI, 1);
- if (retval != ACK)
- return -EIO;
-
- *result = send_command(board, USB_GPIB_READ_DATA, 0);
-
- DIA_LOG(1, "done with %x\n", *result);
-
- retval = set_control_line(board, IB_BUS_EOI, 0);
- if (retval != 0x06)
- return -EIO;
-
- return 0;
-}
-
-/* read */
-
-static int usb_gpib_read(struct gpib_board *board,
- u8 *buffer,
- size_t length,
- int *end,
- size_t *bytes_read)
-{
-#define MAX_READ_EXCESS 16384
-
- struct char_buf b = {NULL, 0};
-
- int retval;
- char c, nc;
- int ic;
- struct timespec64 before, after;
- int read_count = MAX_READ_EXCESS;
- struct usb_gpib_priv *pd = (struct usb_gpib_priv *)board->private_data;
-
- DIA_LOG(1, "enter %p -> %zu\n", board, length);
-
- *bytes_read = 0; /* by default, things go wrong */
- *end = 0;
-
- set_timeout(board);
-
- /* single byte read has a special handling */
-
- if (length == 1) {
- char inbuf[2] = {0, 0};
-
- /* read a single character */
-
- ktime_get_real_ts64 (&before);
-
- retval = write_loop(GPIB_DEV, USB_GPIB_READ_1, strlen(USB_GPIB_READ_1));
- if (retval < 0)
- return retval;
-
- retval = skel_do_read(GPIB_DEV, inbuf, 1);
- retval += skel_do_read(GPIB_DEV, inbuf + 1, 1);
-
- ktime_get_real_ts64 (&after);
-
- DIA_LOG(1, "single read: %x %x %x in %d\n", retval,
- inbuf[0], inbuf[1],
- usec_diff(&after, &before));
-
- /* good char / last char? */
-
- if (retval == 2 && inbuf[1] == ACK) {
- buffer[0] = inbuf[0];
- *bytes_read = 1;
- return 0;
- }
- if (retval < 2)
- return -EIO;
- else
- return -ETIME;
- }
-
- /* allocate buffer for multibyte read */
-
- b.inbuf = kmalloc(INBUF_SIZE, GFP_KERNEL);
- if (!b.inbuf)
- return -ENOMEM;
-
- /* send read command and check <DLE><STX> sequence */
-
- retval = write_loop(GPIB_DEV, USB_GPIB_READ, strlen(USB_GPIB_READ));
- if (retval < 0)
- goto read_return;
-
- if (one_char(board, &b) != DLE || one_char(board, &b) != STX) {
- dev_err(board->gpib_dev, "wrong <DLE><STX> sequence\n");
- retval = -EIO;
- goto read_return;
- }
-
- /* get data flow */
-
- while (1) {
- ic = one_char(board, &b);
- if (ic == -EIO) {
- retval = -EIO;
- goto read_return;
- }
- c = ic;
-
- if (c == DLE)
- nc = one_char(board, &b);
- if (c != DLE || nc == DLE) {
- /* data byte - store into buffer */
-
- if (*bytes_read == length)
- break; /* data overflow */
- if (c == DLE)
- c = nc;
- buffer[(*bytes_read)++] = c;
- if (c == pd->eos) {
- *end = 1;
- break;
- }
-
- } else {
- /* we are in the closing <DLE><ETX> sequence */
- c = nc;
- if (c == ETX) {
- c = one_char(board, &b);
- if (c == ACK) {
- *end = 1;
- retval = 0;
- goto read_return;
- } else {
- dev_err(board->gpib_dev, "wrong end of message %x", c);
- retval = -ETIME;
- goto read_return;
- }
- } else {
- dev_err(board->gpib_dev, "lone <DLE> in stream");
- retval = -EIO;
- goto read_return;
- }
- }
- }
-
- /* we had a data overflow - flush excess data */
-
- while (read_count--) {
- if (one_char(board, &b) != DLE)
- continue;
- c = one_char(board, &b);
- if (c == DLE)
- continue;
- if (c == ETX) {
- c = one_char(board, &b);
- if (c == ACK) {
- if (MAX_READ_EXCESS - read_count > 1)
- dev_dbg(board->gpib_dev, "small buffer - maybe some data lost");
- retval = 0;
- goto read_return;
- }
- break;
- }
- }
-
- dev_err(board->gpib_dev, "no input end - board in odd state\n");
- retval = -EIO;
-
-read_return:
- kfree(b.inbuf);
-
- DIA_LOG(1, "done with byte/status: %d %x %d\n", (int)*bytes_read, retval, *end);
-
- if (retval == 0 || retval == -ETIME) {
- if (send_command(board, USB_GPIB_UNTALK, sizeof(USB_GPIB_UNTALK)) == 0x06)
- return retval;
- return -EIO;
- }
-
- return retval;
-}
-
-/* remote_enable */
-
-static void usb_gpib_remote_enable(struct gpib_board *board, int enable)
-{
- int retval;
-
- retval = set_control_line(board, IB_BUS_REN, enable ? 1 : 0);
- if (retval != ACK)
- dev_err(board->gpib_dev, "could not set REN line: %x\n", retval);
-
- DIA_LOG(1, "done with %x\n", retval);
-}
-
-/* request_system_control */
-
-static int usb_gpib_request_system_control(struct gpib_board *board, int request_control)
-{
- if (!request_control)
- return -EINVAL;
-
- DIA_LOG(1, "done with %d -> %lx\n", request_control, board->status);
- return 0;
-}
-
-/* take_control */
-/* beware: the sync flag is ignored; what is its real meaning? */
-
-static int usb_gpib_take_control(struct gpib_board *board, int sync)
-{
- int retval;
-
- retval = set_control_line(board, IB_BUS_ATN, 1);
-
- DIA_LOG(1, "done with %d %x\n", sync, retval);
-
- if (retval == ACK)
- return 0;
- return -EIO;
-}
-
-/* update_status */
-
-static unsigned int usb_gpib_update_status(struct gpib_board *board,
- unsigned int clear_mask)
-{
- /* There is nothing we can do here, I guess */
-
- board->status &= ~clear_mask;
-
- DIA_LOG(1, "done with %x %lx\n", clear_mask, board->status);
-
- return board->status;
-}
-
-/* write */
-/* beware: DLE characters are not escaped - can only send ASCII data */
-
-static int usb_gpib_write(struct gpib_board *board,
- u8 *buffer,
- size_t length,
- int send_eoi,
- size_t *bytes_written)
-{
- int retval;
- char *msg;
-
- DIA_LOG(1, "enter %p -> %zu\n", board, length);
-
- set_timeout(board);
-
- msg = kmalloc(length + 8, GFP_KERNEL);
- if (!msg)
- return -ENOMEM;
-
- memcpy(msg, "\nIB\020\002", 5);
- memcpy(msg + 5, buffer, length);
- memcpy(msg + 5 + length, "\020\003\n", 3);
-
- retval = send_command(board, msg, length + 8);
- kfree(msg);
-
- DIA_LOG(1, "<%.*s> -> %x\n", (int)length, buffer, retval);
-
- if (retval != ACK)
- return -EPIPE;
-
- *bytes_written = length;
-
- if (send_command(board, USB_GPIB_UNLISTEN, sizeof(USB_GPIB_UNLISTEN)) != 0x06)
- return -EPIPE;
-
- return length;
-}
-
-/*
- * *** following functions not implemented yet ***
- */
-
-/* parallel_poll configure */
-
-static void usb_gpib_parallel_poll_configure(struct gpib_board *board,
- u8 configuration)
-{
-}
-
-/* parallel_poll_response */
-
-static void usb_gpib_parallel_poll_response(struct gpib_board *board, int ist)
-{
-}
-
-/* primary_address */
-
-static int usb_gpib_primary_address(struct gpib_board *board, unsigned int address)
-{
- return 0;
-}
-
-/* return_to_local */
-
-static void usb_gpib_return_to_local(struct gpib_board *board)
-{
-}
-
-/* secondary_address */
-
-static int usb_gpib_secondary_address(struct gpib_board *board,
- unsigned int address,
- int enable)
-{
- return 0;
-}
-
-/* serial_poll_response */
-
-static void usb_gpib_serial_poll_response(struct gpib_board *board, u8 status)
-{
-}
-
-/* serial_poll_status */
-
-static u8 usb_gpib_serial_poll_status(struct gpib_board *board)
-{
- return 0;
-}
-
-/* t1_delay */
-
-static int usb_gpib_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- return 0;
-}
-
-/*
- * *** module dispatch table and init/exit functions ***
- */
-
-static struct gpib_interface usb_gpib_interface = {
- .name = NAME,
- .attach = usb_gpib_attach,
- .detach = usb_gpib_detach,
- .read = usb_gpib_read,
- .write = usb_gpib_write,
- .command = usb_gpib_command,
- .take_control = usb_gpib_take_control,
- .go_to_standby = usb_gpib_go_to_standby,
- .request_system_control = usb_gpib_request_system_control,
- .interface_clear = usb_gpib_interface_clear,
- .remote_enable = usb_gpib_remote_enable,
- .enable_eos = usb_gpib_enable_eos,
- .disable_eos = usb_gpib_disable_eos,
- .parallel_poll = usb_gpib_parallel_poll,
- .parallel_poll_configure = usb_gpib_parallel_poll_configure,
- .parallel_poll_response = usb_gpib_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = usb_gpib_line_status,
- .update_status = usb_gpib_update_status,
- .primary_address = usb_gpib_primary_address,
- .secondary_address = usb_gpib_secondary_address,
- .serial_poll_response = usb_gpib_serial_poll_response,
- .serial_poll_status = usb_gpib_serial_poll_status,
- .t1_delay = usb_gpib_t1_delay,
- .return_to_local = usb_gpib_return_to_local,
- .skip_check_for_command_acceptors = 1
-};
-
-/*
- * usb_gpib_init_module(), usb_gpib_exit_module()
- *
- * This functions are called every time a new device is detected
- * and registered or is removed and unregistered.
- * We must take note of created and destroyed usb minors to be used
- * when usb_gpib_attach() and usb_gpib_detach() will be called on
- * request by gpib_config.
- */
-
-static int usb_gpib_init_module(struct usb_interface *interface)
-{
- int j, mask, rv;
-
- rv = mutex_lock_interruptible(&minors_lock);
- if (rv < 0)
- return rv;
-
- if (!assigned_usb_minors) {
- rv = gpib_register_driver(&usb_gpib_interface, THIS_MODULE);
- if (rv) {
- pr_err("gpib_register_driver failed: error = %d\n", rv);
- goto exit;
- }
- } else {
- /*
- * check if minor is already registered - maybe useless, but if
- * it happens the code is inconsistent somewhere
- */
-
- for (j = 0 ; j < MAX_DEV ; j++) {
- if (usb_minors[j] == interface->minor && assigned_usb_minors & 1 << j) {
- pr_err("CODE BUG: USB minor %d registered at %d.\n",
- interface->minor, j);
- rv = -1;
- goto exit;
- }
- }
- }
-
- /* find a free slot */
-
- for (j = 0 ; j < MAX_DEV ; j++) {
- mask = 1 << j;
- if ((assigned_usb_minors & mask) == 0) {
- usb_minors[j] = interface->minor;
- lpvo_usb_interfaces[j] = interface;
- assigned_usb_minors |= mask;
- rv = 0;
- goto exit;
- }
- }
- pr_err("No slot available for interface %p minor %d\n", interface, interface->minor);
- rv = -1;
-
-exit:
- mutex_unlock(&minors_lock);
- return rv;
-}
-
-static void usb_gpib_exit_module(int minor)
-{
- int j;
-
- mutex_lock(&minors_lock);
- for (j = 0 ; j < MAX_DEV ; j++) {
- if (usb_minors[j] == minor && assigned_usb_minors & 1 << j) {
- assigned_usb_minors &= ~(1 << j);
- usb_minors[j] = -1;
- if (assigned_usb_minors == 0)
- gpib_unregister_driver(&usb_gpib_interface);
- goto exit;
- }
- }
- pr_err("CODE BUG: USB minor %d not found.\n", minor);
-
-exit:
- mutex_unlock(&minors_lock);
-}
-
-/*
- * Default latency time (16 msec) is too long.
- * We must use 1 msec (best); anyhow, no more than 5 msec.
- *
- * Defines and function taken and modified from the kernel tree
- * (see ftdi_sio.h and ftdi_sio.c).
- */
-
-#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
-#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER
-#define FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40
-#define WDR_TIMEOUT 5000 /* default urb timeout */
-#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */
-
-#define LATENCY_TIMER 1 /* use a small latency timer: 1 ... 5 msec */
-#define LATENCY_CHANNEL 0 /* channel selection in multichannel devices */
-static int write_latency_timer(struct usb_device *udev)
-{
- int rv = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
- FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
- LATENCY_TIMER, LATENCY_CHANNEL,
- NULL, 0, WDR_TIMEOUT);
- if (rv < 0)
- dev_err(&udev->dev, "Unable to write latency timer: %i\n", rv);
- return rv;
-}
-
-/*****************************************************************************
- * *
- * The following code is a modified version of the USB Skeleton driver *
- * written by Greg Kroah-Hartman and available in the kernel tree. *
- * *
- * Functions skel_open() and skel_release() have been rewritten and named *
- * skel_do_open() and skel_do_release() to process the attach and detach *
- * requests coming from gpib_config. *
- * *
- * Functions skel_read() and skel_write() have been split into a *
- * skel_do_read() and skel_do_write(), that cover the kernel stuff of read *
- * and write operations, and the original skel_read() and skel_write(), *
- * that handle communication with user space and call their _do_ companion. *
- * *
- * Only the _do_ versions are used by the lpvo_usb_gpib driver; other ones *
- * can be (optionally) maintained in the compilation to have direct access *
- * to a gpib controller for debug and diagnostics. *
- * *
- * To avoid collisions in names, devices in user space have been renamed *
- * lpvo_raw1, lpvo_raw2 .... and the usb driver has been renamed with the *
- * gpib module name. *
- * *
- *****************************************************************************/
-
-/*
- * USB Skeleton driver - 2.2
- *
- * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- *
- * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
- * but has been rewritten to be easier to read and use.
- */
-
-#include <linux/errno.h>
-#include <linux/kref.h>
-#include <linux/uaccess.h>
-#include <linux/mutex.h>
-
-/* Get a minor range for your devices from the usb maintainer */
-#define USB_SKEL_MINOR_BASE 192
-
-/* private defines */
-
-#define MAX_TRANSFER (PAGE_SIZE - 512)
-/*
- * MAX_TRANSFER is chosen so that the VM is not stressed by
- * allocations > PAGE_SIZE and the number of packets in a page
- * is an integer 512 is the largest possible packet on EHCI
- */
-
-#define WRITES_IN_FLIGHT 1 /* we do not want more than one pending write */
-#define USER_DEVICE 1 /* compile for device(s) in user space */
-
-/* Structure to hold all of our device specific stuff */
-struct usb_skel {
- struct usb_device *udev; /* the usb device for this device */
- struct usb_interface *interface; /* the interface for this device */
- struct semaphore limit_sem; /* limiting the number of writes in progress */
- struct usb_anchor submitted; /* in case need to retract our submissions */
- struct urb *bulk_in_urb; /* the urb to read data with */
- unsigned char *bulk_in_buffer; /* the buffer to receive data */
- size_t bulk_in_size; /* the size of the receive buffer */
- size_t bulk_in_filled; /* number of bytes in the buffer */
- size_t bulk_in_copied; /* already copied to user space */
- __u8 bulk_in_endpoint_addr; /* the address of the bulk in endpoint */
- __u8 bulk_out_endpoint_addr; /* the address of the bulk out endpoint */
- int errors; /* the last request tanked */
- bool ongoing_read; /* a read is going on */
- spinlock_t err_lock; /* lock for errors */
- struct kref kref;
- struct mutex io_mutex; /* synchronize I/O with disconnect */
- wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */
-};
-
-#define to_skel_dev(d) container_of(d, struct usb_skel, kref)
-
-static struct usb_driver skel_driver;
-static void skel_draw_down(struct usb_skel *dev);
-
-static void skel_delete(struct kref *kref)
-{
- struct usb_skel *dev = to_skel_dev(kref);
-
- usb_free_urb(dev->bulk_in_urb);
- usb_put_dev(dev->udev);
- kfree(dev->bulk_in_buffer);
- kfree(dev);
-}
-
-/*
- * skel_do_open() - to be called by usb_gpib_attach
- */
-
-static int skel_do_open(struct gpib_board *board, int subminor)
-{
- struct usb_skel *dev;
- struct usb_interface *interface;
- int retval = 0;
-
- interface = usb_find_interface(&skel_driver, subminor);
- if (!interface) {
- dev_err(board->gpib_dev, "can't find device for minor %d\n", subminor);
- retval = -ENODEV;
- goto exit;
- }
-
- dev = usb_get_intfdata(interface);
- if (!dev) {
- retval = -ENODEV;
- goto exit;
- }
-
- retval = usb_autopm_get_interface(interface);
- if (retval)
- goto exit;
-
- /* increment our usage count for the device */
- kref_get(&dev->kref);
-
- /* save our object in the file's private structure */
- GPIB_DEV = dev;
-
-exit:
- return retval;
-}
-
-/*
- * skel_do_release() - to be called by usb_gpib_detach
- */
-
-static int skel_do_release(struct gpib_board *board)
-{
- struct usb_skel *dev;
-
- dev = GPIB_DEV;
- if (!dev)
- return -ENODEV;
-
- /* allow the device to be autosuspended */
- mutex_lock(&dev->io_mutex);
- if (dev->interface)
- usb_autopm_put_interface(dev->interface);
- mutex_unlock(&dev->io_mutex);
-
- /* decrement the count on our device */
- kref_put(&dev->kref, skel_delete);
- return 0;
-}
-
-/*
- * read functions
- */
-
-static void skel_read_bulk_callback(struct urb *urb)
-{
- struct usb_skel *dev;
- unsigned long flags;
-
- dev = urb->context;
-
- spin_lock_irqsave(&dev->err_lock, flags);
- /* sync/async unlink faults aren't errors */
- if (urb->status) {
- if (!(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
- dev_err(&dev->interface->dev, "nonzero read bulk status received: %d\n",
- urb->status);
-
- dev->errors = urb->status;
- } else {
- dev->bulk_in_filled = urb->actual_length;
- }
- dev->ongoing_read = 0;
- spin_unlock_irqrestore(&dev->err_lock, flags);
-
- wake_up_interruptible(&dev->bulk_in_wait);
-}
-
-static int skel_do_read_io(struct usb_skel *dev, size_t count)
-{
- int rv;
-
- /* prepare a read */
- usb_fill_bulk_urb(dev->bulk_in_urb,
- dev->udev,
- usb_rcvbulkpipe(dev->udev,
- dev->bulk_in_endpoint_addr),
- dev->bulk_in_buffer,
- min(dev->bulk_in_size, count),
- skel_read_bulk_callback,
- dev);
- /* tell everybody to leave the URB alone */
- spin_lock_irq(&dev->err_lock);
- dev->ongoing_read = 1;
- spin_unlock_irq(&dev->err_lock);
-
- /* submit bulk in urb, which means no data to deliver */
- dev->bulk_in_filled = 0;
- dev->bulk_in_copied = 0;
-
- /* do it */
- rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
- if (rv < 0) {
- dev_err(&dev->interface->dev, "failed submitting read urb, error %d\n", rv);
- rv = (rv == -ENOMEM) ? rv : -EIO;
- spin_lock_irq(&dev->err_lock);
- dev->ongoing_read = 0;
- spin_unlock_irq(&dev->err_lock);
- }
-
- return rv;
-}
-
-/*
- * skel_do_read() - read operations from lpvo_usb_gpib
- */
-
-static ssize_t skel_do_read(struct usb_skel *dev, char *buffer, size_t count)
-{
- int rv;
- bool ongoing_io;
-
- /* if we cannot read at all, return EOF */
-
- if (!dev->bulk_in_urb || !count)
- return 0;
-
-restart: /* added to comply with ftdi timeout technique */
-
- /* no concurrent readers */
-
- rv = mutex_lock_interruptible(&dev->io_mutex);
- if (rv < 0)
- return rv;
-
- if (!dev->interface) { /* disconnect() was called */
- rv = -ENODEV;
- goto exit;
- }
-
-retry:
- /* if IO is under way, we must not touch things */
- spin_lock_irq(&dev->err_lock);
- ongoing_io = dev->ongoing_read;
- spin_unlock_irq(&dev->err_lock);
-
- if (ongoing_io) {
-// /* nonblocking IO shall not wait */
-// /* no file, no O_NONBLOCK; maybe provide when from user space */
-// if (file->f_flags & O_NONBLOCK) {
-// rv = -EAGAIN;
-// goto exit;
-// }
-
- /*
- * IO may take forever
- * hence wait in an interruptible state
- */
- rv = wait_event_interruptible(dev->bulk_in_wait, (!dev->ongoing_read));
- if (rv < 0)
- goto exit;
- }
-
- /* errors must be reported */
- rv = dev->errors;
- if (rv < 0) {
- /* any error is reported once */
- dev->errors = 0;
- /* to preserve notifications about reset */
- rv = (rv == -EPIPE) ? rv : -EIO;
- /* report it */
- goto exit;
- }
-
- /*
- * if the buffer is filled we may satisfy the read
- * else we need to start IO
- */
-
- if (dev->bulk_in_filled) {
- /* we had read data */
-
- size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
-// size_t chunk = min(available, count); /* compute chunk later */
- size_t chunk;
-
- if (!available) {
- /*
- * all data has been used
- * actual IO needs to be done
- */
- /*
- * it seems that requests for less than dev->bulk_in_size
- * are not accepted
- */
- rv = skel_do_read_io(dev, dev->bulk_in_size);
- if (rv < 0)
- goto exit;
- else
- goto retry;
- }
-
- /*
- * data is available - chunk tells us how much shall be copied
- */
-
- /*
- * Condition dev->bulk_in_copied > 0 maybe will never happen. In case,
- * signal the event and copy using the original procedure, i.e., copy
- * first two bytes also
- */
-
- if (dev->bulk_in_copied) {
- chunk = min(available, count);
- memcpy(buffer, dev->bulk_in_buffer + dev->bulk_in_copied, chunk);
- rv = chunk;
- dev->bulk_in_copied += chunk;
-
- /* copy discarding first two bytes that contain ftdi chip status */
-
- } else {
- /* account for two bytes to be discarded */
- chunk = min(available, count + 2);
- if (chunk < 2) {
- dev_err(&dev->udev->dev, "BAD READ - chunk: %zu\n", chunk);
- rv = -EIO;
- goto exit;
- }
-
- memcpy(buffer, dev->bulk_in_buffer + 2, chunk - 2);
- rv = chunk;
- dev->bulk_in_copied += chunk;
- }
-
- /*
- * if we are asked for more than we have,
- * we start IO but don't wait
- *
- * No, no read ahead allowed; if the case, more data will be
- * asked for by the lpvo_usb_gpib layer.
- */
-// if (available < count)
-// skel_do_read_io(dev, dev->bulk_in_size);
- } else {
- /* no data in the buffer */
- rv = skel_do_read_io(dev, dev->bulk_in_size);
- if (rv < 0)
- goto exit;
- else
- goto retry;
- }
-exit:
- mutex_unlock(&dev->io_mutex);
- if (rv == 2)
- goto restart; /* ftdi chip returns two status bytes after a latency anyhow */
-
- if (rv > 0)
- return rv - 2; /* account for 2 discarded bytes in a valid buffer */
- return rv;
-}
-
-/*
- * write functions
- */
-
-static void skel_write_bulk_callback(struct urb *urb)
-{
- struct usb_skel *dev;
- unsigned long flags;
-
- dev = urb->context;
-
- /* sync/async unlink faults aren't errors */
- if (urb->status) {
- if (!(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
- dev_err(&dev->interface->dev,
- "nonzero write bulk status received: %d\n", urb->status);
-
- spin_lock_irqsave(&dev->err_lock, flags);
- dev->errors = urb->status;
- spin_unlock_irqrestore(&dev->err_lock, flags);
- }
-
- /* free up our allocated buffer */
- usb_free_coherent(urb->dev, urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
- up(&dev->limit_sem);
-}
-
-/*
- * skel_do_write() - write operations from lpvo_usb_gpib
- */
-
-static ssize_t skel_do_write(struct usb_skel *dev, const char *buffer, size_t count)
-{
- int retval = 0;
- struct urb *urb = NULL;
- char *buf = NULL;
- size_t writesize = min_t(size_t, count, (size_t)MAX_TRANSFER);
-
- /* verify that we actually have some data to write */
- if (count == 0)
- goto exit;
-
- /*
- * limit the number of URBs in flight to stop a user from using up all
- * RAM
- */
- /* Only one URB is used, because we can't have a pending write() and go on */
-
-// if (!(file->f_flags & O_NONBLOCK)) { /* no NONBLOCK provided */
- if (down_interruptible(&dev->limit_sem)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-// } else {
-// if (down_trylock(&dev->limit_sem)) {
-// retval = -EAGAIN;
-// goto exit;
-// }
-// }
-
- spin_lock_irq(&dev->err_lock);
- retval = dev->errors;
- if (retval < 0) {
- /* any error is reported once */
- dev->errors = 0;
- /* to preserve notifications about reset */
- retval = (retval == -EPIPE) ? retval : -EIO;
- }
- spin_unlock_irq(&dev->err_lock);
- if (retval < 0)
- goto error;
-
- /* create a urb, and a buffer for it, and copy the data to the urb */
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- retval = -ENOMEM;
- goto error;
- }
-
- buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
- &urb->transfer_dma);
- if (!buf) {
- retval = -ENOMEM;
- goto error;
- }
-
- memcpy(buf, buffer, count);
-
- /* this lock makes sure we don't submit URBs to gone devices */
- mutex_lock(&dev->io_mutex);
- if (!dev->interface) { /* disconnect() was called */
- mutex_unlock(&dev->io_mutex);
- retval = -ENODEV;
- goto error;
- }
-
- /* initialize the urb properly */
- usb_fill_bulk_urb(urb, dev->udev,
- usb_sndbulkpipe(dev->udev, dev->bulk_out_endpoint_addr),
- buf, writesize, skel_write_bulk_callback, dev);
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- usb_anchor_urb(urb, &dev->submitted);
-
- /* send the data out the bulk port */
- retval = usb_submit_urb(urb, GFP_KERNEL);
- mutex_unlock(&dev->io_mutex);
- if (retval) {
- dev_err(&dev->interface->dev, "failed submitting write urb, error %d\n", retval);
- goto error_unanchor;
- }
-
- /*
- * release our reference to this urb, the USB core will eventually free
- * it entirely
- */
- usb_free_urb(urb);
-
- return writesize;
-
-error_unanchor:
- usb_unanchor_urb(urb);
-error:
- if (urb) {
- usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
- usb_free_urb(urb);
- }
- up(&dev->limit_sem);
-
-exit:
- return retval;
-}
-
-/*
- * services for the user space devices
- */
-
-#if USER_DEVICE /* conditional compilation of user space device */
-
-static int skel_flush(struct file *file, fl_owner_t id)
-{
- struct usb_skel *dev;
- int res;
-
- dev = file->private_data;
- if (!dev)
- return -ENODEV;
-
- /* wait for io to stop */
- mutex_lock(&dev->io_mutex);
- skel_draw_down(dev);
-
- /* read out errors, leave subsequent opens a clean slate */
- spin_lock_irq(&dev->err_lock);
- res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0;
- dev->errors = 0;
- spin_unlock_irq(&dev->err_lock);
-
- mutex_unlock(&dev->io_mutex);
-
- return res;
-}
-
-static int skel_open(struct inode *inode, struct file *file)
-{
- struct usb_skel *dev;
- struct usb_interface *interface;
- int subminor;
- int retval = 0;
-
- subminor = iminor(inode);
-
- interface = usb_find_interface(&skel_driver, subminor);
- if (!interface) {
- pr_err("can't find device for minor %d\n", subminor);
- retval = -ENODEV;
- goto exit;
- }
-
- dev = usb_get_intfdata(interface);
- if (!dev) {
- retval = -ENODEV;
- goto exit;
- }
-
- retval = usb_autopm_get_interface(interface);
- if (retval)
- goto exit;
-
- /* increment our usage count for the device */
- kref_get(&dev->kref);
-
- /* save our object in the file's private structure */
- file->private_data = dev;
-
-exit:
- return retval;
-}
-
-static int skel_release(struct inode *inode, struct file *file)
-{
- struct usb_skel *dev;
-
- dev = file->private_data;
- if (!dev)
- return -ENODEV;
-
- /* allow the device to be autosuspended */
- mutex_lock(&dev->io_mutex);
- if (dev->interface)
- usb_autopm_put_interface(dev->interface);
- mutex_unlock(&dev->io_mutex);
-
- /* decrement the count on our device */
- kref_put(&dev->kref, skel_delete);
- return 0;
-}
-
-/*
- * user space access to read function
- */
-
-static ssize_t skel_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
-{
- struct usb_skel *dev;
- char *buf;
- ssize_t rv;
-
- dev = file->private_data;
-
- buf = kmalloc(count, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- rv = skel_do_read(dev, buf, count);
-
- if (rv > 0) {
- if (copy_to_user(buffer, buf, rv)) {
- kfree(buf);
- return -EFAULT;
- }
- }
- kfree(buf);
- return rv;
-}
-
-/*
- * user space access to write function
- */
-
-static ssize_t skel_write(struct file *file, const char __user *user_buffer,
- size_t count, loff_t *ppos)
-{
- struct usb_skel *dev;
- char *buf;
- ssize_t rv;
-
- dev = file->private_data;
-
- buf = kmalloc(count, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (copy_from_user(buf, user_buffer, count)) {
- kfree(buf);
- return -EFAULT;
- }
-
- rv = skel_do_write(dev, buf, count);
- kfree(buf);
- return rv;
-}
-#endif
-
-static const struct file_operations skel_fops = {
- .owner = THIS_MODULE,
-#if USER_DEVICE
- .read = skel_read,
- .write = skel_write,
- .open = skel_open,
- .release = skel_release,
- .flush = skel_flush,
- .llseek = noop_llseek,
-#endif
-};
-
-/*
- * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with the driver core
- */
-#if USER_DEVICE
-static struct usb_class_driver skel_class = {
- .name = "lpvo_raw%d",
- .fops = &skel_fops,
- .minor_base = USB_SKEL_MINOR_BASE,
-};
-#endif
-
-static int skel_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_skel *dev;
- struct usb_endpoint_descriptor *bulk_in, *bulk_out;
- int retval;
- char *device_path;
-
- mutex_init(&minors_lock); /* required for handling minor numbers table */
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- kref_init(&dev->kref);
- sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
- mutex_init(&dev->io_mutex);
- spin_lock_init(&dev->err_lock);
- init_usb_anchor(&dev->submitted);
- init_waitqueue_head(&dev->bulk_in_wait);
-
- dev->udev = usb_get_dev(interface_to_usbdev(interface));
- dev->interface = interface;
-
- /* set up the endpoint information */
- /* use only the first bulk-in and bulk-out endpoints */
- retval = usb_find_common_endpoints(interface->cur_altsetting,
- &bulk_in, &bulk_out, NULL, NULL);
- if (retval) {
- dev_err(&interface->dev,
- "Could not find both bulk-in and bulk-out endpoints\n");
- goto error;
- }
-
- dev->bulk_in_size = usb_endpoint_maxp(bulk_in);
- dev->bulk_in_endpoint_addr = bulk_in->bEndpointAddress;
- dev->bulk_in_buffer = kmalloc(dev->bulk_in_size, GFP_KERNEL);
- if (!dev->bulk_in_buffer) {
- retval = -ENOMEM;
- goto error;
- }
- dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->bulk_in_urb) {
- retval = -ENOMEM;
- goto error;
- }
-
- dev->bulk_out_endpoint_addr = bulk_out->bEndpointAddress;
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- /* let the world know */
-
- device_path = kobject_get_path(&dev->udev->dev.kobj, GFP_KERNEL);
- dev_dbg(&interface->dev, "New lpvo_usb_device -> bus: %d dev: %d path: %s\n",
- dev->udev->bus->busnum, dev->udev->devnum, device_path);
- kfree(device_path);
-
-#if USER_DEVICE
- /* we can register the device now, as it is ready */
- retval = usb_register_dev(interface, &skel_class);
- if (retval) {
- /* something prevented us from registering this driver */
- dev_err(&interface->dev,
- "Not able to get a minor for this device.\n");
- usb_set_intfdata(interface, NULL);
- goto error;
- }
-#endif
-
- write_latency_timer(dev->udev); /* adjust the latency timer */
-
- usb_gpib_init_module(interface); /* last, init the lpvo for this minor */
-
- return 0;
-
-error:
- /* this frees allocated memory */
- kref_put(&dev->kref, skel_delete);
-
- return retval;
-}
-
-static void skel_disconnect(struct usb_interface *interface)
-{
- struct usb_skel *dev;
- int minor = interface->minor;
-
- usb_gpib_exit_module(minor); /* first, disactivate the lpvo */
-
- dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
-#if USER_DEVICE
- /* give back our minor */
- usb_deregister_dev(interface, &skel_class);
-#endif
-
- /* prevent more I/O from starting */
- mutex_lock(&dev->io_mutex);
- dev->interface = NULL;
- mutex_unlock(&dev->io_mutex);
-
- usb_kill_anchored_urbs(&dev->submitted);
-
- /* decrement our usage count */
- kref_put(&dev->kref, skel_delete);
-}
-
-static void skel_draw_down(struct usb_skel *dev)
-{
- int time;
-
- time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
- if (!time)
- usb_kill_anchored_urbs(&dev->submitted);
- usb_kill_urb(dev->bulk_in_urb);
-}
-
-static int skel_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct usb_skel *dev = usb_get_intfdata(intf);
-
- if (!dev)
- return 0;
- skel_draw_down(dev);
- return 0;
-}
-
-static int skel_resume(struct usb_interface *intf)
-{
- return 0;
-}
-
-static int skel_pre_reset(struct usb_interface *intf)
-{
- struct usb_skel *dev = usb_get_intfdata(intf);
-
- mutex_lock(&dev->io_mutex);
- skel_draw_down(dev);
-
- return 0;
-}
-
-static int skel_post_reset(struct usb_interface *intf)
-{
- struct usb_skel *dev = usb_get_intfdata(intf);
-
- /* we are sure no URBs are active - no locking needed */
- dev->errors = -EPIPE;
- mutex_unlock(&dev->io_mutex);
-
- return 0;
-}
-
-static struct usb_driver skel_driver = {
- .name = NAME,
- .probe = skel_probe,
- .disconnect = skel_disconnect,
- .suspend = skel_suspend,
- .resume = skel_resume,
- .pre_reset = skel_pre_reset,
- .post_reset = skel_post_reset,
- .id_table = skel_table,
- .supports_autosuspend = 1,
-};
-
-module_usb_driver(skel_driver);
diff --git a/drivers/staging/gpib/nec7210/Makefile b/drivers/staging/gpib/nec7210/Makefile
deleted file mode 100644
index 64330f2e89d1..000000000000
--- a/drivers/staging/gpib/nec7210/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-obj-$(CONFIG_GPIB_NEC7210) += nec7210.o
-
-
diff --git a/drivers/staging/gpib/nec7210/board.h b/drivers/staging/gpib/nec7210/board.h
deleted file mode 100644
index ac3fe38ade57..000000000000
--- a/drivers/staging/gpib/nec7210/board.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_PCIIA_BOARD_H
-#define _GPIB_PCIIA_BOARD_H
-
-#include "gpibP.h"
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-
-#include "nec7210.h"
-
-#endif //_GPIB_PCIIA_BOARD_H
-
diff --git a/drivers/staging/gpib/nec7210/nec7210.c b/drivers/staging/gpib/nec7210/nec7210.c
deleted file mode 100644
index bbf39367f5e4..000000000000
--- a/drivers/staging/gpib/nec7210/nec7210.c
+++ /dev/null
@@ -1,1121 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include "board.h"
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/dma.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB library code for NEC uPD7210");
-
-int nec7210_enable_eos(struct gpib_board *board, struct nec7210_priv *priv, u8 eos_byte,
- int compare_8_bits)
-{
- write_byte(priv, eos_byte, EOSR);
- priv->auxa_bits |= HR_REOS;
- if (compare_8_bits)
- priv->auxa_bits |= HR_BIN;
- else
- priv->auxa_bits &= ~HR_BIN;
- write_byte(priv, priv->auxa_bits, AUXMR);
- return 0;
-}
-EXPORT_SYMBOL(nec7210_enable_eos);
-
-void nec7210_disable_eos(struct gpib_board *board, struct nec7210_priv *priv)
-{
- priv->auxa_bits &= ~HR_REOS;
- write_byte(priv, priv->auxa_bits, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_disable_eos);
-
-int nec7210_parallel_poll(struct gpib_board *board, struct nec7210_priv *priv, u8 *result)
-{
- int ret;
-
- clear_bit(COMMAND_READY_BN, &priv->state);
-
- // execute parallel poll
- write_byte(priv, AUX_EPP, AUXMR);
- // wait for result FIXME: support timeouts
- ret = wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state));
- if (ret) {
- dev_dbg(board->gpib_dev, "gpib: parallel poll interrupted\n");
- return -ERESTARTSYS;
- }
- *result = read_byte(priv, CPTR);
-
- return 0;
-}
-EXPORT_SYMBOL(nec7210_parallel_poll);
-
-void nec7210_parallel_poll_configure(struct gpib_board *board,
- struct nec7210_priv *priv, unsigned int configuration)
-{
- write_byte(priv, PPR | configuration, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_parallel_poll_configure);
-
-void nec7210_parallel_poll_response(struct gpib_board *board, struct nec7210_priv *priv, int ist)
-{
- if (ist)
- write_byte(priv, AUX_SPPF, AUXMR);
- else
- write_byte(priv, AUX_CPPF, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_parallel_poll_response);
-/*
- * This is really only adequate for chips that do a 488.2 style reqt/reqf
- * based on bit 6 of the SPMR (see chapter 11.3.3 of 488.2). For simpler chips that simply
- * set rsv directly based on bit 6, we either need to do more hardware setup to expose
- * the 488.2 capability (for example with NI chips), or we need to implement the
- * 488.2 set srv state machine in the driver (if that is even viable).
- */
-void nec7210_serial_poll_response(struct gpib_board *board,
- struct nec7210_priv *priv, u8 status)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
- if (status & request_service_bit) {
- priv->srq_pending = 1;
- clear_bit(SPOLL_NUM, &board->status);
-
- } else {
- priv->srq_pending = 0;
- }
- write_byte(priv, status, SPMR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-EXPORT_SYMBOL(nec7210_serial_poll_response);
-
-u8 nec7210_serial_poll_status(struct gpib_board *board, struct nec7210_priv *priv)
-{
- return read_byte(priv, SPSR);
-}
-EXPORT_SYMBOL(nec7210_serial_poll_status);
-
-int nec7210_primary_address(const struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int address)
-{
- // put primary address in address0
- write_byte(priv, address & ADDRESS_MASK, ADR);
- return 0;
-}
-EXPORT_SYMBOL(nec7210_primary_address);
-
-int nec7210_secondary_address(const struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int address, int enable)
-{
- if (enable) {
- // put secondary address in address1
- write_byte(priv, HR_ARS | (address & ADDRESS_MASK), ADR);
- // go to address mode 2
- priv->reg_bits[ADMR] &= ~HR_ADM0;
- priv->reg_bits[ADMR] |= HR_ADM1;
- } else {
- // disable address1 register
- write_byte(priv, HR_ARS | HR_DT | HR_DL, ADR);
- // go to address mode 1
- priv->reg_bits[ADMR] |= HR_ADM0;
- priv->reg_bits[ADMR] &= ~HR_ADM1;
- }
- write_byte(priv, priv->reg_bits[ADMR], ADMR);
- return 0;
-}
-EXPORT_SYMBOL(nec7210_secondary_address);
-
-static void update_talker_state(struct nec7210_priv *priv, unsigned int address_status_bits)
-{
- if ((address_status_bits & HR_TA)) {
- if ((address_status_bits & HR_NATN)) {
- if (address_status_bits & HR_SPMS)
- priv->talker_state = serial_poll_active;
- else
- priv->talker_state = talker_active;
- } else {
- priv->talker_state = talker_addressed;
- }
- } else {
- priv->talker_state = talker_idle;
- }
-}
-
-static void update_listener_state(struct nec7210_priv *priv, unsigned int address_status_bits)
-{
- if (address_status_bits & HR_LA) {
- if ((address_status_bits & HR_NATN))
- priv->listener_state = listener_active;
- else
- priv->listener_state = listener_addressed;
- } else {
- priv->listener_state = listener_idle;
- }
-}
-
-unsigned int nec7210_update_status_nolock(struct gpib_board *board, struct nec7210_priv *priv)
-{
- int address_status_bits;
- u8 spoll_status;
-
- if (!priv)
- return 0;
-
- address_status_bits = read_byte(priv, ADSR);
- if (address_status_bits & HR_CIC)
- set_bit(CIC_NUM, &board->status);
- else
- clear_bit(CIC_NUM, &board->status);
- // check for talker/listener addressed
- update_talker_state(priv, address_status_bits);
- if (priv->talker_state == talker_active || priv->talker_state == talker_addressed)
- set_bit(TACS_NUM, &board->status);
- else
- clear_bit(TACS_NUM, &board->status);
- update_listener_state(priv, address_status_bits);
- if (priv->listener_state == listener_active ||
- priv->listener_state == listener_addressed)
- set_bit(LACS_NUM, &board->status);
- else
- clear_bit(LACS_NUM, &board->status);
- if (address_status_bits & HR_NATN)
- clear_bit(ATN_NUM, &board->status);
- else
- set_bit(ATN_NUM, &board->status);
- spoll_status = nec7210_serial_poll_status(board, priv);
- if (priv->srq_pending && (spoll_status & request_service_bit) == 0) {
- priv->srq_pending = 0;
- set_bit(SPOLL_NUM, &board->status);
- }
-
- /*
- * we rely on the interrupt handler to set the
- * rest of the status bits
- */
-
- return board->status;
-}
-EXPORT_SYMBOL(nec7210_update_status_nolock);
-
-unsigned int nec7210_update_status(struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int clear_mask)
-{
- unsigned long flags;
- unsigned int retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- board->status &= ~clear_mask;
- retval = nec7210_update_status_nolock(board, priv);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_update_status);
-
-unsigned int nec7210_set_reg_bits(struct nec7210_priv *priv, unsigned int reg,
- unsigned int mask, unsigned int bits)
-{
- priv->reg_bits[reg] &= ~mask;
- priv->reg_bits[reg] |= mask & bits;
- write_byte(priv, priv->reg_bits[reg], reg);
- return priv->reg_bits[reg];
-}
-EXPORT_SYMBOL(nec7210_set_reg_bits);
-
-void nec7210_set_handshake_mode(struct gpib_board *board, struct nec7210_priv *priv, int mode)
-{
- unsigned long flags;
-
- mode &= HR_HANDSHAKE_MASK;
-
- spin_lock_irqsave(&board->spinlock, flags);
- if ((priv->auxa_bits & HR_HANDSHAKE_MASK) != mode) {
- priv->auxa_bits &= ~HR_HANDSHAKE_MASK;
- priv->auxa_bits |= mode;
- write_byte(priv, priv->auxa_bits, AUXMR);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-EXPORT_SYMBOL(nec7210_set_handshake_mode);
-
-u8 nec7210_read_data_in(struct gpib_board *board, struct nec7210_priv *priv, int *end)
-{
- unsigned long flags;
- u8 data;
-
- spin_lock_irqsave(&board->spinlock, flags);
- data = read_byte(priv, DIR);
- clear_bit(READ_READY_BN, &priv->state);
- if (test_and_clear_bit(RECEIVED_END_BN, &priv->state))
- *end = 1;
- else
- *end = 0;
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return data;
-}
-EXPORT_SYMBOL(nec7210_read_data_in);
-
-int nec7210_take_control(struct gpib_board *board, struct nec7210_priv *priv, int syncronous)
-{
- int i;
- const int timeout = 100;
- int retval = 0;
- unsigned int adsr_bits = 0;
-
- if (syncronous)
- write_byte(priv, AUX_TCS, AUXMR);
- else
- write_byte(priv, AUX_TCA, AUXMR);
- // busy wait until ATN is asserted
- for (i = 0; i < timeout; i++) {
- adsr_bits = read_byte(priv, ADSR);
- if ((adsr_bits & HR_NATN) == 0)
- break;
- udelay(1);
- }
- if (i == timeout)
- return -ETIMEDOUT;
-
- clear_bit(WRITE_READY_BN, &priv->state);
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_take_control);
-
-int nec7210_go_to_standby(struct gpib_board *board, struct nec7210_priv *priv)
-{
- int i;
- const int timeout = 1000;
- unsigned int adsr_bits = 0;
- int retval = 0;
-
- write_byte(priv, AUX_GTS, AUXMR);
- // busy wait until ATN is released
- for (i = 0; i < timeout; i++) {
- adsr_bits = read_byte(priv, ADSR);
- if (adsr_bits & HR_NATN)
- break;
- udelay(1);
- }
- // if busy wait has failed, try sleeping
- if (i == timeout) {
- for (i = 0; i < HZ; i++) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(1))
- return -ERESTARTSYS;
- adsr_bits = read_byte(priv, ADSR);
- if (adsr_bits & HR_NATN)
- break;
- }
- if (i == HZ)
- return -ETIMEDOUT;
- }
-
- clear_bit(COMMAND_READY_BN, &priv->state);
- return retval;
-}
-EXPORT_SYMBOL(nec7210_go_to_standby);
-
-int nec7210_request_system_control(struct gpib_board *board, struct nec7210_priv *priv,
- int request_control)
-{
- if (request_control == 0) {
- write_byte(priv, AUX_CREN, AUXMR);
- write_byte(priv, AUX_CIFC, AUXMR);
- write_byte(priv, AUX_DSC, AUXMR);
- }
- return 0;
-}
-EXPORT_SYMBOL(nec7210_request_system_control);
-
-void nec7210_interface_clear(struct gpib_board *board, struct nec7210_priv *priv, int assert)
-{
- if (assert)
- write_byte(priv, AUX_SIFC, AUXMR);
- else
- write_byte(priv, AUX_CIFC, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_interface_clear);
-
-void nec7210_remote_enable(struct gpib_board *board, struct nec7210_priv *priv, int enable)
-{
- if (enable)
- write_byte(priv, AUX_SREN, AUXMR);
- else
- write_byte(priv, AUX_CREN, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_remote_enable);
-
-void nec7210_release_rfd_holdoff(struct gpib_board *board, struct nec7210_priv *priv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
- if (test_bit(RFD_HOLDOFF_BN, &priv->state) &&
- test_bit(READ_READY_BN, &priv->state) == 0) {
- write_byte(priv, AUX_FH, AUXMR);
- clear_bit(RFD_HOLDOFF_BN, &priv->state);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-EXPORT_SYMBOL(nec7210_release_rfd_holdoff);
-
-int nec7210_t1_delay(struct gpib_board *board, struct nec7210_priv *priv,
- unsigned int nano_sec)
-{
- unsigned int retval;
-
- if (nano_sec <= 500) {
- priv->auxb_bits |= HR_TRI;
- retval = 500;
- } else {
- priv->auxb_bits &= ~HR_TRI;
- retval = 2000;
- }
- write_byte(priv, priv->auxb_bits, AUXMR);
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_t1_delay);
-
-void nec7210_return_to_local(const struct gpib_board *board, struct nec7210_priv *priv)
-{
- write_byte(priv, AUX_RTL, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_return_to_local);
-
-static inline short nec7210_atn_has_changed(struct gpib_board *board, struct nec7210_priv *priv)
-{
- short address_status_bits = read_byte(priv, ADSR);
-
- if (address_status_bits & HR_NATN) {
- if (test_bit(ATN_NUM, &board->status))
- return 1;
- else
- return 0;
- } else {
- if (test_bit(ATN_NUM, &board->status))
- return 0;
- else
- return 1;
- }
- return -1;
-}
-
-int nec7210_command(struct gpib_board *board, struct nec7210_priv *priv, u8
- *buffer, size_t length, size_t *bytes_written)
-{
- int retval = 0;
- unsigned long flags;
-
- *bytes_written = 0;
-
- clear_bit(BUS_ERROR_BN, &priv->state);
-
- while (*bytes_written < length) {
- if (wait_event_interruptible(board->wait,
- test_bit(COMMAND_READY_BN, &priv->state) ||
- test_bit(BUS_ERROR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- dev_dbg(board->gpib_dev, "command wait interrupted\n");
- retval = -ERESTARTSYS;
- break;
- }
- if (test_bit(TIMO_NUM, &board->status))
- break;
- if (test_and_clear_bit(BUS_ERROR_BN, &priv->state))
- break;
- spin_lock_irqsave(&board->spinlock, flags);
- clear_bit(COMMAND_READY_BN, &priv->state);
- write_byte(priv, buffer[*bytes_written], CDOR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- ++(*bytes_written);
-
- if (need_resched())
- schedule();
- }
- // wait for last byte to get sent
- if (wait_event_interruptible(board->wait, test_bit(COMMAND_READY_BN, &priv->state) ||
- test_bit(BUS_ERROR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
-
- if (test_and_clear_bit(BUS_ERROR_BN, &priv->state))
- retval = -EIO;
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_command);
-
-static int pio_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
-
- *bytes_read = 0;
- *end = 0;
-
- while (*bytes_read < length) {
- if (wait_event_interruptible(board->wait,
- test_bit(READ_READY_BN, &priv->state) ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- break;
- }
- if (test_bit(READ_READY_BN, &priv->state)) {
- if (*bytes_read == 0) {
- /*
- * We set the handshake mode here because we know
- * no new bytes will arrive (it has already arrived
- * and is awaiting being read out of the chip) while we are changing
- * modes. This ensures we can reliably keep track
- * of the holdoff state.
- */
- nec7210_set_handshake_mode(board, priv, HR_HLDA);
- }
- buffer[(*bytes_read)++] = nec7210_read_data_in(board, priv, end);
- if (*end)
- break;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &priv->state)) {
- retval = -EINTR;
- break;
- }
-
- if (*bytes_read < length)
- nec7210_release_rfd_holdoff(board, priv);
-
- if (need_resched())
- schedule();
- }
- return retval;
-}
-
-#ifdef NEC_DMA
-static ssize_t __dma_read(struct gpib_board *board, struct nec7210_priv *priv, size_t length)
-{
- ssize_t retval = 0;
- size_t count = 0;
- unsigned long flags, dma_irq_flags;
-
- if (length == 0)
- return 0;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- dma_irq_flags = claim_dma_lock();
- disable_dma(priv->dma_channel);
- /* program dma controller */
- clear_dma_ff(priv->dma_channel);
- set_dma_count(priv->dma_channel, length);
- set_dma_addr(priv->dma_channel, priv->dma_buffer_addr);
- set_dma_mode(priv->dma_channel, DMA_MODE_READ);
- release_dma_lock(dma_irq_flags);
-
- enable_dma(priv->dma_channel);
-
- set_bit(DMA_READ_IN_PROGRESS_BN, &priv->state);
- clear_bit(READ_READY_BN, &priv->state);
-
- // enable nec7210 dma
- nec7210_set_reg_bits(priv, IMR2, HR_DMAI, HR_DMAI);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- // wait for data to transfer
- if (wait_event_interruptible(board->wait,
- test_bit(DMA_READ_IN_PROGRESS_BN, &priv->state) == 0 ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &priv->state))
- retval = -EINTR;
-
- // disable nec7210 dma
- nec7210_set_reg_bits(priv, IMR2, HR_DMAI, 0);
-
- // record how many bytes we transferred
- flags = claim_dma_lock();
- clear_dma_ff(priv->dma_channel);
- disable_dma(priv->dma_channel);
- count += length - get_dma_residue(priv->dma_channel);
- release_dma_lock(flags);
-
- return retval ? retval : count;
-}
-
-static ssize_t dma_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length)
-{
- size_t remain = length;
- size_t transfer_size;
- ssize_t retval = 0;
-
- while (remain > 0) {
- transfer_size = (priv->dma_buffer_length < remain) ?
- priv->dma_buffer_length : remain;
- retval = __dma_read(board, priv, transfer_size);
- if (retval < 0)
- break;
- memcpy(buffer, priv->dma_buffer, transfer_size);
- remain -= retval;
- buffer += retval;
- if (test_bit(RECEIVED_END_BN, &priv->state))
- break;
- }
-
- if (retval < 0)
- return retval;
-
- return length - remain;
-}
-#endif
-
-int nec7210_read(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
-
- *end = 0;
- *bytes_read = 0;
-
- if (length == 0)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &priv->state); // XXX wrong
-
- nec7210_release_rfd_holdoff(board, priv);
-
- retval = pio_read(board, priv, buffer, length, end, bytes_read);
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_read);
-
-static int pio_write_wait(struct gpib_board *board, struct nec7210_priv *priv,
- short wake_on_lacs, short wake_on_atn, short wake_on_bus_error)
-{
- // wait until byte is ready to be sent
- if (wait_event_interruptible(board->wait,
- (test_bit(TACS_NUM, &board->status) &&
- test_bit(WRITE_READY_BN, &priv->state)) ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- (wake_on_bus_error && test_bit(BUS_ERROR_BN, &priv->state)) ||
- (wake_on_lacs && test_bit(LACS_NUM, &board->status)) ||
- (wake_on_atn && test_bit(ATN_NUM, &board->status)) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
-
- if (test_bit(DEV_CLEAR_BN, &priv->state))
- return -EINTR;
-
- if (wake_on_bus_error && test_and_clear_bit(BUS_ERROR_BN, &priv->state))
- return -EIO;
-
- return 0;
-}
-
-static int pio_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- size_t last_count = 0;
- ssize_t retval = 0;
- unsigned long flags;
- const int max_bus_errors = (length > 1000) ? length : 1000;
- int bus_error_count = 0;
- *bytes_written = 0;
-
- clear_bit(BUS_ERROR_BN, &priv->state);
-
- while (*bytes_written < length) {
- if (need_resched())
- schedule();
-
- retval = pio_write_wait(board, priv, 0, 0, priv->type == NEC7210);
- if (retval == -EIO) {
- /* resend last byte on bus error */
- *bytes_written = last_count;
- /*
- * we can get unrecoverable bus errors,
- * so give up after a while
- */
- bus_error_count++;
- if (bus_error_count > max_bus_errors)
- return retval;
- continue;
- } else {
- if (retval < 0)
- return retval;
- }
- spin_lock_irqsave(&board->spinlock, flags);
- clear_bit(BUS_ERROR_BN, &priv->state);
- clear_bit(WRITE_READY_BN, &priv->state);
- last_count = *bytes_written;
- write_byte(priv, buffer[(*bytes_written)++], CDOR);
- spin_unlock_irqrestore(&board->spinlock, flags);
- }
- retval = pio_write_wait(board, priv, 1, 1, priv->type == NEC7210);
- return retval;
-}
-
-#ifdef NEC_DMA
-static ssize_t __dma_write(struct gpib_board *board, struct nec7210_priv *priv, dma_addr_t address,
- size_t length)
-{
- unsigned long flags, dma_irq_flags;
- int residue = 0;
- int retval = 0;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- /* program dma controller */
- dma_irq_flags = claim_dma_lock();
- disable_dma(priv->dma_channel);
- clear_dma_ff(priv->dma_channel);
- set_dma_count(priv->dma_channel, length);
- set_dma_addr(priv->dma_channel, address);
- set_dma_mode(priv->dma_channel, DMA_MODE_WRITE);
- enable_dma(priv->dma_channel);
- release_dma_lock(dma_irq_flags);
-
- // enable board's dma for output
- nec7210_set_reg_bits(priv, IMR2, HR_DMAO, HR_DMAO);
-
- clear_bit(WRITE_READY_BN, &priv->state);
- set_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state);
-
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- // suspend until message is sent
- if (wait_event_interruptible(board->wait,
- test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state) == 0 ||
- test_bit(BUS_ERROR_BN, &priv->state) ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_and_clear_bit(DEV_CLEAR_BN, &priv->state))
- retval = -EINTR;
- if (test_and_clear_bit(BUS_ERROR_BN, &priv->state))
- retval = -EIO;
-
- // disable board's dma
- nec7210_set_reg_bits(priv, IMR2, HR_DMAO, 0);
-
- dma_irq_flags = claim_dma_lock();
- clear_dma_ff(priv->dma_channel);
- disable_dma(priv->dma_channel);
- residue = get_dma_residue(priv->dma_channel);
- release_dma_lock(dma_irq_flags);
-
- if (residue)
- retval = -EPIPE;
-
- return retval ? retval : length;
-}
-
-static ssize_t dma_write(struct gpib_board *board, struct nec7210_priv *priv, u8 *buffer,
- size_t length)
-{
- size_t remain = length;
- size_t transfer_size;
- ssize_t retval = 0;
-
- while (remain > 0) {
- transfer_size = (priv->dma_buffer_length < remain) ?
- priv->dma_buffer_length : remain;
- memcpy(priv->dma_buffer, buffer, transfer_size);
- retval = __dma_write(board, priv, priv->dma_buffer_addr, transfer_size);
- if (retval < 0)
- break;
- remain -= retval;
- buffer += retval;
- }
-
- if (retval < 0)
- return retval;
-
- return length - remain;
-}
-#endif
-int nec7210_write(struct gpib_board *board, struct nec7210_priv *priv,
- u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- int retval = 0;
-
- *bytes_written = 0;
-
- clear_bit(DEV_CLEAR_BN, &priv->state); // XXX
-
- if (send_eoi)
- length-- ; // save the last byte for sending EOI
-
- if (length > 0) {
- // isa dma transfer
- if (0 /*priv->dma_channel*/) {
-/*
- * dma writes are unreliable since they can't recover from bus errors
- * (which happen when ATN is asserted in the middle of a write)
- */
-#ifdef NEC_DMA
- retval = dma_write(board, priv, buffer, length);
- if (retval < 0)
- return retval;
- count += retval;
-#endif
- } else { // PIO transfer
- size_t num_bytes;
-
- retval = pio_write(board, priv, buffer, length, &num_bytes);
-
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
- }
- if (send_eoi) {
- size_t num_bytes;
-
- /*
- * We need to wait to make sure we will immediately be able to write the data byte
- * into the chip before sending the associated AUX_SEOI command. This is really
- * only needed for length==1 since otherwise the earlier calls to pio_write
- * will have dont the wait already.
- */
- retval = pio_write_wait(board, priv, 0, 0, priv->type == NEC7210);
- if (retval < 0)
- return retval;
- /*send EOI */
- write_byte(priv, AUX_SEOI, AUXMR);
-
- retval = pio_write(board, priv, &buffer[*bytes_written], 1, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_write);
-
-/*
- * interrupt service routine
- */
-irqreturn_t nec7210_interrupt(struct gpib_board *board, struct nec7210_priv *priv)
-{
- int status1, status2;
-
- // read interrupt status (also clears status)
- status1 = read_byte(priv, ISR1);
- status2 = read_byte(priv, ISR2);
-
- return nec7210_interrupt_have_status(board, priv, status1, status2);
-}
-EXPORT_SYMBOL(nec7210_interrupt);
-
-irqreturn_t nec7210_interrupt_have_status(struct gpib_board *board,
- struct nec7210_priv *priv, int status1, int status2)
-{
-#ifdef NEC_DMA
- unsigned long dma_flags;
-#endif
- int retval = IRQ_NONE;
-
- // record service request in status
- if (status2 & HR_SRQI)
- set_bit(SRQI_NUM, &board->status);
-
- // change in lockout status
- if (status2 & HR_LOKC) {
- if (status2 & HR_LOK)
- set_bit(LOK_NUM, &board->status);
- else
- clear_bit(LOK_NUM, &board->status);
- }
-
- // change in remote status
- if (status2 & HR_REMC) {
- if (status2 & HR_REM)
- set_bit(REM_NUM, &board->status);
- else
- clear_bit(REM_NUM, &board->status);
- }
-
- // record reception of END
- if (status1 & HR_END) {
- set_bit(RECEIVED_END_BN, &priv->state);
- if ((priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDE)
- set_bit(RFD_HOLDOFF_BN, &priv->state);
- }
-
- // get incoming data in PIO mode
- if ((status1 & HR_DI)) {
- set_bit(READ_READY_BN, &priv->state);
- if ((priv->auxa_bits & HR_HANDSHAKE_MASK) == HR_HLDA)
- set_bit(RFD_HOLDOFF_BN, &priv->state);
- }
-#ifdef NEC_DMA
- // check for dma read transfer complete
- if (test_bit(DMA_READ_IN_PROGRESS_BN, &priv->state)) {
- dma_flags = claim_dma_lock();
- disable_dma(priv->dma_channel);
- clear_dma_ff(priv->dma_channel);
- if ((status1 & HR_END) || get_dma_residue(priv->dma_channel) == 0)
- clear_bit(DMA_READ_IN_PROGRESS_BN, &priv->state);
- else
- enable_dma(priv->dma_channel);
- release_dma_lock(dma_flags);
- }
-#endif
- if ((status1 & HR_DO)) {
- if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state) == 0)
- set_bit(WRITE_READY_BN, &priv->state);
-#ifdef NEC_DMA
- if (test_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state)) { // write data, isa dma mode
- // check if dma transfer is complete
- dma_flags = claim_dma_lock();
- disable_dma(priv->dma_channel);
- clear_dma_ff(priv->dma_channel);
- if (get_dma_residue(priv->dma_channel) == 0) {
- clear_bit(DMA_WRITE_IN_PROGRESS_BN, &priv->state);
- // XXX race? byte may still be in CDOR reg
- } else {
- clear_bit(WRITE_READY_BN, &priv->state);
- enable_dma(priv->dma_channel);
- }
- release_dma_lock(dma_flags);
- }
-#endif
- }
-
- // outgoing command can be sent
- if (status2 & HR_CO)
- set_bit(COMMAND_READY_BN, &priv->state);
-
- // command pass through received
- if (status1 & HR_CPT)
- write_byte(priv, AUX_NVAL, AUXMR);
-
- if (status1 & HR_ERR)
- set_bit(BUS_ERROR_BN, &priv->state);
-
- if (status1 & HR_DEC) {
- unsigned short address_status_bits = read_byte(priv, ADSR);
-
- // ignore device clear events if we are controller in charge
- if ((address_status_bits & HR_CIC) == 0) {
- push_gpib_event(board, EVENT_DEV_CLR);
- set_bit(DEV_CLEAR_BN, &priv->state);
- }
- }
-
- if (status1 & HR_DET)
- push_gpib_event(board, EVENT_DEV_TRG);
-
- // Addressing status has changed
- if (status2 & HR_ADSC)
- set_bit(ADR_CHANGE_BN, &priv->state);
-
- if ((status1 & priv->reg_bits[IMR1]) ||
- (status2 & (priv->reg_bits[IMR2] & IMR2_ENABLE_INTR_MASK)) ||
- nec7210_atn_has_changed(board, priv)) {
- nec7210_update_status_nolock(board, priv);
- dev_dbg(board->gpib_dev, "minor %i, stat %lx, isr1 0x%x, imr1 0x%x, isr2 0x%x, imr2 0x%x\n",
- board->minor, board->status, status1, priv->reg_bits[IMR1], status2,
- priv->reg_bits[IMR2]);
- wake_up_interruptible(&board->wait); /* wake up sleeping process */
- retval = IRQ_HANDLED;
- }
-
- return retval;
-}
-EXPORT_SYMBOL(nec7210_interrupt_have_status);
-
-void nec7210_board_reset(struct nec7210_priv *priv, const struct gpib_board *board)
-{
- /* 7210 chip reset */
- write_byte(priv, AUX_CR, AUXMR);
-
- /* disable all interrupts */
- priv->reg_bits[IMR1] = 0;
- write_byte(priv, priv->reg_bits[IMR1], IMR1);
- priv->reg_bits[IMR2] = 0;
- write_byte(priv, priv->reg_bits[IMR2], IMR2);
- write_byte(priv, 0, SPMR);
-
- /* clear registers by reading */
- read_byte(priv, CPTR);
- read_byte(priv, ISR1);
- read_byte(priv, ISR2);
-
- /* parallel poll unconfigure */
- write_byte(priv, PPR | HR_PPU, AUXMR);
-
- priv->reg_bits[ADMR] = HR_TRM0 | HR_TRM1;
-
- priv->auxa_bits = AUXRA | HR_HLDA;
- write_byte(priv, priv->auxa_bits, AUXMR);
-
- write_byte(priv, AUXRE | 0, AUXMR);
-
- /* set INT pin to active high, enable command pass through of unknown commands */
- priv->auxb_bits = AUXRB | HR_CPTE;
- write_byte(priv, priv->auxb_bits, AUXMR);
- write_byte(priv, AUXRE, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_board_reset);
-
-void nec7210_board_online(struct nec7210_priv *priv, const struct gpib_board *board)
-{
- /* set GPIB address */
- nec7210_primary_address(board, priv, board->pad);
- nec7210_secondary_address(board, priv, board->sad, board->sad >= 0);
-
- /* enable interrupts */
- priv->reg_bits[IMR1] = HR_ERRIE | HR_DECIE | HR_ENDIE |
- HR_DETIE | HR_CPTIE | HR_DOIE | HR_DIIE;
- priv->reg_bits[IMR2] = IMR2_ENABLE_INTR_MASK;
- write_byte(priv, priv->reg_bits[IMR1], IMR1);
- write_byte(priv, priv->reg_bits[IMR2], IMR2);
-
- write_byte(priv, AUX_PON, AUXMR);
-}
-EXPORT_SYMBOL(nec7210_board_online);
-
-#ifdef CONFIG_HAS_IOPORT
-/* wrappers for io */
-u8 nec7210_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num)
-{
- return inb(priv->iobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL(nec7210_ioport_read_byte);
-
-void nec7210_ioport_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num)
-{
- if (register_num == AUXMR)
- /*
- * locking makes absolutely sure noone accesses the
- * AUXMR register faster than once per microsecond
- */
- nec7210_locking_ioport_write_byte(priv, data, register_num);
- else
- outb(data, priv->iobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL(nec7210_ioport_write_byte);
-
-/* locking variants of io wrappers, for chips that page-in registers */
-u8 nec7210_locking_ioport_read_byte(struct nec7210_priv *priv, unsigned int register_num)
-{
- u8 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->register_page_lock, flags);
- retval = inb(priv->iobase + register_num * priv->offset);
- spin_unlock_irqrestore(&priv->register_page_lock, flags);
- return retval;
-}
-EXPORT_SYMBOL(nec7210_locking_ioport_read_byte);
-
-void nec7210_locking_ioport_write_byte(struct nec7210_priv *priv, u8 data,
- unsigned int register_num)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->register_page_lock, flags);
- if (register_num == AUXMR)
- udelay(1);
- outb(data, priv->iobase + register_num * priv->offset);
- spin_unlock_irqrestore(&priv->register_page_lock, flags);
-}
-EXPORT_SYMBOL(nec7210_locking_ioport_write_byte);
-#endif
-
-u8 nec7210_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num)
-{
- return readb(priv->mmiobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL(nec7210_iomem_read_byte);
-
-void nec7210_iomem_write_byte(struct nec7210_priv *priv, u8 data, unsigned int register_num)
-{
- if (register_num == AUXMR)
- /*
- * locking makes absolutely sure noone accesses the
- * AUXMR register faster than once per microsecond
- */
- nec7210_locking_iomem_write_byte(priv, data, register_num);
- else
- writeb(data, priv->mmiobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL(nec7210_iomem_write_byte);
-
-u8 nec7210_locking_iomem_read_byte(struct nec7210_priv *priv, unsigned int register_num)
-{
- u8 retval;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->register_page_lock, flags);
- retval = readb(priv->mmiobase + register_num * priv->offset);
- spin_unlock_irqrestore(&priv->register_page_lock, flags);
- return retval;
-}
-EXPORT_SYMBOL(nec7210_locking_iomem_read_byte);
-
-void nec7210_locking_iomem_write_byte(struct nec7210_priv *priv, u8 data,
- unsigned int register_num)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->register_page_lock, flags);
- if (register_num == AUXMR)
- udelay(1);
- writeb(data, priv->mmiobase + register_num * priv->offset);
- spin_unlock_irqrestore(&priv->register_page_lock, flags);
-}
-EXPORT_SYMBOL(nec7210_locking_iomem_write_byte);
-
-static int __init nec7210_init_module(void)
-{
- return 0;
-}
-
-static void __exit nec7210_exit_module(void)
-{
-}
-
-module_init(nec7210_init_module);
-module_exit(nec7210_exit_module);
diff --git a/drivers/staging/gpib/ni_usb/Makefile b/drivers/staging/gpib/ni_usb/Makefile
deleted file mode 100644
index 469c5d16add3..000000000000
--- a/drivers/staging/gpib/ni_usb/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-obj-$(CONFIG_GPIB_NI_USB) += ni_usb_gpib.o
-
-
diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c
deleted file mode 100644
index 1f8412de9fa3..000000000000
--- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c
+++ /dev/null
@@ -1,2678 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * driver for National Instruments usb to gpib adapters
- * copyright : (C) 2004 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "ni_usb_gpib.h"
-#include "gpibP.h"
-#include "nec7210.h"
-#include "tnt4882_registers.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for National Instruments USB devices");
-
-#define MAX_NUM_NI_USB_INTERFACES 128
-static struct usb_interface *ni_usb_driver_interfaces[MAX_NUM_NI_USB_INTERFACES];
-
-static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status);
-static int ni_usb_set_interrupt_monitor(struct gpib_board *board, unsigned int monitored_bits);
-static void ni_usb_stop(struct ni_usb_priv *ni_priv);
-
-static DEFINE_MUTEX(ni_usb_hotplug_lock);
-
-// calculates a reasonable timeout in that can be passed to usb functions
-static inline unsigned long ni_usb_timeout_msecs(unsigned int usec)
-{
- if (usec == 0)
- return 0;
- return 2000 + usec / 500;
-};
-
-// returns timeout code byte for use in ni-usb-b instructions
-static unsigned short ni_usb_timeout_code(unsigned int usec)
-{
- if (usec == 0)
- return 0xf0;
- else if (usec <= 10)
- return 0xf1;
- else if (usec <= 30)
- return 0xf2;
- else if (usec <= 100)
- return 0xf3;
- else if (usec <= 300)
- return 0xf4;
- else if (usec <= 1000)
- return 0xf5;
- else if (usec <= 3000)
- return 0xf6;
- else if (usec <= 10000)
- return 0xf7;
- else if (usec <= 30000)
- return 0xf8;
- else if (usec <= 100000)
- return 0xf9;
- else if (usec <= 300000)
- return 0xfa;
- else if (usec <= 1000000)
- return 0xfb;
- else if (usec <= 3000000)
- return 0xfc;
- else if (usec <= 10000000)
- return 0xfd;
- else if (usec <= 30000000)
- return 0xfe;
- else if (usec <= 100000000)
- return 0xff;
- else if (usec <= 300000000)
- return 0x01;
- /*
- * NI driver actually uses 0xff for timeout T1000s, which is a bug in their code.
- * I've verified on a usb-b that a code of 0x2 is correct for a 1000 sec timeout
- */
- else if (usec <= 1000000000)
- return 0x02;
- pr_err("bug? usec is greater than 1e9\n");
- return 0xf0;
-}
-
-static void ni_usb_bulk_complete(struct urb *urb)
-{
- struct ni_usb_urb_ctx *context = urb->context;
-
- complete(&context->complete);
-}
-
-static void ni_usb_timeout_handler(struct timer_list *t)
-{
- struct ni_usb_priv *ni_priv = timer_container_of(ni_priv, t,
- bulk_timer);
- struct ni_usb_urb_ctx *context = &ni_priv->context;
-
- context->timed_out = 1;
- complete(&context->complete);
-};
-
-// I'm using nonblocking loosely here, it only means -EAGAIN can be returned in certain cases
-static int ni_usb_nonblocking_send_bulk_msg(struct ni_usb_priv *ni_priv, void *data,
- int data_length, int *actual_data_length,
- int timeout_msecs)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int out_pipe;
- struct ni_usb_urb_ctx *context = &ni_priv->context;
-
- *actual_data_length = 0;
- mutex_lock(&ni_priv->bulk_transfer_lock);
- if (!ni_priv->bus_interface) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -ENODEV;
- }
- if (ni_priv->bulk_urb) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -EAGAIN;
- }
- ni_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ni_priv->bulk_urb) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_pipe = usb_sndbulkpipe(usb_dev, ni_priv->bulk_out_endpoint);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(ni_priv->bulk_urb, usb_dev, out_pipe, data, data_length,
- &ni_usb_bulk_complete, context);
-
- if (timeout_msecs)
- mod_timer(&ni_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
-
- retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- timer_delete_sync(&ni_priv->bulk_timer);
- usb_free_urb(ni_priv->bulk_urb);
- ni_priv->bulk_urb = NULL;
- dev_err(&usb_dev->dev, "failed to submit bulk out urb, retval=%i\n",
- retval);
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return retval;
- }
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- wait_for_completion(&context->complete); // wait for ni_usb_bulk_complete
- if (context->timed_out) {
- usb_kill_urb(ni_priv->bulk_urb);
- dev_err(&usb_dev->dev, "killed urb due to timeout\n");
- retval = -ETIMEDOUT;
- } else {
- retval = ni_priv->bulk_urb->status;
- }
-
- timer_delete_sync(&ni_priv->bulk_timer);
- *actual_data_length = ni_priv->bulk_urb->actual_length;
- mutex_lock(&ni_priv->bulk_transfer_lock);
- usb_free_urb(ni_priv->bulk_urb);
- ni_priv->bulk_urb = NULL;
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return retval;
-}
-
-static int ni_usb_send_bulk_msg(struct ni_usb_priv *ni_priv, void *data, int data_length,
- int *actual_data_length, int timeout_msecs)
-{
- int retval;
- int timeout_msecs_remaining = timeout_msecs;
-
- retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, data, data_length, actual_data_length,
- timeout_msecs_remaining);
- while (retval == -EAGAIN && (timeout_msecs == 0 || timeout_msecs_remaining > 0)) {
- usleep_range(1000, 1500);
- retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, data, data_length,
- actual_data_length,
- timeout_msecs_remaining);
- if (timeout_msecs != 0)
- --timeout_msecs_remaining;
- }
- if (timeout_msecs != 0 && timeout_msecs_remaining <= 0)
- return -ETIMEDOUT;
- return retval;
-}
-
-// I'm using nonblocking loosely here, it only means -EAGAIN can be returned in certain cases
-static int ni_usb_nonblocking_receive_bulk_msg(struct ni_usb_priv *ni_priv,
- void *data, int data_length,
- int *actual_data_length, int timeout_msecs,
- int interruptible)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
- struct ni_usb_urb_ctx *context = &ni_priv->context;
-
- *actual_data_length = 0;
- mutex_lock(&ni_priv->bulk_transfer_lock);
- if (!ni_priv->bus_interface) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -ENODEV;
- }
- if (ni_priv->bulk_urb) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -EAGAIN;
- }
- ni_priv->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ni_priv->bulk_urb) {
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- in_pipe = usb_rcvbulkpipe(usb_dev, ni_priv->bulk_in_endpoint);
- init_completion(&context->complete);
- context->timed_out = 0;
- usb_fill_bulk_urb(ni_priv->bulk_urb, usb_dev, in_pipe, data, data_length,
- &ni_usb_bulk_complete, context);
-
- if (timeout_msecs)
- mod_timer(&ni_priv->bulk_timer, jiffies + msecs_to_jiffies(timeout_msecs));
-
- retval = usb_submit_urb(ni_priv->bulk_urb, GFP_KERNEL);
- if (retval) {
- timer_delete_sync(&ni_priv->bulk_timer);
- usb_free_urb(ni_priv->bulk_urb);
- ni_priv->bulk_urb = NULL;
- dev_err(&usb_dev->dev, "failed to submit bulk in urb, retval=%i\n", retval);
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return retval;
- }
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- if (interruptible) {
- if (wait_for_completion_interruptible(&context->complete)) {
- /*
- * If we got interrupted by a signal while
- * waiting for the usb gpib to respond, we
- * should send a stop command so it will
- * finish up with whatever it was doing and
- * send its response now.
- */
- ni_usb_stop(ni_priv);
- retval = -ERESTARTSYS;
- /*
- * now do an uninterruptible wait, it shouldn't take long
- * for the board to respond now.
- */
- wait_for_completion(&context->complete);
- }
- } else {
- wait_for_completion(&context->complete);
- }
- if (context->timed_out) {
- usb_kill_urb(ni_priv->bulk_urb);
- dev_err(&usb_dev->dev, "killed urb due to timeout\n");
- retval = -ETIMEDOUT;
- } else {
- if (ni_priv->bulk_urb->status)
- retval = ni_priv->bulk_urb->status;
- }
- timer_delete_sync(&ni_priv->bulk_timer);
- *actual_data_length = ni_priv->bulk_urb->actual_length;
- mutex_lock(&ni_priv->bulk_transfer_lock);
- usb_free_urb(ni_priv->bulk_urb);
- ni_priv->bulk_urb = NULL;
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- return retval;
-}
-
-static int ni_usb_receive_bulk_msg(struct ni_usb_priv *ni_priv, void *data,
- int data_length, int *actual_data_length, int timeout_msecs,
- int interruptible)
-{
- int retval;
- int timeout_msecs_remaining = timeout_msecs;
-
- retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, data, data_length,
- actual_data_length, timeout_msecs_remaining,
- interruptible);
- while (retval == -EAGAIN && (timeout_msecs == 0 || timeout_msecs_remaining > 0)) {
- usleep_range(1000, 1500);
- retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, data, data_length,
- actual_data_length,
- timeout_msecs_remaining,
- interruptible);
- if (timeout_msecs != 0)
- --timeout_msecs_remaining;
- }
- if (timeout_msecs && timeout_msecs_remaining <= 0)
- return -ETIMEDOUT;
- return retval;
-}
-
-static int ni_usb_receive_control_msg(struct ni_usb_priv *ni_priv, __u8 request,
- __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size, int timeout_msecs)
-{
- struct usb_device *usb_dev;
- int retval;
- unsigned int in_pipe;
-
- mutex_lock(&ni_priv->control_transfer_lock);
- if (!ni_priv->bus_interface) {
- mutex_unlock(&ni_priv->control_transfer_lock);
- return -ENODEV;
- }
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- in_pipe = usb_rcvctrlpipe(usb_dev, 0);
- retval = usb_control_msg(usb_dev, in_pipe, request, requesttype, value, index, data,
- size, timeout_msecs);
- mutex_unlock(&ni_priv->control_transfer_lock);
- return retval;
-}
-
-static void ni_usb_soft_update_status(struct gpib_board *board, unsigned int ni_usb_ibsta,
- unsigned int clear_mask)
-{
- static const unsigned int ni_usb_ibsta_mask = SRQI | ATN | CIC | REM | LACS | TACS | LOK;
-
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- unsigned int need_monitoring_bits = ni_usb_ibsta_monitor_mask;
- unsigned long flags;
-
- board->status &= ~clear_mask;
- board->status &= ~ni_usb_ibsta_mask;
- board->status |= ni_usb_ibsta & ni_usb_ibsta_mask;
- if (ni_usb_ibsta & DCAS)
- push_gpib_event(board, EVENT_DEV_CLR);
- if (ni_usb_ibsta & DTAS)
- push_gpib_event(board, EVENT_DEV_TRG);
-
- spin_lock_irqsave(&board->spinlock, flags);
-/* remove set status bits from monitored set why ?***/
- ni_priv->monitored_ibsta_bits &= ~ni_usb_ibsta;
- need_monitoring_bits &= ~ni_priv->monitored_ibsta_bits; /* mm - monitored set */
- spin_unlock_irqrestore(&board->spinlock, flags);
- dev_dbg(&usb_dev->dev, "need_monitoring_bits=0x%x\n", need_monitoring_bits);
-
- if (need_monitoring_bits & ~ni_usb_ibsta)
- ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask);
- else if (need_monitoring_bits & ni_usb_ibsta)
- wake_up_interruptible(&board->wait);
-
- dev_dbg(&usb_dev->dev, "ibsta=0x%x\n", ni_usb_ibsta);
-}
-
-static int ni_usb_parse_status_block(const u8 *buffer, struct ni_usb_status_block *status)
-{
- u16 count;
-
- status->id = buffer[0];
- status->ibsta = (buffer[1] << 8) | buffer[2];
- status->error_code = buffer[3];
- count = buffer[4] | (buffer[5] << 8);
- count = ~count;
- count++;
- status->count = count;
- return 8;
-};
-
-static void ni_usb_dump_raw_block(const u8 *raw_data, int length)
-{
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 8, 1, raw_data, length, true);
-}
-
-static int ni_usb_parse_register_read_block(const u8 *raw_data, unsigned int *results,
- int num_results)
-{
- int i = 0;
- int j;
- int unexpected = 0;
- static const int results_per_chunk = 3;
-
- for (j = 0; j < num_results;) {
- int k;
-
- if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_START_ID) {
- pr_err("parse error: wrong start id\n");
- unexpected = 1;
- }
- for (k = 0; k < results_per_chunk && j < num_results; ++k)
- results[j++] = raw_data[i++];
- }
- while (i % 4)
- i++;
- if (raw_data[i++] != NIUSB_REGISTER_READ_DATA_END_ID) {
- pr_err("parse error: wrong end id\n");
- unexpected = 1;
- }
- if (raw_data[i++] % results_per_chunk != num_results % results_per_chunk) {
- pr_err("parse error: wrong count=%i for NIUSB_REGISTER_READ_DATA_END\n",
- (int)raw_data[i - 1]);
- unexpected = 1;
- }
- while (i % 4) {
- if (raw_data[i++] != 0) {
- pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
- i - 1, (int)raw_data[i - 1]);
- unexpected = 1;
- }
- }
- if (unexpected)
- ni_usb_dump_raw_block(raw_data, i);
- return i;
-}
-
-static int ni_usb_parse_termination_block(const u8 *buffer)
-{
- int i = 0;
-
- if (buffer[i++] != NIUSB_TERM_ID ||
- buffer[i++] != 0x0 ||
- buffer[i++] != 0x0 ||
- buffer[i++] != 0x0) {
- pr_err("received unexpected termination block\n");
- pr_err(" expected: 0x%x 0x%x 0x%x 0x%x\n", NIUSB_TERM_ID, 0x0, 0x0, 0x0);
- pr_err(" received: 0x%x 0x%x 0x%x 0x%x\n",
- buffer[i - 4], buffer[i - 3], buffer[i - 2], buffer[i - 1]);
- }
- return i;
-};
-
-static int parse_board_ibrd_readback(const u8 *raw_data, struct ni_usb_status_block *status,
- u8 *parsed_data, int parsed_data_length,
- int *actual_bytes_read)
-{
- static const int ibrd_data_block_length = 0xf;
- static const int ibrd_extended_data_block_length = 0x1e;
- int data_block_length = 0;
- int i = 0;
- int j = 0;
- int k;
- int num_data_blocks = 0;
- struct ni_usb_status_block register_write_status;
- int unexpected = 0;
-
- while (raw_data[i] == NIUSB_IBRD_DATA_ID || raw_data[i] == NIUSB_IBRD_EXTENDED_DATA_ID) {
- if (raw_data[i] == NIUSB_IBRD_DATA_ID) {
- data_block_length = ibrd_data_block_length;
- } else if (raw_data[i] == NIUSB_IBRD_EXTENDED_DATA_ID) {
- data_block_length = ibrd_extended_data_block_length;
- if (raw_data[++i] != 0) {
- pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
- i, (int)raw_data[i]);
- unexpected = 1;
- }
- } else {
- pr_err("Unexpected NIUSB_IBRD ID\n");
- return -EINVAL;
- }
- ++i;
- for (k = 0; k < data_block_length; k++) {
- if (j < parsed_data_length)
- parsed_data[j++] = raw_data[i++];
- else
- ++i;
- }
- ++num_data_blocks;
- }
- i += ni_usb_parse_status_block(&raw_data[i], status);
- if (status->id != NIUSB_IBRD_STATUS_ID) {
- pr_err("bug: status->id=%i, != ibrd_status_id\n", status->id);
- return -EIO;
- }
- i++;
- if (num_data_blocks) {
- *actual_bytes_read = (num_data_blocks - 1) * data_block_length + raw_data[i++];
- } else {
- ++i;
- *actual_bytes_read = 0;
- }
- if (*actual_bytes_read > j)
- pr_err("bug: discarded data. actual_bytes_read=%i, j=%i\n", *actual_bytes_read, j);
- for (k = 0; k < 2; k++)
- if (raw_data[i++] != 0) {
- pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
- i - 1, (int)raw_data[i - 1]);
- unexpected = 1;
- }
- i += ni_usb_parse_status_block(&raw_data[i], &register_write_status);
- if (register_write_status.id != NIUSB_REG_WRITE_ID) {
- pr_err("unexpected data: register write status id=0x%x, expected 0x%x\n",
- register_write_status.id, NIUSB_REG_WRITE_ID);
- unexpected = 1;
- }
- if (raw_data[i++] != 2) {
- pr_err("unexpected data: register write count=%i, expected 2\n",
- (int)raw_data[i - 1]);
- unexpected = 1;
- }
- for (k = 0; k < 3; k++)
- if (raw_data[i++] != 0) {
- pr_err("unexpected data: raw_data[%i]=0x%x, expected 0\n",
- i - 1, (int)raw_data[i - 1]);
- unexpected = 1;
- }
- i += ni_usb_parse_termination_block(&raw_data[i]);
- if (unexpected)
- ni_usb_dump_raw_block(raw_data, i);
- return i;
-}
-
-static int ni_usb_parse_reg_write_status_block(const u8 *raw_data,
- struct ni_usb_status_block *status,
- int *writes_completed)
-{
- int i = 0;
-
- i += ni_usb_parse_status_block(raw_data, status);
- *writes_completed = raw_data[i++];
- while (i % 4)
- i++;
- return i;
-}
-
-static int ni_usb_write_registers(struct ni_usb_priv *ni_priv,
- const struct ni_usb_register *writes, int num_writes,
- unsigned int *ibsta)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- u8 *out_data, *in_data;
- int out_data_length;
- static const int in_data_length = 0x20;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- int j;
- struct ni_usb_status_block status;
- static const int bytes_per_write = 3;
- int reg_writes_completed;
-
- out_data_length = num_writes * bytes_per_write + 0x10;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- i += ni_usb_bulk_register_write_header(&out_data[i], num_writes);
- for (j = 0; j < num_writes; j++)
- i += ni_usb_bulk_register_write(&out_data[i], writes[j]);
- while (i % 4)
- out_data[i++] = 0x00;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
- if (retval || bytes_read != 16) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- ni_usb_dump_raw_block(in_data, bytes_read);
- kfree(in_data);
- return retval;
- }
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- ni_usb_parse_reg_write_status_block(in_data, &status, &reg_writes_completed);
- // FIXME parse extra 09 status bits and termination
- kfree(in_data);
- if (status.id != NIUSB_REG_WRITE_ID) {
- dev_err(&usb_dev->dev, "parse error, id=0x%x != NIUSB_REG_WRITE_ID\n", status.id);
- return -EIO;
- }
- if (status.error_code) {
- dev_err(&usb_dev->dev, "nonzero error code 0x%x\n", status.error_code);
- return -EIO;
- }
- if (reg_writes_completed != num_writes) {
- dev_err(&usb_dev->dev, "reg_writes_completed=%i, num_writes=%i\n",
- reg_writes_completed, num_writes);
- return -EIO;
- }
- if (ibsta)
- *ibsta = status.ibsta;
- return 0;
-}
-
-// interface functions
-static int ni_usb_read(struct gpib_board *board, u8 *buffer, size_t length,
- int *end, size_t *bytes_read)
-{
- int retval, parse_retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x20;
- int in_data_length;
- int usb_bytes_written = 0, usb_bytes_read = 0;
- int i = 0;
- int complement_count;
- int actual_length;
- struct ni_usb_status_block status;
- static const int max_read_length = 0xffff;
- struct ni_usb_register reg;
-
- *bytes_read = 0;
- if (!ni_priv->bus_interface)
- return -ENODEV;
- if (length > max_read_length)
- return -EINVAL;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = 0x0a;
- out_data[i++] = ni_priv->eos_mode >> 8;
- out_data[i++] = ni_priv->eos_char;
- out_data[i++] = ni_usb_timeout_code(board->usec_timeout);
- complement_count = length - 1;
- complement_count = ~complement_count;
- out_data[i++] = complement_count & 0xff;
- out_data[i++] = (complement_count >> 8) & 0xff;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- i += ni_usb_bulk_register_write_header(&out_data[i], 2);
- reg.device = NIUSB_SUBDEV_TNT4882;
- reg.address = nec7210_to_tnt4882_offset(AUXMR);
- reg.value = AUX_HLDI;
- i += ni_usb_bulk_register_write(&out_data[i], reg);
- reg.value = AUX_CLEAR_END;
- i += ni_usb_bulk_register_write(&out_data[i], reg);
- while (i % 4) // pad with zeros to 4-byte boundary
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &usb_bytes_written, 1000);
- kfree(out_data);
- if (retval || usb_bytes_written != i) {
- if (retval == 0)
- retval = -EIO;
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
- retval, usb_bytes_written, i);
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return retval;
- }
-
- in_data_length = (length / 30 + 1) * 0x20 + 0x20;
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &usb_bytes_read,
- ni_usb_timeout_msecs(board->usec_timeout), 1);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if (retval == -ERESTARTSYS) {
- } else if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, usb_bytes_read=%i\n",
- retval, usb_bytes_read);
- kfree(in_data);
- return retval;
- }
- parse_retval = parse_board_ibrd_readback(in_data, &status, buffer, length, &actual_length);
- if (parse_retval != usb_bytes_read) {
- if (parse_retval >= 0)
- parse_retval = -EIO;
- dev_err(&usb_dev->dev, "retval=%i usb_bytes_read=%i\n",
- parse_retval, usb_bytes_read);
- kfree(in_data);
- return parse_retval;
- }
- if (actual_length != length - status.count) {
- dev_err(&usb_dev->dev, "actual_length=%i expected=%li\n",
- actual_length, (long)(length - status.count));
- ni_usb_dump_raw_block(in_data, usb_bytes_read);
- }
- kfree(in_data);
- switch (status.error_code) {
- case NIUSB_NO_ERROR:
- retval = 0;
- break;
- case NIUSB_ABORTED_ERROR:
- /*
- * this is expected if ni_usb_receive_bulk_msg got
- * interrupted by a signal and returned -ERESTARTSYS
- */
- break;
- case NIUSB_ATN_STATE_ERROR:
- if (status.ibsta & DCAS) {
- retval = -EINTR;
- } else {
- retval = -EIO;
- dev_dbg(&usb_dev->dev, "read when ATN set stat: 0x%06x\n", status.ibsta);
- }
- break;
- case NIUSB_ADDRESSING_ERROR:
- retval = -EIO;
- break;
- case NIUSB_TIMEOUT_ERROR:
- retval = -ETIMEDOUT;
- break;
- case NIUSB_EOSMODE_ERROR:
- dev_err(&usb_dev->dev, "driver bug, we should have been able to avoid NIUSB_EOSMODE_ERROR.\n");
- retval = -EINVAL;
- break;
- default:
- dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
- retval = -EIO;
- break;
- }
- ni_usb_soft_update_status(board, status.ibsta, 0);
- if (status.ibsta & END)
- *end = 1;
- else
- *end = 0;
- *bytes_read = actual_length;
- return retval;
-}
-
-static int ni_usb_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, size_t *bytes_written)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- int out_data_length;
- static const int in_data_length = 0x10;
- int usb_bytes_written = 0, usb_bytes_read = 0;
- int i = 0, j;
- int complement_count;
- struct ni_usb_status_block status;
- static const int max_write_length = 0xffff;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- if (length > max_write_length)
- return -EINVAL;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data_length = length + 0x10;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = 0x0d;
- complement_count = length - 1;
- complement_count = ~complement_count;
- out_data[i++] = complement_count & 0xff;
- out_data[i++] = (complement_count >> 8) & 0xff;
- out_data[i++] = ni_usb_timeout_code(board->usec_timeout);
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- if (send_eoi)
- out_data[i++] = 0x8;
- else
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- for (j = 0; j < length; j++)
- out_data[i++] = buffer[j];
- while (i % 4) // pad with zeros to 4-byte boundary
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &usb_bytes_written,
- ni_usb_timeout_msecs(board->usec_timeout));
- kfree(out_data);
- if (retval || usb_bytes_written != i) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, usb_bytes_written=%i, i=%i\n",
- retval, usb_bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &usb_bytes_read,
- ni_usb_timeout_msecs(board->usec_timeout), 1);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if ((retval && retval != -ERESTARTSYS) || usb_bytes_read != 12) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, usb_bytes_read=%i\n",
- retval, usb_bytes_read);
- kfree(in_data);
- return retval;
- }
- ni_usb_parse_status_block(in_data, &status);
- kfree(in_data);
- switch (status.error_code) {
- case NIUSB_NO_ERROR:
- retval = 0;
- break;
- case NIUSB_ABORTED_ERROR:
- /*
- * this is expected if ni_usb_receive_bulk_msg got
- * interrupted by a signal and returned -ERESTARTSYS
- */
- break;
- case NIUSB_ADDRESSING_ERROR:
- dev_err(&usb_dev->dev, "Addressing error retval %d error code=%i\n",
- retval, status.error_code);
- retval = -ENXIO;
- break;
- case NIUSB_NO_LISTENER_ERROR:
- retval = -ECOMM;
- break;
- case NIUSB_TIMEOUT_ERROR:
- retval = -ETIMEDOUT;
- break;
- default:
- dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
- retval = -EPIPE;
- break;
- }
- ni_usb_soft_update_status(board, status.ibsta, 0);
- *bytes_written = length - status.count;
- return retval;
-}
-
-static int ni_usb_command_chunk(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *command_bytes_written)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- int out_data_length;
- static const int in_data_length = 0x10;
- int bytes_written = 0, bytes_read = 0;
- int i = 0, j;
- unsigned int complement_count;
- struct ni_usb_status_block status;
- // usb-b gives error 4 if you try to send more than 16 command bytes at once
- static const int max_command_length = 0x10;
-
- *command_bytes_written = 0;
- if (!ni_priv->bus_interface)
- return -ENODEV;
- if (length > max_command_length)
- length = max_command_length;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data_length = length + 0x10;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = 0x0c;
- complement_count = length - 1;
- complement_count = ~complement_count;
- out_data[i++] = complement_count;
- out_data[i++] = 0x0;
- out_data[i++] = ni_usb_timeout_code(board->usec_timeout);
- for (j = 0; j < length; j++)
- out_data[i++] = buffer[j];
- while (i % 4) // pad with zeros to 4-byte boundary
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written,
- ni_usb_timeout_msecs(board->usec_timeout));
- kfree(out_data);
- if (retval || bytes_written != i) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
-
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read,
- ni_usb_timeout_msecs(board->usec_timeout), 1);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return retval;
- }
- ni_usb_parse_status_block(in_data, &status);
- kfree(in_data);
- *command_bytes_written = length - status.count;
- switch (status.error_code) {
- case NIUSB_NO_ERROR:
- break;
- case NIUSB_ABORTED_ERROR:
- /*
- * this is expected if ni_usb_receive_bulk_msg got
- * interrupted by a signal and returned -ERESTARTSYS
- */
- break;
- case NIUSB_NO_BUS_ERROR:
- return -ENOTCONN;
- case NIUSB_EOSMODE_ERROR:
- dev_err(&usb_dev->dev, "got eosmode error. Driver bug?\n");
- return -EIO;
- case NIUSB_TIMEOUT_ERROR:
- return -ETIMEDOUT;
- default:
- dev_err(&usb_dev->dev, "unknown error code=%i\n", status.error_code);
- return -EIO;
- }
- ni_usb_soft_update_status(board, status.ibsta, 0);
- return 0;
-}
-
-static int ni_usb_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- size_t count;
- int retval;
-
- *bytes_written = 0;
- while (*bytes_written < length) {
- retval = ni_usb_command_chunk(board, buffer + *bytes_written,
- length - *bytes_written, &count);
- *bytes_written += count;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-
-static int ni_usb_take_control(struct gpib_board *board, int synchronous)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x10;
- static const int in_data_length = 0x10;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- struct ni_usb_status_block status;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
- out_data[i++] = NIUSB_IBCAC_ID;
- if (synchronous)
- out_data[i++] = 0x1;
- else
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval || bytes_written != i) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 1);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if ((retval && retval != -ERESTARTSYS) || bytes_read != 12) {
- if (retval == 0)
- retval = -EIO;
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return retval;
- }
- ni_usb_parse_status_block(in_data, &status);
- kfree(in_data);
- ni_usb_soft_update_status(board, status.ibsta, 0);
- return retval;
-}
-
-static int ni_usb_go_to_standby(struct gpib_board *board)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x10;
- static const int in_data_length = 0x20;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- struct ni_usb_status_block status;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
-
- out_data[i++] = NIUSB_IBGTS_ID;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
-
- mutex_lock(&ni_priv->addressed_transfer_lock);
-
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval || bytes_written != i) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if (retval || bytes_read != 12) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return retval;
- }
- ni_usb_parse_status_block(in_data, &status);
- kfree(in_data);
- if (status.id != NIUSB_IBGTS_ID)
- dev_err(&usb_dev->dev, "bug: status.id 0x%x != INUSB_IBGTS_ID\n", status.id);
- ni_usb_soft_update_status(board, status.ibsta, 0);
- return 0;
-}
-
-static int ni_usb_request_system_control(struct gpib_board *board, int request_control)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[4];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- if (request_control) {
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = CMDR;
- writes[i].value = SETSC;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CIFC;
- i++;
- } else {
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CREN;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CIFC;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_DSC;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = CMDR;
- writes[i].value = CLRSC;
- i++;
- }
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- if (!request_control)
- ni_priv->ren_state = 0;
- ni_usb_soft_update_status(board, ibsta, 0);
- return 0;
-}
-
-// FIXME maybe the interface should have a "pulse interface clear" function that can return an error?
-static void ni_usb_interface_clear(struct gpib_board *board, int assert)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x10;
- static const int in_data_length = 0x10;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- struct ni_usb_status_block status;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
-// FIXME: we are going to pulse when assert is true, and ignore otherwise
- if (assert == 0)
- return;
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return;
- out_data[i++] = NIUSB_IBSIC_ID;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return;
- }
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data)
- return;
-
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
- if (retval || bytes_read != 12) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return;
- }
- ni_usb_parse_status_block(in_data, &status);
- kfree(in_data);
- ni_usb_soft_update_status(board, status.ibsta, 0);
-}
-
-static void ni_usb_remote_enable(struct gpib_board *board, int enable)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- struct ni_usb_register reg;
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- reg.device = NIUSB_SUBDEV_TNT4882;
- reg.address = nec7210_to_tnt4882_offset(AUXMR);
- if (enable)
- reg.value = AUX_SREN;
- else
- reg.value = AUX_CREN;
- retval = ni_usb_write_registers(ni_priv, &reg, 1, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return; //retval;
- }
- ni_priv->ren_state = enable;
- ni_usb_soft_update_status(board, ibsta, 0);
- return;// 0;
-}
-
-static int ni_usb_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct ni_usb_priv *ni_priv = board->private_data;
-
- ni_priv->eos_char = eos_byte;
- ni_priv->eos_mode |= REOS;
- if (compare_8_bits)
- ni_priv->eos_mode |= BIN;
- else
- ni_priv->eos_mode &= ~BIN;
- return 0;
-}
-
-static void ni_usb_disable_eos(struct gpib_board *board)
-{
- struct ni_usb_priv *ni_priv = board->private_data;
- /*
- * adapter gets unhappy if you don't zero all the bits
- * for the eos mode and eos char (returns error 4 on reads).
- */
- ni_priv->eos_mode = 0;
- ni_priv->eos_char = 0;
-}
-
-static unsigned int ni_usb_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- static const int buffer_length = 8;
- u8 *buffer;
- struct ni_usb_status_block status;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- buffer = kmalloc(buffer_length, GFP_KERNEL);
- if (!buffer)
- return board->status;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_WAIT_REQUEST, USB_DIR_IN |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x200, 0x0, buffer, buffer_length, 1000);
- if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
- kfree(buffer);
- return board->status;
- }
- ni_usb_parse_status_block(buffer, &status);
- kfree(buffer);
- ni_usb_soft_update_status(board, status.ibsta, clear_mask);
- return board->status;
-}
-
-// tells ni-usb to immediately stop an ongoing i/o operation
-static void ni_usb_stop(struct ni_usb_priv *ni_priv)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- static const int buffer_length = 8;
- u8 *buffer;
- struct ni_usb_status_block status;
-
- buffer = kmalloc(buffer_length, GFP_KERNEL);
- if (!buffer)
- return;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_STOP_REQUEST, USB_DIR_IN |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, 0x0, buffer, buffer_length, 1000);
- if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
- kfree(buffer);
- return;
- }
- ni_usb_parse_status_block(buffer, &status);
- kfree(buffer);
-}
-
-static int ni_usb_primary_address(struct gpib_board *board, unsigned int address)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[2];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(ADR);
- writes[i].value = address;
- i++;
- writes[i].device = NIUSB_SUBDEV_UNKNOWN2;
- writes[i].address = 0x0;
- writes[i].value = address;
- i++;
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return 0;
-}
-
-static int ni_usb_write_sad(struct ni_usb_register *writes, int address, int enable)
-{
- unsigned int adr_bits, admr_bits;
- int i = 0;
-
- adr_bits = HR_ARS;
- admr_bits = HR_TRM0 | HR_TRM1;
- if (enable) {
- adr_bits |= address;
- admr_bits |= HR_ADM1;
- } else {
- adr_bits |= HR_DT | HR_DL;
- admr_bits |= HR_ADM0;
- }
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(ADR);
- writes[i].value = adr_bits;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(ADMR);
- writes[i].value = admr_bits;
- i++;
- writes[i].device = NIUSB_SUBDEV_UNKNOWN2;
- writes[i].address = 0x1;
- writes[i].value = enable ? MSA(address) : 0x0;
- i++;
- return i;
-}
-
-static int ni_usb_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[3];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- i += ni_usb_write_sad(writes, address, enable);
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return 0;
-}
-
-static int ni_usb_parallel_poll(struct gpib_board *board, u8 *result)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x10;
- static const int in_data_length = 0x20;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- int j = 0;
- struct ni_usb_status_block status;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
-
- out_data[i++] = NIUSB_IBRPP_ID;
- out_data[i++] = 0xf0; // FIXME: this should be the parallel poll timeout code
- out_data[i++] = 0x0;
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
- /*FIXME: 1000 should use parallel poll timeout (not supported yet)*/
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
-
- kfree(out_data);
- if (retval || bytes_written != i) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data)
- return -ENOMEM;
-
- /*FIXME: should use parallel poll timeout (not supported yet)*/
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length,
- &bytes_read, 1000, 1);
-
- if (retval && retval != -ERESTARTSYS) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return retval;
- }
- j += ni_usb_parse_status_block(in_data, &status);
- *result = in_data[j++];
- kfree(in_data);
- ni_usb_soft_update_status(board, status.ibsta, 0);
- return retval;
-}
-
-static void ni_usb_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[1];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = PPR | config;
- i++;
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return;// retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return;// 0;
-}
-
-static void ni_usb_parallel_poll_response(struct gpib_board *board, int ist)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[1];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- if (ist)
- writes[i].value = AUX_SPPF;
- else
- writes[i].value = AUX_CPPF;
- i++;
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return;// retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return;// 0;
-}
-
-static void ni_usb_serial_poll_response(struct gpib_board *board, u8 status)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[1];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(SPMR);
- writes[i].value = status;
- i++;
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return;// retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return;// 0;
-}
-
-static u8 ni_usb_serial_poll_status(struct gpib_board *board)
-{
- return 0;
-}
-
-static void ni_usb_return_to_local(struct gpib_board *board)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int i = 0;
- struct ni_usb_register writes[1];
- unsigned int ibsta;
-
- if (!ni_priv->bus_interface)
- return; // -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_RTL;
- i++;
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return;// retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return;// 0;
-}
-
-static int ni_usb_line_status(const struct gpib_board *board)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- u8 *out_data, *in_data;
- static const int out_data_length = 0x20;
- static const int in_data_length = 0x20;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- unsigned int bsr_bits;
- int line_status = VALID_ALL;
- // NI windows driver reads 0xd(HSSEL), 0xc (ARD0), 0x1f (BSR)
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data)
- return -ENOMEM;
-
- /* line status gets called during ibwait */
- retval = mutex_trylock(&ni_priv->addressed_transfer_lock);
-
- if (retval == 0) {
- kfree(out_data);
- return -EBUSY;
- }
- i += ni_usb_bulk_register_read_header(&out_data[i], 1);
- i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_TNT4882, BSR);
- while (i % 4)
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
- retval = ni_usb_nonblocking_send_bulk_msg(ni_priv, out_data, i, &bytes_written, 1000);
- kfree(out_data);
- if (retval || bytes_written != i) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%i\n",
- retval, bytes_written, i);
- return retval;
- }
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data) {
- mutex_unlock(&ni_priv->addressed_transfer_lock);
- return -ENOMEM;
- }
- retval = ni_usb_nonblocking_receive_bulk_msg(ni_priv, in_data, in_data_length,
- &bytes_read, 1000, 0);
-
- mutex_unlock(&ni_priv->addressed_transfer_lock);
-
- if (retval) {
- if (retval != -EAGAIN)
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- kfree(in_data);
- return retval;
- }
-
- ni_usb_parse_register_read_block(in_data, &bsr_bits, 1);
- kfree(in_data);
- if (bsr_bits & BCSR_REN_BIT)
- line_status |= BUS_REN;
- if (bsr_bits & BCSR_IFC_BIT)
- line_status |= BUS_IFC;
- if (bsr_bits & BCSR_SRQ_BIT)
- line_status |= BUS_SRQ;
- if (bsr_bits & BCSR_EOI_BIT)
- line_status |= BUS_EOI;
- if (bsr_bits & BCSR_NRFD_BIT)
- line_status |= BUS_NRFD;
- if (bsr_bits & BCSR_NDAC_BIT)
- line_status |= BUS_NDAC;
- if (bsr_bits & BCSR_DAV_BIT)
- line_status |= BUS_DAV;
- if (bsr_bits & BCSR_ATN_BIT)
- line_status |= BUS_ATN;
- return line_status;
-}
-
-static int ni_usb_setup_t1_delay(struct ni_usb_register *reg, unsigned int nano_sec,
- unsigned int *actual_ns)
-{
- int i = 0;
-
- *actual_ns = 2000;
-
- reg[i].device = NIUSB_SUBDEV_TNT4882;
- reg[i].address = nec7210_to_tnt4882_offset(AUXMR);
- if (nano_sec <= 1100) {
- reg[i].value = AUXRI | USTD | SISB;
- *actual_ns = 1100;
- } else {
- reg[i].value = AUXRI | SISB;
- }
- i++;
- reg[i].device = NIUSB_SUBDEV_TNT4882;
- reg[i].address = nec7210_to_tnt4882_offset(AUXMR);
- if (nano_sec <= 500) {
- reg[i].value = AUXRB | HR_TRI;
- *actual_ns = 500;
- } else {
- reg[i].value = AUXRB;
- }
- i++;
- reg[i].device = NIUSB_SUBDEV_TNT4882;
- reg[i].address = KEYREG;
- if (nano_sec <= 350) {
- reg[i].value = MSTD;
- *actual_ns = 350;
- } else {
- reg[i].value = 0x0;
- }
- i++;
- return i;
-}
-
-static int ni_usb_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- struct ni_usb_register writes[3];
- unsigned int ibsta;
- unsigned int actual_ns;
- int i;
-
- if (!ni_priv->bus_interface)
- return -ENODEV;
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- i = ni_usb_setup_t1_delay(writes, nano_sec, &actual_ns);
- retval = ni_usb_write_registers(ni_priv, writes, i, &ibsta);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- board->t1_nano_sec = actual_ns;
- ni_usb_soft_update_status(board, ibsta, 0);
- return actual_ns;
-}
-
-static int ni_usb_allocate_private(struct gpib_board *board)
-{
- struct ni_usb_priv *ni_priv;
-
- board->private_data = kmalloc(sizeof(struct ni_usb_priv), GFP_KERNEL);
- if (!board->private_data)
- return -ENOMEM;
- ni_priv = board->private_data;
- memset(ni_priv, 0, sizeof(struct ni_usb_priv));
- mutex_init(&ni_priv->bulk_transfer_lock);
- mutex_init(&ni_priv->control_transfer_lock);
- mutex_init(&ni_priv->interrupt_transfer_lock);
- mutex_init(&ni_priv->addressed_transfer_lock);
- return 0;
-}
-
-static void ni_usb_free_private(struct ni_usb_priv *ni_priv)
-{
- usb_free_urb(ni_priv->interrupt_urb);
- kfree(ni_priv);
-}
-
-#define NUM_INIT_WRITES 26
-static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *writes)
-{
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- unsigned int mask, actual_ns;
- int i = 0;
-
- writes[i].device = NIUSB_SUBDEV_UNKNOWN3;
- writes[i].address = 0x10;
- writes[i].value = 0x0;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = CMDR;
- writes[i].value = SOFT_RESET;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- mask = AUXRA | HR_HLDA;
- if (ni_priv->eos_mode & BIN)
- mask |= HR_BIN;
- writes[i].value = mask;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = AUXCR;
- writes[i].value = mask;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = HSSEL;
- writes[i].value = TNT_ONE_CHIP_BIT;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CR;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = IMR0;
- writes[i].value = TNT_IMR0_ALWAYS_BITS;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(IMR1);
- writes[i].value = 0x0;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(IMR2);
- writes[i].value = 0x0;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = IMR3;
- writes[i].value = 0x0;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_HLDI;
- i++;
-
- i += ni_usb_setup_t1_delay(&writes[i], board->t1_nano_sec, &actual_ns);
-
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUXRG | NTNL_BIT;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = CMDR;
- if (board->master)
- mask = SETSC; // set system controller
- else
- mask = CLRSC; // clear system controller
- writes[i].value = mask;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CIFC;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(ADR);
- writes[i].value = board->pad;
- i++;
- writes[i].device = NIUSB_SUBDEV_UNKNOWN2;
- writes[i].address = 0x0;
- writes[i].value = board->pad;
- i++;
-
- i += ni_usb_write_sad(&writes[i], board->sad, board->sad >= 0);
-
- writes[i].device = NIUSB_SUBDEV_UNKNOWN2;
- writes[i].address = 0x2; // could this be a timeout ?
- writes[i].value = 0xfd;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = 0xf; // undocumented address
- writes[i].value = 0x11;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_PON;
- i++;
- writes[i].device = NIUSB_SUBDEV_TNT4882;
- writes[i].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[i].value = AUX_CPPF;
- i++;
- if (i > NUM_INIT_WRITES) {
- dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i);
- return 0;
- }
- return i;
-}
-
-static int ni_usb_init(struct gpib_board *board)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- struct ni_usb_register *writes;
- unsigned int ibsta;
- int writes_len;
-
- writes = kmalloc_array(NUM_INIT_WRITES, sizeof(*writes), GFP_KERNEL);
- if (!writes)
- return -ENOMEM;
-
- writes_len = ni_usb_setup_init(board, writes);
- if (writes_len)
- retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta);
- else
- return -EFAULT;
- kfree(writes);
- if (retval) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- ni_usb_soft_update_status(board, ibsta, 0);
- return 0;
-}
-
-static void ni_usb_interrupt_complete(struct urb *urb)
-{
- struct gpib_board *board = urb->context;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- struct ni_usb_status_block status;
- unsigned long flags;
-
- switch (urb->status) {
- /* success */
- case 0:
- break;
- /* unlinked, don't resubmit */
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* other error, resubmit */
- retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
- return;
- }
-
- ni_usb_parse_status_block(urb->transfer_buffer, &status);
-
- spin_lock_irqsave(&board->spinlock, flags);
- ni_priv->monitored_ibsta_bits &= ~status.ibsta;
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- wake_up_interruptible(&board->wait);
-
- retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&usb_dev->dev, "failed to resubmit interrupt urb\n");
-}
-
-static int ni_usb_set_interrupt_monitor(struct gpib_board *board, unsigned int monitored_bits)
-{
- int retval;
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- static const int buffer_length = 8;
- u8 *buffer;
- struct ni_usb_status_block status;
- unsigned long flags;
-
- buffer = kmalloc(buffer_length, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- spin_lock_irqsave(&board->spinlock, flags);
- ni_priv->monitored_ibsta_bits = ni_usb_ibsta_monitor_mask & monitored_bits;
- spin_unlock_irqrestore(&board->spinlock, flags);
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_WAIT_REQUEST, USB_DIR_IN |
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x300, ni_usb_ibsta_monitor_mask & monitored_bits,
- buffer, buffer_length, 1000);
- if (retval != buffer_length) {
- dev_err(&usb_dev->dev, "usb_control_msg returned %i\n", retval);
- kfree(buffer);
- return -1;
- }
- ni_usb_parse_status_block(buffer, &status);
- kfree(buffer);
- return 0;
-}
-
-static int ni_usb_setup_urbs(struct gpib_board *board)
-{
- struct ni_usb_priv *ni_priv = board->private_data;
- struct usb_device *usb_dev;
- int int_pipe;
- int retval;
-
- if (ni_priv->interrupt_in_endpoint < 0)
- return 0;
-
- mutex_lock(&ni_priv->interrupt_transfer_lock);
- if (!ni_priv->bus_interface) {
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- return -ENODEV;
- }
- ni_priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ni_priv->interrupt_urb) {
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- return -ENOMEM;
- }
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int_pipe = usb_rcvintpipe(usb_dev, ni_priv->interrupt_in_endpoint);
- usb_fill_int_urb(ni_priv->interrupt_urb, usb_dev, int_pipe, ni_priv->interrupt_buffer,
- sizeof(ni_priv->interrupt_buffer), &ni_usb_interrupt_complete, board, 1);
- retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL);
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- if (retval) {
- dev_err(&usb_dev->dev, "failed to submit first interrupt urb, retval=%i\n", retval);
- return retval;
- }
- return 0;
-}
-
-static void ni_usb_cleanup_urbs(struct ni_usb_priv *ni_priv)
-{
- if (ni_priv && ni_priv->bus_interface) {
- if (ni_priv->interrupt_urb)
- usb_kill_urb(ni_priv->interrupt_urb);
- if (ni_priv->bulk_urb)
- usb_kill_urb(ni_priv->bulk_urb);
- }
-}
-
-static int ni_usb_b_read_serial_number(struct ni_usb_priv *ni_priv)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- u8 *out_data;
- u8 *in_data;
- static const int out_data_length = 0x20;
- static const int in_data_length = 0x20;
- int bytes_written = 0, bytes_read = 0;
- int i = 0;
- static const int num_reads = 4;
- unsigned int results[4];
- int j;
- unsigned int serial_number;
-
- in_data = kmalloc(in_data_length, GFP_KERNEL);
- if (!in_data)
- return -ENOMEM;
-
- out_data = kmalloc(out_data_length, GFP_KERNEL);
- if (!out_data) {
- kfree(in_data);
- return -ENOMEM;
- }
- i += ni_usb_bulk_register_read_header(&out_data[i], num_reads);
- i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_1_REG);
- i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_2_REG);
- i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_3_REG);
- i += ni_usb_bulk_register_read(&out_data[i], NIUSB_SUBDEV_UNKNOWN3, SERIAL_NUMBER_4_REG);
- while (i % 4)
- out_data[i++] = 0x0;
- i += ni_usb_bulk_termination(&out_data[i]);
- retval = ni_usb_send_bulk_msg(ni_priv, out_data, out_data_length, &bytes_written, 1000);
- if (retval) {
- dev_err(&usb_dev->dev, "send_bulk_msg returned %i, bytes_written=%i, i=%li\n",
- retval, bytes_written, (long)out_data_length);
- goto serial_out;
- }
- retval = ni_usb_receive_bulk_msg(ni_priv, in_data, in_data_length, &bytes_read, 1000, 0);
- if (retval) {
- dev_err(&usb_dev->dev, "receive_bulk_msg returned %i, bytes_read=%i\n",
- retval, bytes_read);
- ni_usb_dump_raw_block(in_data, bytes_read);
- goto serial_out;
- }
- if (ARRAY_SIZE(results) < num_reads) {
- dev_err(&usb_dev->dev, "serial number eetup bug\n");
- retval = -EINVAL;
- goto serial_out;
- }
- ni_usb_parse_register_read_block(in_data, results, num_reads);
- serial_number = 0;
- for (j = 0; j < num_reads; ++j)
- serial_number |= (results[j] & 0xff) << (8 * j);
- dev_dbg(&usb_dev->dev, "board serial number is 0x%x\n", serial_number);
- retval = 0;
-serial_out:
- kfree(in_data);
- kfree(out_data);
- return retval;
-}
-
-static int ni_usb_hs_wait_for_ready(struct ni_usb_priv *ni_priv)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- static const int buffer_size = 0x10;
- static const int timeout = 50;
- static const int msec_sleep_duration = 100;
- int i; int retval;
- int j;
- int unexpected = 0;
- unsigned int serial_number;
- u8 *buffer;
-
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_SERIAL_NUMBER_REQUEST,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, 0x0, buffer, buffer_size, 1000);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
- NI_USB_SERIAL_NUMBER_REQUEST, retval);
- goto ready_out;
- }
- j = 0;
- if (buffer[j] != NI_USB_SERIAL_NUMBER_REQUEST) {
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- j, (int)buffer[j], NI_USB_SERIAL_NUMBER_REQUEST);
- unexpected = 1;
- }
- if (unexpected)
- ni_usb_dump_raw_block(buffer, retval);
- // NI-USB-HS+ pads the serial with 0x0 to make 16 bytes
- if (retval != 5 && retval != 16) {
- dev_err(&usb_dev->dev, "received unexpected number of bytes = %i, expected 5 or 16\n",
- retval);
- ni_usb_dump_raw_block(buffer, retval);
- }
- serial_number = 0;
- serial_number |= buffer[++j];
- serial_number |= (buffer[++j] << 8);
- serial_number |= (buffer[++j] << 16);
- serial_number |= (buffer[++j] << 24);
- dev_dbg(&usb_dev->dev, "board serial number is 0x%x\n", serial_number);
- for (i = 0; i < timeout; ++i) {
- int ready = 0;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_POLL_READY_REQUEST,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, 0x0, buffer, buffer_size, 100);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
- NI_USB_POLL_READY_REQUEST, retval);
- goto ready_out;
- }
- j = 0;
- unexpected = 0;
- if (buffer[j] != NI_USB_POLL_READY_REQUEST) { // [0]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- j, (int)buffer[j], NI_USB_POLL_READY_REQUEST);
- unexpected = 1;
- }
- ++j;
- if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [1] HS+ sends 0x0
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- if (buffer[++j] != 0x0) { // [2]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x%x\n",
- j, (int)buffer[j], 0x0);
- unexpected = 1;
- }
- ++j;
- /*
- * MC usb-488 (and sometimes NI-USB-HS?) sends 0x8 here; MC usb-488A sends 0x7 here
- * NI-USB-HS+ sends 0x0
- */
- if (buffer[j] != 0x1 && buffer[j] != 0x8 && buffer[j] != 0x7 && buffer[j] != 0x0) {
- // [3]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0, 0x1, 0x7 or 0x8\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- ++j;
- // NI-USB-HS+ sends 0 here
- if (buffer[j] != 0x30 && buffer[j] != 0x0) { // [4]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x30\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- ++j;
- // MC usb-488 (and sometimes NI-USB-HS?) and NI-USB-HS+ sends 0x0 here
- if (buffer[j] != 0x1 && buffer[j] != 0x0) { // [5]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x1 or 0x0\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- if (buffer[++j] != 0x0) { // [6]
- ready = 1;
- // NI-USB-HS+ sends 0xf or 0x19 here
- if (buffer[j] != 0x2 && buffer[j] != 0xe && buffer[j] != 0xf &&
- buffer[j] != 0x16 && buffer[j] != 0x19) {
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x2, 0xe, 0xf, 0x16 or 0x19\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- }
- if (buffer[++j] != 0x0) { // [7]
- ready = 1;
- // MC usb-488 sends 0x5 here; MC usb-488A sends 0x6 here
- if (buffer[j] != 0x3 && buffer[j] != 0x5 && buffer[j] != 0x6 &&
- buffer[j] != 0x8) {
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x3 or 0x5, 0x6 or 0x08\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- }
- ++j;
- if (buffer[j] != 0x0 && buffer[j] != 0x2) { // [8] MC usb-488 sends 0x2 here
- dev_err(&usb_dev->dev, " unexpected data: buffer[%i]=0x%x, expected 0x0 or 0x2\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- ++j;
- // MC usb-488A and NI-USB-HS sends 0x3 here; NI-USB-HS+ sends 0x30 here
- if (buffer[j] != 0x0 && buffer[j] != 0x3 && buffer[j] != 0x30) { // [9]
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x0, 0x3 or 0x30\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- if (buffer[++j] != 0x0) { // [10] MC usb-488 sends 0x7 here, new HS+ sends 0x59
- ready = 1;
- if (buffer[j] != 0x96 && buffer[j] != 0x7 && buffer[j] != 0x6e &&
- buffer[j] != 0x59) {
- dev_err(&usb_dev->dev, "unexpected data: buffer[%i]=0x%x, expected 0x96, 0x07, 0x6e or 0x59\n",
- j, (int)buffer[j]);
- unexpected = 1;
- }
- }
- if (unexpected)
- ni_usb_dump_raw_block(buffer, retval);
- if (ready)
- break;
- retval = msleep_interruptible(msec_sleep_duration);
- if (retval) {
- retval = -ERESTARTSYS;
- goto ready_out;
- }
- }
- retval = 0;
-
-ready_out:
- kfree(buffer);
- dev_dbg(&usb_dev->dev, "exit retval=%d\n", retval);
- return retval;
-}
-
-/*
- * This does some extra init for HS+ models, as observed on Windows. One of the
- * control requests causes the LED to stop blinking.
- * I'm not sure what the other 2 requests do. None of these requests are actually required
- * for the adapter to work, maybe they do some init for the analyzer interface
- * (which we don't use).
- */
-static int ni_usb_hs_plus_extra_init(struct ni_usb_priv *ni_priv)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- u8 *buffer;
- static const int buffer_size = 16;
- int transfer_size;
-
- buffer = kmalloc(buffer_size, GFP_KERNEL);
- if (!buffer)
- return -ENOMEM;
- do {
- transfer_size = 16;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_0x48_REQUEST,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, 0x0, buffer, transfer_size, 1000);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
- NI_USB_HS_PLUS_0x48_REQUEST, retval);
- break;
- }
- // expected response data: 48 f3 30 00 00 00 00 00 00 00 00 00 00 00 00 00
- if (buffer[0] != NI_USB_HS_PLUS_0x48_REQUEST)
- dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- (int)buffer[0], NI_USB_HS_PLUS_0x48_REQUEST);
-
- transfer_size = 2;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_LED_REQUEST,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x1, 0x0, buffer, transfer_size, 1000);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
- NI_USB_HS_PLUS_LED_REQUEST, retval);
- break;
- }
- // expected response data: 4b 00
- if (buffer[0] != NI_USB_HS_PLUS_LED_REQUEST)
- dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- (int)buffer[0], NI_USB_HS_PLUS_LED_REQUEST);
-
- transfer_size = 9;
-
- retval = ni_usb_receive_control_msg(ni_priv, NI_USB_HS_PLUS_0xf8_REQUEST,
- USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_INTERFACE,
- 0x0, 0x1, buffer, transfer_size, 1000);
- if (retval < 0) {
- dev_err(&usb_dev->dev, "usb_control_msg request 0x%x returned %i\n",
- NI_USB_HS_PLUS_0xf8_REQUEST, retval);
- break;
- }
- // expected response data: f8 01 00 00 00 01 00 00 00
- if (buffer[0] != NI_USB_HS_PLUS_0xf8_REQUEST)
- dev_err(&usb_dev->dev, "unexpected data: buffer[0]=0x%x, expected 0x%x\n",
- (int)buffer[0], NI_USB_HS_PLUS_0xf8_REQUEST);
- } while (0);
-
- // cleanup
- kfree(buffer);
- return retval;
-}
-
-static inline int ni_usb_device_match(struct usb_interface *interface,
- const struct gpib_board_config *config)
-{
- if (gpib_match_device_path(&interface->dev, config->device_path) == 0)
- return 0;
- return 1;
-}
-
-static int ni_usb_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- int retval;
- int i, index;
- struct ni_usb_priv *ni_priv;
- int product_id;
- struct usb_device *usb_dev;
-
- mutex_lock(&ni_usb_hotplug_lock);
- retval = ni_usb_allocate_private(board);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- ni_priv = board->private_data;
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
- if (ni_usb_driver_interfaces[i] &&
- !usb_get_intfdata(ni_usb_driver_interfaces[i]) &&
- ni_usb_device_match(ni_usb_driver_interfaces[i], config)) {
- ni_priv->bus_interface = ni_usb_driver_interfaces[i];
- usb_set_intfdata(ni_usb_driver_interfaces[i], board);
- usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- index = i;
- break;
- }
- }
- if (i == MAX_NUM_NI_USB_INTERFACES) {
- mutex_unlock(&ni_usb_hotplug_lock);
- dev_err(board->gpib_dev, "No supported adapters found, have you loaded its firmware?\n");
- return -ENODEV;
- }
- if (usb_reset_configuration(interface_to_usbdev(ni_priv->bus_interface)))
- dev_err(&usb_dev->dev, "usb_reset_configuration() failed.\n");
-
- product_id = le16_to_cpu(usb_dev->descriptor.idProduct);
- ni_priv->product_id = product_id;
-
- timer_setup(&ni_priv->bulk_timer, ni_usb_timeout_handler, 0);
-
- switch (product_id) {
- case USB_DEVICE_ID_NI_USB_B:
- ni_priv->bulk_out_endpoint = NIUSB_B_BULK_OUT_ENDPOINT;
- ni_priv->bulk_in_endpoint = NIUSB_B_BULK_IN_ENDPOINT;
- ni_priv->interrupt_in_endpoint = NIUSB_B_INTERRUPT_IN_ENDPOINT;
- ni_usb_b_read_serial_number(ni_priv);
- break;
- case USB_DEVICE_ID_NI_USB_HS:
- case USB_DEVICE_ID_MC_USB_488:
- case USB_DEVICE_ID_KUSB_488A:
- ni_priv->bulk_out_endpoint = NIUSB_HS_BULK_OUT_ENDPOINT;
- ni_priv->bulk_in_endpoint = NIUSB_HS_BULK_IN_ENDPOINT;
- ni_priv->interrupt_in_endpoint = NIUSB_HS_INTERRUPT_IN_ENDPOINT;
- retval = ni_usb_hs_wait_for_ready(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- break;
- case USB_DEVICE_ID_NI_USB_HS_PLUS:
- ni_priv->bulk_out_endpoint = NIUSB_HS_PLUS_BULK_OUT_ENDPOINT;
- ni_priv->bulk_in_endpoint = NIUSB_HS_PLUS_BULK_IN_ENDPOINT;
- ni_priv->interrupt_in_endpoint = NIUSB_HS_PLUS_INTERRUPT_IN_ENDPOINT;
- retval = ni_usb_hs_wait_for_ready(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- retval = ni_usb_hs_plus_extra_init(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- break;
- default:
- mutex_unlock(&ni_usb_hotplug_lock);
- dev_err(&usb_dev->dev, "\tDriver bug: unknown endpoints for usb device id %x\n",
- product_id);
- return -EINVAL;
- }
-
- retval = ni_usb_setup_urbs(board);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- retval = ni_usb_set_interrupt_monitor(board, 0);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
-
- board->t1_nano_sec = 500;
-
- retval = ni_usb_init(board);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- retval = ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
-
- mutex_unlock(&ni_usb_hotplug_lock);
- dev_info(&usb_dev->dev,
- "bus %d dev num %d attached to gpib%d, intf %i\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, index);
- return retval;
-}
-
-static int ni_usb_shutdown_hardware(struct ni_usb_priv *ni_priv)
-{
- struct usb_device *usb_dev = interface_to_usbdev(ni_priv->bus_interface);
- int retval;
- struct ni_usb_register writes[2];
- static const int writes_length = ARRAY_SIZE(writes);
- unsigned int ibsta;
-
- writes[0].device = NIUSB_SUBDEV_TNT4882;
- writes[0].address = nec7210_to_tnt4882_offset(AUXMR);
- writes[0].value = AUX_CR;
- writes[1].device = NIUSB_SUBDEV_UNKNOWN3;
- writes[1].address = 0x10;
- writes[1].value = 0x0;
- retval = ni_usb_write_registers(ni_priv, writes, writes_length, &ibsta);
- if (retval) {
- dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval);
- return retval;
- }
- return 0;
-}
-
-static void ni_usb_detach(struct gpib_board *board)
-{
- struct ni_usb_priv *ni_priv;
-
- mutex_lock(&ni_usb_hotplug_lock);
- /*
- * under windows, software unplug does chip_reset nec7210 aux command,
- * then writes 0x0 to address 0x10 of device 3
- */
- ni_priv = board->private_data;
- if (ni_priv) {
- if (ni_priv->bus_interface) {
- ni_usb_set_interrupt_monitor(board, 0);
- ni_usb_shutdown_hardware(ni_priv);
- usb_set_intfdata(ni_priv->bus_interface, NULL);
- }
- mutex_lock(&ni_priv->bulk_transfer_lock);
- mutex_lock(&ni_priv->control_transfer_lock);
- mutex_lock(&ni_priv->interrupt_transfer_lock);
- ni_usb_cleanup_urbs(ni_priv);
- ni_usb_free_private(ni_priv);
- }
- mutex_unlock(&ni_usb_hotplug_lock);
-}
-
-static struct gpib_interface ni_usb_gpib_interface = {
- .name = "ni_usb_b",
- .attach = ni_usb_attach,
- .detach = ni_usb_detach,
- .read = ni_usb_read,
- .write = ni_usb_write,
- .command = ni_usb_command,
- .take_control = ni_usb_take_control,
- .go_to_standby = ni_usb_go_to_standby,
- .request_system_control = ni_usb_request_system_control,
- .interface_clear = ni_usb_interface_clear,
- .remote_enable = ni_usb_remote_enable,
- .enable_eos = ni_usb_enable_eos,
- .disable_eos = ni_usb_disable_eos,
- .parallel_poll = ni_usb_parallel_poll,
- .parallel_poll_configure = ni_usb_parallel_poll_configure,
- .parallel_poll_response = ni_usb_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = ni_usb_line_status,
- .update_status = ni_usb_update_status,
- .primary_address = ni_usb_primary_address,
- .secondary_address = ni_usb_secondary_address,
- .serial_poll_response = ni_usb_serial_poll_response,
- .serial_poll_status = ni_usb_serial_poll_status,
- .t1_delay = ni_usb_t1_delay,
- .return_to_local = ni_usb_return_to_local,
- .skip_check_for_command_acceptors = 1
-};
-
-// Table with the USB-devices: just now only testing IDs
-static struct usb_device_id ni_usb_driver_device_table[] = {
- {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_B)},
- {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_HS)},
- // gpib-usb-hs+ has a second interface for the analyzer, which we ignore
- {USB_DEVICE_INTERFACE_NUMBER(USB_VENDOR_ID_NI, USB_DEVICE_ID_NI_USB_HS_PLUS, 0)},
- {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_KUSB_488A)},
- {USB_DEVICE(USB_VENDOR_ID_NI, USB_DEVICE_ID_MC_USB_488)},
- {} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, ni_usb_driver_device_table);
-
-static int ni_usb_driver_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- int i;
- char *path;
- static const int path_length = 1024;
-
- mutex_lock(&ni_usb_hotplug_lock);
- usb_get_dev(usb_dev);
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
- if (!ni_usb_driver_interfaces[i]) {
- ni_usb_driver_interfaces[i] = interface;
- usb_set_intfdata(interface, NULL);
- break;
- }
- }
- if (i == MAX_NUM_NI_USB_INTERFACES) {
- usb_put_dev(usb_dev);
- mutex_unlock(&ni_usb_hotplug_lock);
- dev_err(&usb_dev->dev, "ni_usb_driver_interfaces[] full\n");
- return -1;
- }
- path = kmalloc(path_length, GFP_KERNEL);
- if (!path) {
- usb_put_dev(usb_dev);
- mutex_unlock(&ni_usb_hotplug_lock);
- return -ENOMEM;
- }
- usb_make_path(usb_dev, path, path_length);
- dev_info(&usb_dev->dev, "probe succeeded for path: %s\n", path);
- kfree(path);
- mutex_unlock(&ni_usb_hotplug_lock);
- return 0;
-}
-
-static void ni_usb_driver_disconnect(struct usb_interface *interface)
-{
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- int i;
-
- mutex_lock(&ni_usb_hotplug_lock);
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
- if (ni_usb_driver_interfaces[i] == interface) {
- struct gpib_board *board = usb_get_intfdata(interface);
-
- if (board) {
- struct ni_usb_priv *ni_priv = board->private_data;
-
- if (ni_priv) {
- mutex_lock(&ni_priv->bulk_transfer_lock);
- mutex_lock(&ni_priv->control_transfer_lock);
- mutex_lock(&ni_priv->interrupt_transfer_lock);
- ni_usb_cleanup_urbs(ni_priv);
- ni_priv->bus_interface = NULL;
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- mutex_unlock(&ni_priv->control_transfer_lock);
- mutex_unlock(&ni_priv->bulk_transfer_lock);
- }
- }
- ni_usb_driver_interfaces[i] = NULL;
- break;
- }
- }
- if (i == MAX_NUM_NI_USB_INTERFACES)
- dev_err(&usb_dev->dev, "unable to find interface bug?\n");
- usb_put_dev(usb_dev);
- mutex_unlock(&ni_usb_hotplug_lock);
-}
-
-static int ni_usb_driver_suspend(struct usb_interface *interface, pm_message_t message)
-{
- struct usb_device *usb_dev = interface_to_usbdev(interface);
- struct gpib_board *board;
- int i, retval;
-
- mutex_lock(&ni_usb_hotplug_lock);
-
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
- if (ni_usb_driver_interfaces[i] == interface) {
- board = usb_get_intfdata(interface);
- if (board)
- break;
- }
- }
- if (i == MAX_NUM_NI_USB_INTERFACES) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return 0;
- }
-
- struct ni_usb_priv *ni_priv = board->private_data;
-
- if (ni_priv) {
- ni_usb_set_interrupt_monitor(board, 0);
- retval = ni_usb_shutdown_hardware(ni_priv);
- if (retval) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- if (ni_priv->interrupt_urb) {
- mutex_lock(&ni_priv->interrupt_transfer_lock);
- ni_usb_cleanup_urbs(ni_priv);
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- }
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib%d, interface %i suspended\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- }
-
- mutex_unlock(&ni_usb_hotplug_lock);
- return 0;
-}
-
-static int ni_usb_driver_resume(struct usb_interface *interface)
-{
- struct usb_device *usb_dev = interface_to_usbdev(interface);
-
- struct gpib_board *board;
- int i, retval;
-
- mutex_lock(&ni_usb_hotplug_lock);
-
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++) {
- if (ni_usb_driver_interfaces[i] == interface) {
- board = usb_get_intfdata(interface);
- if (board)
- break;
- }
- }
- if (i == MAX_NUM_NI_USB_INTERFACES) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return 0;
- }
-
- struct ni_usb_priv *ni_priv = board->private_data;
-
- if (ni_priv) {
- if (ni_priv->interrupt_urb) {
- mutex_lock(&ni_priv->interrupt_transfer_lock);
- retval = usb_submit_urb(ni_priv->interrupt_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&usb_dev->dev, "resume failed to resubmit interrupt urb, retval=%i\n",
- retval);
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- mutex_unlock(&ni_priv->interrupt_transfer_lock);
- } else {
- dev_err(&usb_dev->dev, "bug! resume int urb not set up\n");
- mutex_unlock(&ni_usb_hotplug_lock);
- return -EINVAL;
- }
-
- switch (ni_priv->product_id) {
- case USB_DEVICE_ID_NI_USB_B:
- ni_usb_b_read_serial_number(ni_priv);
- break;
- case USB_DEVICE_ID_NI_USB_HS:
- case USB_DEVICE_ID_MC_USB_488:
- case USB_DEVICE_ID_KUSB_488A:
- retval = ni_usb_hs_wait_for_ready(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- break;
- case USB_DEVICE_ID_NI_USB_HS_PLUS:
- retval = ni_usb_hs_wait_for_ready(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- retval = ni_usb_hs_plus_extra_init(ni_priv);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- break;
- default:
- mutex_unlock(&ni_usb_hotplug_lock);
- dev_err(&usb_dev->dev, "\tDriver bug: unknown endpoints for usb device id\n");
- return -EINVAL;
- }
-
- retval = ni_usb_set_interrupt_monitor(board, 0);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
-
- retval = ni_usb_init(board);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- retval = ni_usb_set_interrupt_monitor(board, ni_usb_ibsta_monitor_mask);
- if (retval < 0) {
- mutex_unlock(&ni_usb_hotplug_lock);
- return retval;
- }
- if (board->master)
- ni_usb_interface_clear(board, 1); // this is a pulsed action
- if (ni_priv->ren_state)
- ni_usb_remote_enable(board, 1);
-
- dev_dbg(&usb_dev->dev,
- "bus %d dev num %d gpib%d, interface %i resumed\n",
- usb_dev->bus->busnum, usb_dev->devnum, board->minor, i);
- }
-
- mutex_unlock(&ni_usb_hotplug_lock);
- return 0;
-}
-
-static struct usb_driver ni_usb_bus_driver = {
- .name = DRV_NAME,
- .probe = ni_usb_driver_probe,
- .disconnect = ni_usb_driver_disconnect,
- .suspend = ni_usb_driver_suspend,
- .resume = ni_usb_driver_resume,
- .id_table = ni_usb_driver_device_table,
-};
-
-static int __init ni_usb_init_module(void)
-{
- int i;
- int ret;
-
- for (i = 0; i < MAX_NUM_NI_USB_INTERFACES; i++)
- ni_usb_driver_interfaces[i] = NULL;
-
- ret = usb_register(&ni_usb_bus_driver);
- if (ret) {
- pr_err("usb_register failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&ni_usb_gpib_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static void __exit ni_usb_exit_module(void)
-{
- gpib_unregister_driver(&ni_usb_gpib_interface);
- usb_deregister(&ni_usb_bus_driver);
-}
-
-module_init(ni_usb_init_module);
-module_exit(ni_usb_exit_module);
diff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.h b/drivers/staging/gpib/ni_usb/ni_usb_gpib.h
deleted file mode 100644
index 688f5e08792f..000000000000
--- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2004 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _NI_USB_GPIB_H
-#define _NI_USB_GPIB_H
-
-#include <linux/mutex.h>
-#include <linux/semaphore.h>
-#include <linux/usb.h>
-#include <linux/timer.h>
-#include "gpibP.h"
-
-enum {
- USB_VENDOR_ID_NI = 0x3923
-};
-
-enum {
- USB_DEVICE_ID_NI_USB_B = 0x702a,
- USB_DEVICE_ID_NI_USB_B_PREINIT = 0x702b, // device id before firmware is loaded
- USB_DEVICE_ID_NI_USB_HS = 0x709b,
- USB_DEVICE_ID_NI_USB_HS_PLUS = 0x7618,
- USB_DEVICE_ID_KUSB_488A = 0x725c,
- USB_DEVICE_ID_MC_USB_488 = 0x725d
-};
-
-enum ni_usb_device {
- NIUSB_SUBDEV_TNT4882 = 1,
- NIUSB_SUBDEV_UNKNOWN2 = 2,
- NIUSB_SUBDEV_UNKNOWN3 = 3,
-};
-
-enum endpoint_addresses {
- NIUSB_B_BULK_OUT_ENDPOINT = 0x2,
- NIUSB_B_BULK_IN_ENDPOINT = 0x2,
- NIUSB_B_BULK_IN_ALT_ENDPOINT = 0x6,
- NIUSB_B_INTERRUPT_IN_ENDPOINT = 0x4,
-};
-
-enum hs_enpoint_addresses {
- NIUSB_HS_BULK_OUT_ENDPOINT = 0x2,
- NIUSB_HS_BULK_OUT_ALT_ENDPOINT = 0x6,
- NIUSB_HS_BULK_IN_ENDPOINT = 0x4,
- NIUSB_HS_BULK_IN_ALT_ENDPOINT = 0x8,
- NIUSB_HS_INTERRUPT_IN_ENDPOINT = 0x1,
-};
-
-enum hs_plus_endpoint_addresses {
- NIUSB_HS_PLUS_BULK_OUT_ENDPOINT = 0x1,
- NIUSB_HS_PLUS_BULK_OUT_ALT_ENDPOINT = 0x4,
- NIUSB_HS_PLUS_BULK_IN_ENDPOINT = 0x2,
- NIUSB_HS_PLUS_BULK_IN_ALT_ENDPOINT = 0x5,
- NIUSB_HS_PLUS_INTERRUPT_IN_ENDPOINT = 0x3,
-};
-
-struct ni_usb_urb_ctx {
- struct completion complete;
- unsigned timed_out : 1;
-};
-
-// struct which defines private_data for ni_usb devices
-struct ni_usb_priv {
- struct usb_interface *bus_interface;
- int bulk_out_endpoint;
- int bulk_in_endpoint;
- int interrupt_in_endpoint;
- u8 eos_char;
- unsigned short eos_mode;
- unsigned int monitored_ibsta_bits;
- struct urb *bulk_urb;
- struct urb *interrupt_urb;
- u8 interrupt_buffer[0x11];
- struct mutex addressed_transfer_lock; // protect transfer lock
- struct mutex bulk_transfer_lock; // protect bulk message sends
- struct mutex control_transfer_lock; // protect control messages
- struct mutex interrupt_transfer_lock; // protect interrupt messages
- struct timer_list bulk_timer;
- struct ni_usb_urb_ctx context;
- int product_id;
- unsigned short ren_state;
-};
-
-struct ni_usb_status_block {
- short id;
- unsigned short ibsta;
- short error_code;
- unsigned short count;
-};
-
-struct ni_usb_register {
- enum ni_usb_device device;
- short address;
- unsigned short value;
-};
-
-enum ni_usb_bulk_ids {
- NIUSB_IBCAC_ID = 0x1,
- NIUSB_UNKNOWN3_ID = 0x3, // device level function id?
- NIUSB_TERM_ID = 0x4,
- NIUSB_IBGTS_ID = 0x6,
- NIUSB_IBRPP_ID = 0x7,
- NIUSB_REG_READ_ID = 0x8,
- NIUSB_REG_WRITE_ID = 0x9,
- NIUSB_IBSIC_ID = 0xf,
- NIUSB_REGISTER_READ_DATA_START_ID = 0x34,
- NIUSB_REGISTER_READ_DATA_END_ID = 0x35,
- NIUSB_IBRD_DATA_ID = 0x36,
- NIUSB_IBRD_EXTENDED_DATA_ID = 0x37,
- NIUSB_IBRD_STATUS_ID = 0x38
-};
-
-enum ni_usb_error_codes {
- NIUSB_NO_ERROR = 0,
- /*
- * NIUSB_ABORTED_ERROR occurs when I/O is interrupted early by
- * doing a NI_USB_STOP_REQUEST on the control endpoint.
- */
- NIUSB_ABORTED_ERROR = 1,
- /*
- * NIUSB_READ_ATN_ERROR occurs when you do a board read while
- * ATN is set
- */
- NIUSB_ATN_STATE_ERROR = 2,
- /*
- * NIUSB_ADDRESSING_ERROR occurs when you do a board
- * read/write as CIC but are not in LACS/TACS
- */
- NIUSB_ADDRESSING_ERROR = 3,
- /*
- * NIUSB_EOSMODE_ERROR occurs on reads if any eos mode or char
- * bits are set when REOS is not set.
- * Have also seen error 4 if you try to send more than 16
- * command bytes at once on a usb-b.
- */
- NIUSB_EOSMODE_ERROR = 4,
- /*
- * NIUSB_NO_BUS_ERROR occurs when you try to write a command
- * byte but there are no devices connected to the gpib bus
- */
- NIUSB_NO_BUS_ERROR = 5,
- /*
- * NIUSB_NO_LISTENER_ERROR occurs when you do a board write as
- * CIC with no listener
- */
- NIUSB_NO_LISTENER_ERROR = 8,
- /* get NIUSB_TIMEOUT_ERROR on board read/write timeout */
- NIUSB_TIMEOUT_ERROR = 10,
-};
-
-enum ni_usb_control_requests {
- NI_USB_STOP_REQUEST = 0x20,
- NI_USB_WAIT_REQUEST = 0x21,
- NI_USB_POLL_READY_REQUEST = 0x40,
- NI_USB_SERIAL_NUMBER_REQUEST = 0x41,
- NI_USB_HS_PLUS_0x48_REQUEST = 0x48,
- NI_USB_HS_PLUS_LED_REQUEST = 0x4b,
- NI_USB_HS_PLUS_0xf8_REQUEST = 0xf8
-};
-
-static const unsigned int ni_usb_ibsta_monitor_mask =
- SRQI | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS;
-
-static inline int nec7210_to_tnt4882_offset(int offset)
-{
- return 2 * offset;
-};
-
-static inline int ni_usb_bulk_termination(u8 *buffer)
-{
- int i = 0;
-
- buffer[i++] = NIUSB_TERM_ID;
- buffer[i++] = 0x0;
- buffer[i++] = 0x0;
- buffer[i++] = 0x0;
- return i;
-}
-
-enum ni_usb_unknown3_register {
- SERIAL_NUMBER_4_REG = 0x8,
- SERIAL_NUMBER_3_REG = 0x9,
- SERIAL_NUMBER_2_REG = 0xa,
- SERIAL_NUMBER_1_REG = 0xb,
-};
-
-static inline int ni_usb_bulk_register_write_header(u8 *buffer, int num_writes)
-{
- int i = 0;
-
- buffer[i++] = NIUSB_REG_WRITE_ID;
- buffer[i++] = num_writes;
- buffer[i++] = 0x0;
- return i;
-}
-
-static inline int ni_usb_bulk_register_write(u8 *buffer, struct ni_usb_register reg)
-{
- int i = 0;
-
- buffer[i++] = reg.device;
- buffer[i++] = reg.address;
- buffer[i++] = reg.value;
- return i;
-}
-
-static inline int ni_usb_bulk_register_read_header(u8 *buffer, int num_reads)
-{
- int i = 0;
-
- buffer[i++] = NIUSB_REG_READ_ID;
- buffer[i++] = num_reads;
- return i;
-}
-
-static inline int ni_usb_bulk_register_read(u8 *buffer, int device, int address)
-{
- int i = 0;
-
- buffer[i++] = device;
- buffer[i++] = address;
- return i;
-}
-
-#endif // _NI_USB_GPIB_H
diff --git a/drivers/staging/gpib/pc2/Makefile b/drivers/staging/gpib/pc2/Makefile
deleted file mode 100644
index 481ee4296e1b..000000000000
--- a/drivers/staging/gpib/pc2/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-
-obj-$(CONFIG_GPIB_PC2) += pc2_gpib.o
-
-
-
diff --git a/drivers/staging/gpib/pc2/pc2_gpib.c b/drivers/staging/gpib/pc2/pc2_gpib.c
deleted file mode 100644
index 9f3943d1df66..000000000000
--- a/drivers/staging/gpib/pc2/pc2_gpib.c
+++ /dev/null
@@ -1,684 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include <asm/dma.h>
-#include <linux/dma-mapping.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include "nec7210.h"
-#include "gpibP.h"
-
-// struct which defines private_data for pc2 driver
-struct pc2_priv {
- struct nec7210_priv nec7210_priv;
- unsigned int irq;
- // io address that clears interrupt for pc2a (0x2f0 + irq)
- unsigned int clear_intr_addr;
-};
-
-// pc2 uses 8 consecutive io addresses
-static const int pc2_iosize = 8;
-static const int pc2a_iosize = 8;
-static const int pc2_2a_iosize = 16;
-
-// offset between io addresses of successive nec7210 registers
-static const int pc2a_reg_offset = 0x400;
-static const int pc2_reg_offset = 1;
-
-// interrupt service routine
-static irqreturn_t pc2_interrupt(int irq, void *arg);
-static irqreturn_t pc2a_interrupt(int irq, void *arg);
-
-// pc2 specific registers and bits
-
-// interrupt clear register address
-static const int pc2a_clear_intr_iobase = 0x2f0;
-static inline unsigned int CLEAR_INTR_REG(unsigned int irq)
-{
- return pc2a_clear_intr_iobase + irq;
-}
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for PC2/PC2a and compatible devices");
-
-/*
- * GPIB interrupt service routines
- */
-
-irqreturn_t pc2_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct pc2_priv *priv = board->private_data;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = nec7210_interrupt(board, &priv->nec7210_priv);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-irqreturn_t pc2a_interrupt(int irq, void *arg)
-{
- struct gpib_board *board = arg;
- struct pc2_priv *priv = board->private_data;
- int status1, status2;
- unsigned long flags;
- irqreturn_t retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- // read interrupt status (also clears status)
- status1 = read_byte(&priv->nec7210_priv, ISR1);
- status2 = read_byte(&priv->nec7210_priv, ISR2);
- /* clear interrupt circuit */
- if (priv->irq)
- outb(0xff, CLEAR_INTR_REG(priv->irq));
- retval = nec7210_interrupt_have_status(board, &priv->nec7210_priv, status1, status2);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return retval;
-}
-
-// wrappers for interface functions
-static int pc2_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-}
-
-static int pc2_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int pc2_command(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int pc2_take_control(struct gpib_board *board, int synchronous)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int pc2_go_to_standby(struct gpib_board *board)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int pc2_request_system_control(struct gpib_board *board, int request_control)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
-}
-
-static void pc2_interface_clear(struct gpib_board *board, int assert)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void pc2_remote_enable(struct gpib_board *board, int enable)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int pc2_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void pc2_disable_eos(struct gpib_board *board)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int pc2_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_update_status(board, &priv->nec7210_priv, clear_mask);
-}
-
-static int pc2_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int pc2_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int pc2_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_parallel_poll(board, &priv->nec7210_priv, result);
-}
-
-static void pc2_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
-}
-
-static void pc2_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-static void pc2_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static u8 pc2_serial_poll_status(struct gpib_board *board)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static int pc2_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct pc2_priv *priv = board->private_data;
-
- return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec);
-}
-
-static void pc2_return_to_local(struct gpib_board *board)
-{
- struct pc2_priv *priv = board->private_data;
-
- nec7210_return_to_local(board, &priv->nec7210_priv);
-}
-
-static int allocate_private(struct gpib_board *board)
-{
- struct pc2_priv *priv;
-
- board->private_data = kmalloc(sizeof(struct pc2_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- priv = board->private_data;
- memset(priv, 0, sizeof(struct pc2_priv));
- init_nec7210_private(&priv->nec7210_priv);
- return 0;
-}
-
-static void free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static int pc2_generic_attach(struct gpib_board *board, const struct gpib_board_config *config,
- enum nec7210_chipset chipset)
-{
- struct pc2_priv *pc2_priv;
- struct nec7210_priv *nec_priv;
-
- board->status = 0;
- if (allocate_private(board))
- return -ENOMEM;
- pc2_priv = board->private_data;
- nec_priv = &pc2_priv->nec7210_priv;
- nec_priv->read_byte = nec7210_ioport_read_byte;
- nec_priv->write_byte = nec7210_ioport_write_byte;
- nec_priv->type = chipset;
-
-#ifndef PC2_DMA
- /*
- * board->dev hasn't been initialized, so forget about DMA until this driver
- * is adapted to use isa_register_driver.
- */
- if (config->ibdma)
- // driver needs to be adapted to use isa_register_driver to get a struct device*
- dev_err(board->gpib_dev, "DMA disabled for pc2 gpib");
-#else
- if (config->ibdma) {
- nec_priv->dma_buffer_length = 0x1000;
- nec_priv->dma_buffer = dma_alloc_coherent(board->dev,
- nec_priv->dma_buffer_length, &
- nec_priv->dma_buffer_addr, GFP_ATOMIC);
- if (!nec_priv->dma_buffer)
- return -ENOMEM;
-
- // request isa dma channel
- if (request_dma(config->ibdma, "pc2")) {
- dev_err(board->gpib_dev, "can't request DMA %d\n", config->ibdma);
- return -1;
- }
- nec_priv->dma_channel = config->ibdma;
- }
-#endif
-
- return 0;
-}
-
-static int pc2_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- int isr_flags = 0;
- struct pc2_priv *pc2_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- retval = pc2_generic_attach(board, config, NEC7210);
- if (retval)
- return retval;
-
- pc2_priv = board->private_data;
- nec_priv = &pc2_priv->nec7210_priv;
- nec_priv->offset = pc2_reg_offset;
-
- if (!request_region(config->ibbase, pc2_iosize, "pc2")) {
- dev_err(board->gpib_dev, "ioports are already in use\n");
- return -EBUSY;
- }
- nec_priv->iobase = config->ibbase;
-
- nec7210_board_reset(nec_priv, board);
-
- // install interrupt handler
- if (config->ibirq) {
- if (request_irq(config->ibirq, pc2_interrupt, isr_flags, "pc2", board)) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
- return -EBUSY;
- }
- }
- pc2_priv->irq = config->ibirq;
- /* poll so we can detect assertion of ATN */
- if (gpib_request_pseudo_irq(board, pc2_interrupt)) {
- dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
- return -1;
- }
- /* set internal counter register for 8 MHz input clock */
- write_byte(nec_priv, ICR | 8, AUXMR);
-
- nec7210_board_online(nec_priv, board);
-
- return 0;
-}
-
-static void pc2_detach(struct gpib_board *board)
-{
- struct pc2_priv *pc2_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (pc2_priv) {
- nec_priv = &pc2_priv->nec7210_priv;
-#ifdef PC2_DMA
- if (nec_priv->dma_channel)
- free_dma(nec_priv->dma_channel);
-#endif
- gpib_free_pseudo_irq(board);
- if (pc2_priv->irq)
- free_irq(pc2_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- release_region(nec_priv->iobase, pc2_iosize);
- }
- if (nec_priv->dma_buffer) {
- dma_free_coherent(board->dev, nec_priv->dma_buffer_length,
- nec_priv->dma_buffer, nec_priv->dma_buffer_addr);
- nec_priv->dma_buffer = NULL;
- }
- }
- free_private(board);
-}
-
-static int pc2a_common_attach(struct gpib_board *board, const struct gpib_board_config *config,
- unsigned int num_registers, enum nec7210_chipset chipset)
-{
- unsigned int i, j;
- struct pc2_priv *pc2_priv;
- struct nec7210_priv *nec_priv;
- int retval;
-
- retval = pc2_generic_attach(board, config, chipset);
- if (retval)
- return retval;
-
- pc2_priv = board->private_data;
- nec_priv = &pc2_priv->nec7210_priv;
- nec_priv->offset = pc2a_reg_offset;
-
- switch (config->ibbase) {
- case 0x02e1:
- case 0x22e1:
- case 0x42e1:
- case 0x62e1:
- break;
- default:
- dev_err(board->gpib_dev, "PCIIa base range invalid, must be one of 0x[0246]2e1, but is 0x%x\n",
- config->ibbase);
- return -1;
- }
-
- if (config->ibirq) {
- if (config->ibirq < 2 || config->ibirq > 7) {
- dev_err(board->gpib_dev, "illegal interrupt level %i\n",
- config->ibirq);
- return -1;
- }
- } else {
- dev_err(board->gpib_dev, "interrupt disabled, using polling mode (slow)\n");
- }
-#ifdef CHECK_IOPORTS
- unsigned int err = 0;
-
- for (i = 0; i < num_registers; i++) {
- if (check_region(config->ibbase + i * pc2a_reg_offset, 1))
- err++;
- }
- if (config->ibirq && check_region(pc2a_clear_intr_iobase + config->ibirq, 1))
- err++;
- if (err) {
- dev_err(board->gpib_dev, "ioports are already in use");
- return -EBUSY;
- }
-#endif
- for (i = 0; i < num_registers; i++) {
- if (!request_region(config->ibbase +
- i * pc2a_reg_offset, 1, "pc2a")) {
- dev_err(board->gpib_dev, "ioports are already in use");
- for (j = 0; j < i; j++)
- release_region(config->ibbase +
- j * pc2a_reg_offset, 1);
- return -EBUSY;
- }
- }
- nec_priv->iobase = config->ibbase;
- if (config->ibirq) {
- if (!request_region(pc2a_clear_intr_iobase + config->ibirq, 1, "pc2a")) {
- dev_err(board->gpib_dev, "ioports are already in use");
- return -1;
- }
- pc2_priv->clear_intr_addr = pc2a_clear_intr_iobase + config->ibirq;
- if (request_irq(config->ibirq, pc2a_interrupt, 0, "pc2a", board)) {
- dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq);
- return -EBUSY;
- }
- }
- pc2_priv->irq = config->ibirq;
- /* poll so we can detect assertion of ATN */
- if (gpib_request_pseudo_irq(board, pc2_interrupt)) {
- dev_err(board->gpib_dev, "failed to allocate pseudo_irq\n");
- return -1;
- }
-
- // make sure interrupt is clear
- if (pc2_priv->irq)
- outb(0xff, CLEAR_INTR_REG(pc2_priv->irq));
-
- nec7210_board_reset(nec_priv, board);
-
- /* set internal counter register for 8 MHz input clock */
- write_byte(nec_priv, ICR | 8, AUXMR);
-
- nec7210_board_online(nec_priv, board);
-
- return 0;
-}
-
-static int pc2a_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return pc2a_common_attach(board, config, pc2a_iosize, NEC7210);
-}
-
-static int pc2a_cb7210_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return pc2a_common_attach(board, config, pc2a_iosize, CB7210);
-}
-
-static int pc2_2a_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return pc2a_common_attach(board, config, pc2_2a_iosize, NAT4882);
-}
-
-static void pc2a_common_detach(struct gpib_board *board, unsigned int num_registers)
-{
- int i;
- struct pc2_priv *pc2_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (pc2_priv) {
- nec_priv = &pc2_priv->nec7210_priv;
-#ifdef PC2_DMA
- if (nec_priv->dma_channel)
- free_dma(nec_priv->dma_channel);
-#endif
- gpib_free_pseudo_irq(board);
- if (pc2_priv->irq)
- free_irq(pc2_priv->irq, board);
- if (nec_priv->iobase) {
- nec7210_board_reset(nec_priv, board);
- for (i = 0; i < num_registers; i++)
- release_region(nec_priv->iobase +
- i * pc2a_reg_offset, 1);
- }
- if (pc2_priv->clear_intr_addr)
- release_region(pc2_priv->clear_intr_addr, 1);
- if (nec_priv->dma_buffer) {
- dma_free_coherent(board->dev, nec_priv->dma_buffer_length,
- nec_priv->dma_buffer,
- nec_priv->dma_buffer_addr);
- nec_priv->dma_buffer = NULL;
- }
- }
- free_private(board);
-}
-
-static void pc2a_detach(struct gpib_board *board)
-{
- pc2a_common_detach(board, pc2a_iosize);
-}
-
-static void pc2_2a_detach(struct gpib_board *board)
-{
- pc2a_common_detach(board, pc2_2a_iosize);
-}
-
-static struct gpib_interface pc2_interface = {
- .name = "pcII",
- .attach = pc2_attach,
- .detach = pc2_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static struct gpib_interface pc2a_interface = {
- .name = "pcIIa",
- .attach = pc2a_attach,
- .detach = pc2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static struct gpib_interface pc2a_cb7210_interface = {
- .name = "pcIIa_cb7210",
- .attach = pc2a_cb7210_attach,
- .detach = pc2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL, // XXX
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static struct gpib_interface pc2_2a_interface = {
- .name = "pcII_IIa",
- .attach = pc2_2a_attach,
- .detach = pc2_2a_detach,
- .read = pc2_read,
- .write = pc2_write,
- .command = pc2_command,
- .take_control = pc2_take_control,
- .go_to_standby = pc2_go_to_standby,
- .request_system_control = pc2_request_system_control,
- .interface_clear = pc2_interface_clear,
- .remote_enable = pc2_remote_enable,
- .enable_eos = pc2_enable_eos,
- .disable_eos = pc2_disable_eos,
- .parallel_poll = pc2_parallel_poll,
- .parallel_poll_configure = pc2_parallel_poll_configure,
- .parallel_poll_response = pc2_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = pc2_update_status,
- .primary_address = pc2_primary_address,
- .secondary_address = pc2_secondary_address,
- .serial_poll_response = pc2_serial_poll_response,
- .serial_poll_status = pc2_serial_poll_status,
- .t1_delay = pc2_t1_delay,
- .return_to_local = pc2_return_to_local,
-};
-
-static int __init pc2_init_module(void)
-{
- int ret;
-
- ret = gpib_register_driver(&pc2_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- return ret;
- }
-
- ret = gpib_register_driver(&pc2a_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pc2a;
- }
-
- ret = gpib_register_driver(&pc2a_cb7210_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_cb7210;
- }
-
- ret = gpib_register_driver(&pc2_2a_interface, THIS_MODULE);
- if (ret) {
- pr_err("gpib_register_driver failed: error = %d\n", ret);
- goto err_pc2_2a;
- }
-
- return 0;
-
-err_pc2_2a:
- gpib_unregister_driver(&pc2a_cb7210_interface);
-err_cb7210:
- gpib_unregister_driver(&pc2a_interface);
-err_pc2a:
- gpib_unregister_driver(&pc2_interface);
-
- return ret;
-}
-
-static void __exit pc2_exit_module(void)
-{
- gpib_unregister_driver(&pc2_interface);
- gpib_unregister_driver(&pc2a_interface);
- gpib_unregister_driver(&pc2a_cb7210_interface);
- gpib_unregister_driver(&pc2_2a_interface);
-}
-
-module_init(pc2_init_module);
-module_exit(pc2_exit_module);
-
diff --git a/drivers/staging/gpib/tms9914/Makefile b/drivers/staging/gpib/tms9914/Makefile
deleted file mode 100644
index 4705ab07f413..000000000000
--- a/drivers/staging/gpib/tms9914/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-
-obj-$(CONFIG_GPIB_TMS9914) += tms9914.o
-
-
-
-
diff --git a/drivers/staging/gpib/tms9914/tms9914.c b/drivers/staging/gpib/tms9914/tms9914.c
deleted file mode 100644
index 0d11b80bb982..000000000000
--- a/drivers/staging/gpib/tms9914/tms9914.c
+++ /dev/null
@@ -1,914 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/dma.h>
-#include <linux/io.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-
-#include "gpibP.h"
-#include "tms9914.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB library for tms9914");
-
-static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv);
-
-int tms9914_take_control(struct gpib_board *board, struct tms9914_priv *priv, int synchronous)
-{
- int i;
- const int timeout = 100;
-
- if (synchronous)
- write_byte(priv, AUX_TCS, AUXCR);
- else
- write_byte(priv, AUX_TCA, AUXCR);
- // busy wait until ATN is asserted
- for (i = 0; i < timeout; i++) {
- if ((read_byte(priv, ADSR) & HR_ATN))
- break;
- udelay(1);
- }
- if (i == timeout)
- return -ETIMEDOUT;
-
- clear_bit(WRITE_READY_BN, &priv->state);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tms9914_take_control);
-
-/*
- * The agilent 82350B has a buggy implementation of tcs which interferes with the
- * operation of tca. It appears to be based on the controller state machine
- * described in the TI 9900 TMS9914A data manual published in 1982. This
- * manual describes tcs as putting the controller into a CWAS
- * state where it waits indefinitely for ANRS and ignores tca. Since a
- * functioning tca is far more important than tcs, we work around the
- * problem by never issuing tcs.
- *
- * I don't know if this problem exists in the real tms9914a or just in the fpga
- * of the 82350B. For now, only the agilent_82350b uses this workaround.
- * The rest of the tms9914 based drivers still use tms9914_take_control
- * directly (which does issue tcs).
- */
-int tms9914_take_control_workaround(struct gpib_board *board,
- struct tms9914_priv *priv, int synchronous)
-{
- if (synchronous)
- return -ETIMEDOUT;
- return tms9914_take_control(board, priv, synchronous);
-}
-EXPORT_SYMBOL_GPL(tms9914_take_control_workaround);
-
-int tms9914_go_to_standby(struct gpib_board *board, struct tms9914_priv *priv)
-{
- int i;
- const int timeout = 1000;
-
- write_byte(priv, AUX_GTS, AUXCR);
- // busy wait until ATN is released
- for (i = 0; i < timeout; i++) {
- if ((read_byte(priv, ADSR) & HR_ATN) == 0)
- break;
- udelay(1);
- }
- if (i == timeout)
- return -ETIMEDOUT;
-
- clear_bit(COMMAND_READY_BN, &priv->state);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tms9914_go_to_standby);
-
-void tms9914_interface_clear(struct gpib_board *board, struct tms9914_priv *priv, int assert)
-{
- if (assert) {
- write_byte(priv, AUX_SIC | AUX_CS, AUXCR);
-
- set_bit(CIC_NUM, &board->status);
- } else {
- write_byte(priv, AUX_SIC, AUXCR);
- }
-}
-EXPORT_SYMBOL_GPL(tms9914_interface_clear);
-
-void tms9914_remote_enable(struct gpib_board *board, struct tms9914_priv *priv, int enable)
-{
- if (enable)
- write_byte(priv, AUX_SRE | AUX_CS, AUXCR);
- else
- write_byte(priv, AUX_SRE, AUXCR);
-}
-EXPORT_SYMBOL_GPL(tms9914_remote_enable);
-
-int tms9914_request_system_control(struct gpib_board *board, struct tms9914_priv *priv,
- int request_control)
-{
- if (request_control) {
- write_byte(priv, AUX_RQC, AUXCR);
- } else {
- clear_bit(CIC_NUM, &board->status);
- write_byte(priv, AUX_RLC, AUXCR);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(tms9914_request_system_control);
-
-unsigned int tms9914_t1_delay(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int nano_sec)
-{
- static const int clock_period = 200; // assuming 5Mhz input clock
- int num_cycles;
-
- num_cycles = 12;
-
- if (nano_sec <= 8 * clock_period) {
- write_byte(priv, AUX_STDL | AUX_CS, AUXCR);
- num_cycles = 8;
- } else {
- write_byte(priv, AUX_STDL, AUXCR);
- }
-
- if (nano_sec <= 4 * clock_period) {
- write_byte(priv, AUX_VSTDL | AUX_CS, AUXCR);
- num_cycles = 4;
- } else {
- write_byte(priv, AUX_VSTDL, AUXCR);
- }
-
- return num_cycles * clock_period;
-}
-EXPORT_SYMBOL_GPL(tms9914_t1_delay);
-
-void tms9914_return_to_local(const struct gpib_board *board, struct tms9914_priv *priv)
-{
- write_byte(priv, AUX_RTL, AUXCR);
-}
-EXPORT_SYMBOL_GPL(tms9914_return_to_local);
-
-void tms9914_set_holdoff_mode(struct tms9914_priv *priv, enum tms9914_holdoff_mode mode)
-{
- switch (mode) {
- case TMS9914_HOLDOFF_NONE:
- write_byte(priv, AUX_HLDE, AUXCR);
- write_byte(priv, AUX_HLDA, AUXCR);
- break;
- case TMS9914_HOLDOFF_EOI:
- write_byte(priv, AUX_HLDE | AUX_CS, AUXCR);
- write_byte(priv, AUX_HLDA, AUXCR);
- break;
- case TMS9914_HOLDOFF_ALL:
- write_byte(priv, AUX_HLDE, AUXCR);
- write_byte(priv, AUX_HLDA | AUX_CS, AUXCR);
- break;
- default:
- pr_err("bug! bad holdoff mode %i\n", mode);
- break;
- }
- priv->holdoff_mode = mode;
-}
-EXPORT_SYMBOL_GPL(tms9914_set_holdoff_mode);
-
-void tms9914_release_holdoff(struct tms9914_priv *priv)
-{
- if (priv->holdoff_active) {
- write_byte(priv, AUX_RHDF, AUXCR);
- priv->holdoff_active = 0;
- }
-}
-EXPORT_SYMBOL_GPL(tms9914_release_holdoff);
-
-int tms9914_enable_eos(struct gpib_board *board, struct tms9914_priv *priv, u8 eos_byte,
- int compare_8_bits)
-{
- priv->eos = eos_byte;
- priv->eos_flags = REOS;
- if (compare_8_bits)
- priv->eos_flags |= BIN;
- return 0;
-}
-EXPORT_SYMBOL(tms9914_enable_eos);
-
-void tms9914_disable_eos(struct gpib_board *board, struct tms9914_priv *priv)
-{
- priv->eos_flags &= ~REOS;
-}
-EXPORT_SYMBOL(tms9914_disable_eos);
-
-int tms9914_parallel_poll(struct gpib_board *board, struct tms9914_priv *priv, u8 *result)
-{
- // execute parallel poll
- write_byte(priv, AUX_CS | AUX_RPP, AUXCR);
- udelay(2);
- *result = read_byte(priv, CPTR);
- // clear parallel poll state
- write_byte(priv, AUX_RPP, AUXCR);
- return 0;
-}
-EXPORT_SYMBOL(tms9914_parallel_poll);
-
-static void set_ppoll_reg(struct tms9914_priv *priv, int enable,
- unsigned int dio_line, int sense, int ist)
-{
- u8 dio_byte;
-
- if (enable && ((sense && ist) || (!sense && !ist))) {
- dio_byte = 1 << (dio_line - 1);
- write_byte(priv, dio_byte, PPR);
- } else {
- write_byte(priv, 0, PPR);
- }
-}
-
-void tms9914_parallel_poll_configure(struct gpib_board *board,
- struct tms9914_priv *priv, u8 config)
-{
- priv->ppoll_enable = (config & PPC_DISABLE) == 0;
- priv->ppoll_line = (config & PPC_DIO_MASK) + 1;
- priv->ppoll_sense = (config & PPC_SENSE) != 0;
- set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, board->ist);
-}
-EXPORT_SYMBOL(tms9914_parallel_poll_configure);
-
-void tms9914_parallel_poll_response(struct gpib_board *board,
- struct tms9914_priv *priv, int ist)
-{
- set_ppoll_reg(priv, priv->ppoll_enable, priv->ppoll_line, priv->ppoll_sense, ist);
-}
-EXPORT_SYMBOL(tms9914_parallel_poll_response);
-
-void tms9914_serial_poll_response(struct gpib_board *board,
- struct tms9914_priv *priv, u8 status)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
- write_byte(priv, status, SPMR);
- priv->spoll_status = status;
- if (status & request_service_bit)
- write_byte(priv, AUX_RSV2 | AUX_CS, AUXCR);
- else
- write_byte(priv, AUX_RSV2, AUXCR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-EXPORT_SYMBOL(tms9914_serial_poll_response);
-
-u8 tms9914_serial_poll_status(struct gpib_board *board, struct tms9914_priv *priv)
-{
- u8 status;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
- status = priv->spoll_status;
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return status;
-}
-EXPORT_SYMBOL(tms9914_serial_poll_status);
-
-int tms9914_primary_address(struct gpib_board *board,
- struct tms9914_priv *priv, unsigned int address)
-{
- // put primary address in address0
- write_byte(priv, address & ADDRESS_MASK, ADR);
- return 0;
-}
-EXPORT_SYMBOL(tms9914_primary_address);
-
-int tms9914_secondary_address(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int address, int enable)
-{
- if (enable)
- priv->imr1_bits |= HR_APTIE;
- else
- priv->imr1_bits &= ~HR_APTIE;
-
- write_byte(priv, priv->imr1_bits, IMR1);
- return 0;
-}
-EXPORT_SYMBOL(tms9914_secondary_address);
-
-unsigned int tms9914_update_status(struct gpib_board *board, struct tms9914_priv *priv,
- unsigned int clear_mask)
-{
- unsigned long flags;
- unsigned int retval;
-
- spin_lock_irqsave(&board->spinlock, flags);
- retval = update_status_nolock(board, priv);
- board->status &= ~clear_mask;
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return retval;
-}
-EXPORT_SYMBOL(tms9914_update_status);
-
-static void update_talker_state(struct tms9914_priv *priv, unsigned int address_status_bits)
-{
- if (address_status_bits & HR_TA) {
- if (address_status_bits & HR_ATN)
- priv->talker_state = talker_addressed;
- else
- /*
- * this could also be serial_poll_active, but the tms9914 provides no
- * way to distinguish, so we'll assume talker_active
- */
- priv->talker_state = talker_active;
- } else {
- priv->talker_state = talker_idle;
- }
-}
-
-static void update_listener_state(struct tms9914_priv *priv, unsigned int address_status_bits)
-{
- if (address_status_bits & HR_LA) {
- if (address_status_bits & HR_ATN)
- priv->listener_state = listener_addressed;
- else
- priv->listener_state = listener_active;
- } else {
- priv->listener_state = listener_idle;
- }
-}
-
-static unsigned int update_status_nolock(struct gpib_board *board, struct tms9914_priv *priv)
-{
- int address_status;
- int bsr_bits;
-
- address_status = read_byte(priv, ADSR);
-
- // check for remote/local
- if (address_status & HR_REM)
- set_bit(REM_NUM, &board->status);
- else
- clear_bit(REM_NUM, &board->status);
- // check for lockout
- if (address_status & HR_LLO)
- set_bit(LOK_NUM, &board->status);
- else
- clear_bit(LOK_NUM, &board->status);
- // check for ATN
- if (address_status & HR_ATN)
- set_bit(ATN_NUM, &board->status);
- else
- clear_bit(ATN_NUM, &board->status);
- // check for talker/listener addressed
- update_talker_state(priv, address_status);
- if (priv->talker_state == talker_active || priv->talker_state == talker_addressed)
- set_bit(TACS_NUM, &board->status);
- else
- clear_bit(TACS_NUM, &board->status);
-
- update_listener_state(priv, address_status);
- if (priv->listener_state == listener_active || priv->listener_state == listener_addressed)
- set_bit(LACS_NUM, &board->status);
- else
- clear_bit(LACS_NUM, &board->status);
- // Check for SRQI - not reset elsewhere except in autospoll
- if (board->status & SRQI) {
- bsr_bits = read_byte(priv, BSR);
- if (!(bsr_bits & BSR_SRQ_BIT))
- clear_bit(SRQI_NUM, &board->status);
- }
-
- dev_dbg(board->gpib_dev, "status 0x%lx, state 0x%lx\n", board->status, priv->state);
-
- return board->status;
-}
-
-int tms9914_line_status(const struct gpib_board *board, struct tms9914_priv *priv)
-{
- int bsr_bits;
- int status = VALID_ALL;
-
- bsr_bits = read_byte(priv, BSR);
-
- if (bsr_bits & BSR_REN_BIT)
- status |= BUS_REN;
- if (bsr_bits & BSR_IFC_BIT)
- status |= BUS_IFC;
- if (bsr_bits & BSR_SRQ_BIT)
- status |= BUS_SRQ;
- if (bsr_bits & BSR_EOI_BIT)
- status |= BUS_EOI;
- if (bsr_bits & BSR_NRFD_BIT)
- status |= BUS_NRFD;
- if (bsr_bits & BSR_NDAC_BIT)
- status |= BUS_NDAC;
- if (bsr_bits & BSR_DAV_BIT)
- status |= BUS_DAV;
- if (bsr_bits & BSR_ATN_BIT)
- status |= BUS_ATN;
-
- return status;
-}
-EXPORT_SYMBOL(tms9914_line_status);
-
-static int check_for_eos(struct tms9914_priv *priv, u8 byte)
-{
- static const u8 seven_bit_compare_mask = 0x7f;
-
- if ((priv->eos_flags & REOS) == 0)
- return 0;
-
- if (priv->eos_flags & BIN) {
- if (priv->eos == byte)
- return 1;
- } else {
- if ((priv->eos & seven_bit_compare_mask) == (byte & seven_bit_compare_mask))
- return 1;
- }
- return 0;
-}
-
-static int wait_for_read_byte(struct gpib_board *board, struct tms9914_priv *priv)
-{
- if (wait_event_interruptible(board->wait,
- test_bit(READ_READY_BN, &priv->state) ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
-
- if (test_bit(DEV_CLEAR_BN, &priv->state))
- return -EINTR;
- return 0;
-}
-
-static inline u8 tms9914_read_data_in(struct gpib_board *board,
- struct tms9914_priv *priv, int *end)
-{
- unsigned long flags;
- u8 data;
-
- spin_lock_irqsave(&board->spinlock, flags);
- clear_bit(READ_READY_BN, &priv->state);
- data = read_byte(priv, DIR);
- if (test_and_clear_bit(RECEIVED_END_BN, &priv->state))
- *end = 1;
- else
- *end = 0;
- switch (priv->holdoff_mode) {
- case TMS9914_HOLDOFF_EOI:
- if (*end)
- priv->holdoff_active = 1;
- break;
- case TMS9914_HOLDOFF_ALL:
- priv->holdoff_active = 1;
- break;
- case TMS9914_HOLDOFF_NONE:
- break;
- default:
- dev_err(board->gpib_dev, "bug! bad holdoff mode %i\n", priv->holdoff_mode);
- break;
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- return data;
-}
-
-static int pio_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
-
- *bytes_read = 0;
- *end = 0;
- while (*bytes_read < length && *end == 0) {
- tms9914_release_holdoff(priv);
- retval = wait_for_read_byte(board, priv);
- if (retval < 0)
- return retval;
- buffer[(*bytes_read)++] = tms9914_read_data_in(board, priv, end);
-
- if (check_for_eos(priv, buffer[*bytes_read - 1]))
- *end = 1;
- }
-
- return retval;
-}
-
-int tms9914_read(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, int *end, size_t *bytes_read)
-{
- ssize_t retval = 0;
- size_t num_bytes;
-
- *end = 0;
- *bytes_read = 0;
- if (length == 0)
- return 0;
-
- clear_bit(DEV_CLEAR_BN, &priv->state);
-
- // transfer data (except for last byte)
- if (length > 1) {
- if (priv->eos_flags & REOS)
- tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
- else
- tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_EOI);
- // PIO transfer
- retval = pio_read(board, priv, buffer, length - 1, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
- buffer += num_bytes;
- length -= num_bytes;
- }
- // read last bytes if we havn't received an END yet
- if (*end == 0) {
- // make sure we holdoff after last byte read
- tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
- retval = pio_read(board, priv, buffer, length, end, &num_bytes);
- *bytes_read += num_bytes;
- if (retval < 0)
- return retval;
- }
- return 0;
-}
-EXPORT_SYMBOL(tms9914_read);
-
-static int pio_write_wait(struct gpib_board *board, struct tms9914_priv *priv)
-{
- // wait until next byte is ready to be sent
- if (wait_event_interruptible(board->wait,
- test_bit(WRITE_READY_BN, &priv->state) ||
- test_bit(BUS_ERROR_BN, &priv->state) ||
- test_bit(DEV_CLEAR_BN, &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (test_bit(BUS_ERROR_BN, &priv->state))
- return -EIO;
- if (test_bit(DEV_CLEAR_BN, &priv->state))
- return -EINTR;
-
- return 0;
-}
-
-static int pio_write(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- ssize_t retval = 0;
- unsigned long flags;
-
- *bytes_written = 0;
- while (*bytes_written < length) {
- retval = pio_write_wait(board, priv);
- if (retval < 0)
- break;
-
- spin_lock_irqsave(&board->spinlock, flags);
- clear_bit(WRITE_READY_BN, &priv->state);
- write_byte(priv, buffer[(*bytes_written)++], CDOR);
- spin_unlock_irqrestore(&board->spinlock, flags);
- }
- retval = pio_write_wait(board, priv);
- if (retval < 0)
- return retval;
-
- return length;
-}
-
-int tms9914_write(struct gpib_board *board, struct tms9914_priv *priv,
- u8 *buffer, size_t length, int send_eoi, size_t *bytes_written)
-{
- ssize_t retval = 0;
-
- *bytes_written = 0;
- if (length == 0)
- return 0;
-
- clear_bit(BUS_ERROR_BN, &priv->state);
- clear_bit(DEV_CLEAR_BN, &priv->state);
-
- if (send_eoi)
- length-- ; /* save the last byte for sending EOI */
-
- if (length > 0) {
- size_t num_bytes;
- // PIO transfer
- retval = pio_write(board, priv, buffer, length, &num_bytes);
- *bytes_written += num_bytes;
- if (retval < 0)
- return retval;
- }
- if (send_eoi) {
- size_t num_bytes;
- /*send EOI */
- write_byte(priv, AUX_SEOI, AUXCR);
-
- retval = pio_write(board, priv, &buffer[*bytes_written], 1, &num_bytes);
- *bytes_written += num_bytes;
- }
- return retval;
-}
-EXPORT_SYMBOL(tms9914_write);
-
-static void check_my_address_state(struct gpib_board *board,
- struct tms9914_priv *priv, int cmd_byte)
-{
- if (cmd_byte == MLA(board->pad)) {
- priv->primary_listen_addressed = 1;
- // become active listener
- if (board->sad < 0)
- write_byte(priv, AUX_LON | AUX_CS, AUXCR);
- } else if (board->sad >= 0 && priv->primary_listen_addressed &&
- cmd_byte == MSA(board->sad)) {
- // become active listener
- write_byte(priv, AUX_LON | AUX_CS, AUXCR);
- } else if (cmd_byte != MLA(board->pad) && (cmd_byte & 0xe0) == LAD) {
- priv->primary_listen_addressed = 0;
- } else if (cmd_byte == UNL) {
- priv->primary_listen_addressed = 0;
- write_byte(priv, AUX_LON, AUXCR);
- } else if (cmd_byte == MTA(board->pad)) {
- priv->primary_talk_addressed = 1;
- if (board->sad < 0)
- // make active talker
- write_byte(priv, AUX_TON | AUX_CS, AUXCR);
- } else if (board->sad >= 0 && priv->primary_talk_addressed &&
- cmd_byte == MSA(board->sad)) {
- // become active talker
- write_byte(priv, AUX_TON | AUX_CS, AUXCR);
- } else if (cmd_byte != MTA(board->pad) && (cmd_byte & 0xe0) == TAD) {
- // Other Talk Address
- priv->primary_talk_addressed = 0;
- write_byte(priv, AUX_TON, AUXCR);
- } else if (cmd_byte == UNT) {
- priv->primary_talk_addressed = 0;
- write_byte(priv, AUX_TON, AUXCR);
- }
-}
-
-int tms9914_command(struct gpib_board *board, struct tms9914_priv *priv, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- int retval = 0;
- unsigned long flags;
-
- *bytes_written = 0;
- while (*bytes_written < length) {
- if (wait_event_interruptible(board->wait,
- test_bit(COMMAND_READY_BN,
- &priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- break;
- if (test_bit(TIMO_NUM, &board->status))
- break;
-
- spin_lock_irqsave(&board->spinlock, flags);
- clear_bit(COMMAND_READY_BN, &priv->state);
- write_byte(priv, buffer[*bytes_written], CDOR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- check_my_address_state(board, priv, buffer[*bytes_written]);
-
- ++(*bytes_written);
- }
- // wait until last command byte is written
- if (wait_event_interruptible(board->wait,
- test_bit(COMMAND_READY_BN,
- &priv->state) || test_bit(TIMO_NUM, &board->status)))
- retval = -ERESTARTSYS;
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
-
- return retval;
-}
-EXPORT_SYMBOL(tms9914_command);
-
-irqreturn_t tms9914_interrupt(struct gpib_board *board, struct tms9914_priv *priv)
-{
- int status0, status1;
-
- // read interrupt status (also clears status)
- status0 = read_byte(priv, ISR0);
- status1 = read_byte(priv, ISR1);
- return tms9914_interrupt_have_status(board, priv, status0, status1);
-}
-EXPORT_SYMBOL(tms9914_interrupt);
-
-irqreturn_t tms9914_interrupt_have_status(struct gpib_board *board, struct tms9914_priv *priv,
- int status0, int status1)
-{
- // record reception of END
- if (status0 & HR_END)
- set_bit(RECEIVED_END_BN, &priv->state);
- // get incoming data in PIO mode
- if ((status0 & HR_BI))
- set_bit(READ_READY_BN, &priv->state);
- if ((status0 & HR_BO)) {
- if (read_byte(priv, ADSR) & HR_ATN)
- set_bit(COMMAND_READY_BN, &priv->state);
- else
- set_bit(WRITE_READY_BN, &priv->state);
- }
-
- if (status0 & HR_SPAS) {
- priv->spoll_status &= ~request_service_bit;
- write_byte(priv, priv->spoll_status, SPMR);
- // FIXME: set SPOLL status bit
- }
- // record service request in status
- if (status1 & HR_SRQ)
- set_bit(SRQI_NUM, &board->status);
- // have been addressed (with secondary addressing disabled)
- if (status1 & HR_MA)
- // clear dac holdoff
- write_byte(priv, AUX_VAL, AUXCR);
- // unrecognized command received
- if (status1 & HR_UNC) {
- unsigned short command_byte = read_byte(priv, CPTR) & gpib_command_mask;
-
- switch (command_byte) {
- case PP_CONFIG:
- priv->ppoll_configure_state = 1;
- /*
- * AUX_PTS generates another UNC interrupt on the next command byte
- * if it is in the secondary address group (such as PPE and PPD).
- */
- write_byte(priv, AUX_PTS, AUXCR);
- write_byte(priv, AUX_VAL, AUXCR);
- break;
- case PPU:
- tms9914_parallel_poll_configure(board, priv, command_byte);
- write_byte(priv, AUX_VAL, AUXCR);
- break;
- default:
- if (is_PPE(command_byte) || is_PPD(command_byte)) {
- if (priv->ppoll_configure_state) {
- tms9914_parallel_poll_configure(board, priv, command_byte);
- write_byte(priv, AUX_VAL, AUXCR);
- } else {// bad parallel poll configure byte
- // clear dac holdoff
- write_byte(priv, AUX_INVAL, AUXCR);
- }
- } else {
- // clear dac holdoff
- write_byte(priv, AUX_INVAL, AUXCR);
- }
- break;
- }
-
- if (in_primary_command_group(command_byte) && command_byte != PP_CONFIG)
- priv->ppoll_configure_state = 0;
- }
-
- if (status1 & HR_ERR) {
- dev_dbg(board->gpib_dev, "gpib bus error\n");
- set_bit(BUS_ERROR_BN, &priv->state);
- }
-
- if (status1 & HR_IFC) {
- push_gpib_event(board, EVENT_IFC);
- clear_bit(CIC_NUM, &board->status);
- }
-
- if (status1 & HR_GET) {
- push_gpib_event(board, EVENT_DEV_TRG);
- // clear dac holdoff
- write_byte(priv, AUX_VAL, AUXCR);
- }
-
- if (status1 & HR_DCAS) {
- push_gpib_event(board, EVENT_DEV_CLR);
- // clear dac holdoff
- write_byte(priv, AUX_VAL, AUXCR);
- set_bit(DEV_CLEAR_BN, &priv->state);
- }
-
- // check for being addressed with secondary addressing
- if (status1 & HR_APT) {
- if (board->sad < 0)
- dev_err(board->gpib_dev, "bug, APT interrupt without secondary addressing?\n");
- if ((read_byte(priv, CPTR) & gpib_command_mask) == MSA(board->sad))
- write_byte(priv, AUX_VAL, AUXCR);
- else
- write_byte(priv, AUX_INVAL, AUXCR);
- }
-
- if ((status0 & priv->imr0_bits) || (status1 & priv->imr1_bits)) {
- dev_dbg(board->gpib_dev, "isr0 0x%x, imr0 0x%x, isr1 0x%x, imr1 0x%x\n",
- status0, priv->imr0_bits, status1, priv->imr1_bits);
- update_status_nolock(board, priv);
- wake_up_interruptible(&board->wait);
- }
- return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(tms9914_interrupt_have_status);
-
-void tms9914_board_reset(struct tms9914_priv *priv)
-{
- /* chip reset */
- write_byte(priv, AUX_CHIP_RESET | AUX_CS, AUXCR);
-
- /* disable all interrupts */
- priv->imr0_bits = 0;
- write_byte(priv, priv->imr0_bits, IMR0);
- priv->imr1_bits = 0;
- write_byte(priv, priv->imr1_bits, IMR1);
- write_byte(priv, AUX_DAI | AUX_CS, AUXCR);
-
- /* clear registers by reading */
- read_byte(priv, CPTR);
- read_byte(priv, ISR0);
- read_byte(priv, ISR1);
-
- write_byte(priv, 0, SPMR);
-
- /* parallel poll unconfigure */
- write_byte(priv, 0, PPR);
- /* request for data holdoff */
- tms9914_set_holdoff_mode(priv, TMS9914_HOLDOFF_ALL);
-}
-EXPORT_SYMBOL_GPL(tms9914_board_reset);
-
-void tms9914_online(struct gpib_board *board, struct tms9914_priv *priv)
-{
- /* set GPIB address */
- tms9914_primary_address(board, priv, board->pad);
- tms9914_secondary_address(board, priv, board->sad, board->sad >= 0);
-
- /* enable tms9914 interrupts */
- priv->imr0_bits |= HR_MACIE | HR_RLCIE | HR_ENDIE | HR_BOIE | HR_BIIE |
- HR_SPASIE;
- priv->imr1_bits |= HR_MAIE | HR_SRQIE | HR_UNCIE | HR_ERRIE | HR_IFCIE |
- HR_GETIE | HR_DCASIE;
- write_byte(priv, priv->imr0_bits, IMR0);
- write_byte(priv, priv->imr1_bits, IMR1);
- write_byte(priv, AUX_DAI, AUXCR);
-
- /* turn off reset state */
- write_byte(priv, AUX_CHIP_RESET, AUXCR);
-}
-EXPORT_SYMBOL_GPL(tms9914_online);
-
-#ifdef CONFIG_HAS_IOPORT
-// wrapper for inb
-u8 tms9914_ioport_read_byte(struct tms9914_priv *priv, unsigned int register_num)
-{
- return inb(priv->iobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL_GPL(tms9914_ioport_read_byte);
-
-// wrapper for outb
-void tms9914_ioport_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
-{
- outb(data, priv->iobase + register_num * priv->offset);
- if (register_num == AUXCR)
- udelay(1);
-}
-EXPORT_SYMBOL_GPL(tms9914_ioport_write_byte);
-#endif
-
-// wrapper for readb
-u8 tms9914_iomem_read_byte(struct tms9914_priv *priv, unsigned int register_num)
-{
- return readb(priv->mmiobase + register_num * priv->offset);
-}
-EXPORT_SYMBOL_GPL(tms9914_iomem_read_byte);
-
-// wrapper for writeb
-void tms9914_iomem_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
-{
- writeb(data, priv->mmiobase + register_num * priv->offset);
- if (register_num == AUXCR)
- udelay(1);
-}
-EXPORT_SYMBOL_GPL(tms9914_iomem_write_byte);
-
-static int __init tms9914_init_module(void)
-{
- return 0;
-}
-
-static void __exit tms9914_exit_module(void)
-{
-}
-
-module_init(tms9914_init_module);
-module_exit(tms9914_exit_module);
-
diff --git a/drivers/staging/gpib/tnt4882/Makefile b/drivers/staging/gpib/tnt4882/Makefile
deleted file mode 100644
index fa1687ad0d1b..000000000000
--- a/drivers/staging/gpib/tnt4882/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_GPIB_NI_PCI_ISA) += tnt4882.o
-
-tnt4882-objs := tnt4882_gpib.o mite.o
-
-
-
diff --git a/drivers/staging/gpib/tnt4882/mite.c b/drivers/staging/gpib/tnt4882/mite.c
deleted file mode 100644
index 847b96f411bd..000000000000
--- a/drivers/staging/gpib/tnt4882/mite.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-/*
- * Hardware driver for NI Mite PCI interface chip,
- * adapted from COMEDI
- *
- * Copyright (C) 1997-8 David A. Schleef
- * Copyright (C) 2002 Frank Mori Hess
- *
- * The PCI-MIO E series driver was originally written by
- * Tomasz Motylewski <...>, and ported to comedi by ds.
- *
- * References for specifications:
- *
- * 321747b.pdf Register Level Programmer Manual (obsolete)
- * 321747c.pdf Register Level Programmer Manual (new)
- * DAQ-STC reference manual
- *
- * Other possibly relevant info:
- *
- * 320517c.pdf User manual (obsolete)
- * 320517f.pdf User manual (new)
- * 320889a.pdf delete
- * 320906c.pdf maximum signal ratings
- * 321066a.pdf about 16x
- * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- * 321808a.pdf about at-mio-16e-10 rev P
- * 321837a.pdf discontinuation of at-mio-16de-10 rev d
- * 321838a.pdf about at-mio-16de-10 rev N
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include "mite.h"
-
-#define PCI_MITE_SIZE 4096
-#define PCI_DAQ_SIZE 4096
-
-struct mite_struct *mite_devices;
-
-#define TOP_OF_PAGE(x) ((x) | (~(PAGE_MASK)))
-
-void mite_init(void)
-{
- struct pci_dev *pcidev;
- struct mite_struct *mite;
-
- for (pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, NULL);
- pcidev;
- pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, pcidev)) {
- mite = kzalloc(sizeof(*mite), GFP_KERNEL);
- if (!mite)
- return;
-
- mite->pcidev = pcidev;
- pci_dev_get(mite->pcidev);
- mite->next = mite_devices;
- mite_devices = mite;
- }
-}
-
-int mite_setup(struct mite_struct *mite)
-{
- u32 addr;
-
- if (pci_enable_device(mite->pcidev)) {
- pr_err("mite: error enabling mite.\n");
- return -EIO;
- }
- pci_set_master(mite->pcidev);
- if (pci_request_regions(mite->pcidev, "mite")) {
- pr_err("mite: failed to request mite io regions.\n");
- return -EIO;
- }
- addr = pci_resource_start(mite->pcidev, 0);
- mite->mite_phys_addr = addr;
- mite->mite_io_addr = ioremap(addr, pci_resource_len(mite->pcidev, 0));
- if (!mite->mite_io_addr) {
- pr_err("mite: failed to remap mite io memory address.\n");
- return -ENOMEM;
- }
- addr = pci_resource_start(mite->pcidev, 1);
- mite->daq_phys_addr = addr;
- mite->daq_io_addr = ioremap(mite->daq_phys_addr, pci_resource_len(mite->pcidev, 1));
- if (!mite->daq_io_addr) {
- pr_err("mite: failed to remap daq io memory address.\n");
- return -ENOMEM;
- }
- writel(mite->daq_phys_addr | WENAB, mite->mite_io_addr + MITE_IODWBSR);
- mite->used = 1;
- return 0;
-}
-
-void mite_cleanup(void)
-{
- struct mite_struct *mite, *next;
-
- for (mite = mite_devices; mite; mite = next) {
- next = mite->next;
- if (mite->pcidev)
- pci_dev_put(mite->pcidev);
- kfree(mite);
- }
-}
-
-void mite_unsetup(struct mite_struct *mite)
-{
- if (!mite)
- return;
- if (mite->mite_io_addr) {
- iounmap(mite->mite_io_addr);
- mite->mite_io_addr = NULL;
- }
- if (mite->daq_io_addr) {
- iounmap(mite->daq_io_addr);
- mite->daq_io_addr = NULL;
- }
- if (mite->mite_phys_addr) {
- pci_release_regions(mite->pcidev);
- pci_disable_device(mite->pcidev);
- mite->mite_phys_addr = 0;
- }
- mite->used = 0;
-}
diff --git a/drivers/staging/gpib/tnt4882/mite.h b/drivers/staging/gpib/tnt4882/mite.h
deleted file mode 100644
index a1fdba9672a0..000000000000
--- a/drivers/staging/gpib/tnt4882/mite.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-/*
- * Hardware driver for NI Mite PCI interface chip
- *
- * Copyright (C) 1999 David A. Schleef <ds@stm.lbl.gov>
- */
-
-#ifndef _MITE_H_
-#define _MITE_H_
-
-#include <linux/pci.h>
-
-#define PCI_VENDOR_ID_NATINST 0x1093
-
-//#define DEBUG_MITE
-
-#ifdef DEBUG_MITE
-#define MDPRINTK(format, args...) pr_debug(format, ## args)
-#else
-#define MDPRINTK(args...)
-#endif
-
-#define MITE_RING_SIZE 3000
-struct mite_dma_chain {
- u32 count;
- u32 addr;
- u32 next;
-};
-
-struct mite_struct {
- struct mite_struct *next;
- int used;
-
- struct pci_dev *pcidev;
- unsigned long mite_phys_addr;
- void __iomem *mite_io_addr;
- unsigned long daq_phys_addr;
- void __iomem *daq_io_addr;
-
- int DMA_CheckNearEnd;
-
- struct mite_dma_chain ring[MITE_RING_SIZE];
-};
-
-extern struct mite_struct *mite_devices;
-
-extern inline unsigned int mite_irq(struct mite_struct *mite)
-{
- return mite->pcidev->irq;
-};
-
-extern inline unsigned int mite_device_id(struct mite_struct *mite)
-{
- return mite->pcidev->device;
-};
-
-void mite_init(void);
-void mite_cleanup(void);
-int mite_setup(struct mite_struct *mite);
-void mite_unsetup(struct mite_struct *mite);
-void mite_list_devices(void);
-
-#define CHAN_OFFSET(x) (0x100 * (x))
-
-/* DMA base for chan 0 is 0x500, chan 1 is 0x600 */
-
-#define MITE_CHOR 0x500
-#define CHOR_DMARESET BIT(31)
-#define CHOR_SET_SEND_TC BIT(11)
-#define CHOR_CLR_SEND_TC BIT(10)
-#define CHOR_SET_LPAUSE BIT(9)
-#define CHOR_CLR_LPAUSE BIT(8)
-#define CHOR_CLRDONE BIT(7)
-#define CHOR_CLRRB BIT(6)
-#define CHOR_CLRLC BIT(5)
-#define CHOR_FRESET BIT(4)
-#define CHOR_ABORT BIT(3)
-#define CHOR_STOP BIT(2)
-#define CHOR_CONT BIT(1)
-#define CHOR_START BIT(0)
-#define CHOR_PON (CHOR_CLR_SEND_TC | CHOR_CLR_LPAUSE)
-
-#define MITE_CHCR 0x504
-#define CHCR_SET_DMA_IE BIT(31)
-#define CHCR_CLR_DMA_IE BIT(30)
-#define CHCR_SET_LINKP_IE BIT(29)
-#define CHCR_CLR_LINKP_IE BIT(28)
-#define CHCR_SET_SAR_IE BIT(27)
-#define CHCR_CLR_SAR_IE BIT(26)
-#define CHCR_SET_DONE_IE BIT(25)
-#define CHCR_CLR_DONE_IE BIT(24)
-#define CHCR_SET_MRDY_IE BIT(23)
-#define CHCR_CLR_MRDY_IE BIT(22)
-#define CHCR_SET_DRDY_IE BIT(21)
-#define CHCR_CLR_DRDY_IE BIT(20)
-#define CHCR_SET_LC_IE BIT(19)
-#define CHCR_CLR_LC_IE BIT(18)
-#define CHCR_SET_CONT_RB_IE BIT(17)
-#define CHCR_CLR_CONT_RB_IE BIT(16)
-#define CHCR_FIFODIS BIT(15)
-#define CHCR_FIFO_ON 0
-#define CHCR_BURSTEN BIT(14)
-#define CHCR_NO_BURSTEN 0
-#define CHCR_NFTP(x) ((x) << 11)
-#define CHCR_NFTP0 CHCR_NFTP(0)
-#define CHCR_NFTP1 CHCR_NFTP(1)
-#define CHCR_NFTP2 CHCR_NFTP(2)
-#define CHCR_NFTP4 CHCR_NFTP(3)
-#define CHCR_NFTP8 CHCR_NFTP(4)
-#define CHCR_NFTP16 CHCR_NFTP(5)
-#define CHCR_NETP(x) ((x) << 11)
-#define CHCR_NETP0 CHCR_NETP(0)
-#define CHCR_NETP1 CHCR_NETP(1)
-#define CHCR_NETP2 CHCR_NETP(2)
-#define CHCR_NETP4 CHCR_NETP(3)
-#define CHCR_NETP8 CHCR_NETP(4)
-#define CHCR_CHEND1 BIT(5)
-#define CHCR_CHEND0 BIT(4)
-#define CHCR_DIR BIT(3)
-#define CHCR_DEV_TO_MEM CHCR_DIR
-#define CHCR_MEM_TO_DEV 0
-#define CHCR_NORMAL ((0) << 0)
-#define CHCR_CONTINUE ((1) << 0)
-#define CHCR_RINGBUFF ((2) << 0)
-#define CHCR_LINKSHORT ((4) << 0)
-#define CHCR_LINKLONG ((5) << 0)
-#define CHCRPON (CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | \
- CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | \
- CHCR_CLR_LC_IE | CHCR_CLR_CONT_IE)
-
-#define MITE_TCR 0x508
-
-/* CR bits */
-#define CR_RL(x) ((x) << 21)
-#define CR_RL0 CR_RL(0)
-#define CR_RL1 CR_RL(1)
-#define CR_RL2 CR_RL(2)
-#define CR_RL4 CR_RL(3)
-#define CR_RL8 CR_RL(4)
-#define CR_RL16 CR_RL(5)
-#define CR_RL32 CR_RL(6)
-#define CR_RL64 CR_RL(7)
-#define CR_RD(x) ((x) << 19)
-#define CR_RD0 CR_RD(0)
-#define CR_RD32 CR_RD(1)
-#define CR_RD512 CR_RD(2)
-#define CR_RD8192 CR_RD(3)
-#define CR_REQS(x) ((x) << 16)
-#define CR_REQSDRQ0 CR_REQS(4)
-#define CR_REQSDRQ1 CR_REQS(5)
-#define CR_REQSDRQ2 CR_REQS(6)
-#define CR_REQSDRQ3 CR_REQS(7)
-#define CR_ASEQX(x) ((x) << 10)
-#define CR_ASEQX0 CR_ASEQX(0)
-#define CR_ASEQDONT CR_ASEQX0
-#define CR_ASEQXP1 CR_ASEQX(1)
-#define CR_ASEQUP CR_ASEQXP1
-#define CR_ASEQXP2 CR_ASEQX(2)
-#define CR_ASEQDOWN CR_ASEQXP2
-#define CR_ASEQXP4 CR_ASEQX(3)
-#define CR_ASEQXP8 CR_ASEQX(4)
-#define CR_ASEQXP16 CR_ASEQX(5)
-#define CR_ASEQXP32 CR_ASEQX(6)
-#define CR_ASEQXP64 CR_ASEQX(7)
-#define CR_ASEQXM1 CR_ASEQX(9)
-#define CR_ASEQXM2 CR_ASEQX(10)
-#define CR_ASEQXM4 CR_ASEQX(11)
-#define CR_ASEQXM8 CR_ASEQX(12)
-#define CR_ASEQXM16 CR_ASEQX(13)
-#define CR_ASEQXM32 CR_ASEQX(14)
-#define CR_ASEQXM64 CR_ASEQX(15)
-#define CR_PSIZEBYTE BIT(8)
-#define CR_PSIZEHALF (2 << 8)
-#define CR_PSIZEWORD (3 << 8)
-#define CR_PORTCPU (0 << 6)
-#define CR_PORTIO BIT(6)
-#define CR_PORTVXI (2 << 6)
-#define CR_PORTMXI (3 << 6)
-#define CR_AMDEVICE BIT(0)
-
-#define CHSR_INT 0x80000000
-#define CHSR_DONE 0x02000000
-#define CHSR_LINKC 0x00080000
-
-#define MITE_MCR 0x50c
-#define MCRPON 0
-
-#define MITE_MAR 0x510
-
-#define MITE_DCR 0x514
-#define DCR_NORMAL BIT(29)
-#define DCRPON 0
-
-#define MITE_DAR 0x518
-
-#define MITE_LKCR 0x51c
-
-#define MITE_LKAR 0x520
-#define MITE_LLKAR 0x524
-#define MITE_BAR 0x528
-#define MITE_BCR 0x52c
-#define MITE_SAR 0x530
-#define MITE_WSCR 0x534
-#define MITE_WSER 0x538
-#define MITE_CHSR 0x53c
-#define MITE_FCR 0x540
-
-#define MITE_FIFO 0x80
-#define MITE_FIFOEND 0xff
-
-#define MITE_AMRAM 0x00
-#define MITE_AMDEVICE 0x01
-#define MITE_AMHOST_A32_SINGLE 0x09
-#define MITE_AMHOST_A24_SINGLE 0x39
-#define MITE_AMHOST_A16_SINGLE 0x29
-#define MITE_AMHOST_A32_BLOCK 0x0b
-#define MITE_AMHOST_A32D64_BLOCK 0x08
-#define MITE_AMHOST_A24_BLOCK 0x3b
-
-enum mite_registers {
- MITE_IODWBSR = 0xc0, // IO Device Window Base Size Register
- MITE_CSIGR = 0x460, // chip signature
- MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1 (used by 6602 boards)
- MITE_IODWCR_1 = 0xf4
-};
-
-enum MITE_IODWBSR_bits {
- WENAB = 0x80, // window enable
- WENAB_6602 = 0x8c // window enable for 6602 boards
-};
-
-#endif
-
diff --git a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c b/drivers/staging/gpib/tnt4882/tnt4882_gpib.c
deleted file mode 100644
index c03a976b7380..000000000000
--- a/drivers/staging/gpib/tnt4882/tnt4882_gpib.c
+++ /dev/null
@@ -1,1838 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-/***************************************************************************
- * National Instruments boards using tnt4882 or compatible chips (at-gpib, etc).
- * copyright : (C) 2001, 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#define dev_fmt pr_fmt
-#define DRV_NAME KBUILD_MODNAME
-
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/isapnp.h>
-
-#include "nec7210.h"
-#include "gpibP.h"
-#include "mite.h"
-#include "tnt4882_registers.h"
-
-static const int ISAPNP_VENDOR_ID_NI = ISAPNP_VENDOR('N', 'I', 'C');
-static const int ISAPNP_ID_NI_ATGPIB_TNT = 0xc601;
-enum {
- PCI_DEVICE_ID_NI_GPIB = 0xc801,
- PCI_DEVICE_ID_NI_GPIB_PLUS = 0xc811,
- PCI_DEVICE_ID_NI_GPIB_PLUS2 = 0x71ad,
- PCI_DEVICE_ID_NI_PXIGPIB = 0xc821,
- PCI_DEVICE_ID_NI_PMCGPIB = 0xc831,
- PCI_DEVICE_ID_NI_PCIEGPIB = 0x70cf,
- PCI_DEVICE_ID_NI_PCIE2GPIB = 0x710e,
-// Measurement Computing PCI-488 same design as PCI-GPIB with TNT5004
- PCI_DEVICE_ID_MC_PCI488 = 0x7259,
- PCI_DEVICE_ID_CEC_NI_GPIB = 0x7258
-};
-
-// struct which defines private_data for tnt4882 devices
-struct tnt4882_priv {
- struct nec7210_priv nec7210_priv;
- struct mite_struct *mite;
- struct pnp_dev *pnp_dev;
- unsigned int irq;
- unsigned short imr0_bits;
- unsigned short imr3_bits;
- unsigned short auxg_bits; // bits written to auxiliary register G
-};
-
-static irqreturn_t tnt4882_internal_interrupt(struct gpib_board *board);
-
-// register offset for nec7210 compatible registers
-static const int atgpib_reg_offset = 2;
-
-// number of ioports used
-static const int atgpib_iosize = 32;
-
-/* paged io */
-static inline unsigned int tnt_paged_readb(struct tnt4882_priv *priv, unsigned long offset)
-{
- iowrite8(AUX_PAGEIN, priv->nec7210_priv.mmiobase + AUXMR * priv->nec7210_priv.offset);
- udelay(1);
- return ioread8(priv->nec7210_priv.mmiobase + offset);
-}
-
-static inline void tnt_paged_writeb(struct tnt4882_priv *priv, unsigned int value,
- unsigned long offset)
-{
- iowrite8(AUX_PAGEIN, priv->nec7210_priv.mmiobase + AUXMR * priv->nec7210_priv.offset);
- udelay(1);
- iowrite8(value, priv->nec7210_priv.mmiobase + offset);
-}
-
-/* readb/writeb wrappers */
-static inline unsigned short tnt_readb(struct tnt4882_priv *priv, unsigned long offset)
-{
- void __iomem *address = priv->nec7210_priv.mmiobase + offset;
- unsigned long flags;
- unsigned short retval;
- spinlock_t *register_lock = &priv->nec7210_priv.register_page_lock;
-
- spin_lock_irqsave(register_lock, flags);
- switch (offset) {
- case CSR:
- case SASR:
- case ISR0:
- case BSR:
- switch (priv->nec7210_priv.type) {
- case TNT4882:
- case TNT5004:
- retval = ioread8(address);
- break;
- case NAT4882:
- retval = tnt_paged_readb(priv, offset - tnt_pagein_offset);
- break;
- case NEC7210:
- retval = 0;
- break;
- default:
- retval = 0;
- break;
- }
- break;
- default:
- retval = ioread8(address);
- break;
- }
- spin_unlock_irqrestore(register_lock, flags);
- return retval;
-}
-
-static inline void tnt_writeb(struct tnt4882_priv *priv, unsigned short value, unsigned long offset)
-{
- void __iomem *address = priv->nec7210_priv.mmiobase + offset;
- unsigned long flags;
- spinlock_t *register_lock = &priv->nec7210_priv.register_page_lock;
-
- spin_lock_irqsave(register_lock, flags);
- switch (offset) {
- case KEYREG:
- case IMR0:
- case BCR:
- switch (priv->nec7210_priv.type) {
- case TNT4882:
- case TNT5004:
- iowrite8(value, address);
- break;
- case NAT4882:
- tnt_paged_writeb(priv, value, offset - tnt_pagein_offset);
- break;
- case NEC7210:
- break;
- default:
- break;
- }
- break;
- default:
- iowrite8(value, address);
- break;
- }
- spin_unlock_irqrestore(register_lock, flags);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GPIB driver for National Instruments boards using tnt4882 or compatible chips");
-
-static int tnt4882_line_status(const struct gpib_board *board)
-{
- int status = VALID_ALL;
- int bcsr_bits;
- struct tnt4882_priv *tnt_priv;
-
- tnt_priv = board->private_data;
-
- bcsr_bits = tnt_readb(tnt_priv, BSR);
-
- if (bcsr_bits & BCSR_REN_BIT)
- status |= BUS_REN;
- if (bcsr_bits & BCSR_IFC_BIT)
- status |= BUS_IFC;
- if (bcsr_bits & BCSR_SRQ_BIT)
- status |= BUS_SRQ;
- if (bcsr_bits & BCSR_EOI_BIT)
- status |= BUS_EOI;
- if (bcsr_bits & BCSR_NRFD_BIT)
- status |= BUS_NRFD;
- if (bcsr_bits & BCSR_NDAC_BIT)
- status |= BUS_NDAC;
- if (bcsr_bits & BCSR_DAV_BIT)
- status |= BUS_DAV;
- if (bcsr_bits & BCSR_ATN_BIT)
- status |= BUS_ATN;
-
- return status;
-}
-
-static int tnt4882_t1_delay(struct gpib_board *board, unsigned int nano_sec)
-{
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
- unsigned int retval;
-
- retval = nec7210_t1_delay(board, nec_priv, nano_sec);
- if (nec_priv->type == NEC7210)
- return retval;
-
- if (nano_sec <= 350) {
- tnt_writeb(tnt_priv, MSTD, KEYREG);
- retval = 350;
- } else {
- tnt_writeb(tnt_priv, 0, KEYREG);
- }
- if (nano_sec > 500 && nano_sec <= 1100) {
- write_byte(nec_priv, AUXRI | USTD, AUXMR);
- retval = 1100;
- } else {
- write_byte(nec_priv, AUXRI, AUXMR);
- }
- return retval;
-}
-
-static int fifo_word_available(struct tnt4882_priv *tnt_priv)
-{
- int status2;
- int retval;
-
- status2 = tnt_readb(tnt_priv, STS2);
- retval = (status2 & AEFN) && (status2 & BEFN);
-
- return retval;
-}
-
-static int fifo_byte_available(struct tnt4882_priv *tnt_priv)
-{
- int status2;
- int retval;
-
- status2 = tnt_readb(tnt_priv, STS2);
- retval = (status2 & AEFN) || (status2 & BEFN);
-
- return retval;
-}
-
-static int fifo_xfer_done(struct tnt4882_priv *tnt_priv)
-{
- int status1;
- int retval;
-
- status1 = tnt_readb(tnt_priv, STS1);
- retval = status1 & (S_DONE | S_HALT);
-
- return retval;
-}
-
-static int drain_fifo_words(struct tnt4882_priv *tnt_priv, u8 *buffer, int num_bytes)
-{
- int count = 0;
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
-
- while (fifo_word_available(tnt_priv) && count + 2 <= num_bytes) {
- short word;
-
- word = ioread16(nec_priv->mmiobase + FIFOB);
- buffer[count++] = word & 0xff;
- buffer[count++] = (word >> 8) & 0xff;
- }
- return count;
-}
-
-static void tnt4882_release_holdoff(struct gpib_board *board, struct tnt4882_priv *tnt_priv)
-{
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
- unsigned short sasr_bits;
-
- sasr_bits = tnt_readb(tnt_priv, SASR);
-
- /*
- * tnt4882 not in one-chip mode won't always release holdoff unless we
- * are in the right mode when release handshake command is given
- */
- if (sasr_bits & AEHS_BIT) /* holding off due to holdoff on end mode*/ {
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
- write_byte(nec_priv, AUX_FH, AUXMR);
- } else if (sasr_bits & ANHS1_BIT) { /* held off due to holdoff on all data mode*/
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDA);
- write_byte(nec_priv, AUX_FH, AUXMR);
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
- } else { /* held off due to holdoff immediately command */
- nec7210_set_handshake_mode(board, nec_priv, HR_HLDE);
- write_byte(nec_priv, AUX_FH, AUXMR);
- }
-}
-
-static int tnt4882_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- size_t count = 0;
- ssize_t retval = 0;
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
- unsigned int bits;
- s32 hw_count;
- unsigned long flags;
-
- *bytes_read = 0;
- // FIXME: really, DEV_CLEAR_BN should happen elsewhere to prevent race
- clear_bit(DEV_CLEAR_BN, &nec_priv->state);
- clear_bit(ADR_CHANGE_BN, &nec_priv->state);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_ENDIE, HR_ENDIE);
- if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004)
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, HR_DMAI);
- else
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- tnt_writeb(tnt_priv, nec_priv->auxa_bits | HR_HLDA, CCR);
- bits = TNT_B_16BIT | TNT_IN | TNT_CCEN;
- tnt_writeb(tnt_priv, bits, CFG);
- tnt_writeb(tnt_priv, RESET_FIFO, CMDR);
- udelay(1);
- // load 2's complement of count into hardware counters
- hw_count = -length;
- tnt_writeb(tnt_priv, hw_count & 0xff, CNT0);
- tnt_writeb(tnt_priv, (hw_count >> 8) & 0xff, CNT1);
- tnt_writeb(tnt_priv, (hw_count >> 16) & 0xff, CNT2);
- tnt_writeb(tnt_priv, (hw_count >> 24) & 0xff, CNT3);
-
- tnt4882_release_holdoff(board, tnt_priv);
-
- tnt_writeb(tnt_priv, GO, CMDR);
- udelay(1);
-
- spin_lock_irqsave(&board->spinlock, flags);
- tnt_priv->imr3_bits |= HR_DONE | HR_NEF;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- while (count + 2 <= length &&
- test_bit(RECEIVED_END_BN, &nec_priv->state) == 0 &&
- fifo_xfer_done(tnt_priv) == 0) {
- // wait until a word is ready
- if (wait_event_interruptible(board->wait,
- fifo_word_available(tnt_priv) ||
- fifo_xfer_done(tnt_priv) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(ADR_CHANGE_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- break;
- }
- if (test_bit(TIMO_NUM, &board->status)) {
- retval = -ETIMEDOUT;
- break;
- }
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state)) {
- retval = -EINTR;
- break;
- }
- if (test_bit(ADR_CHANGE_BN, &nec_priv->state)) {
- retval = -EINTR;
- break;
- }
-
- spin_lock_irqsave(&board->spinlock, flags);
- count += drain_fifo_words(tnt_priv, &buffer[count], length - count);
- tnt_priv->imr3_bits |= HR_NEF;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- if (need_resched())
- schedule();
- }
- // wait for last byte
- if (count < length) {
- spin_lock_irqsave(&board->spinlock, flags);
- tnt_priv->imr3_bits |= HR_DONE | HR_NEF;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- if (wait_event_interruptible(board->wait,
- fifo_xfer_done(tnt_priv) ||
- test_bit(RECEIVED_END_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(ADR_CHANGE_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status))) {
- retval = -ERESTARTSYS;
- }
- if (test_bit(TIMO_NUM, &board->status))
- retval = -ETIMEDOUT;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- retval = -EINTR;
- if (test_bit(ADR_CHANGE_BN, &nec_priv->state))
- retval = -EINTR;
- count += drain_fifo_words(tnt_priv, &buffer[count], length - count);
- if (fifo_byte_available(tnt_priv) && count < length)
- buffer[count++] = tnt_readb(tnt_priv, FIFOB);
- }
- if (count < length)
- tnt_writeb(tnt_priv, STOP, CMDR);
- udelay(1);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_ENDIE, 0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAI, 0);
- /*
- * force handling of any pending interrupts (seems to be needed
- * to keep interrupts from getting hosed, plus for syncing
- * with RECEIVED_END below)
- */
- tnt4882_internal_interrupt(board);
- /* RECEIVED_END should be in sync now */
- if (test_and_clear_bit(RECEIVED_END_BN, &nec_priv->state))
- *end = 1;
- if (retval < 0) {
- // force immediate holdoff
- write_byte(nec_priv, AUX_HLDI, AUXMR);
-
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
- }
- *bytes_read = count;
-
- return retval;
-}
-
-static int fifo_space_available(struct tnt4882_priv *tnt_priv)
-{
- int status2;
- int retval;
-
- status2 = tnt_readb(tnt_priv, STS2);
- retval = (status2 & AFFN) && (status2 & BFFN);
-
- return retval;
-}
-
-static unsigned int tnt_transfer_count(struct tnt4882_priv *tnt_priv)
-{
- unsigned int count = 0;
-
- count |= tnt_readb(tnt_priv, CNT0) & 0xff;
- count |= (tnt_readb(tnt_priv, CNT1) << 8) & 0xff00;
- count |= (tnt_readb(tnt_priv, CNT2) << 16) & 0xff0000;
- count |= (tnt_readb(tnt_priv, CNT3) << 24) & 0xff000000;
- // return two's complement
- return -count;
-};
-
-static int write_wait(struct gpib_board *board, struct tnt4882_priv *tnt_priv,
- int wait_for_done, int send_commands)
-{
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
-
- if (wait_event_interruptible(board->wait,
- (!wait_for_done && fifo_space_available(tnt_priv)) ||
- fifo_xfer_done(tnt_priv) ||
- test_bit(BUS_ERROR_BN, &nec_priv->state) ||
- test_bit(DEV_CLEAR_BN, &nec_priv->state) ||
- test_bit(TIMO_NUM, &board->status)))
- return -ERESTARTSYS;
-
- if (test_bit(TIMO_NUM, &board->status))
- return -ETIMEDOUT;
- if (test_and_clear_bit(BUS_ERROR_BN, &nec_priv->state))
- return (send_commands) ? -ENOTCONN : -ECOMM;
- if (test_bit(DEV_CLEAR_BN, &nec_priv->state))
- return -EINTR;
- return 0;
-}
-
-static int generic_write(struct gpib_board *board, u8 *buffer, size_t length,
- int send_eoi, int send_commands, size_t *bytes_written)
-{
- size_t count = 0;
- ssize_t retval = 0;
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
- unsigned int bits;
- s32 hw_count;
- unsigned long flags;
-
- *bytes_written = 0;
- // FIXME: really, DEV_CLEAR_BN should happen elsewhere to prevent race
- clear_bit(DEV_CLEAR_BN, &nec_priv->state);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_ERRIE, HR_ERRIE);
-
- if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004)
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, HR_DMAO);
- else
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0);
-
- tnt_writeb(tnt_priv, RESET_FIFO, CMDR);
- udelay(1);
-
- bits = TNT_B_16BIT;
- if (send_eoi) {
- bits |= TNT_CCEN;
- if (nec_priv->type != TNT4882 && nec_priv->type != TNT5004)
- tnt_writeb(tnt_priv, AUX_SEOI, CCR);
- }
- if (send_commands)
- bits |= TNT_COMMAND;
- tnt_writeb(tnt_priv, bits, CFG);
-
- // load 2's complement of count into hardware counters
- hw_count = -length;
- tnt_writeb(tnt_priv, hw_count & 0xff, CNT0);
- tnt_writeb(tnt_priv, (hw_count >> 8) & 0xff, CNT1);
- tnt_writeb(tnt_priv, (hw_count >> 16) & 0xff, CNT2);
- tnt_writeb(tnt_priv, (hw_count >> 24) & 0xff, CNT3);
-
- tnt_writeb(tnt_priv, GO, CMDR);
- udelay(1);
-
- spin_lock_irqsave(&board->spinlock, flags);
- tnt_priv->imr3_bits |= HR_DONE;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- while (count < length) {
- // wait until byte is ready to be sent
- retval = write_wait(board, tnt_priv, 0, send_commands);
- if (retval < 0)
- break;
- if (fifo_xfer_done(tnt_priv))
- break;
- spin_lock_irqsave(&board->spinlock, flags);
- while (fifo_space_available(tnt_priv) && count < length) {
- u16 word;
-
- word = buffer[count++] & 0xff;
- if (count < length)
- word |= (buffer[count++] << 8) & 0xff00;
- iowrite16(word, nec_priv->mmiobase + FIFOB);
- }
-// avoid unnecessary HR_NFF interrupts
-// tnt_priv->imr3_bits |= HR_NFF;
-// tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- spin_unlock_irqrestore(&board->spinlock, flags);
-
- if (need_resched())
- schedule();
- }
- // wait last byte has been sent
- if (retval == 0)
- retval = write_wait(board, tnt_priv, 1, send_commands);
-
- tnt_writeb(tnt_priv, STOP, CMDR);
- udelay(1);
-
- nec7210_set_reg_bits(nec_priv, IMR1, HR_ERR, 0x0);
- nec7210_set_reg_bits(nec_priv, IMR2, HR_DMAO, 0x0);
- /*
- * force handling of any interrupts that happened
- * while they were masked (this appears to be needed)
- */
- tnt4882_internal_interrupt(board);
- *bytes_written = length - tnt_transfer_count(tnt_priv);
- return retval;
-}
-
-static int tnt4882_accel_write(struct gpib_board *board, u8 *buffer,
- size_t length, int send_eoi, size_t *bytes_written)
-{
- return generic_write(board, buffer, length, send_eoi, 0, bytes_written);
-}
-
-static int tnt4882_command(struct gpib_board *board, u8 *buffer, size_t length,
- size_t *bytes_written)
-{
- return generic_write(board, buffer, length, 0, 1, bytes_written);
-}
-
-static irqreturn_t tnt4882_internal_interrupt(struct gpib_board *board)
-{
- struct tnt4882_priv *priv = board->private_data;
- int isr0_bits, isr3_bits, imr3_bits;
- unsigned long flags;
-
- spin_lock_irqsave(&board->spinlock, flags);
-
- nec7210_interrupt(board, &priv->nec7210_priv);
-
- isr0_bits = tnt_readb(priv, ISR0);
- isr3_bits = tnt_readb(priv, ISR3);
- imr3_bits = priv->imr3_bits;
-
- if (isr0_bits & TNT_IFCI_BIT)
- push_gpib_event(board, EVENT_IFC);
- // XXX don't need this wakeup, one below should do?
-// wake_up_interruptible(&board->wait);
-
- if (isr3_bits & HR_NFF)
- priv->imr3_bits &= ~HR_NFF;
- if (isr3_bits & HR_NEF)
- priv->imr3_bits &= ~HR_NEF;
- if (isr3_bits & HR_DONE)
- priv->imr3_bits &= ~HR_DONE;
- if (isr3_bits & (HR_INTR | HR_TLCI)) {
- dev_dbg(board->gpib_dev, "minor %i isr0 0x%x imr0 0x%x isr3 0x%x imr3 0x%x\n",
- board->minor, isr0_bits, priv->imr0_bits, isr3_bits, imr3_bits);
- tnt_writeb(priv, priv->imr3_bits, IMR3);
- wake_up_interruptible(&board->wait);
- }
- spin_unlock_irqrestore(&board->spinlock, flags);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t tnt4882_interrupt(int irq, void *arg)
-{
- return tnt4882_internal_interrupt(arg);
-}
-
-// wrappers for interface functions
-static int tnt4882_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
- size_t *bytes_read)
-{
- struct tnt4882_priv *priv = board->private_data;
- struct nec7210_priv *nec_priv = &priv->nec7210_priv;
- int retval;
- int dummy;
-
- retval = nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read);
-
- if (retval < 0) { // force immediate holdoff
- write_byte(nec_priv, AUX_HLDI, AUXMR);
-
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
-
- nec7210_read_data_in(board, nec_priv, &dummy);
- }
- return retval;
-}
-
-static int tnt4882_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
- size_t *bytes_written)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written);
-}
-
-static int tnt4882_command_unaccel(struct gpib_board *board, u8 *buffer,
- size_t length, size_t *bytes_written)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written);
-}
-
-static int tnt4882_take_control(struct gpib_board *board, int synchronous)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_take_control(board, &priv->nec7210_priv, synchronous);
-}
-
-static int tnt4882_go_to_standby(struct gpib_board *board)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_go_to_standby(board, &priv->nec7210_priv);
-}
-
-static int tnt4882_request_system_control(struct gpib_board *board, int request_control)
-{
- struct tnt4882_priv *priv = board->private_data;
- int retval;
-
- if (request_control) {
- tnt_writeb(priv, SETSC, CMDR);
- udelay(1);
- }
- retval = nec7210_request_system_control(board, &priv->nec7210_priv, request_control);
- if (!request_control) {
- tnt_writeb(priv, CLRSC, CMDR);
- udelay(1);
- }
- return retval;
-}
-
-static void tnt4882_interface_clear(struct gpib_board *board, int assert)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_interface_clear(board, &priv->nec7210_priv, assert);
-}
-
-static void tnt4882_remote_enable(struct gpib_board *board, int enable)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_remote_enable(board, &priv->nec7210_priv, enable);
-}
-
-static int tnt4882_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits);
-}
-
-static void tnt4882_disable_eos(struct gpib_board *board)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_disable_eos(board, &priv->nec7210_priv);
-}
-
-static unsigned int tnt4882_update_status(struct gpib_board *board, unsigned int clear_mask)
-{
- unsigned long flags;
- u8 line_status;
- struct tnt4882_priv *priv = board->private_data;
-
- spin_lock_irqsave(&board->spinlock, flags);
- board->status &= ~clear_mask;
- nec7210_update_status_nolock(board, &priv->nec7210_priv);
- /* set / clear SRQ state since it is not cleared by interrupt */
- line_status = tnt_readb(priv, BSR);
- if (line_status & BCSR_SRQ_BIT)
- set_bit(SRQI_NUM, &board->status);
- else
- clear_bit(SRQI_NUM, &board->status);
- spin_unlock_irqrestore(&board->spinlock, flags);
- return board->status;
-}
-
-static int tnt4882_primary_address(struct gpib_board *board, unsigned int address)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_primary_address(board, &priv->nec7210_priv, address);
-}
-
-static int tnt4882_secondary_address(struct gpib_board *board, unsigned int address, int enable)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable);
-}
-
-static int tnt4882_parallel_poll(struct gpib_board *board, u8 *result)
-{
- struct tnt4882_priv *tnt_priv = board->private_data;
-
- if (tnt_priv->nec7210_priv.type != NEC7210) {
- tnt_priv->auxg_bits |= RPP2_BIT;
- write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR);
- udelay(2); // FIXME use parallel poll timeout
- *result = read_byte(&tnt_priv->nec7210_priv, CPTR);
- tnt_priv->auxg_bits &= ~RPP2_BIT;
- write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR);
- return 0;
- } else {
- return nec7210_parallel_poll(board, &tnt_priv->nec7210_priv, result);
- }
-}
-
-static void tnt4882_parallel_poll_configure(struct gpib_board *board, u8 config)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- if (priv->nec7210_priv.type == TNT5004) {
- /* configure locally */
- write_byte(&priv->nec7210_priv, AUXRI | 0x4, AUXMR);
- if (config)
- /* set response + clear sense */
- write_byte(&priv->nec7210_priv, PPR | config, AUXMR);
- else
- /* disable ppoll */
- write_byte(&priv->nec7210_priv, PPR | 0x10, AUXMR);
- } else {
- nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config);
- }
-}
-
-static void tnt4882_parallel_poll_response(struct gpib_board *board, int ist)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist);
-}
-
-/*
- * this is just used by the old nec7210 isa interfaces, the newer
- * boards use tnt4882_serial_poll_response2
- */
-static void tnt4882_serial_poll_response(struct gpib_board *board, u8 status)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_serial_poll_response(board, &priv->nec7210_priv, status);
-}
-
-static void tnt4882_serial_poll_response2(struct gpib_board *board, u8 status,
- int new_reason_for_service)
-{
- struct tnt4882_priv *priv = board->private_data;
- unsigned long flags;
- const int MSS = status & request_service_bit;
- const int reqt = MSS && new_reason_for_service;
- const int reqf = MSS == 0;
-
- spin_lock_irqsave(&board->spinlock, flags);
- if (reqt) {
- priv->nec7210_priv.srq_pending = 1;
- clear_bit(SPOLL_NUM, &board->status);
- } else {
- if (reqf)
- priv->nec7210_priv.srq_pending = 0;
- }
- if (reqt)
- /*
- * It may seem like a race to issue reqt before updating
- * the status byte, but it is not. The chip does not
- * issue the reqt until the SPMR is written to at
- * a later time.
- */
- write_byte(&priv->nec7210_priv, AUX_REQT, AUXMR);
- else if (reqf)
- write_byte(&priv->nec7210_priv, AUX_REQF, AUXMR);
- /*
- * We need to always zero bit 6 of the status byte before writing it to
- * the SPMR to insure we are using
- * serial poll mode SP1, and not accidentally triggering mode SP3.
- */
- write_byte(&priv->nec7210_priv, status & ~request_service_bit, SPMR);
- spin_unlock_irqrestore(&board->spinlock, flags);
-}
-
-static u8 tnt4882_serial_poll_status(struct gpib_board *board)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- return nec7210_serial_poll_status(board, &priv->nec7210_priv);
-}
-
-static void tnt4882_return_to_local(struct gpib_board *board)
-{
- struct tnt4882_priv *priv = board->private_data;
-
- nec7210_return_to_local(board, &priv->nec7210_priv);
-}
-
-static void tnt4882_board_reset(struct tnt4882_priv *tnt_priv, struct gpib_board *board)
-{
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
-
- tnt_priv->imr0_bits = 0;
- tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0);
- tnt_priv->imr3_bits = 0;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
- tnt_readb(tnt_priv, IMR0);
- tnt_readb(tnt_priv, IMR3);
- nec7210_board_reset(nec_priv, board);
-}
-
-static int tnt4882_allocate_private(struct gpib_board *board)
-{
- struct tnt4882_priv *tnt_priv;
-
- board->private_data = kmalloc(sizeof(struct tnt4882_priv), GFP_KERNEL);
- if (!board->private_data)
- return -1;
- tnt_priv = board->private_data;
- memset(tnt_priv, 0, sizeof(struct tnt4882_priv));
- init_nec7210_private(&tnt_priv->nec7210_priv);
- return 0;
-}
-
-static void tnt4882_free_private(struct gpib_board *board)
-{
- kfree(board->private_data);
- board->private_data = NULL;
-}
-
-static void tnt4882_init(struct tnt4882_priv *tnt_priv, const struct gpib_board *board)
-{
- struct nec7210_priv *nec_priv = &tnt_priv->nec7210_priv;
-
- /* Turbo488 software reset */
- tnt_writeb(tnt_priv, SOFT_RESET, CMDR);
- udelay(1);
-
- // turn off one-chip mode
- tnt_writeb(tnt_priv, NODMA, HSSEL);
- tnt_writeb(tnt_priv, 0, ACCWR);
- // make sure we are in 7210 mode
- tnt_writeb(tnt_priv, AUX_7210, AUXCR);
- udelay(1);
- // registers might be swapped, so write it to the swapped address too
- tnt_writeb(tnt_priv, AUX_7210, SWAPPED_AUXCR);
- udelay(1);
- // turn on one-chip mode
- if (nec_priv->type == TNT4882 || nec_priv->type == TNT5004)
- tnt_writeb(tnt_priv, NODMA | TNT_ONE_CHIP_BIT, HSSEL);
- else
- tnt_writeb(tnt_priv, NODMA, HSSEL);
-
- nec7210_board_reset(nec_priv, board);
- // read-clear isr0
- tnt_readb(tnt_priv, ISR0);
-
- // enable passing of nat4882 interrupts
- tnt_priv->imr3_bits = HR_TLCI;
- tnt_writeb(tnt_priv, tnt_priv->imr3_bits, IMR3);
-
- // enable interrupt
- tnt_writeb(tnt_priv, 0x1, INTRT);
-
- // force immediate holdoff
- write_byte(&tnt_priv->nec7210_priv, AUX_HLDI, AUXMR);
-
- set_bit(RFD_HOLDOFF_BN, &nec_priv->state);
-
- tnt_priv->auxg_bits = AUXRG | NTNL_BIT;
- write_byte(&tnt_priv->nec7210_priv, tnt_priv->auxg_bits, AUXMR);
-
- nec7210_board_online(nec_priv, board);
- // enable interface clear interrupt for event queue
- tnt_priv->imr0_bits = TNT_IMR0_ALWAYS_BITS | TNT_ATNI_BIT | TNT_IFCIE_BIT;
- tnt_writeb(tnt_priv, tnt_priv->imr0_bits, IMR0);
-}
-
-static int ni_pci_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct tnt4882_priv *tnt_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = IRQF_SHARED;
- int retval;
- struct mite_struct *mite;
-
- board->status = 0;
-
- if (tnt4882_allocate_private(board))
- return -ENOMEM;
- tnt_priv = board->private_data;
- nec_priv = &tnt_priv->nec7210_priv;
- nec_priv->type = TNT4882;
- nec_priv->read_byte = nec7210_locking_iomem_read_byte;
- nec_priv->write_byte = nec7210_locking_iomem_write_byte;
- nec_priv->offset = atgpib_reg_offset;
-
- if (!mite_devices)
- return -ENODEV;
-
- for (mite = mite_devices; mite; mite = mite->next) {
- short found_board;
-
- if (mite->used)
- continue;
- if (config->pci_bus >= 0 && config->pci_bus != mite->pcidev->bus->number)
- continue;
- if (config->pci_slot >= 0 && config->pci_slot != PCI_SLOT(mite->pcidev->devfn))
- continue;
- switch (mite_device_id(mite)) {
- case PCI_DEVICE_ID_NI_GPIB:
- case PCI_DEVICE_ID_NI_GPIB_PLUS:
- case PCI_DEVICE_ID_NI_GPIB_PLUS2:
- case PCI_DEVICE_ID_NI_PXIGPIB:
- case PCI_DEVICE_ID_NI_PMCGPIB:
- case PCI_DEVICE_ID_NI_PCIEGPIB:
- case PCI_DEVICE_ID_NI_PCIE2GPIB:
-// support for Measurement Computing PCI-488
- case PCI_DEVICE_ID_MC_PCI488:
- case PCI_DEVICE_ID_CEC_NI_GPIB:
- found_board = 1;
- break;
- default:
- found_board = 0;
- break;
- }
- if (found_board)
- break;
- }
- if (!mite)
- return -ENODEV;
-
- tnt_priv->mite = mite;
- retval = mite_setup(tnt_priv->mite);
- if (retval < 0)
- return retval;
-
- nec_priv->mmiobase = tnt_priv->mite->daq_io_addr;
-
- // get irq
- retval = request_irq(mite_irq(tnt_priv->mite), tnt4882_interrupt, isr_flags, "ni-pci-gpib",
- board);
- if (retval) {
- dev_err(board->gpib_dev, "failed to obtain pci irq %d\n", mite_irq(tnt_priv->mite));
- return retval;
- }
- tnt_priv->irq = mite_irq(tnt_priv->mite);
-
- // TNT5004 detection
- switch (tnt_readb(tnt_priv, CSR) & 0xf0) {
- case 0x30:
- nec_priv->type = TNT4882;
- break;
- case 0x40:
- nec_priv->type = TNT5004;
- break;
- }
- tnt4882_init(tnt_priv, board);
-
- return 0;
-}
-
-static void ni_pci_detach(struct gpib_board *board)
-{
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (tnt_priv) {
- nec_priv = &tnt_priv->nec7210_priv;
-
- if (nec_priv->mmiobase)
- tnt4882_board_reset(tnt_priv, board);
- if (tnt_priv->irq)
- free_irq(tnt_priv->irq, board);
- if (tnt_priv->mite)
- mite_unsetup(tnt_priv->mite);
- }
- tnt4882_free_private(board);
-}
-
-static int ni_isapnp_find(struct pnp_dev **dev)
-{
- *dev = pnp_find_dev(NULL, ISAPNP_VENDOR_ID_NI,
- ISAPNP_FUNCTION(ISAPNP_ID_NI_ATGPIB_TNT), NULL);
- if (!*dev || !(*dev)->card)
- return -ENODEV;
- if (pnp_device_attach(*dev) < 0)
- return -EBUSY;
- if (pnp_activate_dev(*dev) < 0) {
- pnp_device_detach(*dev);
- return -EAGAIN;
- }
- if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) {
- pnp_device_detach(*dev);
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_isa_attach_common(struct gpib_board *board, const struct gpib_board_config *config,
- enum nec7210_chipset chipset)
-{
- struct tnt4882_priv *tnt_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = 0;
- u32 iobase;
- int irq;
- int retval;
-
- board->status = 0;
-
- if (tnt4882_allocate_private(board))
- return -ENOMEM;
- tnt_priv = board->private_data;
- nec_priv = &tnt_priv->nec7210_priv;
- nec_priv->type = chipset;
- nec_priv->read_byte = nec7210_locking_ioport_read_byte;
- nec_priv->write_byte = nec7210_locking_ioport_write_byte;
- nec_priv->offset = atgpib_reg_offset;
-
- // look for plug-n-play board
- if (config->ibbase == 0) {
- struct pnp_dev *dev;
-
- retval = ni_isapnp_find(&dev);
- if (retval < 0)
- return retval;
- tnt_priv->pnp_dev = dev;
- iobase = pnp_port_start(dev, 0);
- irq = pnp_irq(dev, 0);
- } else {
- iobase = config->ibbase;
- irq = config->ibirq;
- }
- // allocate ioports
- if (!request_region(iobase, atgpib_iosize, "atgpib"))
- return -EBUSY;
-
- nec_priv->mmiobase = ioport_map(iobase, atgpib_iosize);
- if (!nec_priv->mmiobase)
- return -EBUSY;
-
- // get irq
- retval = request_irq(irq, tnt4882_interrupt, isr_flags, "atgpib", board);
- if (retval) {
- dev_err(board->gpib_dev, "failed to request ISA irq %d\n", irq);
- return retval;
- }
- tnt_priv->irq = irq;
-
- tnt4882_init(tnt_priv, board);
-
- return 0;
-}
-
-static int ni_tnt_isa_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return ni_isa_attach_common(board, config, TNT4882);
-}
-
-static int ni_nat4882_isa_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return ni_isa_attach_common(board, config, NAT4882);
-}
-
-static int ni_nec_isa_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- return ni_isa_attach_common(board, config, NEC7210);
-}
-
-static void ni_isa_detach(struct gpib_board *board)
-{
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (tnt_priv) {
- nec_priv = &tnt_priv->nec7210_priv;
- if (nec_priv->iobase)
- tnt4882_board_reset(tnt_priv, board);
- if (tnt_priv->irq)
- free_irq(tnt_priv->irq, board);
- if (nec_priv->mmiobase)
- ioport_unmap(nec_priv->mmiobase);
- if (nec_priv->iobase)
- release_region(nec_priv->iobase, atgpib_iosize);
- if (tnt_priv->pnp_dev)
- pnp_device_detach(tnt_priv->pnp_dev);
- }
- tnt4882_free_private(board);
-}
-
-static int tnt4882_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return 0;
-}
-
-static struct gpib_interface ni_pci_interface = {
- .name = "ni_pci",
- .attach = ni_pci_attach,
- .detach = ni_pci_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_pci_accel_interface = {
- .name = "ni_pci_accel",
- .attach = ni_pci_attach,
- .detach = ni_pci_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_isa_interface = {
- .name = "ni_isa",
- .attach = ni_tnt_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_nat4882_isa_interface = {
- .name = "ni_nat4882_isa",
- .attach = ni_nat4882_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_read,
- .write = tnt4882_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_nec_isa_interface = {
- .name = "ni_nec_isa",
- .attach = ni_nec_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_read,
- .write = tnt4882_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_isa_accel_interface = {
- .name = "ni_isa_accel",
- .attach = ni_tnt_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_nat4882_isa_accel_interface = {
- .name = "ni_nat4882_isa_accel",
- .attach = ni_nat4882_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response2 = tnt4882_serial_poll_response2,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_nec_isa_accel_interface = {
- .name = "ni_nec_isa_accel",
- .attach = ni_nec_isa_attach,
- .detach = ni_isa_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command_unaccel,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = NULL,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static const struct pci_device_id tnt4882_pci_table[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB_PLUS)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_GPIB_PLUS2)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PXIGPIB)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PMCGPIB)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PCIEGPIB)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_NI_PCIE2GPIB)},
- // support for Measurement Computing PCI-488
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_MC_PCI488)},
- {PCI_DEVICE(PCI_VENDOR_ID_NATINST, PCI_DEVICE_ID_CEC_NI_GPIB)},
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, tnt4882_pci_table);
-
-static struct pci_driver tnt4882_pci_driver = {
- .name = DRV_NAME,
- .id_table = tnt4882_pci_table,
- .probe = &tnt4882_pci_probe
-};
-
-#if 0
-/* unused, will be needed when the driver is turned into a pnp_driver */
-static const struct pnp_device_id tnt4882_pnp_table[] = {
- {.id = "NICC601"},
- {.id = ""}
-};
-MODULE_DEVICE_TABLE(pnp, tnt4882_pnp_table);
-#endif
-
-#ifdef CONFIG_GPIB_PCMCIA
-static struct gpib_interface ni_pcmcia_interface;
-static struct gpib_interface ni_pcmcia_accel_interface;
-static int __init init_ni_gpib_cs(void);
-static void __exit exit_ni_gpib_cs(void);
-#endif
-
-static int __init tnt4882_init_module(void)
-{
- int result;
-
- result = pci_register_driver(&tnt4882_pci_driver);
- if (result) {
- pr_err("pci_register_driver failed: error = %d\n", result);
- return result;
- }
-
- result = gpib_register_driver(&ni_isa_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_isa;
- }
-
- result = gpib_register_driver(&ni_isa_accel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_isa_accel;
- }
-
- result = gpib_register_driver(&ni_nat4882_isa_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_nat4882_isa;
- }
-
- result = gpib_register_driver(&ni_nat4882_isa_accel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_nat4882_isa_accel;
- }
-
- result = gpib_register_driver(&ni_nec_isa_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_nec_isa;
- }
-
- result = gpib_register_driver(&ni_nec_isa_accel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_nec_isa_accel;
- }
-
- result = gpib_register_driver(&ni_pci_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pci;
- }
-
- result = gpib_register_driver(&ni_pci_accel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pci_accel;
- }
-
-#ifdef CONFIG_GPIB_PCMCIA
- result = gpib_register_driver(&ni_pcmcia_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pcmcia;
- }
-
- result = gpib_register_driver(&ni_pcmcia_accel_interface, THIS_MODULE);
- if (result) {
- pr_err("gpib_register_driver failed: error = %d\n", result);
- goto err_pcmcia_accel;
- }
-
- result = init_ni_gpib_cs();
- if (result) {
- pr_err("pcmcia_register_driver failed: error = %d\n", result);
- goto err_pcmcia_driver;
- }
-#endif
-
- mite_init();
-
- return 0;
-
-#ifdef CONFIG_GPIB_PCMCIA
-err_pcmcia_driver:
- gpib_unregister_driver(&ni_pcmcia_accel_interface);
-err_pcmcia_accel:
- gpib_unregister_driver(&ni_pcmcia_interface);
-err_pcmcia:
-#endif
- gpib_unregister_driver(&ni_pci_accel_interface);
-err_pci_accel:
- gpib_unregister_driver(&ni_pci_interface);
-err_pci:
- gpib_unregister_driver(&ni_nec_isa_accel_interface);
-err_nec_isa_accel:
- gpib_unregister_driver(&ni_nec_isa_interface);
-err_nec_isa:
- gpib_unregister_driver(&ni_nat4882_isa_accel_interface);
-err_nat4882_isa_accel:
- gpib_unregister_driver(&ni_nat4882_isa_interface);
-err_nat4882_isa:
- gpib_unregister_driver(&ni_isa_accel_interface);
-err_isa_accel:
- gpib_unregister_driver(&ni_isa_interface);
-err_isa:
- pci_unregister_driver(&tnt4882_pci_driver);
-
- return result;
-}
-
-static void __exit tnt4882_exit_module(void)
-{
- gpib_unregister_driver(&ni_isa_interface);
- gpib_unregister_driver(&ni_isa_accel_interface);
- gpib_unregister_driver(&ni_nat4882_isa_interface);
- gpib_unregister_driver(&ni_nat4882_isa_accel_interface);
- gpib_unregister_driver(&ni_nec_isa_interface);
- gpib_unregister_driver(&ni_nec_isa_accel_interface);
- gpib_unregister_driver(&ni_pci_interface);
- gpib_unregister_driver(&ni_pci_accel_interface);
-#ifdef CONFIG_GPIB_PCMCIA
- gpib_unregister_driver(&ni_pcmcia_interface);
- gpib_unregister_driver(&ni_pcmcia_accel_interface);
- exit_ni_gpib_cs();
-#endif
-
- mite_cleanup();
-
- pci_unregister_driver(&tnt4882_pci_driver);
-}
-
-#ifdef CONFIG_GPIB_PCMCIA
-
-#include <linux/kernel.h>
-#include <linux/moduleparam.h>
-#include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-static int ni_gpib_config(struct pcmcia_device *link);
-static void ni_gpib_release(struct pcmcia_device *link);
-static void ni_pcmcia_detach(struct gpib_board *board);
-
-/*
- * A linked list of "instances" of the dummy device. Each actual
- * PCMCIA card corresponds to one device instance, and is described
- * by one dev_link_t structure (defined in ds.h).
- *
- * You may not want to use a linked list for this -- for example, the
- * memory card driver uses an array of dev_link_t pointers, where minor
- * device numbers are used to derive the corresponding array index.
- *
- * I think this dev_list is obsolete but the pointer is needed to keep
- * the module instance for the ni_pcmcia_attach function.
- */
-
-static struct pcmcia_device *curr_dev;
-
-struct local_info_t {
- struct pcmcia_device *p_dev;
- struct gpib_board *dev;
- int stop;
- struct bus_operations *bus;
-};
-
-/*
- * ni_gpib_probe() creates an "instance" of the driver, allocating
- * local data structures for one device. The device is registered
- * with Card Services.
- */
-
-static int ni_gpib_probe(struct pcmcia_device *link)
-{
- struct local_info_t *info;
- //struct struct gpib_board *dev;
-
- /* Allocate space for private device-specific data */
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->p_dev = link;
- link->priv = info;
-
- /*
- * General socket configuration defaults can go here. In this
- * client, we assume very little, and rely on the CIS for almost
- * everything. In most clients, many details (i.e., number, sizes,
- * and attributes of IO windows) are fixed by the nature of the
- * device, and can be hard-wired here.
- */
- link->config_flags = CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
- /* Register with Card Services */
- curr_dev = link;
- return ni_gpib_config(link);
-}
-
-/*
- * This deletes a driver "instance". The device is de-registered
- * with Card Services. If it has been released, all local data
- * structures are freed. Otherwise, the structures will be freed
- * when the device is released.
- */
-static void ni_gpib_remove(struct pcmcia_device *link)
-{
- struct local_info_t *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (info->dev)
- ni_pcmcia_detach(info->dev);
- ni_gpib_release(link);
-
- //free_netdev(dev);
- kfree(info);
-}
-
-static int ni_gpib_config_iteration(struct pcmcia_device *link, void *priv_data)
-{
- int retval;
-
- retval = pcmcia_request_io(link);
- if (retval != 0)
- return retval;
-
- return 0;
-}
-
-/*
- * ni_gpib_config() is scheduled to run after a CARD_INSERTION event
- * is received, to configure the PCMCIA socket, and to make the
- * device available to the system.
- */
-static int ni_gpib_config(struct pcmcia_device *link)
-{
- //struct local_info_t *info = link->priv;
- //struct gpib_board *dev = info->dev;
- int last_ret;
-
- last_ret = pcmcia_loop_config(link, &ni_gpib_config_iteration, NULL);
- if (last_ret) {
- dev_warn(&link->dev, "no configuration found\n");
- ni_gpib_release(link);
- return last_ret;
- }
-
- last_ret = pcmcia_enable_device(link);
- if (last_ret) {
- ni_gpib_release(link);
- return last_ret;
- }
- return 0;
-} /* ni_gpib_config */
-
-/*
- * After a card is removed, ni_gpib_release() will unregister the
- * device, and release the PCMCIA configuration. If the device is
- * still open, this will be postponed until it is closed.
- */
-static void ni_gpib_release(struct pcmcia_device *link)
-{
- pcmcia_disable_device(link);
-} /* ni_gpib_release */
-
-static int ni_gpib_suspend(struct pcmcia_device *link)
-{
- //struct local_info_t *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- if (link->open)
- dev_warn(&link->dev, "Device still open\n");
- //netif_device_detach(dev);
-
- return 0;
-}
-
-static int ni_gpib_resume(struct pcmcia_device *link)
-{
- //struct local_info_t *info = link->priv;
- //struct struct gpib_board *dev = info->dev;
-
- /*if (link->open) {
- * ni_gpib_probe(dev); / really?
- * //netif_device_attach(dev);
- *}
- */
- return ni_gpib_config(link);
-}
-
-static struct pcmcia_device_id ni_pcmcia_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4882),
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0c71), // NI PCMCIA-GPIB+
- PCMCIA_DEVICE_NULL
-};
-
-MODULE_DEVICE_TABLE(pcmcia, ni_pcmcia_ids);
-
-static struct pcmcia_driver ni_gpib_cs_driver = {
- .name = "ni_gpib_cs",
- .owner = THIS_MODULE,
- .drv = { .name = "ni_gpib_cs", },
- .id_table = ni_pcmcia_ids,
- .probe = ni_gpib_probe,
- .remove = ni_gpib_remove,
- .suspend = ni_gpib_suspend,
- .resume = ni_gpib_resume,
-};
-
-static int __init init_ni_gpib_cs(void)
-{
- return pcmcia_register_driver(&ni_gpib_cs_driver);
-}
-
-static void __exit exit_ni_gpib_cs(void)
-{
- pcmcia_unregister_driver(&ni_gpib_cs_driver);
-}
-
-static const int pcmcia_gpib_iosize = 32;
-
-static int ni_pcmcia_attach(struct gpib_board *board, const struct gpib_board_config *config)
-{
- struct local_info_t *info;
- struct tnt4882_priv *tnt_priv;
- struct nec7210_priv *nec_priv;
- int isr_flags = IRQF_SHARED;
- int retval;
-
- if (!curr_dev)
- return -ENODEV;
-
- info = curr_dev->priv;
- info->dev = board;
-
- board->status = 0;
-
- if (tnt4882_allocate_private(board))
- return -ENOMEM;
-
- tnt_priv = board->private_data;
- nec_priv = &tnt_priv->nec7210_priv;
- nec_priv->type = TNT4882;
- nec_priv->read_byte = nec7210_locking_ioport_read_byte;
- nec_priv->write_byte = nec7210_locking_ioport_write_byte;
- nec_priv->offset = atgpib_reg_offset;
-
- if (!request_region(curr_dev->resource[0]->start, resource_size(curr_dev->resource[0]),
- DRV_NAME))
- return -ENOMEM;
-
- nec_priv->mmiobase = ioport_map(curr_dev->resource[0]->start,
- resource_size(curr_dev->resource[0]));
- if (!nec_priv->mmiobase)
- return -ENOMEM;
-
- // get irq
- retval = request_irq(curr_dev->irq, tnt4882_interrupt, isr_flags, DRV_NAME, board);
- if (retval) {
- dev_err(board->gpib_dev, "failed to obtain PCMCIA irq %d\n", curr_dev->irq);
- return retval;
- }
- tnt_priv->irq = curr_dev->irq;
-
- tnt4882_init(tnt_priv, board);
-
- return 0;
-}
-
-static void ni_pcmcia_detach(struct gpib_board *board)
-{
- struct tnt4882_priv *tnt_priv = board->private_data;
- struct nec7210_priv *nec_priv;
-
- if (tnt_priv) {
- nec_priv = &tnt_priv->nec7210_priv;
- if (tnt_priv->irq)
- free_irq(tnt_priv->irq, board);
- if (nec_priv->mmiobase)
- ioport_unmap(nec_priv->mmiobase);
- if (nec_priv->iobase) {
- tnt4882_board_reset(tnt_priv, board);
- release_region(nec_priv->iobase, pcmcia_gpib_iosize);
- }
- }
- tnt4882_free_private(board);
-}
-
-static struct gpib_interface ni_pcmcia_interface = {
- .name = "ni_pcmcia",
- .attach = ni_pcmcia_attach,
- .detach = ni_pcmcia_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-static struct gpib_interface ni_pcmcia_accel_interface = {
- .name = "ni_pcmcia_accel",
- .attach = ni_pcmcia_attach,
- .detach = ni_pcmcia_detach,
- .read = tnt4882_accel_read,
- .write = tnt4882_accel_write,
- .command = tnt4882_command,
- .take_control = tnt4882_take_control,
- .go_to_standby = tnt4882_go_to_standby,
- .request_system_control = tnt4882_request_system_control,
- .interface_clear = tnt4882_interface_clear,
- .remote_enable = tnt4882_remote_enable,
- .enable_eos = tnt4882_enable_eos,
- .disable_eos = tnt4882_disable_eos,
- .parallel_poll = tnt4882_parallel_poll,
- .parallel_poll_configure = tnt4882_parallel_poll_configure,
- .parallel_poll_response = tnt4882_parallel_poll_response,
- .local_parallel_poll_mode = NULL, // XXX
- .line_status = tnt4882_line_status,
- .update_status = tnt4882_update_status,
- .primary_address = tnt4882_primary_address,
- .secondary_address = tnt4882_secondary_address,
- .serial_poll_response = tnt4882_serial_poll_response,
- .serial_poll_status = tnt4882_serial_poll_status,
- .t1_delay = tnt4882_t1_delay,
- .return_to_local = tnt4882_return_to_local,
-};
-
-#endif // CONFIG_GPIB_PCMCIA
-
-module_init(tnt4882_init_module);
-module_exit(tnt4882_exit_module);
diff --git a/drivers/staging/gpib/uapi/gpib.h b/drivers/staging/gpib/uapi/gpib.h
deleted file mode 100644
index ddf82a4d989f..000000000000
--- a/drivers/staging/gpib/uapi/gpib.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_H
-#define _GPIB_H
-
-#define GPIB_MAX_NUM_BOARDS 16
-#define GPIB_MAX_NUM_DESCRIPTORS 0x1000
-
-enum ibsta_bit_numbers {
- DCAS_NUM = 0,
- DTAS_NUM = 1,
- LACS_NUM = 2,
- TACS_NUM = 3,
- ATN_NUM = 4,
- CIC_NUM = 5,
- REM_NUM = 6,
- LOK_NUM = 7,
- CMPL_NUM = 8,
- EVENT_NUM = 9,
- SPOLL_NUM = 10,
- RQS_NUM = 11,
- SRQI_NUM = 12,
- END_NUM = 13,
- TIMO_NUM = 14,
- ERR_NUM = 15
-};
-
-/* IBSTA status bits (returned by all functions) */
-enum ibsta_bits {
- DCAS = (1 << DCAS_NUM), /* device clear state */
- DTAS = (1 << DTAS_NUM), /* device trigger state */
- LACS = (1 << LACS_NUM), /* GPIB interface is addressed as Listener */
- TACS = (1 << TACS_NUM), /* GPIB interface is addressed as Talker */
- ATN = (1 << ATN_NUM), /* Attention is asserted */
- CIC = (1 << CIC_NUM), /* GPIB interface is Controller-in-Charge */
- REM = (1 << REM_NUM), /* remote state */
- LOK = (1 << LOK_NUM), /* lockout state */
- CMPL = (1 << CMPL_NUM), /* I/O is complete */
- EVENT = (1 << EVENT_NUM), /* DCAS, DTAS, or IFC has occurred */
- SPOLL = (1 << SPOLL_NUM), /* board serial polled by busmaster */
- RQS = (1 << RQS_NUM), /* Device requesting service */
- SRQI = (1 << SRQI_NUM), /* SRQ is asserted */
- END = (1 << END_NUM), /* EOI or EOS encountered */
- TIMO = (1 << TIMO_NUM), /* Time limit on I/O or wait function exceeded */
- ERR = (1 << ERR_NUM), /* Function call terminated on error */
-
- device_status_mask = ERR | TIMO | END | CMPL | RQS,
- board_status_mask = ERR | TIMO | END | CMPL | SPOLL |
- EVENT | LOK | REM | CIC | ATN | TACS | LACS | DTAS | DCAS | SRQI,
-};
-
-/* End-of-string (EOS) modes for use with ibeos */
-
-enum eos_flags {
- EOS_MASK = 0x1c00,
- REOS = 0x0400, /* Terminate reads on EOS */
- XEOS = 0x800, /* assert EOI when EOS char is sent */
- BIN = 0x1000 /* Do 8-bit compare on EOS */
-};
-
-/* GPIB Bus Control Lines bit vector */
-enum bus_control_line {
- VALID_DAV = 0x01,
- VALID_NDAC = 0x02,
- VALID_NRFD = 0x04,
- VALID_IFC = 0x08,
- VALID_REN = 0x10,
- VALID_SRQ = 0x20,
- VALID_ATN = 0x40,
- VALID_EOI = 0x80,
- VALID_ALL = 0xff,
- BUS_DAV = 0x0100, /* DAV line status bit */
- BUS_NDAC = 0x0200, /* NDAC line status bit */
- BUS_NRFD = 0x0400, /* NRFD line status bit */
- BUS_IFC = 0x0800, /* IFC line status bit */
- BUS_REN = 0x1000, /* REN line status bit */
- BUS_SRQ = 0x2000, /* SRQ line status bit */
- BUS_ATN = 0x4000, /* ATN line status bit */
- BUS_EOI = 0x8000 /* EOI line status bit */
-};
-
-enum ppe_bits {
- PPC_DISABLE = 0x10,
- PPC_SENSE = 0x8, /* parallel poll sense bit */
- PPC_DIO_MASK = 0x7
-};
-
-enum {
- request_service_bit = 0x40,
-};
-
-enum gpib_events {
- EVENT_NONE = 0,
- EVENT_DEV_TRG = 1,
- EVENT_DEV_CLR = 2,
- EVENT_IFC = 3
-};
-
-#endif /* _GPIB_H */
-
diff --git a/drivers/staging/gpib/uapi/gpib_ioctl.h b/drivers/staging/gpib/uapi/gpib_ioctl.h
deleted file mode 100644
index 55bf5e55507a..000000000000
--- a/drivers/staging/gpib/uapi/gpib_ioctl.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/***************************************************************************
- * copyright : (C) 2002 by Frank Mori Hess
- ***************************************************************************/
-
-#ifndef _GPIB_IOCTL_H
-#define _GPIB_IOCTL_H
-
-#include <asm/ioctl.h>
-#include <linux/types.h>
-
-#define GPIB_CODE 160
-
-struct gpib_board_type_ioctl {
- char name[100];
-};
-
-/* argument for read/write/command ioctls */
-struct gpib_read_write_ioctl {
- __u64 buffer_ptr;
- __u32 requested_transfer_count;
- __u32 completed_transfer_count;
- __s32 end; /* end flag return for reads, end io suppression request for cmd*/
- __s32 handle;
-};
-
-struct gpib_open_dev_ioctl {
- __u32 handle;
- __u32 pad;
- __s32 sad;
- __u32 is_board;
-};
-
-struct gpib_close_dev_ioctl {
- __u32 handle;
-};
-
-struct gpib_serial_poll_ioctl {
- __u32 pad;
- __s32 sad;
- __u8 status_byte;
- __u8 padding[3]; // align to 32 bit boundary
-};
-
-struct gpib_eos_ioctl {
- __s32 eos;
- __s32 eos_flags;
-};
-
-struct gpib_wait_ioctl {
- __s32 handle;
- __s32 wait_mask;
- __s32 clear_mask;
- __s32 set_mask;
- __s32 ibsta;
- __s32 pad;
- __s32 sad;
- __u32 usec_timeout;
-};
-
-struct gpib_online_ioctl {
- __u64 init_data_ptr;
- __s32 init_data_length;
- __s32 online;
-};
-
-struct gpib_spoll_bytes_ioctl {
- __u32 num_bytes;
- __u32 pad;
- __s32 sad;
-};
-
-struct gpib_board_info_ioctl {
- __u32 pad;
- __s32 sad;
- __s32 parallel_poll_configuration;
- __s32 autopolling;
- __s32 is_system_controller;
- __u32 t1_delay;
- unsigned ist : 1;
- unsigned no_7_bit_eos : 1;
- unsigned padding :30; // align to 32 bit boundary
-};
-
-struct gpib_select_pci_ioctl {
- __s32 pci_bus;
- __s32 pci_slot;
-};
-
-struct gpib_ppoll_config_ioctl {
- __u8 config;
- unsigned set_ist : 1;
- unsigned clear_ist : 1;
- unsigned padding :22; // align to 32 bit boundary
-};
-
-struct gpib_pad_ioctl {
- __u32 handle;
- __u32 pad;
-};
-
-struct gpib_sad_ioctl {
- __u32 handle;
- __s32 sad;
-};
-
-// select a piece of hardware to attach by its sysfs device path
-struct gpib_select_device_path_ioctl {
- char device_path[0x1000];
-};
-
-// update status byte and request service
-struct gpib_request_service2 {
- __u8 status_byte;
- __u8 padding[3]; // align to 32 bit boundary
- __s32 new_reason_for_service;
-};
-
-/* Standard functions. */
-enum gpib_ioctl {
- IBRD = _IOWR(GPIB_CODE, 100, struct gpib_read_write_ioctl),
- IBWRT = _IOWR(GPIB_CODE, 101, struct gpib_read_write_ioctl),
- IBCMD = _IOWR(GPIB_CODE, 102, struct gpib_read_write_ioctl),
- IBOPENDEV = _IOWR(GPIB_CODE, 3, struct gpib_open_dev_ioctl),
- IBCLOSEDEV = _IOW(GPIB_CODE, 4, struct gpib_close_dev_ioctl),
- IBWAIT = _IOWR(GPIB_CODE, 5, struct gpib_wait_ioctl),
- IBRPP = _IOWR(GPIB_CODE, 6, __u8),
-
- IBSIC = _IOW(GPIB_CODE, 9, __u32),
- IBSRE = _IOW(GPIB_CODE, 10, __s32),
- IBGTS = _IO(GPIB_CODE, 11),
- IBCAC = _IOW(GPIB_CODE, 12, __s32),
- IBLINES = _IOR(GPIB_CODE, 14, __s16),
- IBPAD = _IOW(GPIB_CODE, 15, struct gpib_pad_ioctl),
- IBSAD = _IOW(GPIB_CODE, 16, struct gpib_sad_ioctl),
- IBTMO = _IOW(GPIB_CODE, 17, __u32),
- IBRSP = _IOWR(GPIB_CODE, 18, struct gpib_serial_poll_ioctl),
- IBEOS = _IOW(GPIB_CODE, 19, struct gpib_eos_ioctl),
- IBRSV = _IOW(GPIB_CODE, 20, __u8),
- CFCBASE = _IOW(GPIB_CODE, 21, __u64),
- CFCIRQ = _IOW(GPIB_CODE, 22, __u32),
- CFCDMA = _IOW(GPIB_CODE, 23, __u32),
- CFCBOARDTYPE = _IOW(GPIB_CODE, 24, struct gpib_board_type_ioctl),
-
- IBMUTEX = _IOW(GPIB_CODE, 26, __s32),
- IBSPOLL_BYTES = _IOWR(GPIB_CODE, 27, struct gpib_spoll_bytes_ioctl),
- IBPPC = _IOW(GPIB_CODE, 28, struct gpib_ppoll_config_ioctl),
- IBBOARD_INFO = _IOR(GPIB_CODE, 29, struct gpib_board_info_ioctl),
-
- IBQUERY_BOARD_RSV = _IOR(GPIB_CODE, 31, __s32),
- IBSELECT_PCI = _IOWR(GPIB_CODE, 32, struct gpib_select_pci_ioctl),
- IBEVENT = _IOR(GPIB_CODE, 33, __s16),
- IBRSC = _IOW(GPIB_CODE, 34, __s32),
- IB_T1_DELAY = _IOW(GPIB_CODE, 35, __u32),
- IBLOC = _IO(GPIB_CODE, 36),
-
- IBAUTOSPOLL = _IOW(GPIB_CODE, 38, __s16),
- IBONL = _IOW(GPIB_CODE, 39, struct gpib_online_ioctl),
- IBPP2_SET = _IOW(GPIB_CODE, 40, __s16),
- IBPP2_GET = _IOR(GPIB_CODE, 41, __s16),
- IBSELECT_DEVICE_PATH = _IOW(GPIB_CODE, 43, struct gpib_select_device_path_ioctl),
- // 44 was IBSELECT_SERIAL_NUMBER
- IBRSV2 = _IOW(GPIB_CODE, 45, struct gpib_request_service2)
-};
-
-#endif /* _GPIB_IOCTL_H */
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index 2f05e761fb9a..444c53b4e08d 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -807,6 +807,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
{
int ret;
struct snd_soc_component *comp;
+ struct snd_soc_dapm_context *dapm;
struct gbaudio_jack *jack = NULL;
if (!gbcodec) {
@@ -815,6 +816,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
}
comp = gbcodec->component;
+ dapm = snd_soc_component_to_dapm(comp);
mutex_lock(&gbcodec->register_mutex);
@@ -833,18 +835,18 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
}
if (module->dapm_widgets)
- snd_soc_dapm_new_controls(&comp->dapm, module->dapm_widgets,
+ snd_soc_dapm_new_controls(dapm, module->dapm_widgets,
module->num_dapm_widgets);
if (module->controls)
snd_soc_add_component_controls(comp, module->controls,
module->num_controls);
if (module->dapm_routes)
- snd_soc_dapm_add_routes(&comp->dapm, module->dapm_routes,
+ snd_soc_dapm_add_routes(dapm, module->dapm_routes,
module->num_dapm_routes);
/* card already instantiated, create widgets here only */
if (comp->card->instantiated) {
- gbaudio_dapm_link_component_dai_widgets(comp->card, &comp->dapm);
+ gbaudio_dapm_link_component_dai_widgets(comp->card, dapm);
#ifdef CONFIG_SND_JACK
/*
* register jack devices for this module
@@ -966,9 +968,11 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
#endif
if (module->dapm_routes) {
+ struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp);
+
dev_dbg(comp->dev, "Removing %d routes\n",
module->num_dapm_routes);
- snd_soc_dapm_del_routes(&comp->dapm, module->dapm_routes,
+ snd_soc_dapm_del_routes(dapm, module->dapm_routes,
module->num_dapm_routes);
}
if (module->controls) {
@@ -979,9 +983,11 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
module->num_controls);
}
if (module->dapm_widgets) {
+ struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(comp);
+
dev_dbg(comp->dev, "Removing %d widgets\n",
module->num_dapm_widgets);
- gbaudio_dapm_free_controls(&comp->dapm, module->dapm_widgets,
+ gbaudio_dapm_free_controls(dapm, module->dapm_widgets,
module->num_dapm_widgets);
}
diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c
index 97ce5b9ad7fd..b4873c6d6bed 100644
--- a/drivers/staging/greybus/audio_helper.c
+++ b/drivers/staging/greybus/audio_helper.c
@@ -115,12 +115,13 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
{
int i;
struct snd_soc_dapm_widget *w, *tmp_w;
+ struct snd_soc_card *card = snd_soc_dapm_to_card(dapm);
- mutex_lock(&dapm->card->dapm_mutex);
+ mutex_lock(&card->dapm_mutex);
for (i = 0; i < num; i++) {
/* below logic can be optimized to identify widget pointer */
w = NULL;
- list_for_each_entry(tmp_w, &dapm->card->widgets, list) {
+ list_for_each_entry(tmp_w, &card->widgets, list) {
if (tmp_w->dapm == dapm &&
!strcmp(tmp_w->name, widget->name)) {
w = tmp_w;
@@ -128,7 +129,7 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
}
}
if (!w) {
- dev_err(dapm->dev, "%s: widget not found\n",
+ dev_err(card->dev, "%s: widget not found\n",
widget->name);
widget++;
continue;
@@ -136,7 +137,7 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
widget++;
gbaudio_dapm_free_widget(w);
}
- mutex_unlock(&dapm->card->dapm_mutex);
+ mutex_unlock(&card->dapm_mutex);
return 0;
}
diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c
index 6ca938dca4fd..76146f91cddc 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -163,7 +163,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_info *info;
struct gbaudio_module_info *module;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gbcodec = snd_soc_component_get_drvdata(comp);
dev_dbg(comp->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
@@ -214,7 +214,7 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_value gbvalue;
struct gbaudio_module_info *module;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct gb_bundle *bundle;
@@ -276,7 +276,7 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_value gbvalue;
struct gbaudio_module_info *module;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct gb_bundle *bundle;
@@ -380,7 +380,7 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
struct gbaudio_module_info *module;
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct device *codec_dev = widget->dapm->dev;
+ struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm);
struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev);
struct gb_bundle *bundle;
@@ -393,7 +393,7 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
bundle = to_gb_bundle(module->dev);
if (data->vcount == 2)
- dev_warn(widget->dapm->dev,
+ dev_warn(codec_dev,
"GB: Control '%s' is stereo, which is not supported\n",
kcontrol->id.name);
@@ -429,7 +429,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
struct gbaudio_module_info *module;
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
- struct device *codec_dev = widget->dapm->dev;
+ struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm);
struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev);
struct gb_bundle *bundle;
@@ -443,7 +443,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
bundle = to_gb_bundle(module->dev);
if (data->vcount == 2)
- dev_warn(widget->dapm->dev,
+ dev_warn(codec_dev,
"GB: Control '%s' is stereo, which is not supported\n",
kcontrol->id.name);
@@ -543,7 +543,7 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret, ctl_id;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct gb_audio_ctl_elem_value gbvalue;
@@ -588,7 +588,7 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret, ctl_id;
- struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct gb_audio_ctl_elem_value gbvalue;
@@ -712,7 +712,7 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
struct gbaudio_module_info *module;
struct gb_audio_ctl_elem_value gbvalue;
- struct device *codec_dev = widget->dapm->dev;
+ struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm);
struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct gb_bundle *bundle;
@@ -759,7 +759,7 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
struct gb_audio_ctl_elem_value gbvalue;
struct gbaudio_module_info *module;
- struct device *codec_dev = widget->dapm->dev;
+ struct device *codec_dev = snd_soc_dapm_to_dev(widget->dapm);
struct gbaudio_codec_info *gb = dev_get_drvdata(codec_dev);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct gb_bundle *bundle;
@@ -924,7 +924,7 @@ static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
{
int wid;
int ret;
- struct device *codec_dev = w->dapm->dev;
+ struct device *codec_dev = snd_soc_dapm_to_dev(w->dapm);
struct gbaudio_codec_info *gbcodec = dev_get_drvdata(codec_dev);
struct gbaudio_module_info *module;
struct gb_bundle *bundle;
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 10df5c37c83e..5cece0a6606f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -879,14 +879,18 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
if (retval)
goto exit_put_port;
- send_control(gb_tty, gb_tty->ctrlout);
+ retval = send_control(gb_tty, gb_tty->ctrlout);
+ if (retval)
+ goto exit_connection_disable;
/* initialize the uart to be 9600n81 */
gb_tty->line_coding.rate = cpu_to_le32(9600);
gb_tty->line_coding.format = GB_SERIAL_1_STOP_BITS;
gb_tty->line_coding.parity = GB_SERIAL_NO_PARITY;
gb_tty->line_coding.data_bits = 8;
- send_line_coding(gb_tty);
+ retval = send_line_coding(gb_tty);
+ if (retval)
+ goto exit_connection_disable;
retval = gb_connection_enable(connection);
if (retval)
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 16f30c4f1aa0..8a9a8262c2be 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -216,7 +216,7 @@ static ssize_t adt7316_show_enabled(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN));
+ return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_EN));
}
static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip,
@@ -274,7 +274,7 @@ static ssize_t adt7316_show_select_ex_temp(struct device *dev,
if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
return -EPERM;
- return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
+ return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
}
static ssize_t adt7316_store_select_ex_temp(struct device *dev,
@@ -316,9 +316,9 @@ static ssize_t adt7316_show_mode(struct device *dev,
struct adt7316_chip_info *chip = iio_priv(dev_info);
if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE)
- return sprintf(buf, "single_channel\n");
+ return sysfs_emit(buf, "single_channel\n");
- return sprintf(buf, "round_robin\n");
+ return sysfs_emit(buf, "round_robin\n");
}
static ssize_t adt7316_store_mode(struct device *dev,
@@ -353,7 +353,7 @@ static ssize_t adt7316_show_all_modes(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "single_channel\nround_robin\n");
+ return sysfs_emit(buf, "single_channel\nround_robin\n");
}
static IIO_DEVICE_ATTR(all_modes, 0444, adt7316_show_all_modes, NULL, 0);
@@ -370,29 +370,29 @@ static ssize_t adt7316_show_ad_channel(struct device *dev,
switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) {
case ADT7316_AD_SINGLE_CH_VDD:
- return sprintf(buf, "0 - VDD\n");
+ return sysfs_emit(buf, "0 - VDD\n");
case ADT7316_AD_SINGLE_CH_IN:
- return sprintf(buf, "1 - Internal Temperature\n");
+ return sysfs_emit(buf, "1 - Internal Temperature\n");
case ADT7316_AD_SINGLE_CH_EX:
if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) &&
(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
- return sprintf(buf, "2 - AIN1\n");
+ return sysfs_emit(buf, "2 - AIN1\n");
- return sprintf(buf, "2 - External Temperature\n");
+ return sysfs_emit(buf, "2 - External Temperature\n");
case ADT7516_AD_SINGLE_CH_AIN2:
if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
- return sprintf(buf, "3 - AIN2\n");
+ return sysfs_emit(buf, "3 - AIN2\n");
- return sprintf(buf, "N/A\n");
+ return sysfs_emit(buf, "N/A\n");
case ADT7516_AD_SINGLE_CH_AIN3:
if (chip->config1 & ADT7516_SEL_AIN3)
- return sprintf(buf, "4 - AIN3\n");
+ return sysfs_emit(buf, "4 - AIN3\n");
- return sprintf(buf, "N/A\n");
+ return sysfs_emit(buf, "N/A\n");
case ADT7516_AD_SINGLE_CH_AIN4:
- return sprintf(buf, "5 - AIN4\n");
+ return sysfs_emit(buf, "5 - AIN4\n");
default:
- return sprintf(buf, "N/A\n");
+ return sysfs_emit(buf, "N/A\n");
}
}
@@ -453,10 +453,10 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev,
return -EPERM;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
- return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+ return sysfs_emit(buf, "0 - VDD\n1 - Internal Temperature\n"
"2 - External Temperature or AIN1\n"
"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
- return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+ return sysfs_emit(buf, "0 - VDD\n1 - Internal Temperature\n"
"2 - External Temperature\n");
}
@@ -470,7 +470,7 @@ static ssize_t adt7316_show_disable_averaging(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->config2 & ADT7316_DISABLE_AVERAGING));
}
@@ -509,7 +509,7 @@ static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT));
}
@@ -548,7 +548,7 @@ static ssize_t adt7316_show_powerdown(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD));
+ return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_PD));
}
static ssize_t adt7316_store_powerdown(struct device *dev,
@@ -586,7 +586,7 @@ static ssize_t adt7316_show_fast_ad_clock(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5));
+ return sysfs_emit(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5));
}
static ssize_t adt7316_store_fast_ad_clock(struct device *dev,
@@ -626,10 +626,10 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev,
if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
if (chip->id != ID_ADT7318 && chip->id != ID_ADT7519)
- return sprintf(buf, "1 (10 bits)\n");
+ return sysfs_emit(buf, "1 (10 bits)\n");
}
- return sprintf(buf, "0 (8 bits)\n");
+ return sysfs_emit(buf, "0 (8 bits)\n");
}
static ssize_t adt7316_store_da_high_resolution(struct device *dev,
@@ -673,7 +673,7 @@ static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev,
if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
return -EPERM;
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->config3 & ADT7516_AIN_IN_VREF));
}
@@ -716,7 +716,7 @@ static ssize_t adt7316_show_enable_prop_DACA(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA));
}
@@ -755,7 +755,7 @@ static ssize_t adt7316_show_enable_prop_DACB(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB));
}
@@ -794,7 +794,7 @@ static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "0x%x\n",
+ return sysfs_emit(buf, "0x%x\n",
chip->dac_config & ADT7316_DA_2VREF_CH_MASK);
}
@@ -838,20 +838,20 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev,
struct adt7316_chip_info *chip = iio_priv(dev_info);
if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC))
- return sprintf(buf, "manual\n");
+ return sysfs_emit(buf, "manual\n");
switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) {
case ADT7316_DA_EN_MODE_SINGLE:
- return sprintf(buf,
+ return sysfs_emit(buf,
"0 - auto at any MSB DAC writing\n");
case ADT7316_DA_EN_MODE_AB_CD:
- return sprintf(buf,
+ return sysfs_emit(buf,
"1 - auto at MSB DAC AB and CD writing\n");
case ADT7316_DA_EN_MODE_ABCD:
- return sprintf(buf,
+ return sysfs_emit(buf,
"2 - auto at MSB DAC ABCD writing\n");
default: /* ADT7316_DA_EN_MODE_LDAC */
- return sprintf(buf, "3 - manual\n");
+ return sysfs_emit(buf, "3 - manual\n");
}
}
@@ -898,11 +898,11 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev,
struct adt7316_chip_info *chip = iio_priv(dev_info);
if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)
- return sprintf(buf, "0 - auto at any MSB DAC writing\n"
+ return sysfs_emit(buf, "0 - auto at any MSB DAC writing\n"
"1 - auto at MSB DAC AB and CD writing\n"
"2 - auto at MSB DAC ABCD writing\n"
"3 - manual\n");
- return sprintf(buf, "manual\n");
+ return sysfs_emit(buf, "manual\n");
}
static IIO_DEVICE_ATTR(all_DAC_update_modes, 0444,
@@ -955,7 +955,7 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB));
}
@@ -994,7 +994,7 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD));
}
@@ -1034,10 +1034,10 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
struct adt7316_chip_info *chip = iio_priv(dev_info);
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
- return sprintf(buf, "0x%x\n",
+ return sysfs_emit(buf, "0x%x\n",
(chip->ldac_config & ADT7516_DAC_IN_VREF_MASK) >>
ADT7516_DAC_IN_VREF_OFFSET);
- return sprintf(buf, "%d\n",
+ return sysfs_emit(buf, "%d\n",
!!(chip->ldac_config & ADT7316_DAC_IN_VREF));
}
@@ -1128,7 +1128,7 @@ static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
data = msb << ADT7316_T_VALUE_FLOAT_OFFSET;
data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
- return sprintf(buf, "%d\n", data);
+ return sysfs_emit(buf, "%d\n", data);
default: /* ex_temp and ain */
ret = chip->bus.read(chip->bus.client,
ADT7316_LSB_EX_TEMP_AIN, &lsb);
@@ -1146,7 +1146,7 @@ static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
(ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE))));
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
- return sprintf(buf, "%d\n", data);
+ return sysfs_emit(buf, "%d\n", data);
break;
}
@@ -1157,7 +1157,7 @@ static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
sign = '-';
}
- return sprintf(buf, "%c%d.%.2d\n", sign,
+ return sysfs_emit(buf, "%c%d.%.2d\n", sign,
(data >> ADT7316_T_VALUE_FLOAT_OFFSET),
(data & ADT7316_T_VALUE_FLOAT_MASK) * 25);
}
@@ -1247,7 +1247,7 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
if (val & 0x80)
data -= 256;
- return sprintf(buf, "%d\n", data);
+ return sysfs_emit(buf, "%d\n", data);
}
static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
@@ -1415,7 +1415,7 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip,
data = lsb >> ADT7316_DA_10_BIT_LSB_SHIFT;
data |= msb << offset;
- return sprintf(buf, "%d\n", data);
+ return sysfs_emit(buf, "%d\n", data);
}
static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
@@ -1568,7 +1568,7 @@ static ssize_t adt7316_show_device_id(struct device *dev,
if (ret)
return -EIO;
- return sprintf(buf, "%d\n", id);
+ return sysfs_emit(buf, "%d\n", id);
}
static IIO_DEVICE_ATTR(device_id, 0444, adt7316_show_device_id, NULL, 0);
@@ -1586,7 +1586,7 @@ static ssize_t adt7316_show_manufactorer_id(struct device *dev,
if (ret)
return -EIO;
- return sprintf(buf, "%d\n", id);
+ return sysfs_emit(buf, "%d\n", id);
}
static IIO_DEVICE_ATTR(manufactorer_id, 0444,
@@ -1605,7 +1605,7 @@ static ssize_t adt7316_show_device_rev(struct device *dev,
if (ret)
return -EIO;
- return sprintf(buf, "%d\n", rev);
+ return sysfs_emit(buf, "%d\n", rev);
}
static IIO_DEVICE_ATTR(device_rev, 0444, adt7316_show_device_rev, NULL, 0);
@@ -1624,9 +1624,9 @@ static ssize_t adt7316_show_bus_type(struct device *dev,
return -EIO;
if (stat)
- return sprintf(buf, "spi\n");
+ return sysfs_emit(buf, "spi\n");
- return sprintf(buf, "i2c\n");
+ return sysfs_emit(buf, "i2c\n");
}
static IIO_DEVICE_ATTR(bus_type, 0444, adt7316_show_bus_type, NULL, 0);
@@ -1836,7 +1836,7 @@ static ssize_t adt7316_show_int_mask(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "0x%x\n", chip->int_mask);
+ return sysfs_emit(buf, "0x%x\n", chip->int_mask);
}
/*
@@ -1910,7 +1910,7 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev,
data -= 256;
}
- return sprintf(buf, "%d\n", data);
+ return sysfs_emit(buf, "%d\n", data);
}
static inline ssize_t adt7316_set_ad_bound(struct device *dev,
@@ -1961,7 +1961,7 @@ static ssize_t adt7316_show_int_enabled(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN));
+ return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN));
}
static ssize_t adt7316_set_int_enabled(struct device *dev,
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 0038eb234d40..d339d5e8e043 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -21,9 +21,8 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-#include "dds.h"
-#include "ad9834.h"
+#include "dds.h"
/* Registers */
diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h
deleted file mode 100644
index 521943aa0e61..000000000000
--- a/drivers/staging/iio/frequency/ad9834.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * AD9833/AD9834/AD9837/AD9838 SPI DDS driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- */
-#ifndef IIO_DDS_AD9834_H_
-#define IIO_DDS_AD9834_H_
-
-#endif /* IIO_DDS_AD9834_H_ */
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 6fc39ab95e46..6050637a0def 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -491,7 +491,7 @@ static int gc2235_s_power(struct v4l2_subdev *sd, int on)
return ret;
}
-static int startup(struct v4l2_subdev *sd)
+static int gc2235_startup(struct v4l2_subdev *sd)
{
struct gc2235_device *dev = to_gc2235_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -556,7 +556,7 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
return 0;
}
- ret = startup(sd);
+ ret = gc2235_startup(sd);
if (ret) {
dev_err(&client->dev, "gc2235 startup err\n");
goto err;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index c7de7800799a..a4519babf37d 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -600,7 +600,7 @@ static int ov2722_s_power(struct v4l2_subdev *sd, int on)
}
/* TODO: remove it. */
-static int startup(struct v4l2_subdev *sd)
+static int ov2722_startup(struct v4l2_subdev *sd)
{
struct ov2722_device *dev = to_ov2722_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -662,7 +662,7 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
dev->pixels_per_line = dev->res->pixels_per_line;
dev->lines_per_frame = dev->res->lines_per_frame;
- ret = startup(sd);
+ ret = ov2722_startup(sd);
if (ret) {
int i = 0;
@@ -677,7 +677,7 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
dev_err(&client->dev, "power up failed, continue\n");
continue;
}
- ret = startup(sd);
+ ret = ov2722_startup(sd);
if (ret) {
dev_err(&client->dev, " startup FAILED!\n");
} else {
diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c
index bc9a2a40afcb..602342d1174f 100644
--- a/drivers/staging/media/av7110/av7110.c
+++ b/drivers/staging/media/av7110/av7110.c
@@ -321,7 +321,7 @@ static inline void print_time(char *s)
struct timespec64 ts;
ktime_get_real_ts64(&ts);
- pr_info("%s(): %lld.%09ld\n", s, (s64)ts.tv_sec, ts.tv_nsec);
+ pr_info("%s(): %ptSp\n", s, &ts);
#endif
}
diff --git a/drivers/staging/media/av7110/av7110_ca.c b/drivers/staging/media/av7110/av7110_ca.c
index fce4023c9dea..63d9c97a5190 100644
--- a/drivers/staging/media/av7110/av7110_ca.c
+++ b/drivers/staging/media/av7110/av7110_ca.c
@@ -26,7 +26,7 @@
void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
{
- unsigned slot_num;
+ unsigned int slot_num;
dprintk(8, "av7110:%p\n", av7110);
diff --git a/drivers/staging/media/av7110/av7110_v4l.c b/drivers/staging/media/av7110/av7110_v4l.c
index 04e659243f02..200a7a29ea31 100644
--- a/drivers/staging/media/av7110/av7110_v4l.c
+++ b/drivers/staging/media/av7110/av7110_v4l.c
@@ -940,7 +940,7 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .vbi_fops.write = av7110_vbi_write,
+ .vbi_write = av7110_vbi_write,
};
static struct saa7146_ext_vv av7110_vv_data_c = {
@@ -953,6 +953,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .vbi_fops.write = av7110_vbi_write,
+ .vbi_write = av7110_vbi_write,
};
diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
index 1869c5792ecb..0a27330f9790 100644
--- a/drivers/staging/media/imx/imx-media-csc-scaler.c
+++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
@@ -99,7 +99,7 @@ static void ipu_ic_pp_complete(struct ipu_image_convert_run *run, void *_ctx)
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
+ v4l2_m2m_buf_copy_metadata(src_buf, dst_buf);
src_buf->sequence = ctx->sequence++;
dst_buf->sequence = src_buf->sequence;
diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c
index e22a9c092195..bdf5a457752b 100644
--- a/drivers/staging/media/ipu3/ipu3.c
+++ b/drivers/staging/media/ipu3/ipu3.c
@@ -530,8 +530,7 @@ static irqreturn_t imgu_isr_threaded(int irq, void *imgu_ptr)
if (IS_ERR(b)) {
if (PTR_ERR(b) != -EBUSY) /* All done */
dev_err(&imgu->pci_dev->dev,
- "failed to dequeue buffers (%ld)\n",
- PTR_ERR(b));
+ "failed to dequeue buffers (%pe)\n", b);
break;
}
diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h
index d2ad0a95c5aa..7b2a1eee2c7f 100644
--- a/drivers/staging/media/ipu3/ipu3.h
+++ b/drivers/staging/media/ipu3/ipu3.h
@@ -127,7 +127,6 @@ struct imgu_device {
/* Private fields */
struct v4l2_device v4l2_dev;
struct media_device media_dev;
- struct v4l2_file_operations v4l2_file_ops;
/* MMU driver for css */
struct imgu_mmu_info *mmu;
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
index b8c5db7ae300..2d5717883518 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
@@ -307,8 +307,8 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity);
if (IS_ERR(pad)) {
- dev_warn(dev, "can't get remote source pad of %s (%ld)\n",
- csi2->asd.sd.name, PTR_ERR(pad));
+ dev_warn(dev, "can't get remote source pad of %s (%pe)\n",
+ csi2->asd.sd.name, pad);
return PTR_ERR(pad);
}
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
index 4023db4a6466..f34eabfe8a98 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
@@ -55,8 +55,8 @@ s64 ipu7_isys_csi2_get_link_freq(struct ipu7_isys_csi2 *csi2)
src_pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity);
if (IS_ERR(src_pad)) {
dev_err(&csi2->isys->adev->auxdev.dev,
- "can't get source pad of %s (%ld)\n",
- csi2->asd.sd.name, PTR_ERR(src_pad));
+ "can't get source pad of %s (%pe)\n",
+ csi2->asd.sd.name, src_pad);
return PTR_ERR(src_pad);
}
diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c
index 1a7c8a91fffb..8c6730833f24 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-video.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-video.c
@@ -88,11 +88,6 @@ const struct ipu7_isys_pixelformat ipu7_isys_pfmts[] = {
IPU_INSYS_FRAME_FORMAT_RGBA888},
};
-static int video_open(struct file *file)
-{
- return v4l2_fh_open(file);
-}
-
const struct ipu7_isys_pixelformat *ipu7_isys_get_isys_format(u32 pixelformat)
{
unsigned int i;
@@ -867,7 +862,7 @@ static const struct v4l2_file_operations isys_fops = {
.poll = vb2_fop_poll,
.unlocked_ioctl = video_ioctl2,
.mmap = vb2_fop_mmap,
- .open = video_open,
+ .open = v4l2_fh_open,
.release = vb2_fop_release,
};
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index fbbf9e6f0f50..9f8b0555b7dc 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -90,7 +90,7 @@ void cedrus_device_run(void *priv)
break;
}
- v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
+ v4l2_m2m_buf_copy_metadata(run.src, run.dst);
cedrus_dst_format_set(dev, &ctx->dst_fmt);
diff --git a/drivers/staging/media/tegra-video/tegra20.c b/drivers/staging/media/tegra-video/tegra20.c
index 1473f1b1f203..aa9ff7fec4f9 100644
--- a/drivers/staging/media/tegra-video/tegra20.c
+++ b/drivers/staging/media/tegra-video/tegra20.c
@@ -255,7 +255,7 @@ static int tegra20_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
out_sp = host1x_syncpt_request(&vi->client, HOST1X_SYNCPT_CLIENT_MANAGED);
if (!out_sp)
- return dev_err_probe(vi->dev, -ENOMEM, "failed to request syncpoint\n");
+ return -ENOMEM;
chan->mw_ack_sp[0] = out_sp;
diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig
index 6f420cbcdcff..e89658df6f12 100644
--- a/drivers/staging/most/Kconfig
+++ b/drivers/staging/most/Kconfig
@@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig"
source "drivers/staging/most/dim2/Kconfig"
-source "drivers/staging/most/i2c/Kconfig"
-
endif
diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile
index 8b3fc5a7af51..e45084df7803 100644
--- a/drivers/staging/most/Makefile
+++ b/drivers/staging/most/Makefile
@@ -3,4 +3,3 @@
obj-$(CONFIG_MOST_NET) += net/
obj-$(CONFIG_MOST_VIDEO) += video/
obj-$(CONFIG_MOST_DIM2) += dim2/
-obj-$(CONFIG_MOST_I2C) += i2c/
diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig
deleted file mode 100644
index ff64283cbad1..000000000000
--- a/drivers/staging/most/i2c/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# MOST I2C configuration
-#
-
-config MOST_I2C
- tristate "I2C"
- depends on I2C
- help
- Say Y here if you want to connect via I2C to network transceiver.
-
- To compile this driver as a module, choose M here: the
- module will be called most_i2c.
diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile
deleted file mode 100644
index 71099dd0f85b..000000000000
--- a/drivers/staging/most/i2c/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_MOST_I2C) += most_i2c.o
-
-most_i2c-objs := i2c.o
diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c
deleted file mode 100644
index 184b2dd11fc3..000000000000
--- a/drivers/staging/most/i2c/i2c.c
+++ /dev/null
@@ -1,374 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * i2c.c - Hardware Dependent Module for I2C Interface
- *
- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/most.h>
-
-enum { CH_RX, CH_TX, NUM_CHANNELS };
-
-#define MAX_BUFFERS_CONTROL 32
-#define MAX_BUF_SIZE_CONTROL 256
-
-/**
- * list_first_mbo - get the first mbo from a list
- * @ptr: the list head to take the mbo from.
- */
-#define list_first_mbo(ptr) \
- list_first_entry(ptr, struct mbo, list)
-
-static unsigned int polling_rate;
-module_param(polling_rate, uint, 0644);
-MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)");
-
-struct hdm_i2c {
- struct most_interface most_iface;
- struct most_channel_capability capabilities[NUM_CHANNELS];
- struct i2c_client *client;
- struct rx {
- struct delayed_work dwork;
- struct list_head list;
- bool int_disabled;
- unsigned int delay;
- } rx;
- char name[64];
-};
-
-static inline struct hdm_i2c *to_hdm(struct most_interface *iface)
-{
- return container_of(iface, struct hdm_i2c, most_iface);
-}
-
-static irqreturn_t most_irq_handler(int, void *);
-static void pending_rx_work(struct work_struct *);
-
-/**
- * configure_channel - called from MOST core to configure a channel
- * @most_iface: interface the channel belongs to
- * @ch_idx: channel to be configured
- * @channel_config: structure that holds the configuration information
- *
- * Return 0 on success, negative on failure.
- *
- * Receives configuration information from MOST core and initialize the
- * corresponding channel.
- */
-static int configure_channel(struct most_interface *most_iface,
- int ch_idx,
- struct most_channel_config *channel_config)
-{
- int ret;
- struct hdm_i2c *dev = to_hdm(most_iface);
- unsigned int delay, pr;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (channel_config->data_type != MOST_CH_CONTROL) {
- pr_err("bad data type for channel %d\n", ch_idx);
- return -EPERM;
- }
-
- if (channel_config->direction != dev->capabilities[ch_idx].direction) {
- pr_err("bad direction for channel %d\n", ch_idx);
- return -EPERM;
- }
-
- if (channel_config->direction == MOST_CH_RX) {
- if (!polling_rate) {
- if (dev->client->irq <= 0) {
- pr_err("bad irq: %d\n", dev->client->irq);
- return -ENOENT;
- }
- dev->rx.int_disabled = false;
- ret = request_irq(dev->client->irq, most_irq_handler, 0,
- dev->client->name, dev);
- if (ret) {
- pr_err("request_irq(%d) failed: %d\n",
- dev->client->irq, ret);
- return ret;
- }
- } else {
- delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate);
- dev->rx.delay = delay ? delay : 1;
- pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay);
- pr_info("polling rate is %u Hz\n", pr);
- }
- }
-
- return 0;
-}
-
-/**
- * enqueue - called from MOST core to enqueue a buffer for data transfer
- * @most_iface: intended interface
- * @ch_idx: ID of the channel the buffer is intended for
- * @mbo: pointer to the buffer object
- *
- * Return 0 on success, negative on failure.
- *
- * Transmit the data over I2C if it is a "write" request or push the buffer into
- * list if it is an "read" request
- */
-static int enqueue(struct most_interface *most_iface,
- int ch_idx, struct mbo *mbo)
-{
- struct hdm_i2c *dev = to_hdm(most_iface);
- int ret;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (ch_idx == CH_RX) {
- /* RX */
- if (!polling_rate)
- disable_irq(dev->client->irq);
- cancel_delayed_work_sync(&dev->rx.dwork);
- list_add_tail(&mbo->list, &dev->rx.list);
- if (dev->rx.int_disabled || polling_rate)
- pending_rx_work(&dev->rx.dwork.work);
- if (!polling_rate)
- enable_irq(dev->client->irq);
- } else {
- /* TX */
- ret = i2c_master_send(dev->client, mbo->virt_address,
- mbo->buffer_length);
- if (ret <= 0) {
- mbo->processed_length = 0;
- mbo->status = MBO_E_INVAL;
- } else {
- mbo->processed_length = mbo->buffer_length;
- mbo->status = MBO_SUCCESS;
- }
- mbo->complete(mbo);
- }
-
- return 0;
-}
-
-/**
- * poison_channel - called from MOST core to poison buffers of a channel
- * @most_iface: pointer to the interface the channel to be poisoned belongs to
- * @ch_idx: corresponding channel ID
- *
- * Return 0 on success, negative on failure.
- *
- * If channel direction is RX, complete the buffers in list with
- * status MBO_E_CLOSE
- */
-static int poison_channel(struct most_interface *most_iface,
- int ch_idx)
-{
- struct hdm_i2c *dev = to_hdm(most_iface);
- struct mbo *mbo;
-
- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS);
-
- if (ch_idx == CH_RX) {
- if (!polling_rate)
- free_irq(dev->client->irq, dev);
- cancel_delayed_work_sync(&dev->rx.dwork);
-
- while (!list_empty(&dev->rx.list)) {
- mbo = list_first_mbo(&dev->rx.list);
- list_del(&mbo->list);
-
- mbo->processed_length = 0;
- mbo->status = MBO_E_CLOSE;
- mbo->complete(mbo);
- }
- }
-
- return 0;
-}
-
-static void do_rx_work(struct hdm_i2c *dev)
-{
- struct mbo *mbo;
- unsigned char msg[MAX_BUF_SIZE_CONTROL];
- int ret;
- u16 pml, data_size;
-
- /* Read PML (2 bytes) */
- ret = i2c_master_recv(dev->client, msg, 2);
- if (ret <= 0) {
- pr_err("Failed to receive PML\n");
- return;
- }
-
- pml = (msg[0] << 8) | msg[1];
- if (!pml)
- return;
-
- data_size = pml + 2;
-
- /* Read the whole message, including PML */
- ret = i2c_master_recv(dev->client, msg, data_size);
- if (ret <= 0) {
- pr_err("Failed to receive a Port Message\n");
- return;
- }
-
- mbo = list_first_mbo(&dev->rx.list);
- list_del(&mbo->list);
-
- mbo->processed_length = min(data_size, mbo->buffer_length);
- memcpy(mbo->virt_address, msg, mbo->processed_length);
- mbo->status = MBO_SUCCESS;
- mbo->complete(mbo);
-}
-
-/**
- * pending_rx_work - Read pending messages through I2C
- * @work: definition of this work item
- *
- * Invoked by the Interrupt Service Routine, most_irq_handler()
- */
-static void pending_rx_work(struct work_struct *work)
-{
- struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work);
-
- if (list_empty(&dev->rx.list))
- return;
-
- do_rx_work(dev);
-
- if (polling_rate) {
- schedule_delayed_work(&dev->rx.dwork, dev->rx.delay);
- } else {
- dev->rx.int_disabled = false;
- enable_irq(dev->client->irq);
- }
-}
-
-/*
- * most_irq_handler - Interrupt Service Routine
- * @irq: irq number
- * @_dev: private data
- *
- * Schedules a delayed work
- *
- * By default the interrupt line behavior is Active Low. Once an interrupt is
- * generated by the device, until driver clears the interrupt (by reading
- * the PMP message), device keeps the interrupt line in low state. Since i2c
- * read is done in work queue, the interrupt line must be disabled temporarily
- * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue,
- * after reading the message.
- *
- * Note: If we use the interrupt line in Falling edge mode, there is a
- * possibility to miss interrupts when ISR is getting executed.
- *
- */
-static irqreturn_t most_irq_handler(int irq, void *_dev)
-{
- struct hdm_i2c *dev = _dev;
-
- disable_irq_nosync(irq);
- dev->rx.int_disabled = true;
- schedule_delayed_work(&dev->rx.dwork, 0);
-
- return IRQ_HANDLED;
-}
-
-/*
- * i2c_probe - i2c probe handler
- * @client: i2c client device structure
- * @id: i2c client device id
- *
- * Return 0 on success, negative on failure.
- *
- * Register the i2c client device as a MOST interface
- */
-static int i2c_probe(struct i2c_client *client)
-{
- struct hdm_i2c *dev;
- int ret, i;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- /* ID format: i2c-<bus>-<address> */
- snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x",
- client->adapter->nr, client->addr);
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- dev->capabilities[i].data_type = MOST_CH_CONTROL;
- dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL;
- dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL;
- }
- dev->capabilities[CH_RX].direction = MOST_CH_RX;
- dev->capabilities[CH_RX].name_suffix = "rx";
- dev->capabilities[CH_TX].direction = MOST_CH_TX;
- dev->capabilities[CH_TX].name_suffix = "tx";
-
- dev->most_iface.interface = ITYPE_I2C;
- dev->most_iface.description = dev->name;
- dev->most_iface.num_channels = NUM_CHANNELS;
- dev->most_iface.channel_vector = dev->capabilities;
- dev->most_iface.configure = configure_channel;
- dev->most_iface.enqueue = enqueue;
- dev->most_iface.poison_channel = poison_channel;
-
- INIT_LIST_HEAD(&dev->rx.list);
-
- INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work);
-
- dev->client = client;
- i2c_set_clientdata(client, dev);
-
- ret = most_register_interface(&dev->most_iface);
- if (ret) {
- pr_err("Failed to register i2c as a MOST interface\n");
- kfree(dev);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * i2c_remove - i2c remove handler
- * @client: i2c client device structure
- *
- * Return 0 on success.
- *
- * Unregister the i2c client device as a MOST interface
- */
-static void i2c_remove(struct i2c_client *client)
-{
- struct hdm_i2c *dev = i2c_get_clientdata(client);
-
- most_deregister_interface(&dev->most_iface);
- kfree(dev);
-}
-
-static const struct i2c_device_id i2c_id[] = {
- { "most_i2c" },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(i2c, i2c_id);
-
-static struct i2c_driver i2c_driver = {
- .driver = {
- .name = "hdm_i2c",
- },
- .probe = i2c_probe,
- .remove = i2c_remove,
- .id_table = i2c_id,
-};
-
-module_i2c_driver(i2c_driver);
-
-MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>");
-MODULE_DESCRIPTION("I2C Hardware Dependent Module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c
index 575233fa1677..2db57795ea2f 100644
--- a/drivers/staging/nvec/nvec_ps2.c
+++ b/drivers/staging/nvec/nvec_ps2.c
@@ -23,14 +23,6 @@
#define DISABLE_MOUSE 0xf5
#define PSMOUSE_RST 0xff
-#ifdef NVEC_PS2_DEBUG
-#define NVEC_PHD(str, buf, len) \
- print_hex_dump(KERN_DEBUG, str, DUMP_PREFIX_NONE, \
- 16, 1, buf, len, false)
-#else
-#define NVEC_PHD(str, buf, len) do { } while (0)
-#endif
-
enum ps2_subcmds {
SEND_COMMAND = 1,
RECEIVE_N,
@@ -70,18 +62,14 @@ static int nvec_ps2_notifier(struct notifier_block *nb,
case NVEC_PS2_EVT:
for (i = 0; i < msg[1]; i++)
serio_interrupt(ps2_dev.ser_dev, msg[2 + i], 0);
- NVEC_PHD("ps/2 mouse event: ", &msg[2], msg[1]);
return NOTIFY_STOP;
case NVEC_PS2:
if (msg[2] == 1) {
for (i = 0; i < (msg[1] - 2); i++)
serio_interrupt(ps2_dev.ser_dev, msg[i + 4], 0);
- NVEC_PHD("ps/2 mouse reply: ", &msg[4], msg[1] - 2);
}
- else if (msg[1] != 2) /* !ack */
- NVEC_PHD("unhandled mouse event: ", msg, msg[1] + 2);
return NOTIFY_STOP;
}
diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c
index 0908f2234f67..67197c7d4a4d 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
@@ -391,8 +391,6 @@ void update_bmc_sta(struct adapter *padapter)
memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
- /* psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this. */
-
/* prepare for add_RATid */
supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->supported_rates);
network_type = rtw_check_network_type((u8 *)&pcur_network->supported_rates,
@@ -436,7 +434,6 @@ void update_bmc_sta(struct adapter *padapter)
spin_lock_bh(&psta->lock);
psta->state = _FW_LINKED;
spin_unlock_bh(&psta->lock);
-
}
}
@@ -480,14 +477,14 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
/* check if sta supports rx ampdu */
phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
- phtpriv_sta->rx_ampdu_min_spacing = (
- phtpriv_sta->ht_cap.ampdu_params_info & IEEE80211_HT_CAP_AMPDU_DENSITY
- ) >> 2;
+ phtpriv_sta->rx_ampdu_min_spacing =
+ (phtpriv_sta->ht_cap.ampdu_params_info &
+ IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
/* bwmode */
- if ((
- phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
- ) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
+ if ((phtpriv_sta->ht_cap.cap_info &
+ phtpriv_ap->ht_cap.cap_info) &
+ cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
psta->bw_mode = CHANNEL_WIDTH_40;
else
psta->bw_mode = CHANNEL_WIDTH_20;
@@ -498,15 +495,15 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
/* check if sta support s Short GI 20M */
- if ((
- phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
- ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
+ if ((phtpriv_sta->ht_cap.cap_info &
+ phtpriv_ap->ht_cap.cap_info) &
+ cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
phtpriv_sta->sgi_20m = true;
/* check if sta support s Short GI 40M */
- if ((
- phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
- ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) {
+ if ((phtpriv_sta->ht_cap.cap_info &
+ phtpriv_ap->ht_cap.cap_info) &
+ cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) {
if (psta->bw_mode == CHANNEL_WIDTH_40) /* according to psta->bw_mode */
phtpriv_sta->sgi_40m = true;
else
@@ -625,9 +622,9 @@ static void update_hw_ht_param(struct adapter *padapter)
/* */
/* Config SM Power Save setting */
/* */
- pmlmeinfo->SM_PS = (le16_to_cpu(
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info
- ) & 0x0C) >> 2;
+ pmlmeinfo->SM_PS =
+ (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) &
+ 0x0C) >> 2;
/* */
/* Config current HT Protection mode. */
@@ -658,9 +655,12 @@ void start_bss_network(struct adapter *padapter)
cur_bwmode = CHANNEL_WIDTH_20;
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- /* check if there is wps ie, */
- /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
- /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
+ /*
+ * check if there is wps ie,
+ * if there is wpsie in beacon,
+ * the hostapd will update beacon twice when stating hostapd,
+ * and at first time the security ie (RSN/WPA IE) will not include in beacon.
+ */
if (!rtw_get_wps_ie(pnetwork->ies + _FIXED_IE_LENGTH_,
pnetwork->ie_length - _FIXED_IE_LENGTH_, NULL, NULL))
pmlmeext->bstart_bss = true;
@@ -705,9 +705,8 @@ void start_bss_network(struct adapter *padapter)
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
/* Set Security */
- val8 = (
- psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X
- ) ? 0xcc : 0xcf;
+ val8 = (psecuritypriv->dot11AuthAlgrthm ==
+ dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
/* Beacon Control related register */
@@ -778,14 +777,12 @@ void start_bss_network(struct adapter *padapter)
update_wireless_mode(padapter);
/* update RRSR after set channel and bandwidth */
- UpdateBrateTbl(padapter, pnetwork->supported_rates);
+ update_basic_rate_table(padapter, pnetwork->supported_rates);
rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->supported_rates);
/* update capability after cur_wireless_mode updated */
- update_capinfo(
- padapter,
- rtw_get_capability((struct wlan_bssid_ex *)pnetwork)
- );
+ update_capinfo(padapter,
+ rtw_get_capability((struct wlan_bssid_ex *)pnetwork));
if (pmlmeext->bstart_bss) {
update_beacon(padapter, WLAN_EID_TIM, NULL, true);
@@ -841,7 +838,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
memcpy(pbss_network->mac_address, myid(&padapter->eeprompriv), ETH_ALEN);
/* beacon interval */
- p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
+ /* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
+ p = rtw_get_beacon_interval_from_ie(ie);
/* pbss_network->configuration.beacon_period = le16_to_cpu(*(unsigned short*)p); */
pbss_network->configuration.beacon_period = get_unaligned_le16(p);
@@ -851,12 +849,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
cap = get_unaligned_le16(ie);
/* SSID */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_SSID,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_SSID,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
memset(&pbss_network->ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(pbss_network->ssid.ssid, (p + 2), ie_len);
@@ -866,11 +862,9 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
/* channel */
channel = 0;
pbss_network->configuration.length = 0;
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_DS_PARAMS, &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_DS_PARAMS, &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
channel = *(p + 2);
@@ -878,24 +872,20 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
/* get supported rates */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_SUPP_RATES,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_SUPP_RATES,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p) {
memcpy(supportRate, p + 2, ie_len);
supportRateNum = ie_len;
}
/* get ext_supported rates */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_EXT_SUPP_RATES,
- &ie_len,
- pbss_network->ie_length - _BEACON_IE_OFFSET_
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_EXT_SUPP_RATES,
+ &ie_len,
+ pbss_network->ie_length - _BEACON_IE_OFFSET_);
if (p) {
memcpy(supportRate + supportRateNum, p + 2, ie_len);
supportRateNum += ie_len;
@@ -906,12 +896,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
rtw_set_supported_rate(pbss_network->supported_rates, network_type);
/* parsing ERP_IE */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_ERP_INFO,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_ERP_INFO,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
ERP_IE_handler(padapter, (struct ndis_80211_var_ie *)p);
@@ -927,20 +915,16 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
group_cipher = 0; pairwise_cipher = 0;
psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_RSN,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_RSN,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
- if (rtw_parse_wpa2_ie(
- p,
- ie_len + 2,
- &group_cipher,
- &pairwise_cipher,
- NULL
- ) == _SUCCESS) {
+ if (rtw_parse_wpa2_ie(p,
+ ie_len + 2,
+ &group_cipher,
+ &pairwise_cipher,
+ NULL) == _SUCCESS) {
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
@@ -957,20 +941,16 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
- p = rtw_get_ie(
- p,
- WLAN_EID_VENDOR_SPECIFIC,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2))
- );
+ p = rtw_get_ie(p,
+ WLAN_EID_VENDOR_SPECIFIC,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2)));
if ((p) && (!memcmp(p + 2, OUI1, 4))) {
- if (rtw_parse_wpa_ie(
- p,
- ie_len + 2,
- &group_cipher,
- &pairwise_cipher,
- NULL
- ) == _SUCCESS) {
+ if (rtw_parse_wpa_ie(p,
+ ie_len + 2,
+ &group_cipher,
+ &pairwise_cipher,
+ NULL) == _SUCCESS) {
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
@@ -993,12 +973,11 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pmlmepriv->qospriv.qos_option = 0;
if (pregistrypriv->wmm_enable) {
for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
- p = rtw_get_ie(
- p,
- WLAN_EID_VENDOR_SPECIFIC,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2))
- );
+ p = rtw_get_ie(p,
+ WLAN_EID_VENDOR_SPECIFIC,
+ &ie_len,
+ (pbss_network->ie_length -
+ _BEACON_IE_OFFSET_ - (ie_len + 2)));
if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) {
pmlmepriv->qospriv.qos_option = 1;
@@ -1020,12 +999,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
}
/* parsing HT_CAP_IE */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_HT_CAPABILITY,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_HT_CAPABILITY,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
u8 max_rx_ampdu_factor = 0;
struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2);
@@ -1052,9 +1029,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX))
pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_RX_STBC_3R));
- pht_cap->ampdu_params_info &= ~(
- IEEE80211_HT_CAP_AMPDU_FACTOR | IEEE80211_HT_CAP_AMPDU_DENSITY
- );
+ pht_cap->ampdu_params_info &= ~(IEEE80211_HT_CAP_AMPDU_FACTOR |
+ IEEE80211_HT_CAP_AMPDU_DENSITY);
if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) {
@@ -1065,14 +1041,12 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
0x00);
}
- rtw_hal_get_def_var(
- padapter,
- HW_VAR_MAX_RX_AMPDU_FACTOR,
- &max_rx_ampdu_factor
- );
- pht_cap->ampdu_params_info |= (
- IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor
- ); /* set Max Rx AMPDU size to 64K */
+ rtw_hal_get_def_var(padapter,
+ HW_VAR_MAX_RX_AMPDU_FACTOR,
+ &max_rx_ampdu_factor);
+ /* set Max Rx AMPDU size to 64K */
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR &
+ max_rx_ampdu_factor);
pht_cap->mcs.rx_mask[0] = 0xff;
pht_cap->mcs.rx_mask[1] = 0x0;
@@ -1081,12 +1055,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
}
/* parsing HT_INFO_IE */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_HT_OPERATION,
- &ie_len,
- (pbss_network->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_HT_OPERATION,
+ &ie_len,
+ (pbss_network->ie_length - _BEACON_IE_OFFSET_));
if (p && ie_len > 0)
pHT_info_ie = p;
@@ -1128,9 +1100,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
HT_info_handler(padapter, (struct ndis_80211_var_ie *)pHT_info_ie);
}
- pbss_network->length = get_wlan_bssid_ex_sz(
- (struct wlan_bssid_ex *)pbss_network
- );
+ pbss_network->length =
+ get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pbss_network);
/* issue beacon to start bss network */
/* start_bss_network(padapter, (u8 *)pbss_network); */
@@ -1147,7 +1118,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
/* update AP's sta info */
update_ap_info(padapter, psta);
- psta->state |= WIFI_AP_STATE; /* Aries, add, fix bug of flush_cam_entry at STOP AP mode , 0724 */
+ psta->state |= WIFI_AP_STATE;
rtw_indicate_connect(padapter);
pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
@@ -1237,10 +1208,8 @@ void rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
list_for_each_safe(plist, tmp, phead) {
paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
- if (
- !memcmp(paclnode->addr, addr, ETH_ALEN) ||
- is_broadcast_ether_addr(addr)
- ) {
+ if (!memcmp(paclnode->addr, addr, ETH_ALEN) ||
+ is_broadcast_ether_addr(addr)) {
if (paclnode->valid) {
paclnode->valid = false;
@@ -1252,7 +1221,6 @@ void rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
}
spin_unlock_bh(&pacl_node_q->lock);
-
}
u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
@@ -1290,13 +1258,11 @@ exit:
return res;
}
-static int rtw_ap_set_key(
- struct adapter *padapter,
- u8 *key,
- u8 alg,
- int keyid,
- u8 set_tx
-)
+static int rtw_ap_set_key(struct adapter *padapter,
+ u8 *key,
+ u8 alg,
+ int keyid,
+ u8 set_tx)
{
u8 keylen;
struct cmd_obj *pcmd;
@@ -1360,13 +1326,11 @@ int rtw_ap_set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
return rtw_ap_set_key(padapter, key, alg, keyid, 1);
}
-int rtw_ap_set_wep_key(
- struct adapter *padapter,
- u8 *key,
- u8 keylen,
- int keyid,
- u8 set_tx
-)
+int rtw_ap_set_wep_key(struct adapter *padapter,
+ u8 *key,
+ u8 keylen,
+ int keyid,
+ u8 set_tx)
{
u8 alg;
@@ -1401,21 +1365,18 @@ static void update_bcn_erpinfo_ie(struct adapter *padapter)
return;
/* parsing ERP_IE */
- p = rtw_get_ie(
- ie + _BEACON_IE_OFFSET_,
- WLAN_EID_ERP_INFO,
- &len,
- (pnetwork->ie_length - _BEACON_IE_OFFSET_)
- );
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_,
+ WLAN_EID_ERP_INFO,
+ &len,
+ (pnetwork->ie_length - _BEACON_IE_OFFSET_));
if (p && len > 0) {
struct ndis_80211_var_ie *pIE = (struct ndis_80211_var_ie *)p;
if (pmlmepriv->num_sta_non_erp == 1)
pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION;
else
- pIE->data[0] &= ~(
- RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION
- );
+ pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT |
+ RTW_ERP_INFO_USE_PROTECTION);
if (pmlmepriv->num_sta_no_short_preamble > 0)
pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
@@ -1461,12 +1422,10 @@ static void update_bcn_wps_ie(struct adapter *padapter)
unsigned char *ie = pnetwork->ies;
u32 ielen = pnetwork->ie_length;
- pwps_ie = rtw_get_wps_ie(
- ie + _FIXED_IE_LENGTH_,
- ielen - _FIXED_IE_LENGTH_,
- NULL,
- &wps_ielen
- );
+ pwps_ie = rtw_get_wps_ie(ie + _FIXED_IE_LENGTH_,
+ ielen - _FIXED_IE_LENGTH_,
+ NULL,
+ &wps_ielen);
if (!pwps_ie || wps_ielen == 0)
return;
@@ -1490,7 +1449,7 @@ static void update_bcn_wps_ie(struct adapter *padapter)
wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2);
- pwps_ie += (wps_ielen+2);
+ pwps_ie += (wps_ielen + 2);
if (pbackup_remainder_ie)
memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
@@ -1651,9 +1610,9 @@ static int rtw_ht_operation_update(struct adapter *padapter)
if (pmlmepriv->num_sta_no_ht ||
(pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
- else if (
- (le16_to_cpu(phtpriv_ap->ht_cap.cap_info) & IEEE80211_HT_CAP_SUP_WIDTH)
- && pmlmepriv->num_sta_ht_20mhz)
+ else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
+ IEEE80211_HT_CAP_SUP_WIDTH) &&
+ pmlmepriv->num_sta_ht_20mhz)
new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
else if (pmlmepriv->olbc_ht)
new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
@@ -1874,12 +1833,10 @@ u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
return beacon_updated;
}
-u8 ap_free_sta(
- struct adapter *padapter,
- struct sta_info *psta,
- bool active,
- u16 reason
-)
+u8 ap_free_sta(struct adapter *padapter,
+ struct sta_info *psta,
+ bool active,
+ u16 reason)
{
u8 beacon_updated = false;
@@ -1993,6 +1950,7 @@ void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */
}
}
+
/* restore hw setting from sw data structures */
void rtw_ap_restore_network(struct adapter *padapter)
{
@@ -2007,25 +1965,21 @@ void rtw_ap_restore_network(struct adapter *padapter)
rtw_setopmode_cmd(padapter, Ndis802_11APMode, false);
- set_channel_bwmode(
- padapter,
- pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset,
- pmlmeext->cur_bwmode
- );
+ set_channel_bwmode(padapter,
+ pmlmeext->cur_channel,
+ pmlmeext->cur_ch_offset,
+ pmlmeext->cur_bwmode);
start_bss_network(padapter);
if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
/* restore group key, WEP keys is restored in ips_leave() */
- rtw_set_key(
- padapter,
- psecuritypriv,
- psecuritypriv->dot118021XGrpKeyid,
- 0,
- false
- );
+ rtw_set_key(padapter,
+ psecuritypriv,
+ psecuritypriv->dot118021XGrpKeyid,
+ 0,
+ false);
}
spin_lock_bh(&pstapriv->asoc_list_lock);
@@ -2126,11 +2080,9 @@ void stop_ap_mode(struct adapter *padapter)
pmlmeext->bstart_bss = false;
/* reset and init security priv , this can refine with rtw_reset_securitypriv */
- memset(
- (unsigned char *)&padapter->securitypriv,
- 0,
- sizeof(struct security_priv)
- );
+ memset((unsigned char *)&padapter->securitypriv,
+ 0,
+ sizeof(struct security_priv));
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c
index d5c53b614f61..98b15ca10074 100644
--- a/drivers/staging/rtl8723bs/core/rtw_efuse.c
+++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c
@@ -26,9 +26,6 @@ u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
-#define REG_EFUSE_CTRL 0x0030
-#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
-
/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
u8
Efuse_CalculateWordCnts(u8 word_en)
diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
index 53d4c113b19c..8fdeeda88a6d 100644
--- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c
@@ -132,30 +132,30 @@ u8 *rtw_set_ie(u8 *pbuf,
return pbuf + len + 2;
}
-/*----------------------------------------------------------------------------
-index: the information element id index, limit is the limit for search
------------------------------------------------------------------------------*/
+/* index: the information element id index, limit is the limit for search */
u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit)
{
signed int tmp, i;
u8 *p;
- if (limit < 1)
+ if (limit < 2)
return NULL;
p = pbuf;
i = 0;
*len = 0;
- while (1) {
+ while (i + 2 <= limit) {
+ tmp = *(p + 1);
+ if (i + 2 + tmp > limit)
+ break;
+
if (*p == index) {
- *len = *(p + 1);
+ *len = tmp;
return p;
}
- tmp = *(p + 1);
+
p += (tmp + 2);
i += (tmp + 2);
- if (i >= limit)
- break;
}
return NULL;
}
@@ -560,7 +560,6 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi
return ret;
}
-/* ifdef CONFIG_WAPI_SUPPORT */
int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len)
{
int len = 0;
@@ -600,7 +599,6 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len)
return len;
}
-/* endif */
void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len)
{
@@ -769,21 +767,27 @@ static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen,
{
unsigned int oui;
- /* first 3 bytes in vendor specific information element are the IEEE
+ /*
+ * first 3 bytes in vendor specific information element are the IEEE
* OUI of the vendor. The following byte is used a vendor specific
- * sub-type. */
+ * sub-type.
+ */
if (elen < 4)
return -1;
oui = get_unaligned_be24(pos);
switch (oui) {
case OUI_MICROSOFT:
- /* Microsoft/Wi-Fi information elements are further typed and
- * subtyped */
+ /*
+ * Microsoft/Wi-Fi information elements are further typed and
+ * subtyped
+ */
switch (pos[3]) {
case 1:
- /* Microsoft OUI (00:50:F2) with OUI Type 1:
- * real WPA information element */
+ /*
+ * Microsoft OUI (00:50:F2) with OUI Type 1:
+ * real WPA information element
+ */
elems->wpa_ie = pos;
elems->wpa_ie_len = elen;
break;
diff --git a/drivers/staging/rtl8723bs/core/rtw_io.c b/drivers/staging/rtl8723bs/core/rtw_io.c
index 79d543d88278..fe9f94001eed 100644
--- a/drivers/staging/rtl8723bs/core/rtw_io.c
+++ b/drivers/staging/rtl8723bs/core/rtw_io.c
@@ -5,25 +5,23 @@
*
******************************************************************************/
/*
-
-The purpose of rtw_io.c
-
-a. provides the API
-
-b. provides the protocol engine
-
-c. provides the software interface between caller and the hardware interface
-
-
-Compiler Flag Option:
-
-1. CONFIG_SDIO_HCI:
- a. USE_SYNC_IRP: Only sync operations are provided.
- b. USE_ASYNC_IRP:Both sync/async operations are provided.
-
-jackson@realtek.com.tw
-
-*/
+ * The purpose of rtw_io.c
+ *
+ * a. provides the API
+ *
+ * b. provides the protocol engine
+ *
+ * c. provides the software interface between caller and the hardware interface
+ *
+ *
+ * Compiler Flag Option:
+ *
+ * 1. CONFIG_SDIO_HCI:
+ * a. USE_SYNC_IRP: Only sync operations are provided.
+ * b. USE_ASYNC_IRP:Both sync/async operations are provided.
+ *
+ * jackson@realtek.com.tw
+ */
#include <drv_types.h>
@@ -135,10 +133,10 @@ int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct adapt
}
/*
-* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
-* @return true:
-* @return false:
-*/
+ * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
+ * @return true:
+ * @return false:
+ */
int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
{
int error_count = atomic_inc_return(&dvobj->continual_io_error);
@@ -149,9 +147,7 @@ int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
return false;
}
-/*
-* Set the continual_io_error of this @param dvobjprive to 0
-*/
+/* Set the continual_io_error of this @param dvobjprive to 0 */
void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
{
atomic_set(&dvobj->continual_io_error, 0);
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
index c06d990350e6..98704179ad35 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -214,10 +214,10 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *
}
/*
- return the wlan_network with the matching addr
-
- Shall be called under atomic context... to avoid possible racing condition...
-*/
+ * return the wlan_network with the matching addr
+ *
+ * Shall be called under atomic context... to avoid possible racing condition...
+ */
struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
{
struct list_head *phead, *plist;
@@ -319,10 +319,10 @@ void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnet
}
/*
- return the wlan_network with the matching addr
-
- Shall be called under atomic context... to avoid possible racing condition...
-*/
+ * return the wlan_network with the matching addr
+ *
+ * Shall be called under atomic context... to avoid possible racing condition...
+ */
struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
{
struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
@@ -476,9 +476,7 @@ static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex
}
}
-/*
-Caller must hold pmlmepriv->lock first.
-*/
+/* Caller must hold pmlmepriv->lock first. */
void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
{
struct list_head *plist, *phead;
@@ -510,8 +508,10 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
oldest = pnetwork;
}
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
+ /*
+ * If we didn't find a match, then get a new network slot to initialize
+ * with this beacon's information
+ */
if (!target_find) {
if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
/* If there are no more slots, expire the oldest */
@@ -843,9 +843,7 @@ static void find_network(struct adapter *adapter)
rtw_free_network_nolock(adapter, pwlan);
}
-/*
-*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
-*/
+/* rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock */
void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue)
{
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
@@ -879,9 +877,7 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue)
rtw_reset_rx_info(pdbgpriv);
}
-/*
-*rtw_indicate_connect: the caller has to lock pmlmepriv->lock
-*/
+/* rtw_indicate_connect: the caller has to lock pmlmepriv->lock */
void rtw_indicate_connect(struct adapter *padapter)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -908,9 +904,7 @@ void rtw_indicate_connect(struct adapter *padapter)
rtw_set_scan_deny(padapter, 3000);
}
-/*
-*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
-*/
+/* rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock */
void rtw_indicate_disconnect(struct adapter *padapter)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -1543,9 +1537,9 @@ void rtw_wmm_event_callback(struct adapter *padapter, u8 *pbuf)
}
/*
-* _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
-* @adapter: pointer to struct adapter structure
-*/
+ * _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
+ * @adapter: pointer to struct adapter structure
+ */
void _rtw_join_timeout_handler(struct timer_list *t)
{
struct adapter *adapter = timer_container_of(adapter, t,
@@ -1586,9 +1580,9 @@ void _rtw_join_timeout_handler(struct timer_list *t)
}
/*
-* rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
-* @adapter: pointer to struct adapter structure
-*/
+ * rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
+ * @adapter: pointer to struct adapter structure
+ */
void rtw_scan_timeout_handler(struct timer_list *t)
{
struct adapter *adapter = timer_container_of(adapter, t,
@@ -1704,10 +1698,10 @@ void rtw_set_scan_deny(struct adapter *adapter, u32 ms)
}
/*
-* Select a new roaming candidate from the original @param candidate and @param competitor
-* @return true: candidate is updated
-* @return false: candidate is not updated
-*/
+ * Select a new roaming candidate from the original @param candidate and @param competitor
+ * @return true: candidate is updated
+ * @return false: candidate is not updated
+ */
static int rtw_check_roaming_candidate(struct mlme_priv *mlme
, struct wlan_network **candidate, struct wlan_network *competitor)
{
@@ -1785,10 +1779,10 @@ exit:
}
/*
-* Select a new join candidate from the original @param candidate and @param competitor
-* @return true: candidate is updated
-* @return false: candidate is not updated
-*/
+ * Select a new join candidate from the original @param candidate and @param competitor
+ * @return true: candidate is updated
+ * @return false: candidate is not updated
+ */
static int rtw_check_join_candidate(struct mlme_priv *mlme
, struct wlan_network **candidate, struct wlan_network *competitor)
{
@@ -1829,11 +1823,11 @@ exit:
}
/*
-Calling context:
-The caller of the sub-routine will be in critical section...
-The caller must hold the following spinlock
-pmlmepriv->lock
-*/
+ * Calling context:
+ * The caller of the sub-routine will be in critical section...
+ * The caller must hold the following spinlock
+ * pmlmepriv->lock
+ */
int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
{
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index a897c433d2b0..ac49bfbaa5bb 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -18,9 +18,7 @@ static struct mlme_handler mlme_sta_tbl[] = {
{WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
{WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
- /*----------------------------------------------------------
- below 2 are reserved
- -----------------------------------------------------------*/
+ /* below 2 are reserved */
{0, "DoReserved", &DoReserved},
{0, "DoReserved", &DoReserved},
{WIFI_BEACON, "OnBeacon", &OnBeacon},
@@ -50,9 +48,7 @@ static struct action_handler OnAction_tbl[] = {
static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
-/**************************************************
-OUI definitions for the vendor specific IE
-***************************************************/
+/* OUI definitions for the vendor specific IE */
unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
@@ -64,9 +60,7 @@ unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
-/********************************************************
-ChannelPlan definitions
-*********************************************************/
+/* ChannelPlan definitions */
static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
@@ -187,11 +181,7 @@ int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
return i;
}
-/****************************************************************************
-
-Following are the initialization functions for WiFi MLME
-
-*****************************************************************************/
+/* Following are the initialization functions for WiFi MLME */
int init_hw_mlme_ext(struct adapter *padapter)
{
@@ -507,11 +497,7 @@ void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame)
}
}
-/****************************************************************************
-
-Following are the callback functions for each subtype of the management frames
-
-*****************************************************************************/
+/* Following are the callback functions for each subtype of the management frames */
unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame)
{
@@ -588,9 +574,11 @@ unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame)
p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
if (p && ielen > 0) {
- if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
- /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
- *(p + 1) = ielen - 1;
+ if (p + 2 + ielen < pframe + len) {
+ if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
+ /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
+ *(p + 1) = ielen - 1;
+ }
}
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
@@ -1042,6 +1030,9 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
status = WLAN_STATUS_CHALLENGE_FAIL;
goto OnAssocReqFail;
} else {
+ if (ie_len > sizeof(supportRate))
+ ie_len = sizeof(supportRate);
+
memcpy(supportRate, p+2, ie_len);
supportRateNum = ie_len;
@@ -1049,7 +1040,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
pkt_len - WLAN_HDR_A3_LEN - ie_offset);
if (p) {
- if (supportRateNum <= sizeof(supportRate)) {
+ if (supportRateNum + ie_len <= sizeof(supportRate)) {
memcpy(supportRate+supportRateNum, p+2, ie_len);
supportRateNum += ie_len;
}
@@ -1062,7 +1053,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
/* update station supportRate */
pstat->bssratelen = supportRateNum;
memcpy(pstat->bssrateset, supportRate, supportRateNum);
- UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
+ update_basic_rate_table_soft_ap(pstat->bssrateset, pstat->bssratelen);
/* check RSN/WPA/WPS */
pstat->dot8021xalg = 0;
@@ -1450,7 +1441,7 @@ unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
- UpdateBrateTbl(padapter, pmlmeinfo->network.supported_rates);
+ update_basic_rate_table(padapter, pmlmeinfo->network.supported_rates);
report_assoc_result:
if (res > 0)
@@ -1950,11 +1941,7 @@ inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
return _alloc_mgtxmitframe(pxmitpriv, false);
}
-/****************************************************************************
-
-Following are some TX functions for WiFi MLME
-
-*****************************************************************************/
+/* Following are some TX functions for WiFi MLME */
void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
{
@@ -3797,11 +3784,7 @@ unsigned int send_beacon(struct adapter *padapter)
return _SUCCESS;
}
-/****************************************************************************
-
-Following are some utility functions for WiFi MLME
-
-*****************************************************************************/
+/* Following are some utility functions for WiFi MLME */
void site_survey(struct adapter *padapter)
{
@@ -4392,11 +4375,7 @@ static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid
}
}
-/****************************************************************************
-
-Following are the functions to report events
-
-*****************************************************************************/
+/* Following are the functions to report events */
void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame)
{
@@ -4692,11 +4671,7 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
}
-/****************************************************************************
-
-Following are the event callback functions
-
-*****************************************************************************/
+/* Following are the event callback functions */
/* for sta/adhoc mode */
void update_sta_info(struct adapter *padapter, struct sta_info *psta)
@@ -4863,8 +4838,10 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
rtw_sta_media_status_rpt(padapter, psta, 1);
- /* wakeup macid after join bss successfully to ensure
- the subsequent data frames can be sent out normally */
+ /*
+ * wakeup macid after join bss successfully to ensure
+ * the subsequent data frames can be sent out normally
+ */
rtw_hal_macid_wakeup(padapter, psta->mac_id);
}
@@ -4940,11 +4917,8 @@ void mlmeext_sta_del_event_callback(struct adapter *padapter)
rtw_mlmeext_disconnect(padapter);
}
-/****************************************************************************
-
-Following are the functions for the timer handlers
+/* Following are the functions for the timer handlers */
-*****************************************************************************/
void _linked_info_dump(struct adapter *padapter)
{
int i;
@@ -5275,7 +5249,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
/* clear CAM */
flush_all_cam_entry(padapter);
- memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, ie_length));
+ memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, ie_length));
pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
if (pnetwork->ie_length > MAX_IE_SZ)/* Check pbuf->ie_length */
@@ -5339,7 +5313,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
pmlmeinfo->VHT_enable = 0;
- memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, ie_length));
+ memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, ie_length));
pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
if (pnetwork->ie_length > MAX_IE_SZ)/* Check pbuf->ie_length */
diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
index 7b643ac320f0..0ef788abf403 100644
--- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c
@@ -999,11 +999,11 @@ inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
}
/*
-* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
-* @adapter: pointer to struct adapter structure
-* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
-* Return _SUCCESS or _FAIL
-*/
+ * rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
+ * @adapter: pointer to struct adapter structure
+ * @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
+ * Return _SUCCESS or _FAIL
+ */
int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller)
{
diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c
index 3d99d045f4b6..2f941ffbd465 100644
--- a/drivers/staging/rtl8723bs/core/rtw_security.c
+++ b/drivers/staging/rtl8723bs/core/rtw_security.c
@@ -30,9 +30,7 @@ const char *security_type_str(u8 value)
/* WEP related ===== */
-/*
- Need to consider the fragment situation
-*/
+/* Need to consider the fragment situation */
void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
{ /* exclude ICV */
union {
@@ -62,14 +60,14 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
keylength = psecuritypriv->dot11DefKeylen[psecuritypriv->dot11PrivacyKeyIndex];
for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- iv = pframe+pattrib->hdrlen;
+ iv = pframe + pattrib->hdrlen;
memcpy(&wepkey[0], iv, 3);
memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength);
- payload = pframe+pattrib->iv_len+pattrib->hdrlen;
+ payload = pframe + pattrib->iv_len + pattrib->hdrlen;
- if ((curfragnum+1) == pattrib->nr_frags) { /* the last fragment */
+ if ((curfragnum + 1) == pattrib->nr_frags) { /* the last fragment */
- length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
@@ -78,7 +76,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
arc4_crypt(ctx, payload + length, crc.f1, 4);
} else {
- length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
arc4_setkey(ctx, wepkey, 3 + keylength);
arc4_crypt(ctx, payload, payload, length);
@@ -107,16 +105,16 @@ void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
/* start to decrypt recvframe */
if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == _WEP104_)) {
- iv = pframe+prxattrib->hdrlen;
+ iv = pframe + prxattrib->hdrlen;
/* keyindex =(iv[3]&0x3); */
keyindex = prxattrib->key_index;
keylength = psecuritypriv->dot11DefKeylen[keyindex];
memcpy(&wepkey[0], iv, 3);
/* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[keyindex].skey[0], keylength);
- length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
+ length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;
- payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
+ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
/* decrypt payload include icv */
arc4_setkey(ctx, wepkey, 3 + keylength);
@@ -174,7 +172,7 @@ void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key)
void rtw_secmicappendbyte(struct mic_data *pmicdata, u8 b)
{
/* Append the byte to our word-sized buffer */
- pmicdata->M |= ((unsigned long)b) << (8*pmicdata->nBytesInM);
+ pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
pmicdata->nBytesInM++;
/* Process the word if it is full. */
if (pmicdata->nBytesInM >= 4) {
@@ -261,7 +259,7 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod
#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
-#define TK16(N) Mk16(tk[2*(N)+1], tk[2*(N)])
+#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
/* S-box lookup: 16 bits --> 16 bits */
#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
@@ -343,23 +341,20 @@ static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in R
}
};
- /*
-**********************************************************************
-* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
-*
-* Inputs:
-* tk[] = temporal key [128 bits]
-* ta[] = transmitter's MAC address [ 48 bits]
-* iv32 = upper 32 bits of IV [ 32 bits]
-* Output:
-* p1k[] = Phase 1 key [ 80 bits]
-*
-* Note:
-* This function only needs to be called every 2**16 packets,
-* although in theory it could be called every packet.
-*
-**********************************************************************
-*/
+/*
+ * Routine: Phase 1 -- generate P1K, given TA, TK, IV32
+ *
+ * Inputs:
+ * tk[] = temporal key [128 bits]
+ * ta[] = transmitter's MAC address [ 48 bits]
+ * iv32 = upper 32 bits of IV [ 32 bits]
+ * Output:
+ * p1k[] = Phase 1 key [ 80 bits]
+ *
+ * Note:
+ * This function only needs to be called every 2**16 packets,
+ * although in theory it could be called every packet.
+ */
static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
{
signed int i;
@@ -375,39 +370,36 @@ static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
/* size on the 80-bit block P1K[], using the 128-bit key TK[] */
for (i = 0; i < PHASE1_LOOP_CNT; i++) {
/* Each add operation here is mod 2**16 */
- p1k[0] += _S_(p1k[4] ^ TK16((i&1)+0));
- p1k[1] += _S_(p1k[0] ^ TK16((i&1)+2));
- p1k[2] += _S_(p1k[1] ^ TK16((i&1)+4));
- p1k[3] += _S_(p1k[2] ^ TK16((i&1)+6));
- p1k[4] += _S_(p1k[3] ^ TK16((i&1)+0));
+ p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
+ p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
+ p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
+ p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
+ p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
p1k[4] += (unsigned short)i; /* avoid "slide attacks" */
}
}
/*
-**********************************************************************
-* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
-*
-* Inputs:
-* tk[] = Temporal key [128 bits]
-* p1k[] = Phase 1 output key [ 80 bits]
-* iv16 = low 16 bits of IV counter [ 16 bits]
-* Output:
-* rc4key[] = the key used to encrypt the packet [128 bits]
-*
-* Note:
-* The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
-* across all packets using the same key TK value. Then, for a
-* given value of TK[], this TKIP48 construction guarantees that
-* the final RC4KEY value is unique across all packets.
-*
-* Suggested implementation optimization: if PPK[] is "overlaid"
-* appropriately on RC4KEY[], there is no need for the final
-* for loop below that copies the PPK[] result into RC4KEY[].
-*
-**********************************************************************
-*/
+ * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
+ *
+ * Inputs:
+ * tk[] = Temporal key [128 bits]
+ * p1k[] = Phase 1 output key [ 80 bits]
+ * iv16 = low 16 bits of IV counter [ 16 bits]
+ * Output:
+ * rc4key[] = the key used to encrypt the packet [128 bits]
+ *
+ * Note:
+ * The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
+ * across all packets using the same key TK value. Then, for a
+ * given value of TK[], this TKIP48 construction guarantees that
+ * the final RC4KEY value is unique across all packets.
+ *
+ * Suggested implementation optimization: if PPK[] is "overlaid"
+ * appropriately on RC4KEY[], there is no need for the final
+ * for loop below that copies the PPK[] result into RC4KEY[].
+ */
static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
{
signed int i;
@@ -417,7 +409,7 @@ static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
for (i = 0; i < 5; i++)
PPK[i] = p1k[i]; /* first, copy P1K to PPK */
- PPK[5] = p1k[4]+iv16; /* next, add in IV16 */
+ PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
/* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
@@ -448,8 +440,8 @@ static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
/* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
for (i = 0; i < 6; i++) {
- rc4key[4+2*i] = Lo8(PPK[i]);
- rc4key[5+2*i] = Hi8(PPK[i]);
+ rc4key[4 + 2 * i] = Lo8(PPK[i]);
+ rc4key[5 + 2 * i] = Hi8(PPK[i]);
}
}
@@ -492,20 +484,20 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
prwskey = pattrib->dot118021x_UncstKey.skey;
for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- iv = pframe+pattrib->hdrlen;
- payload = pframe+pattrib->iv_len+pattrib->hdrlen;
+ iv = pframe + pattrib->hdrlen;
+ payload = pframe + pattrib->iv_len + pattrib->hdrlen;
GET_TKIP_PN(iv, dot11txpn);
pnl = (u16)(dot11txpn.val);
- pnh = (u32)(dot11txpn.val>>16);
+ pnh = (u32)(dot11txpn.val >> 16);
phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
- if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
- length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */
+ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
arc4_setkey(ctx, rc4key, 16);
@@ -513,7 +505,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
arc4_crypt(ctx, payload + length, crc.f1, 4);
} else {
- length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
crc.f0 = cpu_to_le32(~crc32_le(~0, payload, length));
arc4_setkey(ctx, rc4key, 16);
@@ -601,14 +593,14 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)
prwskey = &stainfo->dot118021x_UncstKey.skey[0];
}
- iv = pframe+prxattrib->hdrlen;
- payload = pframe+prxattrib->iv_len+prxattrib->hdrlen;
- length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
+ iv = pframe + prxattrib->hdrlen;
+ payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
+ length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;
GET_TKIP_PN(iv, dot11txpn);
pnl = (u16)(dot11txpn.val);
- pnh = (u32)(dot11txpn.val>>16);
+ pnh = (u32)(dot11txpn.val >> 16);
phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
@@ -758,7 +750,7 @@ static void construct_mic_header2(u8 *mic_header2,
if (!qc_exists && a4_exists) {
for (i = 0; i < 6; i++)
- mic_header2[8+i] = mpdu[24+i]; /* A4 */
+ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
}
if (qc_exists && !a4_exists) {
@@ -768,7 +760,7 @@ static void construct_mic_header2(u8 *mic_header2,
if (qc_exists && a4_exists) {
for (i = 0; i < 6; i++)
- mic_header2[8+i] = mpdu[24+i]; /* A4 */
+ mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
mic_header2[14] = mpdu[30] & 0x0f;
mic_header2[15] = mpdu[31] & 0x00;
@@ -839,16 +831,16 @@ static signed int aes_cipher(u8 *key, uint hdrlen,
uint frtype = GetFrameType(pframe);
uint frsubtype = GetFrameSubType(pframe);
- frsubtype = frsubtype>>4;
+ frsubtype = frsubtype >> 4;
if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
a4_exists = 0;
else
a4_exists = 1;
- if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
- ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
- ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
+ if (((frtype | frsubtype) == WIFI_DATA_CFACK) ||
+ ((frtype | frsubtype) == WIFI_DATA_CFPOLL) ||
+ ((frtype | frsubtype) == WIFI_DATA_CFACKPOLL)) {
qc_exists = 1;
if (hdrlen != WLAN_HDR_A3_QOS_LEN)
hdrlen += 2;
@@ -867,11 +859,11 @@ static signed int aes_cipher(u8 *key, uint hdrlen,
}
pn_vector[0] = pframe[hdrlen];
- pn_vector[1] = pframe[hdrlen+1];
- pn_vector[2] = pframe[hdrlen+4];
- pn_vector[3] = pframe[hdrlen+5];
- pn_vector[4] = pframe[hdrlen+6];
- pn_vector[5] = pframe[hdrlen+7];
+ pn_vector[1] = pframe[hdrlen + 1];
+ pn_vector[2] = pframe[hdrlen + 4];
+ pn_vector[3] = pframe[hdrlen + 5];
+ pn_vector[4] = pframe[hdrlen + 6];
+ pn_vector[5] = pframe[hdrlen + 7];
construct_mic_iv(mic_iv,
qc_exists,
@@ -927,12 +919,12 @@ static signed int aes_cipher(u8 *key, uint hdrlen,
/* Insert MIC into payload */
for (j = 0; j < 8; j++)
- pframe[payload_index+j] = mic[j];
+ pframe[payload_index + j] = mic[j];
payload_index = hdrlen + 8;
for (i = 0; i < num_blocks; i++) {
construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, /* message, */
- pn_vector, i+1, frtype);
+ pn_vector, i + 1, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, &pframe[payload_index], 16);
@@ -944,13 +936,13 @@ static signed int aes_cipher(u8 *key, uint hdrlen,
/* If there is a short final block, then pad it,*/
/* encrypt it and copy the unpadded part back */
construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, /* message, */
- pn_vector, num_blocks+1, frtype);
+ pn_vector, num_blocks + 1, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
for (j = 0; j < 16; j++)
padded_buffer[j] = 0x00;
for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = pframe[payload_index+j];
+ padded_buffer[j] = pframe[payload_index + j];
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, padded_buffer, 16);
@@ -966,7 +958,7 @@ static signed int aes_cipher(u8 *key, uint hdrlen,
for (j = 0; j < 16; j++)
padded_buffer[j] = 0x00;
for (j = 0; j < 8; j++)
- padded_buffer[j] = pframe[j+hdrlen+8+plen];
+ padded_buffer[j] = pframe[j + hdrlen + 8 + plen];
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, padded_buffer, 16);
@@ -1006,12 +998,12 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
prwskey = pattrib->dot118021x_UncstKey.skey;
for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- if ((curfragnum+1) == pattrib->nr_frags) { /* 4 the last fragment */
- length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */
+ length = pattrib->last_txcmdsz - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
} else {
- length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len;
+ length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
pframe += pxmitpriv->frag_len;
@@ -1044,13 +1036,13 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
uint frtype = GetFrameType(pframe);
uint frsubtype = GetFrameSubType(pframe);
- frsubtype = frsubtype>>4;
+ frsubtype = frsubtype >> 4;
/* start to decrypt the payload */
- num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
+ num_blocks = (plen - 8) / 16; /* plen including LLC, payload_length and mic) */
- payload_remainder = (plen-8) % 16;
+ payload_remainder = (plen - 8) % 16;
pn_vector[0] = pframe[hdrlen];
pn_vector[1] = pframe[hdrlen + 1];
@@ -1064,9 +1056,9 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
else
a4_exists = 1;
- if (((frtype|frsubtype) == WIFI_DATA_CFACK) ||
- ((frtype|frsubtype) == WIFI_DATA_CFPOLL) ||
- ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL)) {
+ if (((frtype | frsubtype) == WIFI_DATA_CFACK) ||
+ ((frtype | frsubtype) == WIFI_DATA_CFPOLL) ||
+ ((frtype | frsubtype) == WIFI_DATA_CFACKPOLL)) {
qc_exists = 1;
if (hdrlen != WLAN_HDR_A3_QOS_LEN)
hdrlen += 2;
@@ -1105,13 +1097,13 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
/* If there is a short final block, then pad it,*/
/* encrypt it and copy the unpadded part back */
construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe, pn_vector,
- num_blocks+1, frtype);
+ num_blocks + 1, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
for (j = 0; j < 16; j++)
padded_buffer[j] = 0x00;
for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = pframe[payload_index+j];
+ padded_buffer[j] = pframe[payload_index + j];
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, padded_buffer, 16);
@@ -1120,25 +1112,25 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
}
/* start to calculate the mic */
- if ((hdrlen + plen+8) <= MAX_MSG_SIZE)
- memcpy((void *)message, pframe, (hdrlen + plen+8)); /* 8 is for ext iv len */
+ if ((hdrlen + plen + 8) <= MAX_MSG_SIZE)
+ memcpy((void *)message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */
pn_vector[0] = pframe[hdrlen];
- pn_vector[1] = pframe[hdrlen+1];
- pn_vector[2] = pframe[hdrlen+4];
- pn_vector[3] = pframe[hdrlen+5];
- pn_vector[4] = pframe[hdrlen+6];
- pn_vector[5] = pframe[hdrlen+7];
+ pn_vector[1] = pframe[hdrlen + 1];
+ pn_vector[2] = pframe[hdrlen + 4];
+ pn_vector[3] = pframe[hdrlen + 5];
+ pn_vector[4] = pframe[hdrlen + 6];
+ pn_vector[5] = pframe[hdrlen + 7];
- construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen-8, pn_vector, frtype);
+ construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, pn_vector, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
construct_mic_header1(mic_header1, hdrlen, message, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
- payload_remainder = (plen-8) % 16;
- num_blocks = (plen-8) / 16;
+ payload_remainder = (plen - 8) % 16;
+ num_blocks = (plen - 8) / 16;
/* Find start of payload */
payload_index = (hdrlen + 8);
@@ -1173,11 +1165,11 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
/* Insert MIC into payload */
for (j = 0; j < 8; j++)
- message[payload_index+j] = mic[j];
+ message[payload_index + j] = mic[j];
payload_index = hdrlen + 8;
for (i = 0; i < num_blocks; i++) {
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i+1,
+ construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector, i + 1,
frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
aes128k128d(key, ctr_preload, aes_out);
@@ -1190,13 +1182,13 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
/* If there is a short final block, then pad it,*/
/* encrypt it and copy the unpadded part back */
construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, pn_vector,
- num_blocks+1, frtype);
+ num_blocks + 1, frtype);
/* add for CONFIG_IEEE80211W, none 11w also can use */
for (j = 0; j < 16; j++)
padded_buffer[j] = 0x00;
for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = message[payload_index+j];
+ padded_buffer[j] = message[payload_index + j];
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, padded_buffer, 16);
@@ -1211,7 +1203,7 @@ static signed int aes_decipher(u8 *key, uint hdrlen,
for (j = 0; j < 16; j++)
padded_buffer[j] = 0x00;
for (j = 0; j < 8; j++)
- padded_buffer[j] = message[j+hdrlen+8+plen-8];
+ padded_buffer[j] = message[j + hdrlen + 8 + plen - 8];
aes128k128d(key, ctr_preload, aes_out);
crypto_xor_cpy(chain_buffer, aes_out, padded_buffer, 16);
@@ -1298,7 +1290,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
prwskey = &stainfo->dot118021x_UncstKey.skey[0];
}
- length = ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
+ length = ((union recv_frame *)precvframe)->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len;
res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
@@ -1323,7 +1315,7 @@ u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
__le16 le_tmp;
__le64 le_tmp64;
- ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
+ ori_len = pattrib->pkt_len - WLAN_HDR_A3_LEN + BIP_AAD_SIZE;
BIP_AAD = rtw_zmalloc(ori_len);
if (!BIP_AAD)
@@ -1334,28 +1326,28 @@ u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe)
/* mapping to wlan header */
pwlanhdr = (struct ieee80211_hdr *)pframe;
/* save the frame body + MME */
- memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
+ memcpy(BIP_AAD + BIP_AAD_SIZE, pframe + WLAN_HDR_A3_LEN, pattrib->pkt_len - WLAN_HDR_A3_LEN);
/* find MME IE pointer */
- p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, WLAN_EID_MMIE, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
+ p = rtw_get_ie(BIP_AAD + BIP_AAD_SIZE, WLAN_EID_MMIE, &len, pattrib->pkt_len - WLAN_HDR_A3_LEN);
/* Baron */
if (p) {
u16 keyid = 0;
u64 temp_ipn = 0;
/* save packet number */
- memcpy(&le_tmp64, p+4, 6);
+ memcpy(&le_tmp64, p + 4, 6);
temp_ipn = le64_to_cpu(le_tmp64);
/* BIP packet number should bigger than previous BIP packet */
if (temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx)
goto BIP_exit;
/* copy key index */
- memcpy(&le_tmp, p+2, 2);
+ memcpy(&le_tmp, p + 2, 2);
keyid = le16_to_cpu(le_tmp);
if (keyid != padapter->securitypriv.dot11wBIPKeyid)
goto BIP_exit;
/* clear the MIC field of MME to zero */
- memset(p+2+len-8, 0, 8);
+ memset(p + 2 + len - 8, 0, 8);
/* conscruct AAD, copy frame control field */
memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
@@ -1483,7 +1475,8 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem,
* This is a mode for using block cipher (AES in this case) for authentication.
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B.
- * modify for CONFIG_IEEE80211W */
+ * modify for CONFIG_IEEE80211W
+ */
int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
@@ -1515,7 +1508,7 @@ u8 rtw_handle_tkip_countermeasure(struct adapter *adapter, const char *caller)
if (securitypriv->btkip_countermeasure) {
unsigned long passing_ms = jiffies_to_msecs(jiffies - securitypriv->btkip_countermeasure_time);
- if (passing_ms > 60*1000) {
+ if (passing_ms > 60 * 1000) {
netdev_dbg(adapter->pnetdev,
"%s(%s) countermeasure time:%lus > 60s\n",
caller, ADPT_ARG(adapter),
diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
index d1f6030799cb..3e80d03c4ec9 100644
--- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c
@@ -383,12 +383,6 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
/* release mac id for non-bc/mc station, */
rtw_release_macid(pstapriv->padapter, psta);
-
-/*
- spin_lock_bh(&pstapriv->asoc_list_lock);
- list_del_init(&psta->asoc_list);
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-*/
spin_lock_bh(&pstapriv->auth_list_lock);
if (!list_empty(&psta->auth_list)) {
list_del_init(&psta->auth_list);
diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
index 1def9758852c..5ffefa50699e 100644
--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
@@ -181,7 +181,7 @@ void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask)
mcs_set[3] &= mcs_rate_4r;
}
-void UpdateBrateTbl(struct adapter *Adapter, u8 *mBratesOS)
+void update_basic_rate_table(struct adapter *Adapter, u8 *mBratesOS)
{
u8 i;
u8 rate;
@@ -203,7 +203,7 @@ void UpdateBrateTbl(struct adapter *Adapter, u8 *mBratesOS)
}
}
-void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
+void update_basic_rate_table_soft_ap(u8 *bssrateset, u32 bssratelen)
{
u8 i;
u8 rate;
@@ -1021,9 +1021,9 @@ void HTOnAssocRsp(struct adapter *padapter)
/* handle A-MPDU parameter field */
/*
- AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
- AMPDU_para [4:2]:Min MPDU Start Spacing
- */
+ * AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
+ * AMPDU_para [4:2]:Min MPDU Start Spacing
+ */
max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
@@ -1689,15 +1689,6 @@ void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
else
pmlmeext->bcn_delay_cnt[delay_ms]++;
/* pmlmeext->bcn_delay_ratio[delay_ms] = (pmlmeext->bcn_delay_cnt[delay_ms] * 100) /pmlmeext->bcn_cnt; */
-
-/*
-
- for (i = 0; i<9; i++)
- {
- pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]);
- }
-*/
-
/* dump for adaptive_early_32k */
if (pmlmeext->bcn_cnt > 100 && (pmlmeext->adaptive_tsf_done == true)) {
u8 ratio_20_delay, ratio_80_delay;
diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c
index 07e9d3423651..70b5b289f9cb 100644
--- a/drivers/staging/rtl8723bs/hal/hal_com.c
+++ b/drivers/staging/rtl8723bs/hal/hal_com.c
@@ -663,71 +663,6 @@ void GetHwReg(struct adapter *adapter, u8 variable, u8 *val)
}
}
-
-
-
-u8 SetHalDefVar(
- struct adapter *adapter, enum hal_def_variable variable, void *value
-)
-{
- struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
- struct dm_odm_t *odm = &(hal_data->odmpriv);
- u8 bResult = _SUCCESS;
-
- switch (variable) {
- case HW_DEF_ODM_DBG_FLAG:
- ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u64 *)value));
- break;
- case HW_DEF_ODM_DBG_LEVEL:
- ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u32 *)value));
- break;
- case HAL_DEF_DBG_DM_FUNC:
- {
- u8 dm_func = *((u8 *)value);
- struct dm_priv *dm = &hal_data->dmpriv;
-
- if (dm_func == 0) { /* disable all dynamic func */
- odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
- } else if (dm_func == 1) {/* disable DIG */
- odm->SupportAbility &= (~DYNAMIC_BB_DIG);
- } else if (dm_func == 2) {/* disable High power */
- odm->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
- } else if (dm_func == 3) {/* disable tx power tracking */
- odm->SupportAbility &= (~DYNAMIC_RF_CALIBRATION);
- } else if (dm_func == 4) {/* disable BT coexistence */
- dm->DMFlag &= (~DYNAMIC_FUNC_BT);
- } else if (dm_func == 5) {/* disable antenna diversity */
- odm->SupportAbility &= (~DYNAMIC_BB_ANT_DIV);
- } else if (dm_func == 6) {/* turn on all dynamic func */
- if (!(odm->SupportAbility & DYNAMIC_BB_DIG)) {
- struct dig_t *pDigTable = &odm->DM_DigTable;
- pDigTable->CurIGValue = rtw_read8(adapter, 0xc50);
- }
- dm->DMFlag |= DYNAMIC_FUNC_BT;
- odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
- }
- }
- break;
- case HAL_DEF_DBG_DUMP_RXPKT:
- hal_data->bDumpRxPkt = *((u8 *)value);
- break;
- case HAL_DEF_DBG_DUMP_TXPKT:
- hal_data->bDumpTxPkt = *((u8 *)value);
- break;
- case HAL_DEF_ANT_DETECT:
- hal_data->AntDetection = *((u8 *)value);
- break;
- default:
- netdev_dbg(adapter->pnetdev,
- "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n",
- __func__, variable);
- bResult = _FAIL;
- break;
- }
-
- return bResult;
-}
-
u8 GetHalDefVar(
struct adapter *adapter, enum hal_def_variable variable, void *value
)
diff --git a/drivers/staging/rtl8723bs/hal/hal_intf.c b/drivers/staging/rtl8723bs/hal/hal_intf.c
index 961b0563951d..462553d296ff 100644
--- a/drivers/staging/rtl8723bs/hal/hal_intf.c
+++ b/drivers/staging/rtl8723bs/hal/hal_intf.c
@@ -115,11 +115,6 @@ void rtw_hal_set_hwreg_with_buf(struct adapter *padapter, u8 variable, u8 *pbuf,
SetHwRegWithBuf8723B(padapter, variable, pbuf, len);
}
-u8 rtw_hal_set_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue)
-{
- return SetHalDefVar8723BSDIO(padapter, eVariable, pValue);
-}
-
u8 rtw_hal_get_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue)
{
return GetHalDefVar8723BSDIO(padapter, eVariable, pValue);
diff --git a/drivers/staging/rtl8723bs/hal/odm.c b/drivers/staging/rtl8723bs/hal/odm.c
index 4b36af47f680..639b6da2302b 100644
--- a/drivers/staging/rtl8723bs/hal/odm.c
+++ b/drivers/staging/rtl8723bs/hal/odm.c
@@ -609,15 +609,12 @@ void ODM_DMWatchdog(struct dm_odm_t *pDM_Odm)
/* 8723A or 8189ES platform */
/* NeilChen--2012--08--24-- */
/* Fix Leave LPS issue */
- if ((adapter_to_pwrctl(pDM_Odm->Adapter)->pwr_mode != PS_MODE_ACTIVE) /* in LPS mode */
- /* */
- /* (pDM_Odm->SupportICType & (ODM_RTL8723A))|| */
- /* (pDM_Odm->SupportICType & (ODM_RTL8188E) &&(&&(((pDM_Odm->SupportInterface == ODM_ITRF_SDIO))) */
- /* */
- ) {
- odm_DIGbyRSSI_LPS(pDM_Odm);
- } else
+ if (adapter_to_pwrctl(pDM_Odm->Adapter)->pwr_mode != PS_MODE_ACTIVE) {
+ /* in LPS mode */
+ odm_DIGbyRSSI_LPS(pDM_Odm);
+ } else {
odm_DIG(pDM_Odm);
+ }
{
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c
index 63c4ebe9df12..af6cdda8238d 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723b_cmd.c
@@ -7,6 +7,7 @@
#include <drv_types.h>
#include <rtl8723b_hal.h>
+#include <linux/etherdevice.h>
#include "hal_com_h2c.h"
#define MAX_H2C_BOX_NUMS 4
@@ -117,8 +118,8 @@ static void ConstructBeacon(struct adapter *padapter, u8 *pframe, u32 *pLength)
*(fctrl) = 0;
eth_broadcast_addr(pwlanhdr->addr1);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, get_my_bssid(cur_network));
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
/* pmlmeext->mgnt_seq++; */
@@ -209,10 +210,10 @@ static void ConstructPSPoll(struct adapter *padapter, u8 *pframe, u32 *pLength)
SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
/* BSSID. */
- memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)));
/* TA. */
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
*pLength = 16;
}
@@ -246,21 +247,21 @@ static void ConstructNullFunctionData(
switch (cur_network->network.infrastructure_mode) {
case Ndis802_11Infrastructure:
SetToDs(fctrl);
- memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)));
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, StaAddr);
break;
case Ndis802_11APMode:
SetFrDs(fctrl);
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)));
+ ether_addr_copy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)));
break;
case Ndis802_11IBSS:
default:
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)));
break;
}
@@ -765,9 +766,9 @@ static void ConstructBtNullFunctionData(
SetPwrMgt(fctrl);
SetFrDs(fctrl);
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
+ ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
SetDuration(pwlanhdr, 0);
SetSeqNum(pwlanhdr, 0);
diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
index 18244adad9e0..57c83f332e74 100644
--- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
+++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c
@@ -2840,22 +2840,6 @@ void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val)
}
/* Description:
- * Change default setting of specified variable.
- */
-u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval)
-{
- u8 bResult = _SUCCESS;
-
- switch (variable) {
- default:
- bResult = SetHalDefVar(padapter, variable, pval);
- break;
- }
-
- return bResult;
-}
-
-/* Description:
* Query setting of specified variable.
*/
u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, void *pval)
diff --git a/drivers/staging/rtl8723bs/hal/sdio_halinit.c b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
index 7fcb874d0eb3..4e81ef53dc47 100644
--- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c
+++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c
@@ -1014,14 +1014,10 @@ static void Hal_EfuseParseMACAddr_8723BS(
struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail
)
{
- u16 i;
- u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0xb7, 0x23, 0x00};
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
if (AutoLoadFail) {
-/* sMacAddr[5] = (u8)GetRandomNumber(1, 254); */
- for (i = 0; i < 6; i++)
- pEEPROM->mac_addr[i] = sMacAddr[i];
+ eth_random_addr(pEEPROM->mac_addr);
} else {
/* Read Permanent MAC address */
memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723BS], ETH_ALEN);
@@ -1236,12 +1232,3 @@ u8 GetHalDefVar8723BSDIO(
return bResult;
}
-
-/* */
-/* Description: */
-/* Change default setting of specified variable. */
-/* */
-u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue)
-{
- return SetHalDefVar8723B(Adapter, eVariable, pValue);
-}
diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c
index 8736c124f857..0ee50b4a1149 100644
--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c
+++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c
@@ -997,10 +997,7 @@ u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
return true;
}
-/* */
-/* Description: */
-/* Query SDIO Local register to get the current number of TX OQT Free Space. */
-/* */
+/* Read the TX OQT free page count from the SDIO local register. */
void HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
{
struct hal_com_data *haldata = GET_HAL_DATA(adapter);
diff --git a/drivers/staging/rtl8723bs/include/basic_types.h b/drivers/staging/rtl8723bs/include/basic_types.h
index 1c2da18e6210..8adb95f9f1e5 100644
--- a/drivers/staging/rtl8723bs/include/basic_types.h
+++ b/drivers/staging/rtl8723bs/include/basic_types.h
@@ -12,8 +12,7 @@
#define FAIL (-1)
#include <linux/types.h>
-
-#define FIELD_OFFSET(s, field) ((__kernel_ssize_t)&((s *)(0))->field)
+#include <linux/stddef.h>
#define SIZE_PTR __kernel_size_t
#define SSIZE_PTR __kernel_ssize_t
diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h
index dd9018aa4ee5..f86180dc350c 100644
--- a/drivers/staging/rtl8723bs/include/drv_types.h
+++ b/drivers/staging/rtl8723bs/include/drv_types.h
@@ -171,13 +171,6 @@ struct registry_priv {
u8 hiq_filter;
};
-
-/* For registry parameters */
-#define RGTRY_OFT(field) ((u32)FIELD_OFFSET(struct registry_priv, field))
-#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field)
-#define BSSID_OFT(field) ((u32)FIELD_OFFSET(struct wlan_bssid_ex, field))
-#define BSSID_SZ(field) sizeof(((struct wlan_bssid_ex *) 0)->field)
-
#include <drv_types_sdio.h>
#define GET_PRIMARY_ADAPTER(padapter) (((struct adapter *)padapter)->dvobj->if1)
diff --git a/drivers/staging/rtl8723bs/include/hal_com.h b/drivers/staging/rtl8723bs/include/hal_com.h
index 7ea9ee2b3975..74d6c892c401 100644
--- a/drivers/staging/rtl8723bs/include/hal_com.h
+++ b/drivers/staging/rtl8723bs/include/hal_com.h
@@ -138,8 +138,6 @@ void SetHwReg(struct adapter *padapter, u8 variable, u8 *val);
void GetHwReg(struct adapter *padapter, u8 variable, u8 *val);
void rtw_hal_check_rxfifo_full(struct adapter *adapter);
-u8 SetHalDefVar(struct adapter *adapter, enum hal_def_variable variable,
- void *value);
u8 GetHalDefVar(struct adapter *adapter, enum hal_def_variable variable,
void *value);
diff --git a/drivers/staging/rtl8723bs/include/hal_com_reg.h b/drivers/staging/rtl8723bs/include/hal_com_reg.h
index 9a02ae69d7a4..cf5c15dc2bfd 100644
--- a/drivers/staging/rtl8723bs/include/hal_com_reg.h
+++ b/drivers/staging/rtl8723bs/include/hal_com_reg.h
@@ -189,10 +189,6 @@
/* Redifine 8192C register definition for compatibility */
/* */
/* */
-
-/* TODO: use these definition when using REG_xxx naming rule. */
-/* NOTE: DO NOT Remove these definition. Use later. */
-
#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
#define EFUSE_TEST REG_EFUSE_TEST /* E-Fuse Test. */
#define MSR (REG_CR + 2) /* Media Status register */
diff --git a/drivers/staging/rtl8723bs/include/hal_intf.h b/drivers/staging/rtl8723bs/include/hal_intf.h
index 2fa2382ad5f3..82b60899129d 100644
--- a/drivers/staging/rtl8723bs/include/hal_intf.h
+++ b/drivers/staging/rtl8723bs/include/hal_intf.h
@@ -199,7 +199,6 @@ void rtw_hal_chip_configure(struct adapter *padapter);
void rtw_hal_read_chip_info(struct adapter *padapter);
void rtw_hal_read_chip_version(struct adapter *padapter);
-u8 rtw_hal_set_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue);
u8 rtw_hal_get_def_var(struct adapter *padapter, enum hal_def_variable eVariable, void *pValue);
void rtw_hal_set_odm_var(struct adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet);
@@ -262,7 +261,6 @@ void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val);
void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val);
void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf, int len);
u8 GetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue);
-u8 SetHalDefVar8723BSDIO(struct adapter *Adapter, enum hal_def_variable eVariable, void *pValue);
void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level);
void rtl8723b_SetBeaconRelatedRegisters(struct adapter *padapter);
void Hal_EfusePowerSwitch(struct adapter *padapter, u8 PwrState);
diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
index 2ed1fc8549ec..06e0a549fa9d 100644
--- a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
+++ b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h
@@ -223,8 +223,6 @@ void C2HPacketHandler_8723B(struct adapter *padapter, u8 *pbuffer, u16 length);
void SetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val);
void GetHwReg8723B(struct adapter *padapter, u8 variable, u8 *val);
-u8 SetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable,
- void *pval);
u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable,
void *pval);
diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme.h b/drivers/staging/rtl8723bs/include/rtw_mlme.h
index 4c15d0194d4f..2a128568c6df 100644
--- a/drivers/staging/rtl8723bs/include/rtw_mlme.h
+++ b/drivers/staging/rtl8723bs/include/rtw_mlme.h
@@ -18,11 +18,7 @@
#define SCANNING_TIMEOUT 8000
-#ifdef PALTFORM_OS_WINCE
-#define SCANQUEUE_LIFETIME 12000000 /* unit:us */
-#else
#define SCANQUEUE_LIFETIME 20000 /* 20sec, unit:msec */
-#endif
#define WIFI_NULL_STATE 0x00000000
#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state... */
diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
index 53fac838c36a..dd5080056e58 100644
--- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h
@@ -434,8 +434,8 @@ u8 networktype_to_raid_ex(struct adapter *adapter, struct sta_info *psta);
void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len);
void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask);
-void UpdateBrateTbl(struct adapter *padapter, u8 *mBratesOS);
-void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen);
+void update_basic_rate_table(struct adapter *padapter, u8 *mBratesOS);
+void update_basic_rate_table_soft_ap(u8 *bssrateset, u32 bssratelen);
void Save_DM_Func_Flag(struct adapter *padapter);
void Restore_DM_Func_Flag(struct adapter *padapter);
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index 315bab373729..60edeae1cffe 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -1712,7 +1712,8 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
if (wep_key_len > 0) {
wep_key_len = wep_key_len <= 5 ? 5 : 13;
- wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
+ wep_total_len = wep_key_len +
+ offsetof(struct ndis_802_11_wep, key_material);
pwep = rtw_malloc(wep_total_len);
if (!pwep) {
ret = -ENOMEM;
diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
index f3caaa857c86..1d0239eef114 100644
--- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
+++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c
@@ -490,3 +490,5 @@ static void __exit rtw_drv_halt(void)
sdio_unregister_driver(&rtl8723bs_sdio_driver);
}
module_exit(rtw_drv_halt);
+
+MODULE_DESCRIPTION("Realtek RTL8723BS SDIO WiFi driver");
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 3659af7e519d..fecd7457e615 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -121,8 +121,8 @@ static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor)
sm750_hw_cursor_disable(cursor);
if (fbcursor->set & FB_CUR_SETSIZE)
sm750_hw_cursor_set_size(cursor,
- fbcursor->image.width,
- fbcursor->image.height);
+ fbcursor->image.width,
+ fbcursor->image.height);
if (fbcursor->set & FB_CUR_SETPOS)
sm750_hw_cursor_set_pos(cursor,
@@ -537,8 +537,13 @@ static int lynxfb_ops_setcolreg(unsigned int regno,
return -EINVAL;
}
- if (info->var.grayscale)
- red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ if (info->var.grayscale) {
+ int lum = (red * 77 + green * 151 + blue * 28) >> 8;
+
+ red = lum;
+ green = lum;
+ blue = lum;
+ }
if (var->bits_per_pixel == 8 &&
info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index b07c1aa68621..046b9282b24a 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -89,7 +89,7 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
u32 x, u32 y, u32 width, u32 height,
u32 color, u32 rop)
{
- u32 deCtrl;
+ u32 de_ctrl;
if (accel->de_wait() != 0) {
/*
@@ -121,11 +121,11 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) |
(height & DE_DIMENSION_Y_ET_MASK)); /* dpr8 */
- deCtrl = DE_CONTROL_STATUS | DE_CONTROL_LAST_PIXEL |
+ de_ctrl = DE_CONTROL_STATUS | DE_CONTROL_LAST_PIXEL |
DE_CONTROL_COMMAND_RECTANGLE_FILL | DE_CONTROL_ROP_SELECT |
(rop & DE_CONTROL_ROP_MASK); /* dpr0xc */
- write_dpr(accel, DE_CONTROL, deCtrl);
+ write_dpr(accel, DE_CONTROL, de_ctrl);
return 0;
}
@@ -284,7 +284,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
return 0;
}
-static unsigned int deGetTransparency(struct lynx_accel *accel)
+static unsigned int de_get_transparency(struct lynx_accel *accel)
{
unsigned int de_ctrl;
@@ -391,7 +391,7 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE |
DE_CONTROL_HOST | DE_CONTROL_STATUS;
- write_dpr(accel, DE_CONTROL, de_ctrl | deGetTransparency(accel));
+ write_dpr(accel, DE_CONTROL, de_ctrl | de_get_transparency(accel));
/* Write MONO data (line by line) to 2D Engine data port */
for (i = 0; i < height; i++) {
diff --git a/drivers/staging/vc04_services/Kconfig b/drivers/staging/vc04_services/Kconfig
index ccc8e1588648..2f6d1aaffdb2 100644
--- a/drivers/staging/vc04_services/Kconfig
+++ b/drivers/staging/vc04_services/Kconfig
@@ -1,56 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-menuconfig BCM_VIDEOCORE
- tristate "Broadcom VideoCore support"
- depends on OF
- depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
- default y
- help
- Support for Broadcom VideoCore services including
- the BCM2835 family of products which is used
- by the Raspberry PI.
-
if BCM_VIDEOCORE
-config BCM2835_VCHIQ
- tristate "BCM2835 VCHIQ"
- depends on HAS_DMA
- imply VCHIQ_CDEV
- help
- Broadcom BCM2835 and similar SoCs have a VPU called VideoCore.
- This config enables the VCHIQ driver, which implements a
- messaging interface between the kernel and the firmware running
- on VideoCore. Other drivers use this interface to communicate to
- the VPU. More specifically, the VCHIQ driver is used by
- audio/video and camera drivers as well as for implementing MMAL
- API, which is in turn used by several multimedia services on the
- BCM2835 family of SoCs.
-
- Defaults to Y when the Broadcom Videocore services are included
- in the build, N otherwise.
-
-if BCM2835_VCHIQ
-
-config VCHIQ_CDEV
- bool "VCHIQ Character Driver"
- help
- Enable the creation of VCHIQ character driver. The cdev exposes
- ioctls used by userspace libraries and testing tools to interact
- with VideoCore, via the VCHIQ core driver (Check BCM2835_VCHIQ
- for more info).
-
- This can be set to 'N' if the VideoCore communication is not
- needed by userspace but only by other kernel modules
- (like bcm2835-audio).
-
- If not sure, set this to 'Y'.
-
-endif
-
source "drivers/staging/vc04_services/bcm2835-audio/Kconfig"
-source "drivers/staging/vc04_services/bcm2835-camera/Kconfig"
-
-source "drivers/staging/vc04_services/vchiq-mmal/Kconfig"
-
endif
diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile
index dad3789522b8..ba15ec663af0 100644
--- a/drivers/staging/vc04_services/Makefile
+++ b/drivers/staging/vc04_services/Makefile
@@ -1,17 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_BCM2835_VCHIQ) += vchiq.o
-
-vchiq-objs := \
- interface/vchiq_arm/vchiq_core.o \
- interface/vchiq_arm/vchiq_arm.o \
- interface/vchiq_arm/vchiq_bus.o \
- interface/vchiq_arm/vchiq_debugfs.o \
-
-ifdef CONFIG_VCHIQ_CDEV
-vchiq-objs += interface/vchiq_arm/vchiq_dev.o
-endif
-
obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/
-obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/
-obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index 0dbe76ee5570..7368b384497f 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -4,11 +4,12 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/completion.h>
+
+#include <linux/raspberrypi/vchiq_arm.h>
+
#include "bcm2835.h"
#include "vc_vchi_audioserv_defs.h"
-#include "../interface/vchiq_arm/vchiq_arm.h"
-
struct bcm2835_audio_instance {
struct device *dev;
unsigned int service_handle;
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
index b74cb104e9de..f292a6618166 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
@@ -6,7 +6,8 @@
#include <linux/slab.h>
#include <linux/module.h>
-#include "../interface/vchiq_arm/vchiq_bus.h"
+#include <linux/raspberrypi/vchiq_bus.h>
+
#include "bcm2835.h"
static bool enable_hdmi;
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
index 49ec5b496edb..5a1348747ff4 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
@@ -5,13 +5,12 @@
#define __SOUND_ARM_BCM2835_H
#include <linux/device.h>
+#include <linux/raspberrypi/vchiq.h>
#include <linux/wait.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm-indirect.h>
-#include "../include/linux/raspberrypi/vchiq.h"
-
#define MAX_SUBSTREAMS (8)
#define AVAIL_SUBSTREAMS_MASK (0xff)
diff --git a/drivers/staging/vc04_services/bcm2835-camera/Kconfig b/drivers/staging/vc04_services/bcm2835-camera/Kconfig
deleted file mode 100644
index 870c9afb223a..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config VIDEO_BCM2835
- tristate "BCM2835 Camera"
- depends on MEDIA_SUPPORT
- depends on VIDEO_DEV && (ARCH_BCM2835 || COMPILE_TEST)
- select BCM2835_VCHIQ if HAS_DMA
- select BCM2835_VCHIQ_MMAL if HAS_DMA
- select VIDEOBUF2_VMALLOC
- select BTREE
- help
- Say Y here to enable camera host interface devices for
- Broadcom BCM2835 SoC. This operates over the VCHIQ interface
- to a service running on VideoCore.
diff --git a/drivers/staging/vc04_services/bcm2835-camera/Makefile b/drivers/staging/vc04_services/bcm2835-camera/Makefile
deleted file mode 100644
index 203b93899b20..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \
- bcm2835-camera.o \
- controls.o
-
-obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o
diff --git a/drivers/staging/vc04_services/bcm2835-camera/TODO b/drivers/staging/vc04_services/bcm2835-camera/TODO
deleted file mode 100644
index 6c2b4ffe4996..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/TODO
+++ /dev/null
@@ -1,17 +0,0 @@
-1) Support dma-buf memory management.
-
-In order to zero-copy import camera images into the 3D or display
-pipelines, we need to export our buffers through dma-buf so that the
-vc4 driver can import them. This may involve bringing in the VCSM
-driver (which allows long-term management of regions of memory in the
-space that the VPU reserved and Linux otherwise doesn't have access
-to), or building some new protocol that allows VCSM-style management
-of Linux's CMA memory.
-
-2) Avoid extra copies for padding of images.
-
-We expose V4L2_PIX_FMT_* formats that have a specified stride/height
-padding in the V4L2 spec, but that padding doesn't match what the
-hardware can do. If we exposed the native padding requirements
-through the V4L2 "multiplanar" formats, the firmware would have one
-less copy it needed to do.
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
deleted file mode 100644
index fa7ea4ca4c36..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ /dev/null
@@ -1,2011 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
-#include <linux/delay.h>
-
-#include "../interface/vchiq_arm/vchiq_bus.h"
-#include "../vchiq-mmal/mmal-common.h"
-#include "../vchiq-mmal/mmal-encodings.h"
-#include "../vchiq-mmal/mmal-vchiq.h"
-#include "../vchiq-mmal/mmal-msg.h"
-#include "../vchiq-mmal/mmal-parameters.h"
-#include "bcm2835-camera.h"
-
-#define MIN_WIDTH 32
-#define MIN_HEIGHT 32
-#define MIN_BUFFER_SIZE (80 * 1024)
-
-#define MAX_VIDEO_MODE_WIDTH 1280
-#define MAX_VIDEO_MODE_HEIGHT 720
-
-#define MAX_BCM2835_CAMERAS 2
-
-int bcm2835_v4l2_debug;
-module_param_named(debug, bcm2835_v4l2_debug, int, 0644);
-MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2");
-
-#define UNSET (-1)
-static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET };
-module_param_array(video_nr, int, NULL, 0644);
-MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect");
-
-static int max_video_width = MAX_VIDEO_MODE_WIDTH;
-static int max_video_height = MAX_VIDEO_MODE_HEIGHT;
-module_param(max_video_width, int, 0644);
-MODULE_PARM_DESC(max_video_width, "Threshold for video mode");
-module_param(max_video_height, int, 0644);
-MODULE_PARM_DESC(max_video_height, "Threshold for video mode");
-
-/* camera instance counter */
-static atomic_t camera_instance = ATOMIC_INIT(0);
-
-/* global device data array */
-static struct bcm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
-
-#define FPS_MIN 1
-#define FPS_MAX 90
-
-/* timeperframe: min/max and default */
-static const struct v4l2_fract
- tpf_min = {.numerator = 1, .denominator = FPS_MAX},
- tpf_max = {.numerator = 1, .denominator = FPS_MIN},
- tpf_default = {.numerator = 1000, .denominator = 30000};
-
-/* Container for MMAL and VB2 buffers*/
-struct vb2_mmal_buffer {
- struct vb2_v4l2_buffer vb;
- struct mmal_buffer mmal;
-};
-
-/* video formats */
-static struct mmal_fmt formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .mmal = MMAL_ENCODING_I420,
- .depth = 12,
- .mmal_component = COMP_CAMERA,
- .ybbp = 1,
- .remove_padding = true,
- }, {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .mmal = MMAL_ENCODING_YUYV,
- .depth = 16,
- .mmal_component = COMP_CAMERA,
- .ybbp = 2,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB24,
- .mmal = MMAL_ENCODING_RGB24,
- .depth = 24,
- .mmal_component = COMP_CAMERA,
- .ybbp = 3,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_JPEG,
- .flags = V4L2_FMT_FLAG_COMPRESSED,
- .mmal = MMAL_ENCODING_JPEG,
- .depth = 8,
- .mmal_component = COMP_IMAGE_ENCODE,
- .ybbp = 0,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_H264,
- .flags = V4L2_FMT_FLAG_COMPRESSED,
- .mmal = MMAL_ENCODING_H264,
- .depth = 8,
- .mmal_component = COMP_VIDEO_ENCODE,
- .ybbp = 0,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_MJPEG,
- .flags = V4L2_FMT_FLAG_COMPRESSED,
- .mmal = MMAL_ENCODING_MJPEG,
- .depth = 8,
- .mmal_component = COMP_VIDEO_ENCODE,
- .ybbp = 0,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .mmal = MMAL_ENCODING_YVYU,
- .depth = 16,
- .mmal_component = COMP_CAMERA,
- .ybbp = 2,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .mmal = MMAL_ENCODING_VYUY,
- .depth = 16,
- .mmal_component = COMP_CAMERA,
- .ybbp = 2,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .mmal = MMAL_ENCODING_UYVY,
- .depth = 16,
- .mmal_component = COMP_CAMERA,
- .ybbp = 2,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12,
- .mmal = MMAL_ENCODING_NV12,
- .depth = 12,
- .mmal_component = COMP_CAMERA,
- .ybbp = 1,
- .remove_padding = true,
- }, {
- .fourcc = V4L2_PIX_FMT_BGR24,
- .mmal = MMAL_ENCODING_BGR24,
- .depth = 24,
- .mmal_component = COMP_CAMERA,
- .ybbp = 3,
- .remove_padding = false,
- }, {
- .fourcc = V4L2_PIX_FMT_YVU420,
- .mmal = MMAL_ENCODING_YV12,
- .depth = 12,
- .mmal_component = COMP_CAMERA,
- .ybbp = 1,
- .remove_padding = true,
- }, {
- .fourcc = V4L2_PIX_FMT_NV21,
- .mmal = MMAL_ENCODING_NV21,
- .depth = 12,
- .mmal_component = COMP_CAMERA,
- .ybbp = 1,
- .remove_padding = true,
- }, {
- .fourcc = V4L2_PIX_FMT_BGR32,
- .mmal = MMAL_ENCODING_BGRA,
- .depth = 32,
- .mmal_component = COMP_CAMERA,
- .ybbp = 4,
- .remove_padding = false,
- },
-};
-
-static struct mmal_fmt *get_format(struct v4l2_format *f)
-{
- struct mmal_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < ARRAY_SIZE(formats); k++) {
- fmt = &formats[k];
- if (fmt->fourcc == f->fmt.pix.pixelformat)
- return fmt;
- }
-
- return NULL;
-}
-
-/* ------------------------------------------------------------------
- * Videobuf queue operations
- * ------------------------------------------------------------------
- */
-
-static int queue_setup(struct vb2_queue *vq,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], struct device *alloc_ctxs[])
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
- unsigned long size;
-
- /* refuse queue setup if port is not configured */
- if (!dev->capture.port) {
- v4l2_err(&dev->v4l2_dev,
- "%s: capture port not configured\n", __func__);
- return -EINVAL;
- }
-
- /* Handle CREATE_BUFS situation - *nplanes != 0 */
- if (*nplanes) {
- if (*nplanes != 1 ||
- sizes[0] < dev->capture.port->current_buffer.size) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: dev:%p Invalid buffer request from CREATE_BUFS, size %u < %u, nplanes %u != 1\n",
- __func__, dev, sizes[0],
- dev->capture.port->current_buffer.size,
- *nplanes);
- return -EINVAL;
- } else {
- return 0;
- }
- }
-
- /* Handle REQBUFS situation */
- size = dev->capture.port->current_buffer.size;
- if (size == 0) {
- v4l2_err(&dev->v4l2_dev,
- "%s: capture port buffer size is zero\n", __func__);
- return -EINVAL;
- }
-
- if (*nbuffers < dev->capture.port->minimum_buffer.num)
- *nbuffers = dev->capture.port->minimum_buffer.num;
-
- dev->capture.port->current_buffer.num = *nbuffers;
-
- *nplanes = 1;
-
- sizes[0] = size;
-
- /*
- * videobuf2-vmalloc allocator is context-less so no need to set
- * alloc_ctxs array.
- */
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
- __func__, dev);
-
- return 0;
-}
-
-static int buffer_init(struct vb2_buffer *vb)
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
- struct vb2_mmal_buffer *buf =
- container_of(vb2, struct vb2_mmal_buffer, vb);
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
- __func__, dev, vb);
- buf->mmal.buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
- buf->mmal.buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-
- return mmal_vchi_buffer_init(dev->instance, &buf->mmal);
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- unsigned long size;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
- __func__, dev, vb);
-
- if (!dev->capture.port || !dev->capture.fmt)
- return -ENODEV;
-
- size = dev->capture.stride * dev->capture.height;
- if (vb2_plane_size(vb, 0) < size) {
- v4l2_err(&dev->v4l2_dev,
- "%s data will not fit into plane (%lu < %lu)\n",
- __func__, vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void buffer_cleanup(struct vb2_buffer *vb)
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
- struct vb2_mmal_buffer *buf =
- container_of(vb2, struct vb2_mmal_buffer, vb);
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
- __func__, dev, vb);
-
- mmal_vchi_buffer_cleanup(&buf->mmal);
-}
-
-static inline bool is_capturing(struct bcm2835_mmal_dev *dev)
-{
- return dev->capture.camera_port ==
- &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
-}
-
-static void buffer_cb(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- int status,
- struct mmal_buffer *mmal_buf)
-{
- struct bcm2835_mmal_dev *dev = port->cb_ctx;
- struct vb2_mmal_buffer *buf =
- container_of(mmal_buf, struct vb2_mmal_buffer, mmal);
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n",
- __func__, status, buf, mmal_buf->length, mmal_buf->mmal_flags,
- mmal_buf->pts);
-
- if (status) {
- /* error in transfer */
- if (buf) {
- /* there was a buffer with the error so return it */
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
- return;
- }
-
- if (mmal_buf->length == 0) {
- /* stream ended */
- if (dev->capture.frame_count) {
- /* empty buffer whilst capturing - expected to be an
- * EOS, so grab another frame
- */
- if (is_capturing(dev)) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Grab another frame");
- vchiq_mmal_port_parameter_set(instance,
- dev->capture.camera_port,
- MMAL_PARAMETER_CAPTURE,
- &dev->capture.frame_count,
- sizeof(dev->capture.frame_count));
- }
- if (vchiq_mmal_submit_buffer(instance, port,
- &buf->mmal))
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Failed to return EOS buffer");
- } else {
- /* stopping streaming.
- * return buffer, and signal frame completion
- */
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- complete(&dev->capture.frame_cmplt);
- }
- return;
- }
-
- if (!dev->capture.frame_count) {
- /* signal frame completion */
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- complete(&dev->capture.frame_cmplt);
- return;
- }
-
- if (dev->capture.vc_start_timestamp != -1 && mmal_buf->pts) {
- ktime_t timestamp;
- s64 runtime_us = mmal_buf->pts -
- dev->capture.vc_start_timestamp;
- timestamp = ktime_add_us(dev->capture.kernel_start_ts,
- runtime_us);
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Convert start time %llu and %llu with offset %llu to %llu\n",
- ktime_to_ns(dev->capture.kernel_start_ts),
- dev->capture.vc_start_timestamp, mmal_buf->pts,
- ktime_to_ns(timestamp));
- buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp);
- } else {
- buf->vb.vb2_buf.timestamp = ktime_get_ns();
- }
- buf->vb.sequence = dev->capture.sequence++;
- buf->vb.field = V4L2_FIELD_NONE;
-
- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length);
- if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
- buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
-
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
- if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS &&
- is_capturing(dev)) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Grab another frame as buffer has EOS");
- vchiq_mmal_port_parameter_set(instance,
- dev->capture.camera_port,
- MMAL_PARAMETER_CAPTURE,
- &dev->capture.frame_count,
- sizeof(dev->capture.frame_count));
- }
-}
-
-static int enable_camera(struct bcm2835_mmal_dev *dev)
-{
- int ret;
-
- if (!dev->camera_use_count) {
- ret = vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_CAMERA]->control,
- MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
- sizeof(dev->camera_num));
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev,
- "Failed setting camera num, ret %d\n", ret);
- return -EINVAL;
- }
-
- ret = vchiq_mmal_component_enable(dev->instance,
- dev->component[COMP_CAMERA]);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev,
- "Failed enabling camera, ret %d\n", ret);
- return -EINVAL;
- }
- }
- dev->camera_use_count++;
- v4l2_dbg(1, bcm2835_v4l2_debug,
- &dev->v4l2_dev, "enabled camera (refcount %d)\n",
- dev->camera_use_count);
- return 0;
-}
-
-static int disable_camera(struct bcm2835_mmal_dev *dev)
-{
- int ret;
-
- if (!dev->camera_use_count) {
- v4l2_err(&dev->v4l2_dev,
- "Disabled the camera when already disabled\n");
- return -EINVAL;
- }
- dev->camera_use_count--;
- if (!dev->camera_use_count) {
- unsigned int i = 0xFFFFFFFF;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Disabling camera\n");
- ret = vchiq_mmal_component_disable(dev->instance,
- dev->component[COMP_CAMERA]);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev,
- "Failed disabling camera, ret %d\n", ret);
- return -EINVAL;
- }
- vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_CAMERA]->control,
- MMAL_PARAMETER_CAMERA_NUM,
- &i,
- sizeof(i));
- }
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Camera refcount now %d\n", dev->camera_use_count);
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
- struct vb2_mmal_buffer *buf =
- container_of(vb2, struct vb2_mmal_buffer, vb);
- int ret;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: dev:%p buf:%p, idx %u\n",
- __func__, dev, buf, vb2->vb2_buf.index);
-
- ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port,
- &buf->mmal);
- if (ret < 0)
- v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n",
- __func__);
-}
-
-static int start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
- int ret;
- u32 parameter_size;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
- __func__, dev);
-
- /* ensure a format has actually been set */
- if (!dev->capture.port)
- return -EINVAL;
-
- if (enable_camera(dev) < 0) {
- v4l2_err(&dev->v4l2_dev, "Failed to enable camera\n");
- return -EINVAL;
- }
-
- /*init_completion(&dev->capture.frame_cmplt); */
-
- /* enable frame capture */
- dev->capture.frame_count = 1;
-
- /* reset sequence number */
- dev->capture.sequence = 0;
-
- /* if the preview is not already running, wait for a few frames for AGC
- * to settle down.
- */
- if (!dev->component[COMP_PREVIEW]->enabled)
- msleep(300);
-
- /* enable the connection from camera to encoder (if applicable) */
- if (dev->capture.camera_port != dev->capture.port &&
- dev->capture.camera_port) {
- ret = vchiq_mmal_port_enable(dev->instance,
- dev->capture.camera_port, NULL);
- if (ret) {
- v4l2_err(&dev->v4l2_dev,
- "Failed to enable encode tunnel - error %d\n",
- ret);
- return -1;
- }
- }
-
- /* Get VC timestamp at this point in time */
- parameter_size = sizeof(dev->capture.vc_start_timestamp);
- if (vchiq_mmal_port_parameter_get(dev->instance,
- dev->capture.camera_port,
- MMAL_PARAMETER_SYSTEM_TIME,
- &dev->capture.vc_start_timestamp,
- &parameter_size)) {
- v4l2_err(&dev->v4l2_dev,
- "Failed to get VC start time - update your VC f/w\n");
-
- /* Flag to indicate just to rely on kernel timestamps */
- dev->capture.vc_start_timestamp = -1;
- } else {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Start time %lld size %d\n",
- dev->capture.vc_start_timestamp, parameter_size);
- }
-
- dev->capture.kernel_start_ts = ktime_get();
-
- /* enable the camera port */
- dev->capture.port->cb_ctx = dev;
- ret = vchiq_mmal_port_enable(dev->instance, dev->capture.port,
- buffer_cb);
- if (ret) {
- v4l2_err(&dev->v4l2_dev,
- "Failed to enable capture port - error %d. Disabling camera port again\n",
- ret);
-
- vchiq_mmal_port_disable(dev->instance,
- dev->capture.camera_port);
- if (disable_camera(dev) < 0) {
- v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
- return -EINVAL;
- }
- return -1;
- }
-
- /* capture the first frame */
- vchiq_mmal_port_parameter_set(dev->instance,
- dev->capture.camera_port,
- MMAL_PARAMETER_CAPTURE,
- &dev->capture.frame_count,
- sizeof(dev->capture.frame_count));
- return 0;
-}
-
-/* abort streaming and wait for last buffer */
-static void stop_streaming(struct vb2_queue *vq)
-{
- int ret;
- unsigned long time_left;
- struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
- struct vchiq_mmal_port *port = dev->capture.port;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
- __func__, dev);
-
- init_completion(&dev->capture.frame_cmplt);
- dev->capture.frame_count = 0;
-
- /* ensure a format has actually been set */
- if (!port) {
- v4l2_err(&dev->v4l2_dev,
- "no capture port - stream not started?\n");
- return;
- }
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "stopping capturing\n");
-
- /* stop capturing frames */
- vchiq_mmal_port_parameter_set(dev->instance,
- dev->capture.camera_port,
- MMAL_PARAMETER_CAPTURE,
- &dev->capture.frame_count,
- sizeof(dev->capture.frame_count));
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "disabling connection\n");
-
- /* disable the connection from camera to encoder */
- ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port);
- if (!ret && dev->capture.camera_port != port) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "disabling port\n");
- ret = vchiq_mmal_port_disable(dev->instance, port);
- } else if (dev->capture.camera_port != port) {
- v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n",
- ret);
- }
-
- /* wait for all buffers to be returned */
- while (atomic_read(&port->buffers_with_vpu)) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: Waiting for buffers to be returned - %d outstanding\n",
- __func__, atomic_read(&port->buffers_with_vpu));
- time_left = wait_for_completion_timeout(&dev->capture.frame_cmplt,
- HZ);
- if (time_left == 0) {
- v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
- __func__,
- atomic_read(&port->buffers_with_vpu));
- break;
- }
- }
-
- if (disable_camera(dev) < 0)
- v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
-}
-
-static const struct vb2_ops bcm2835_mmal_video_qops = {
- .queue_setup = queue_setup,
- .buf_init = buffer_init,
- .buf_prepare = buffer_prepare,
- .buf_cleanup = buffer_cleanup,
- .buf_queue = buffer_queue,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-/* ------------------------------------------------------------------
- * IOCTL operations
- * ------------------------------------------------------------------
- */
-
-static int set_overlay_params(struct bcm2835_mmal_dev *dev,
- struct vchiq_mmal_port *port)
-{
- struct mmal_parameter_displayregion prev_config = {
- .set = MMAL_DISPLAY_SET_LAYER |
- MMAL_DISPLAY_SET_ALPHA |
- MMAL_DISPLAY_SET_DEST_RECT |
- MMAL_DISPLAY_SET_FULLSCREEN,
- .layer = 2,
- .alpha = dev->overlay.global_alpha,
- .fullscreen = 0,
- .dest_rect = {
- .x = dev->overlay.w.left,
- .y = dev->overlay.w.top,
- .width = dev->overlay.w.width,
- .height = dev->overlay.w.height,
- },
- };
- return vchiq_mmal_port_parameter_set(dev->instance, port,
- MMAL_PARAMETER_DISPLAYREGION,
- &prev_config, sizeof(prev_config));
-}
-
-/* overlay ioctl */
-static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct mmal_fmt *fmt;
-
- if (f->index >= ARRAY_SIZE(formats))
- return -EINVAL;
-
- fmt = &formats[f->index];
-
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
-
- f->fmt.win = dev->overlay;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
-
- f->fmt.win.field = V4L2_FIELD_NONE;
- f->fmt.win.chromakey = 0;
- f->fmt.win.clips = NULL;
- f->fmt.win.clipcount = 0;
- f->fmt.win.bitmap = NULL;
-
- v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1,
- &f->fmt.win.w.height, MIN_HEIGHT, dev->max_height,
- 1, 0);
- v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1,
- &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height,
- 1, 0);
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Overlay: Now w/h %dx%d l/t %dx%d\n",
- f->fmt.win.w.width, f->fmt.win.w.height,
- f->fmt.win.w.left, f->fmt.win.w.top);
-
- v4l2_dump_win_format(1,
- bcm2835_v4l2_debug,
- &dev->v4l2_dev,
- &f->fmt.win,
- __func__);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
-
- vidioc_try_fmt_vid_overlay(file, priv, f);
-
- dev->overlay = f->fmt.win;
- if (dev->component[COMP_PREVIEW]->enabled) {
- set_overlay_params(dev,
- &dev->component[COMP_PREVIEW]->input[0]);
- }
-
- return 0;
-}
-
-static int vidioc_overlay(struct file *file, void *f, unsigned int on)
-{
- int ret;
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- struct vchiq_mmal_port *src;
- struct vchiq_mmal_port *dst;
-
- if ((on && dev->component[COMP_PREVIEW]->enabled) ||
- (!on && !dev->component[COMP_PREVIEW]->enabled))
- return 0; /* already in requested state */
-
- src = &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
-
- if (!on) {
- /* disconnect preview ports and disable component */
- ret = vchiq_mmal_port_disable(dev->instance, src);
- if (!ret)
- ret = vchiq_mmal_port_connect_tunnel(dev->instance, src,
- NULL);
- if (ret >= 0)
- ret = vchiq_mmal_component_disable(dev->instance,
- dev->component[COMP_PREVIEW]);
-
- disable_camera(dev);
- return ret;
- }
-
- /* set preview port format and connect it to output */
- dst = &dev->component[COMP_PREVIEW]->input[0];
-
- ret = vchiq_mmal_port_set_format(dev->instance, src);
- if (ret < 0)
- return ret;
-
- ret = set_overlay_params(dev, dst);
- if (ret < 0)
- return ret;
-
- if (enable_camera(dev) < 0)
- return -EINVAL;
-
- ret = vchiq_mmal_component_enable(dev->instance,
- dev->component[COMP_PREVIEW]);
- if (ret < 0)
- return ret;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "connecting %p to %p\n",
- src, dst);
- ret = vchiq_mmal_port_connect_tunnel(dev->instance, src, dst);
- if (ret)
- return ret;
-
- return vchiq_mmal_port_enable(dev->instance, src, NULL);
-}
-
-static int vidioc_g_fbuf(struct file *file, void *fh,
- struct v4l2_framebuffer *a)
-{
- /* The video overlay must stay within the framebuffer and can't be
- * positioned independently.
- */
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- struct vchiq_mmal_port *preview_port =
- &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
-
- a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
- V4L2_FBUF_CAP_GLOBAL_ALPHA;
- a->flags = V4L2_FBUF_FLAG_OVERLAY;
- a->fmt.width = preview_port->es.video.width;
- a->fmt.height = preview_port->es.video.height;
- a->fmt.pixelformat = V4L2_PIX_FMT_YUV420;
- a->fmt.bytesperline = preview_port->es.video.width;
- a->fmt.sizeimage = (preview_port->es.video.width *
- preview_port->es.video.height * 3) >> 1;
- a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
- return 0;
-}
-
-/* input ioctls */
-static int vidioc_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- /* only a single camera input */
- if (inp->index)
- return -EINVAL;
-
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- snprintf((char *)inp->name, sizeof(inp->name), "Camera %u", inp->index);
- return 0;
-}
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- if (i)
- return -EINVAL;
-
- return 0;
-}
-
-/* capture ioctls */
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- u32 major;
- u32 minor;
-
- vchiq_mmal_version(dev->instance, &major, &minor);
-
- strscpy(cap->driver, "bcm2835 mmal", sizeof(cap->driver));
- snprintf((char *)cap->card, sizeof(cap->card), "mmal service %d.%d", major, minor);
-
- snprintf((char *)cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev->v4l2_dev.name);
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct mmal_fmt *fmt;
-
- if (f->index >= ARRAY_SIZE(formats))
- return -EINVAL;
-
- fmt = &formats[f->index];
-
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
-
- f->fmt.pix.width = dev->capture.width;
- f->fmt.pix.height = dev->capture.height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = dev->capture.fmt->fourcc;
- f->fmt.pix.bytesperline = dev->capture.stride;
- f->fmt.pix.sizeimage = dev->capture.buffersize;
-
- if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_RGB24)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- else if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_JPEG)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- else
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
-
- v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix,
- __func__);
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- struct mmal_fmt *mfmt;
-
- mfmt = get_format(f);
- if (!mfmt) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Fourcc format (0x%08x) unknown.\n",
- f->fmt.pix.pixelformat);
- f->fmt.pix.pixelformat = formats[0].fourcc;
- mfmt = get_format(f);
- }
-
- f->fmt.pix.field = V4L2_FIELD_NONE;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Clipping/aligning %dx%d format %08X\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
-
- v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1,
- &f->fmt.pix.height, MIN_HEIGHT, dev->max_height,
- 1, 0);
- f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp;
- if (!mfmt->remove_padding) {
- if (mfmt->depth == 24) {
- /*
- * 24bpp is a pain as we can't use simple masking.
- * Min stride is width aligned to 16, times 24bpp.
- */
- f->fmt.pix.bytesperline =
- ((f->fmt.pix.width + 15) & ~15) * 3;
- } else {
- /*
- * GPU isn't removing padding, so stride is aligned to
- * 32
- */
- int align_mask = ((32 * mfmt->depth) >> 3) - 1;
-
- f->fmt.pix.bytesperline =
- (f->fmt.pix.bytesperline + align_mask) &
- ~align_mask;
- }
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Not removing padding, so bytes/line = %d\n",
- f->fmt.pix.bytesperline);
- }
-
- /* Image buffer has to be padded to allow for alignment, even though
- * we sometimes then remove that padding before delivering the buffer.
- */
- f->fmt.pix.sizeimage = ((f->fmt.pix.height + 15) & ~15) *
- (((f->fmt.pix.width + 31) & ~31) * mfmt->depth) >> 3;
-
- if ((mfmt->flags & V4L2_FMT_FLAG_COMPRESSED) &&
- f->fmt.pix.sizeimage < MIN_BUFFER_SIZE)
- f->fmt.pix.sizeimage = MIN_BUFFER_SIZE;
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
- f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- else
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Now %dx%d format %08X\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
-
- v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix,
- __func__);
- return 0;
-}
-
-static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
- struct v4l2_format *f)
-{
- bool overlay_enabled = !!dev->component[COMP_PREVIEW]->enabled;
- struct vchiq_mmal_port *preview_port;
- int ret;
-
- preview_port = &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
-
- /* Preview and encode ports need to match on resolution */
- if (overlay_enabled) {
- /* Need to disable the overlay before we can update
- * the resolution
- */
- ret = vchiq_mmal_port_disable(dev->instance, preview_port);
- if (!ret) {
- ret = vchiq_mmal_port_connect_tunnel(dev->instance,
- preview_port,
- NULL);
- }
- }
- preview_port->es.video.width = f->fmt.pix.width;
- preview_port->es.video.height = f->fmt.pix.height;
- preview_port->es.video.crop.x = 0;
- preview_port->es.video.crop.y = 0;
- preview_port->es.video.crop.width = f->fmt.pix.width;
- preview_port->es.video.crop.height = f->fmt.pix.height;
- preview_port->es.video.frame_rate.numerator =
- dev->capture.timeperframe.denominator;
- preview_port->es.video.frame_rate.denominator =
- dev->capture.timeperframe.numerator;
- ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
-
- if (overlay_enabled) {
- ret = vchiq_mmal_port_connect_tunnel(dev->instance,
- preview_port,
- &dev->component[COMP_PREVIEW]->input[0]);
- if (ret)
- return ret;
-
- ret = vchiq_mmal_port_enable(dev->instance, preview_port, NULL);
- }
-
- return ret;
-}
-
-static int mmal_setup_encode_component(struct bcm2835_mmal_dev *dev,
- struct v4l2_format *f,
- struct vchiq_mmal_port *port,
- struct vchiq_mmal_port *camera_port,
- struct vchiq_mmal_component *component)
-{
- struct mmal_fmt *mfmt = get_format(f);
- int ret;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "vid_cap - set up encode comp\n");
-
- /* configure buffering */
- camera_port->current_buffer.size = camera_port->recommended_buffer.size;
- camera_port->current_buffer.num = camera_port->recommended_buffer.num;
-
- ret = vchiq_mmal_port_connect_tunnel(dev->instance, camera_port,
- &component->input[0]);
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s failed to create connection\n", __func__);
- /* ensure capture is not going to be tried */
- dev->capture.port = NULL;
- return ret;
- }
-
- port->es.video.width = f->fmt.pix.width;
- port->es.video.height = f->fmt.pix.height;
- port->es.video.crop.x = 0;
- port->es.video.crop.y = 0;
- port->es.video.crop.width = f->fmt.pix.width;
- port->es.video.crop.height = f->fmt.pix.height;
- port->es.video.frame_rate.numerator =
- dev->capture.timeperframe.denominator;
- port->es.video.frame_rate.denominator =
- dev->capture.timeperframe.numerator;
-
- port->format.encoding = mfmt->mmal;
- port->format.encoding_variant = 0;
- /* Set any encoding specific parameters */
- switch (mfmt->mmal_component) {
- case COMP_VIDEO_ENCODE:
- port->format.bitrate = dev->capture.encode_bitrate;
- break;
- case COMP_IMAGE_ENCODE:
- /* Could set EXIF parameters here */
- break;
- default:
- break;
- }
-
- ret = vchiq_mmal_port_set_format(dev->instance, port);
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s failed to set format %dx%d fmt %08X\n",
- __func__,
- f->fmt.pix.width,
- f->fmt.pix.height,
- f->fmt.pix.pixelformat);
- return ret;
- }
-
- ret = vchiq_mmal_component_enable(dev->instance, component);
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s Failed to enable encode components\n", __func__);
- return ret;
- }
-
- /* configure buffering */
- port->current_buffer.num = 1;
- port->current_buffer.size = f->fmt.pix.sizeimage;
- if (port->format.encoding == MMAL_ENCODING_JPEG) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "JPG - buf size now %d was %d\n",
- f->fmt.pix.sizeimage,
- port->current_buffer.size);
- port->current_buffer.size =
- (f->fmt.pix.sizeimage < (100 << 10)) ?
- (100 << 10) : f->fmt.pix.sizeimage;
- }
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "vid_cap - cur_buf.size set to %d\n", f->fmt.pix.sizeimage);
- port->current_buffer.alignment = 0;
-
- return 0;
-}
-
-static int mmal_setup_components(struct bcm2835_mmal_dev *dev,
- struct v4l2_format *f)
-{
- int ret;
- struct vchiq_mmal_port *port = NULL, *camera_port = NULL;
- struct vchiq_mmal_component *encode_component = NULL;
- struct mmal_fmt *mfmt = get_format(f);
- bool remove_padding;
-
- if (!mfmt)
- return -EINVAL;
-
- if (dev->capture.encode_component) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "vid_cap - disconnect previous tunnel\n");
-
- /* Disconnect any previous connection */
- vchiq_mmal_port_connect_tunnel(dev->instance,
- dev->capture.camera_port, NULL);
- dev->capture.camera_port = NULL;
- ret = vchiq_mmal_component_disable(dev->instance,
- dev->capture.encode_component);
- if (ret)
- v4l2_err(&dev->v4l2_dev,
- "Failed to disable encode component %d\n",
- ret);
-
- dev->capture.encode_component = NULL;
- }
- /* format dependent port setup */
- switch (mfmt->mmal_component) {
- case COMP_CAMERA:
- /* Make a further decision on port based on resolution */
- if (f->fmt.pix.width <= max_video_width &&
- f->fmt.pix.height <= max_video_height)
- camera_port =
- &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO];
- else
- camera_port =
- &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
- port = camera_port;
- break;
- case COMP_IMAGE_ENCODE:
- encode_component = dev->component[COMP_IMAGE_ENCODE];
- port = &dev->component[COMP_IMAGE_ENCODE]->output[0];
- camera_port =
- &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
- break;
- case COMP_VIDEO_ENCODE:
- encode_component = dev->component[COMP_VIDEO_ENCODE];
- port = &dev->component[COMP_VIDEO_ENCODE]->output[0];
- camera_port =
- &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO];
- break;
- default:
- break;
- }
-
- if (!port)
- return -EINVAL;
-
- if (encode_component)
- camera_port->format.encoding = MMAL_ENCODING_OPAQUE;
- else
- camera_port->format.encoding = mfmt->mmal;
-
- if (dev->rgb_bgr_swapped) {
- if (camera_port->format.encoding == MMAL_ENCODING_RGB24)
- camera_port->format.encoding = MMAL_ENCODING_BGR24;
- else if (camera_port->format.encoding == MMAL_ENCODING_BGR24)
- camera_port->format.encoding = MMAL_ENCODING_RGB24;
- }
-
- remove_padding = mfmt->remove_padding;
- vchiq_mmal_port_parameter_set(dev->instance, camera_port,
- MMAL_PARAMETER_NO_IMAGE_PADDING,
- &remove_padding, sizeof(remove_padding));
-
- camera_port->format.encoding_variant = 0;
- camera_port->es.video.width = f->fmt.pix.width;
- camera_port->es.video.height = f->fmt.pix.height;
- camera_port->es.video.crop.x = 0;
- camera_port->es.video.crop.y = 0;
- camera_port->es.video.crop.width = f->fmt.pix.width;
- camera_port->es.video.crop.height = f->fmt.pix.height;
- camera_port->es.video.frame_rate.numerator = 0;
- camera_port->es.video.frame_rate.denominator = 1;
- camera_port->es.video.color_space = MMAL_COLOR_SPACE_JPEG_JFIF;
-
- ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
-
- if (!ret &&
- camera_port ==
- &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]) {
- ret = mmal_setup_video_component(dev, f);
- }
-
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s failed to set format %dx%d %08X\n", __func__,
- f->fmt.pix.width, f->fmt.pix.height,
- f->fmt.pix.pixelformat);
- /* ensure capture is not going to be tried */
- dev->capture.port = NULL;
- return ret;
- }
-
- if (encode_component) {
- ret = mmal_setup_encode_component(dev, f, port,
- camera_port,
- encode_component);
-
- if (ret)
- return ret;
- } else {
- /* configure buffering */
- camera_port->current_buffer.num = 1;
- camera_port->current_buffer.size = f->fmt.pix.sizeimage;
- camera_port->current_buffer.alignment = 0;
- }
-
- dev->capture.fmt = mfmt;
- dev->capture.stride = f->fmt.pix.bytesperline;
- dev->capture.width = camera_port->es.video.crop.width;
- dev->capture.height = camera_port->es.video.crop.height;
- dev->capture.buffersize = port->current_buffer.size;
-
- /* select port for capture */
- dev->capture.port = port;
- dev->capture.camera_port = camera_port;
- dev->capture.encode_component = encode_component;
- v4l2_dbg(1, bcm2835_v4l2_debug,
- &dev->v4l2_dev,
- "Set dev->capture.fmt %08X, %dx%d, stride %d, size %d",
- port->format.encoding,
- dev->capture.width, dev->capture.height,
- dev->capture.stride, dev->capture.buffersize);
-
- /* todo: Need to convert the vchiq/mmal error into a v4l2 error. */
- return ret;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- int ret;
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- struct mmal_fmt *mfmt;
-
- /* try the format to set valid parameters */
- ret = vidioc_try_fmt_vid_cap(file, priv, f);
- if (ret) {
- v4l2_err(&dev->v4l2_dev,
- "vid_cap - vidioc_try_fmt_vid_cap failed\n");
- return ret;
- }
-
- /* if a capture is running refuse to set format */
- if (vb2_is_busy(&dev->capture.vb_vidq)) {
- v4l2_info(&dev->v4l2_dev, "%s device busy\n", __func__);
- return -EBUSY;
- }
-
- /* If the format is unsupported v4l2 says we should switch to
- * a supported one and not return an error.
- */
- mfmt = get_format(f);
- if (!mfmt) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Fourcc format (0x%08x) unknown.\n",
- f->fmt.pix.pixelformat);
- f->fmt.pix.pixelformat = formats[0].fourcc;
- mfmt = get_format(f);
- }
-
- ret = mmal_setup_components(dev, f);
- if (ret) {
- v4l2_err(&dev->v4l2_dev,
- "%s: failed to setup mmal components: %d\n",
- __func__, ret);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- static const struct v4l2_frmsize_stepwise sizes = {
- MIN_WIDTH, 0, 2,
- MIN_HEIGHT, 0, 2
- };
- int i;
-
- if (fsize->index)
- return -EINVAL;
- for (i = 0; i < ARRAY_SIZE(formats); i++)
- if (formats[i].fourcc == fsize->pixel_format)
- break;
- if (i == ARRAY_SIZE(formats))
- return -EINVAL;
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
- fsize->stepwise = sizes;
- fsize->stepwise.max_width = dev->max_width;
- fsize->stepwise.max_height = dev->max_height;
- return 0;
-}
-
-/* timeperframe is arbitrary and continuous */
-static int vidioc_enum_frameintervals(struct file *file, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- int i;
-
- if (fival->index)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(formats); i++)
- if (formats[i].fourcc == fival->pixel_format)
- break;
- if (i == ARRAY_SIZE(formats))
- return -EINVAL;
-
- /* regarding width & height - we support any within range */
- if (fival->width < MIN_WIDTH || fival->width > dev->max_width ||
- fival->height < MIN_HEIGHT || fival->height > dev->max_height)
- return -EINVAL;
-
- fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
-
- /* fill in stepwise (step=1.0 is required by V4L2 spec) */
- fival->stepwise.min = tpf_min;
- fival->stepwise.max = tpf_max;
- fival->stepwise.step = (struct v4l2_fract) {1, 1};
-
- return 0;
-}
-
-static int vidioc_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- parm->parm.capture.timeperframe = dev->capture.timeperframe;
- parm->parm.capture.readbuffers = 1;
- return 0;
-}
-
-static int vidioc_s_parm(struct file *file, void *priv,
- struct v4l2_streamparm *parm)
-{
- struct bcm2835_mmal_dev *dev = video_drvdata(file);
- struct v4l2_fract tpf;
-
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- tpf = parm->parm.capture.timeperframe;
-
- /* tpf: {*, 0} resets timing; clip to [min, max]*/
- tpf = tpf.denominator ? tpf : tpf_default;
- tpf = V4L2_FRACT_COMPARE(tpf, <, tpf_min) ? tpf_min : tpf;
- tpf = V4L2_FRACT_COMPARE(tpf, >, tpf_max) ? tpf_max : tpf;
-
- dev->capture.timeperframe = tpf;
- parm->parm.capture.timeperframe = tpf;
- parm->parm.capture.readbuffers = 1;
- parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
-
- set_framerate_params(dev);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
- /* overlay */
- .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
- .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
- .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
- .vidioc_overlay = vidioc_overlay,
- .vidioc_g_fbuf = vidioc_g_fbuf,
-
- /* inputs */
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
-
- /* capture */
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-
- /* buffer management */
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
- .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
- .vidioc_g_parm = vidioc_g_parm,
- .vidioc_s_parm = vidioc_s_parm,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
-
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/* ------------------------------------------------------------------
- * Driver init/finalise
- * ------------------------------------------------------------------
- */
-
-static const struct v4l2_file_operations camera0_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = vb2_fop_mmap,
-};
-
-static const struct video_device vdev_template = {
- .name = "camera0",
- .fops = &camera0_fops,
- .ioctl_ops = &camera0_ioctl_ops,
- .release = video_device_release_empty,
- .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_STREAMING | V4L2_CAP_READWRITE,
-};
-
-/* Returns the number of cameras, and also the max resolution supported
- * by those cameras.
- */
-static int get_num_cameras(struct vchiq_mmal_instance *instance,
- unsigned int resolutions[][2], int num_resolutions)
-{
- int ret;
- struct vchiq_mmal_component *cam_info_component;
- struct mmal_parameter_camera_info cam_info = {0};
- u32 param_size = sizeof(cam_info);
- int i;
-
- /* create a camera_info component */
- ret = vchiq_mmal_component_init(instance, "camera_info",
- &cam_info_component);
- if (ret < 0)
- /* Unusual failure - let's guess one camera. */
- return 1;
-
- if (vchiq_mmal_port_parameter_get(instance,
- &cam_info_component->control,
- MMAL_PARAMETER_CAMERA_INFO,
- &cam_info,
- &param_size)) {
- pr_info("Failed to get camera info\n");
- }
- for (i = 0;
- i < min_t(unsigned int, cam_info.num_cameras, num_resolutions);
- i++) {
- resolutions[i][0] = cam_info.cameras[i].max_width;
- resolutions[i][1] = cam_info.cameras[i].max_height;
- }
-
- vchiq_mmal_component_finalise(instance,
- cam_info_component);
-
- return cam_info.num_cameras;
-}
-
-static int set_camera_parameters(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *camera,
- struct bcm2835_mmal_dev *dev)
-{
- struct mmal_parameter_camera_config cam_config = {
- .max_stills_w = dev->max_width,
- .max_stills_h = dev->max_height,
- .stills_yuv422 = 1,
- .one_shot_stills = 1,
- .max_preview_video_w = (max_video_width > 1920) ?
- max_video_width : 1920,
- .max_preview_video_h = (max_video_height > 1088) ?
- max_video_height : 1088,
- .num_preview_video_frames = 3,
- .stills_capture_circular_buffer_height = 0,
- .fast_preview_resume = 0,
- .use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RAW_STC
- };
-
- return vchiq_mmal_port_parameter_set(instance, &camera->control,
- MMAL_PARAMETER_CAMERA_CONFIG,
- &cam_config, sizeof(cam_config));
-}
-
-#define MAX_SUPPORTED_ENCODINGS 20
-
-/* MMAL instance and component init */
-static int mmal_init(struct bcm2835_mmal_dev *dev)
-{
- int ret;
- struct mmal_es_format_local *format;
- u32 supported_encodings[MAX_SUPPORTED_ENCODINGS];
- u32 param_size;
- struct vchiq_mmal_component *camera;
-
- ret = vchiq_mmal_init(dev->v4l2_dev.dev, &dev->instance);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: vchiq mmal init failed %d\n",
- __func__, ret);
- return ret;
- }
-
- /* get the camera component ready */
- ret = vchiq_mmal_component_init(dev->instance, "ril.camera",
- &dev->component[COMP_CAMERA]);
- if (ret < 0)
- goto unreg_mmal;
-
- camera = dev->component[COMP_CAMERA];
- if (camera->outputs < CAM_PORT_COUNT) {
- v4l2_err(&dev->v4l2_dev, "%s: too few camera outputs %d needed %d\n",
- __func__, camera->outputs, CAM_PORT_COUNT);
- ret = -EINVAL;
- goto unreg_camera;
- }
-
- ret = set_camera_parameters(dev->instance,
- camera,
- dev);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: unable to set camera parameters: %d\n",
- __func__, ret);
- goto unreg_camera;
- }
-
- /* There was an error in the firmware that meant the camera component
- * produced BGR instead of RGB.
- * This is now fixed, but in order to support the old firmwares, we
- * have to check.
- */
- dev->rgb_bgr_swapped = true;
- param_size = sizeof(supported_encodings);
- ret = vchiq_mmal_port_parameter_get(dev->instance,
- &camera->output[CAM_PORT_CAPTURE],
- MMAL_PARAMETER_SUPPORTED_ENCODINGS,
- &supported_encodings,
- &param_size);
- if (ret == 0) {
- int i;
-
- for (i = 0; i < param_size / sizeof(u32); i++) {
- if (supported_encodings[i] == MMAL_ENCODING_BGR24) {
- /* Found BGR24 first - old firmware. */
- break;
- }
- if (supported_encodings[i] == MMAL_ENCODING_RGB24) {
- /* Found RGB24 first
- * new firmware, so use RGB24.
- */
- dev->rgb_bgr_swapped = false;
- break;
- }
- }
- }
- format = &camera->output[CAM_PORT_PREVIEW].format;
-
- format->encoding = MMAL_ENCODING_OPAQUE;
- format->encoding_variant = MMAL_ENCODING_I420;
-
- format->es->video.width = 1024;
- format->es->video.height = 768;
- format->es->video.crop.x = 0;
- format->es->video.crop.y = 0;
- format->es->video.crop.width = 1024;
- format->es->video.crop.height = 768;
- format->es->video.frame_rate.numerator = 0; /* Rely on fps_range */
- format->es->video.frame_rate.denominator = 1;
-
- format = &camera->output[CAM_PORT_VIDEO].format;
-
- format->encoding = MMAL_ENCODING_OPAQUE;
- format->encoding_variant = MMAL_ENCODING_I420;
-
- format->es->video.width = 1024;
- format->es->video.height = 768;
- format->es->video.crop.x = 0;
- format->es->video.crop.y = 0;
- format->es->video.crop.width = 1024;
- format->es->video.crop.height = 768;
- format->es->video.frame_rate.numerator = 0; /* Rely on fps_range */
- format->es->video.frame_rate.denominator = 1;
-
- format = &camera->output[CAM_PORT_CAPTURE].format;
-
- format->encoding = MMAL_ENCODING_OPAQUE;
-
- format->es->video.width = 2592;
- format->es->video.height = 1944;
- format->es->video.crop.x = 0;
- format->es->video.crop.y = 0;
- format->es->video.crop.width = 2592;
- format->es->video.crop.height = 1944;
- format->es->video.frame_rate.numerator = 0; /* Rely on fps_range */
- format->es->video.frame_rate.denominator = 1;
-
- dev->capture.width = format->es->video.width;
- dev->capture.height = format->es->video.height;
- dev->capture.fmt = &formats[0];
- dev->capture.encode_component = NULL;
- dev->capture.timeperframe = tpf_default;
- dev->capture.enc_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
- dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
-
- /* get the preview component ready */
- ret = vchiq_mmal_component_init(dev->instance, "ril.video_render",
- &dev->component[COMP_PREVIEW]);
- if (ret < 0)
- goto unreg_camera;
-
- if (dev->component[COMP_PREVIEW]->inputs < 1) {
- ret = -EINVAL;
- v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
- __func__, dev->component[COMP_PREVIEW]->inputs, 1);
- goto unreg_preview;
- }
-
- /* get the image encoder component ready */
- ret = vchiq_mmal_component_init(dev->instance, "ril.image_encode",
- &dev->component[COMP_IMAGE_ENCODE]);
- if (ret < 0)
- goto unreg_preview;
-
- if (dev->component[COMP_IMAGE_ENCODE]->inputs < 1) {
- ret = -EINVAL;
- v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
- __func__, dev->component[COMP_IMAGE_ENCODE]->inputs,
- 1);
- goto unreg_image_encoder;
- }
-
- /* get the video encoder component ready */
- ret = vchiq_mmal_component_init(dev->instance, "ril.video_encode",
- &dev->component[COMP_VIDEO_ENCODE]);
- if (ret < 0)
- goto unreg_image_encoder;
-
- if (dev->component[COMP_VIDEO_ENCODE]->inputs < 1) {
- ret = -EINVAL;
- v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
- __func__, dev->component[COMP_VIDEO_ENCODE]->inputs,
- 1);
- goto unreg_vid_encoder;
- }
-
- {
- struct vchiq_mmal_port *encoder_port =
- &dev->component[COMP_VIDEO_ENCODE]->output[0];
- encoder_port->format.encoding = MMAL_ENCODING_H264;
- ret = vchiq_mmal_port_set_format(dev->instance,
- encoder_port);
- }
-
- {
- unsigned int enable = 1;
-
- vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_VIDEO_ENCODE]->control,
- MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
- &enable,
- sizeof(enable));
-
- vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_VIDEO_ENCODE]->control,
- MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
- &enable,
- sizeof(enable));
- }
- ret = bcm2835_mmal_set_all_camera_controls(dev);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: failed to set all camera controls: %d\n",
- __func__, ret);
- goto unreg_vid_encoder;
- }
-
- return 0;
-
-unreg_vid_encoder:
- pr_err("Cleanup: Destroy video encoder\n");
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_VIDEO_ENCODE]);
-
-unreg_image_encoder:
- pr_err("Cleanup: Destroy image encoder\n");
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_IMAGE_ENCODE]);
-
-unreg_preview:
- pr_err("Cleanup: Destroy video render\n");
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_PREVIEW]);
-
-unreg_camera:
- pr_err("Cleanup: Destroy camera\n");
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_CAMERA]);
-
-unreg_mmal:
- vchiq_mmal_finalise(dev->instance);
- return ret;
-}
-
-static int bcm2835_mmal_init_device(struct bcm2835_mmal_dev *dev, struct video_device *vfd)
-{
- int ret;
-
- *vfd = vdev_template;
-
- vfd->v4l2_dev = &dev->v4l2_dev;
-
- vfd->lock = &dev->mutex;
-
- vfd->queue = &dev->capture.vb_vidq;
-
- /* video device needs to be able to access instance data */
- video_set_drvdata(vfd, dev);
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO,
- video_nr[dev->camera_num]);
- if (ret < 0)
- return ret;
-
- v4l2_info(vfd->v4l2_dev,
- "V4L2 device registered as %s - stills mode > %dx%d\n",
- video_device_node_name(vfd),
- max_video_width, max_video_height);
-
- return 0;
-}
-
-static void bcm2835_cleanup_instance(struct bcm2835_mmal_dev *dev)
-{
- if (!dev)
- return;
-
- v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
- video_device_node_name(&dev->vdev));
-
- video_unregister_device(&dev->vdev);
-
- if (dev->capture.encode_component) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "mmal_exit - disconnect tunnel\n");
- vchiq_mmal_port_connect_tunnel(dev->instance,
- dev->capture.camera_port, NULL);
- vchiq_mmal_component_disable(dev->instance,
- dev->capture.encode_component);
- }
- vchiq_mmal_component_disable(dev->instance,
- dev->component[COMP_CAMERA]);
-
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_VIDEO_ENCODE]);
-
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_IMAGE_ENCODE]);
-
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_PREVIEW]);
-
- vchiq_mmal_component_finalise(dev->instance,
- dev->component[COMP_CAMERA]);
-
- v4l2_ctrl_handler_free(&dev->ctrl_handler);
-
- v4l2_device_unregister(&dev->v4l2_dev);
-
- kfree(dev);
-}
-
-static struct v4l2_format default_v4l2_format = {
- .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG,
- .fmt.pix.width = 1024,
- .fmt.pix.bytesperline = 0,
- .fmt.pix.height = 768,
- .fmt.pix.sizeimage = 1024 * 768,
-};
-
-static int bcm2835_mmal_probe(struct vchiq_device *device)
-{
- int ret;
- struct bcm2835_mmal_dev *dev;
- struct vb2_queue *q;
- int camera;
- unsigned int num_cameras;
- struct vchiq_mmal_instance *instance;
- unsigned int resolutions[MAX_BCM2835_CAMERAS][2];
- int i;
-
- ret = dma_set_mask_and_coherent(&device->dev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(&device->dev, "dma_set_mask_and_coherent failed: %d\n", ret);
- return ret;
- }
-
- ret = vchiq_mmal_init(&device->dev, &instance);
- if (ret < 0)
- return ret;
-
- num_cameras = get_num_cameras(instance,
- resolutions,
- MAX_BCM2835_CAMERAS);
-
- if (num_cameras < 1) {
- ret = -ENODEV;
- goto cleanup_mmal;
- }
-
- if (num_cameras > MAX_BCM2835_CAMERAS)
- num_cameras = MAX_BCM2835_CAMERAS;
-
- for (camera = 0; camera < num_cameras; camera++) {
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- ret = -ENOMEM;
- goto cleanup_gdev;
- }
-
- /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
- mutex_init(&dev->mutex);
- dev->max_width = resolutions[camera][0];
- dev->max_height = resolutions[camera][1];
-
- /* setup device defaults */
- dev->overlay.w.left = 150;
- dev->overlay.w.top = 50;
- dev->overlay.w.width = 1024;
- dev->overlay.w.height = 768;
- dev->overlay.clipcount = 0;
- dev->overlay.field = V4L2_FIELD_NONE;
- dev->overlay.global_alpha = 255;
-
- dev->capture.fmt = &formats[3]; /* JPEG */
-
- /* v4l device registration */
- dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev, KBUILD_MODNAME,
- &camera_instance);
- ret = v4l2_device_register(NULL, &dev->v4l2_dev);
- if (ret) {
- dev_err(&device->dev, "%s: could not register V4L2 device: %d\n",
- __func__, ret);
- goto free_dev;
- }
- dev->v4l2_dev.dev = &device->dev;
-
- /* setup v4l controls */
- ret = bcm2835_mmal_init_controls(dev, &dev->ctrl_handler);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: could not init controls: %d\n",
- __func__, ret);
- goto unreg_dev;
- }
- dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
-
- /* mmal init */
- dev->instance = instance;
- ret = mmal_init(dev);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: mmal init failed: %d\n",
- __func__, ret);
- goto unreg_dev;
- }
- /* initialize queue */
- q = &dev->capture.vb_vidq;
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
- q->drv_priv = dev;
- q->buf_struct_size = sizeof(struct vb2_mmal_buffer);
- q->ops = &bcm2835_mmal_video_qops;
- q->mem_ops = &vb2_vmalloc_memops;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &dev->mutex;
- ret = vb2_queue_init(q);
- if (ret < 0)
- goto unreg_dev;
-
- /* initialise video devices */
- ret = bcm2835_mmal_init_device(dev, &dev->vdev);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: could not init device: %d\n",
- __func__, ret);
- goto unreg_dev;
- }
-
- /* Really want to call vidioc_s_fmt_vid_cap with the default
- * format, but currently the APIs don't join up.
- */
- ret = mmal_setup_components(dev, &default_v4l2_format);
- if (ret < 0) {
- v4l2_err(&dev->v4l2_dev, "%s: could not setup components: %d\n",
- __func__, ret);
- goto unreg_dev;
- }
-
- v4l2_info(&dev->v4l2_dev, "Broadcom 2835 MMAL video capture loaded.\n");
-
- gdev[camera] = dev;
- }
- return 0;
-
-unreg_dev:
- v4l2_ctrl_handler_free(&dev->ctrl_handler);
- v4l2_device_unregister(&dev->v4l2_dev);
-
-free_dev:
- kfree(dev);
-
-cleanup_gdev:
- for (i = 0; i < camera; i++) {
- bcm2835_cleanup_instance(gdev[i]);
- gdev[i] = NULL;
- }
-
-cleanup_mmal:
- vchiq_mmal_finalise(instance);
-
- return ret;
-}
-
-static void bcm2835_mmal_remove(struct vchiq_device *device)
-{
- int camera;
- struct vchiq_mmal_instance *instance = gdev[0]->instance;
-
- for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) {
- bcm2835_cleanup_instance(gdev[camera]);
- gdev[camera] = NULL;
- }
- vchiq_mmal_finalise(instance);
-}
-
-static const struct vchiq_device_id device_id_table[] = {
- { .name = "bcm2835-camera" },
- {}
-};
-MODULE_DEVICE_TABLE(vchiq, device_id_table);
-
-static struct vchiq_driver bcm2835_camera_driver = {
- .probe = bcm2835_mmal_probe,
- .remove = bcm2835_mmal_remove,
- .id_table = device_id_table,
- .driver = {
- .name = "bcm2835-camera",
- },
-};
-
-module_vchiq_driver(bcm2835_camera_driver)
-
-MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture");
-MODULE_AUTHOR("Vincent Sanders");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
deleted file mode 100644
index 0f0c6f7a3764..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- *
- * core driver device
- */
-
-#define V4L2_CTRL_COUNT 29 /* number of v4l controls */
-
-enum {
- COMP_CAMERA = 0,
- COMP_PREVIEW,
- COMP_IMAGE_ENCODE,
- COMP_VIDEO_ENCODE,
- COMP_COUNT
-};
-
-enum {
- CAM_PORT_PREVIEW = 0,
- CAM_PORT_VIDEO,
- CAM_PORT_CAPTURE,
- CAM_PORT_COUNT
-};
-
-extern int bcm2835_v4l2_debug;
-
-struct bcm2835_mmal_dev {
- /* v4l2 devices */
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct mutex mutex;
-
- /* controls */
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *ctrls[V4L2_CTRL_COUNT];
- enum v4l2_scene_mode scene_mode;
- struct mmal_colourfx colourfx;
- int hflip;
- int vflip;
- int red_gain;
- int blue_gain;
- enum mmal_parameter_exposuremode exposure_mode_user;
- enum v4l2_exposure_auto_type exposure_mode_v4l2_user;
- /* active exposure mode may differ if selected via a scene mode */
- enum mmal_parameter_exposuremode exposure_mode_active;
- enum mmal_parameter_exposuremeteringmode metering_mode;
- unsigned int manual_shutter_speed;
- bool exp_auto_priority;
- bool manual_iso_enabled;
- u32 iso;
-
- /* allocated mmal instance and components */
- struct vchiq_mmal_instance *instance;
- struct vchiq_mmal_component *component[COMP_COUNT];
- int camera_use_count;
-
- struct v4l2_window overlay;
-
- struct {
- unsigned int width; /* width */
- unsigned int height; /* height */
- unsigned int stride; /* stride */
- unsigned int buffersize; /* buffer size with padding */
- struct mmal_fmt *fmt;
- struct v4l2_fract timeperframe;
-
- /* H264 encode bitrate */
- int encode_bitrate;
- /* H264 bitrate mode. CBR/VBR */
- int encode_bitrate_mode;
- /* H264 profile */
- enum v4l2_mpeg_video_h264_profile enc_profile;
- /* H264 level */
- enum v4l2_mpeg_video_h264_level enc_level;
- /* JPEG Q-factor */
- int q_factor;
-
- struct vb2_queue vb_vidq;
-
- /* VC start timestamp for streaming */
- s64 vc_start_timestamp;
- /* Kernel start timestamp for streaming */
- ktime_t kernel_start_ts;
- /* Sequence number of last buffer */
- u32 sequence;
-
- struct vchiq_mmal_port *port; /* port being used for capture */
- /* camera port being used for capture */
- struct vchiq_mmal_port *camera_port;
- /* component being used for encode */
- struct vchiq_mmal_component *encode_component;
- /* number of frames remaining which driver should capture */
- unsigned int frame_count;
- /* last frame completion */
- struct completion frame_cmplt;
-
- } capture;
-
- unsigned int camera_num;
- unsigned int max_width;
- unsigned int max_height;
- unsigned int rgb_bgr_swapped;
-};
-
-int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_handler *hdl);
-
-int bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev);
-int set_framerate_params(struct bcm2835_mmal_dev *dev);
-
-/* Debug helpers */
-
-#define v4l2_dump_pix_format(level, debug, dev, pix_fmt, desc) \
-{ \
- v4l2_dbg(level, debug, dev, \
-"%s: w %u h %u field %u pfmt 0x%x bpl %u sz_img %u colorspace 0x%x priv %u\n", \
- desc, \
- (pix_fmt)->width, (pix_fmt)->height, (pix_fmt)->field, \
- (pix_fmt)->pixelformat, (pix_fmt)->bytesperline, \
- (pix_fmt)->sizeimage, (pix_fmt)->colorspace, (pix_fmt)->priv); \
-}
-
-#define v4l2_dump_win_format(level, debug, dev, win_fmt, desc) \
-{ \
- v4l2_dbg(level, debug, dev, \
-"%s: w %u h %u l %u t %u field %u chromakey %06X clip %p " \
-"clipcount %u bitmap %p\n", \
- desc, \
- (win_fmt)->w.width, (win_fmt)->w.height, \
- (win_fmt)->w.left, (win_fmt)->w.top, \
- (win_fmt)->field, \
- (win_fmt)->chromakey, \
- (win_fmt)->clips, (win_fmt)->clipcount, \
- (win_fmt)->bitmap); \
-}
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
deleted file mode 100644
index e670226f1edf..000000000000
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ /dev/null
@@ -1,1399 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
-
-#include "../vchiq-mmal/mmal-common.h"
-#include "../vchiq-mmal/mmal-vchiq.h"
-#include "../vchiq-mmal/mmal-parameters.h"
-#include "bcm2835-camera.h"
-
-/* The supported V4L2_CID_AUTO_EXPOSURE_BIAS values are from -4.0 to +4.0.
- * MMAL values are in 1/6th increments so the MMAL range is -24 to +24.
- * V4L2 docs say value "is expressed in terms of EV, drivers should interpret
- * the values as 0.001 EV units, where the value 1000 stands for +1 EV."
- * V4L2 is limited to a max of 32 values in a menu, so count in 1/3rds from
- * -4 to +4
- */
-static const s64 ev_bias_qmenu[] = {
- -4000, -3667, -3333,
- -3000, -2667, -2333,
- -2000, -1667, -1333,
- -1000, -667, -333,
- 0, 333, 667,
- 1000, 1333, 1667,
- 2000, 2333, 2667,
- 3000, 3333, 3667,
- 4000
-};
-
-/* Supported ISO values (*1000)
- * ISOO = auto ISO
- */
-static const s64 iso_qmenu[] = {
- 0, 100000, 200000, 400000, 800000,
-};
-
-static const u32 iso_values[] = {
- 0, 100, 200, 400, 800,
-};
-
-enum bcm2835_mmal_ctrl_type {
- MMAL_CONTROL_TYPE_STD,
- MMAL_CONTROL_TYPE_STD_MENU,
- MMAL_CONTROL_TYPE_INT_MENU,
- MMAL_CONTROL_TYPE_CLUSTER, /* special cluster entry */
-};
-
-struct bcm2835_mmal_v4l2_ctrl {
- u32 id; /* v4l2 control identifier */
- enum bcm2835_mmal_ctrl_type type;
- /* control minimum value or
- * mask for MMAL_CONTROL_TYPE_STD_MENU
- */
- s64 min;
- s64 max; /* maximum value of control */
- s64 def; /* default value of control */
- u64 step; /* step size of the control */
- const s64 *imenu; /* integer menu array */
- u32 mmal_id; /* mmal parameter id */
- int (*setter)(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl);
-};
-
-struct v4l2_to_mmal_effects_setting {
- u32 v4l2_effect;
- u32 mmal_effect;
- s32 col_fx_enable;
- s32 col_fx_fixed_cbcr;
- u32 u;
- u32 v;
- u32 num_effect_params;
- u32 effect_params[MMAL_MAX_IMAGEFX_PARAMETERS];
-};
-
-static const struct v4l2_to_mmal_effects_setting
- v4l2_to_mmal_effects_values[] = {
- { V4L2_COLORFX_NONE, MMAL_PARAM_IMAGEFX_NONE,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_BW, MMAL_PARAM_IMAGEFX_NONE,
- 1, 0, 128, 128, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SEPIA, MMAL_PARAM_IMAGEFX_NONE,
- 1, 0, 87, 151, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_NEGATIVE, MMAL_PARAM_IMAGEFX_NEGATIVE,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_EMBOSS, MMAL_PARAM_IMAGEFX_EMBOSS,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SKETCH, MMAL_PARAM_IMAGEFX_SKETCH,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SKY_BLUE, MMAL_PARAM_IMAGEFX_PASTEL,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_GRASS_GREEN, MMAL_PARAM_IMAGEFX_WATERCOLOUR,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SKIN_WHITEN, MMAL_PARAM_IMAGEFX_WASHEDOUT,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_VIVID, MMAL_PARAM_IMAGEFX_SATURATION,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_AQUA, MMAL_PARAM_IMAGEFX_NONE,
- 1, 0, 171, 121, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_ART_FREEZE, MMAL_PARAM_IMAGEFX_HATCH,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SILHOUETTE, MMAL_PARAM_IMAGEFX_FILM,
- 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
- { V4L2_COLORFX_SOLARIZATION, MMAL_PARAM_IMAGEFX_SOLARIZE,
- 0, 0, 0, 0, 5, {1, 128, 160, 160, 48} },
- { V4L2_COLORFX_ANTIQUE, MMAL_PARAM_IMAGEFX_COLOURBALANCE,
- 0, 0, 0, 0, 3, {108, 274, 238, 0, 0} },
- { V4L2_COLORFX_SET_CBCR, MMAL_PARAM_IMAGEFX_NONE,
- 1, 1, 0, 0, 0, {0, 0, 0, 0, 0} }
-};
-
-struct v4l2_mmal_scene_config {
- enum v4l2_scene_mode v4l2_scene;
- enum mmal_parameter_exposuremode exposure_mode;
- enum mmal_parameter_exposuremeteringmode metering_mode;
-};
-
-static const struct v4l2_mmal_scene_config scene_configs[] = {
- /* V4L2_SCENE_MODE_NONE automatically added */
- {
- V4L2_SCENE_MODE_NIGHT,
- MMAL_PARAM_EXPOSUREMODE_NIGHT,
- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
- },
- {
- V4L2_SCENE_MODE_SPORTS,
- MMAL_PARAM_EXPOSUREMODE_SPORTS,
- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
- },
-};
-
-/* control handlers*/
-
-static int ctrl_set_rational(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- struct s32_fract rational_value;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- rational_value.numerator = ctrl->val;
- rational_value.denominator = 100;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &rational_value,
- sizeof(rational_value));
-}
-
-static int ctrl_set_value(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- u32_value = ctrl->val;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_iso(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *control;
-
- if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min)
- return 1;
-
- if (ctrl->id == V4L2_CID_ISO_SENSITIVITY)
- dev->iso = iso_values[ctrl->val];
- else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO)
- dev->manual_iso_enabled =
- (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL);
-
- control = &dev->component[COMP_CAMERA]->control;
-
- if (dev->manual_iso_enabled)
- u32_value = dev->iso;
- else
- u32_value = 0;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_ISO,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_value_ev(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- s32 s32_value;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- s32_value = (ctrl->val - 12) * 2; /* Convert from index to 1/6ths */
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &s32_value, sizeof(s32_value));
-}
-
-static int ctrl_set_rotate(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret;
- u32 u32_value;
- struct vchiq_mmal_component *camera;
-
- camera = dev->component[COMP_CAMERA];
-
- u32_value = ((ctrl->val % 360) / 90) * 90;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
- if (ret < 0)
- return ret;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
- if (ret < 0)
- return ret;
-
- return vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_flip(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret;
- u32 u32_value;
- struct vchiq_mmal_component *camera;
-
- if (ctrl->id == V4L2_CID_HFLIP)
- dev->hflip = ctrl->val;
- else
- dev->vflip = ctrl->val;
-
- camera = dev->component[COMP_CAMERA];
-
- if (dev->hflip && dev->vflip)
- u32_value = MMAL_PARAM_MIRROR_BOTH;
- else if (dev->hflip)
- u32_value = MMAL_PARAM_MIRROR_HORIZONTAL;
- else if (dev->vflip)
- u32_value = MMAL_PARAM_MIRROR_VERTICAL;
- else
- u32_value = MMAL_PARAM_MIRROR_NONE;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
- if (ret < 0)
- return ret;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
- if (ret < 0)
- return ret;
-
- return vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_exposure(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user;
- u32 shutter_speed = 0;
- struct vchiq_mmal_port *control;
- int ret = 0;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED) {
- /* V4L2 is in 100usec increments.
- * MMAL is 1usec.
- */
- dev->manual_shutter_speed = ctrl->val * 100;
- } else if (mmal_ctrl->mmal_id == MMAL_PARAMETER_EXPOSURE_MODE) {
- switch (ctrl->val) {
- case V4L2_EXPOSURE_AUTO:
- exp_mode = MMAL_PARAM_EXPOSUREMODE_AUTO;
- break;
-
- case V4L2_EXPOSURE_MANUAL:
- exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF;
- break;
- }
- dev->exposure_mode_user = exp_mode;
- dev->exposure_mode_v4l2_user = ctrl->val;
- } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) {
- dev->exp_auto_priority = ctrl->val;
- }
-
- if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
- if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
- shutter_speed = dev->manual_shutter_speed;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance,
- control,
- MMAL_PARAMETER_SHUTTER_SPEED,
- &shutter_speed,
- sizeof(shutter_speed));
- ret += vchiq_mmal_port_parameter_set(dev->instance,
- control,
- MMAL_PARAMETER_EXPOSURE_MODE,
- &exp_mode,
- sizeof(u32));
- dev->exposure_mode_active = exp_mode;
- }
- /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should
- * always apply irrespective of scene mode.
- */
- ret += set_framerate_params(dev);
-
- return ret;
-}
-
-static int ctrl_set_metering_mode(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- switch (ctrl->val) {
- case V4L2_EXPOSURE_METERING_AVERAGE:
- dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
- break;
-
- case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
- dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
- break;
-
- case V4L2_EXPOSURE_METERING_SPOT:
- dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
- break;
-
- case V4L2_EXPOSURE_METERING_MATRIX:
- dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
- break;
- }
-
- if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
- struct vchiq_mmal_port *control;
- u32 u32_value = dev->metering_mode;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
- } else {
- return 0;
- }
-}
-
-static int ctrl_set_flicker_avoidance(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- switch (ctrl->val) {
- case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
- u32_value = MMAL_PARAM_FLICKERAVOID_OFF;
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
- u32_value = MMAL_PARAM_FLICKERAVOID_50HZ;
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
- u32_value = MMAL_PARAM_FLICKERAVOID_60HZ;
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
- u32_value = MMAL_PARAM_FLICKERAVOID_AUTO;
- break;
- }
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_awb_mode(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- switch (ctrl->val) {
- case V4L2_WHITE_BALANCE_MANUAL:
- u32_value = MMAL_PARAM_AWBMODE_OFF;
- break;
-
- case V4L2_WHITE_BALANCE_AUTO:
- u32_value = MMAL_PARAM_AWBMODE_AUTO;
- break;
-
- case V4L2_WHITE_BALANCE_INCANDESCENT:
- u32_value = MMAL_PARAM_AWBMODE_INCANDESCENT;
- break;
-
- case V4L2_WHITE_BALANCE_FLUORESCENT:
- u32_value = MMAL_PARAM_AWBMODE_FLUORESCENT;
- break;
-
- case V4L2_WHITE_BALANCE_FLUORESCENT_H:
- u32_value = MMAL_PARAM_AWBMODE_TUNGSTEN;
- break;
-
- case V4L2_WHITE_BALANCE_HORIZON:
- u32_value = MMAL_PARAM_AWBMODE_HORIZON;
- break;
-
- case V4L2_WHITE_BALANCE_DAYLIGHT:
- u32_value = MMAL_PARAM_AWBMODE_SUNLIGHT;
- break;
-
- case V4L2_WHITE_BALANCE_FLASH:
- u32_value = MMAL_PARAM_AWBMODE_FLASH;
- break;
-
- case V4L2_WHITE_BALANCE_CLOUDY:
- u32_value = MMAL_PARAM_AWBMODE_CLOUDY;
- break;
-
- case V4L2_WHITE_BALANCE_SHADE:
- u32_value = MMAL_PARAM_AWBMODE_SHADE;
- break;
- }
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_awb_gains(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- struct vchiq_mmal_port *control;
- struct mmal_parameter_awbgains gains;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- if (ctrl->id == V4L2_CID_RED_BALANCE)
- dev->red_gain = ctrl->val;
- else if (ctrl->id == V4L2_CID_BLUE_BALANCE)
- dev->blue_gain = ctrl->val;
-
- gains.r_gain.numerator = dev->red_gain;
- gains.r_gain.denominator = 1000;
- gains.b_gain.numerator = dev->blue_gain;
- gains.b_gain.denominator = 1000;
-
- return vchiq_mmal_port_parameter_set(dev->instance, control,
- mmal_ctrl->mmal_id,
- &gains, sizeof(gains));
-}
-
-static int ctrl_set_image_effect(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret = -EINVAL;
- int i, j;
- struct vchiq_mmal_port *control;
- struct mmal_parameter_imagefx_parameters imagefx;
-
- for (i = 0; i < ARRAY_SIZE(v4l2_to_mmal_effects_values); i++) {
- if (ctrl->val != v4l2_to_mmal_effects_values[i].v4l2_effect)
- continue;
-
- imagefx.effect =
- v4l2_to_mmal_effects_values[i].mmal_effect;
- imagefx.num_effect_params =
- v4l2_to_mmal_effects_values[i].num_effect_params;
-
- if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS)
- imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS;
-
- for (j = 0; j < imagefx.num_effect_params; j++)
- imagefx.effect_parameter[j] =
- v4l2_to_mmal_effects_values[i].effect_params[j];
-
- dev->colourfx.enable =
- v4l2_to_mmal_effects_values[i].col_fx_enable;
- if (!v4l2_to_mmal_effects_values[i].col_fx_fixed_cbcr) {
- dev->colourfx.u = v4l2_to_mmal_effects_values[i].u;
- dev->colourfx.v = v4l2_to_mmal_effects_values[i].v;
- }
-
- control = &dev->component[COMP_CAMERA]->control;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
- &imagefx, sizeof(imagefx));
- if (ret)
- goto exit;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_COLOUR_EFFECT,
- &dev->colourfx, sizeof(dev->colourfx));
- }
-
-exit:
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "mmal_ctrl:%p ctrl id:0x%x ctrl val:%d imagefx:0x%x color_effect:%s u:%d v:%d ret %d(%d)\n",
- mmal_ctrl, ctrl->id, ctrl->val, imagefx.effect,
- dev->colourfx.enable ? "true" : "false",
- dev->colourfx.u, dev->colourfx.v,
- ret, (ret == 0 ? 0 : -EINVAL));
- return (ret == 0 ? 0 : -EINVAL);
-}
-
-static int ctrl_set_colfx(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret;
- struct vchiq_mmal_port *control;
-
- control = &dev->component[COMP_CAMERA]->control;
-
- dev->colourfx.u = (ctrl->val & 0xff00) >> 8;
- dev->colourfx.v = ctrl->val & 0xff;
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_COLOUR_EFFECT,
- &dev->colourfx,
- sizeof(dev->colourfx));
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
- __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
- (ret == 0 ? 0 : -EINVAL));
- return (ret == 0 ? 0 : -EINVAL);
-}
-
-static int ctrl_set_bitrate(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret;
- struct vchiq_mmal_port *encoder_out;
-
- dev->capture.encode_bitrate = ctrl->val;
-
- encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
- mmal_ctrl->mmal_id, &ctrl->val,
- sizeof(ctrl->val));
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
- __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
- (ret == 0 ? 0 : -EINVAL));
-
- /*
- * Older firmware versions (pre July 2019) have a bug in handling
- * MMAL_PARAMETER_VIDEO_BIT_RATE that result in the call
- * returning -MMAL_MSG_STATUS_EINVAL. So ignore errors from this call.
- */
- return 0;
-}
-
-static int ctrl_set_bitrate_mode(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 bitrate_mode;
- struct vchiq_mmal_port *encoder_out;
-
- encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
-
- dev->capture.encode_bitrate_mode = ctrl->val;
- switch (ctrl->val) {
- default:
- case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
- bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE;
- break;
- case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
- bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT;
- break;
- }
-
- vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
- mmal_ctrl->mmal_id,
- &bitrate_mode,
- sizeof(bitrate_mode));
- return 0;
-}
-
-static int ctrl_set_image_encode_output(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *jpeg_out;
-
- jpeg_out = &dev->component[COMP_IMAGE_ENCODE]->output[0];
-
- u32_value = ctrl->val;
-
- return vchiq_mmal_port_parameter_set(dev->instance, jpeg_out,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_video_encode_param_output(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- u32 u32_value;
- struct vchiq_mmal_port *vid_enc_ctl;
-
- vid_enc_ctl = &dev->component[COMP_VIDEO_ENCODE]->output[0];
-
- u32_value = ctrl->val;
-
- return vchiq_mmal_port_parameter_set(dev->instance, vid_enc_ctl,
- mmal_ctrl->mmal_id,
- &u32_value, sizeof(u32_value));
-}
-
-static int ctrl_set_video_encode_profile_level(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- struct mmal_parameter_video_profile param;
- int ret = 0;
-
- if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
- switch (ctrl->val) {
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
- case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
- dev->capture.enc_profile = ctrl->val;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
- switch (ctrl->val) {
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
- case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
- dev->capture.enc_level = ctrl->val;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- }
-
- if (!ret) {
- switch (dev->capture.enc_profile) {
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
- param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
- param.profile =
- MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
- param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
- param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
- break;
- default:
- /* Should never get here */
- break;
- }
-
- switch (dev->capture.enc_level) {
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
- param.level = MMAL_VIDEO_LEVEL_H264_1;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
- param.level = MMAL_VIDEO_LEVEL_H264_1b;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
- param.level = MMAL_VIDEO_LEVEL_H264_11;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
- param.level = MMAL_VIDEO_LEVEL_H264_12;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
- param.level = MMAL_VIDEO_LEVEL_H264_13;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
- param.level = MMAL_VIDEO_LEVEL_H264_2;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
- param.level = MMAL_VIDEO_LEVEL_H264_21;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
- param.level = MMAL_VIDEO_LEVEL_H264_22;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
- param.level = MMAL_VIDEO_LEVEL_H264_3;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
- param.level = MMAL_VIDEO_LEVEL_H264_31;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
- param.level = MMAL_VIDEO_LEVEL_H264_32;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
- param.level = MMAL_VIDEO_LEVEL_H264_4;
- break;
- default:
- /* Should never get here */
- break;
- }
-
- ret = vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_VIDEO_ENCODE]->output[0],
- mmal_ctrl->mmal_id,
- &param, sizeof(param));
- }
- return ret;
-}
-
-static int ctrl_set_scene_mode(struct bcm2835_mmal_dev *dev,
- struct v4l2_ctrl *ctrl,
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
-{
- int ret = 0;
- int shutter_speed;
- struct vchiq_mmal_port *control;
-
- v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "scene mode selected %d, was %d\n", ctrl->val,
- dev->scene_mode);
- control = &dev->component[COMP_CAMERA]->control;
-
- if (ctrl->val == dev->scene_mode)
- return 0;
-
- if (ctrl->val == V4L2_SCENE_MODE_NONE) {
- /* Restore all user selections */
- dev->scene_mode = V4L2_SCENE_MODE_NONE;
-
- if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
- shutter_speed = dev->manual_shutter_speed;
- else
- shutter_speed = 0;
-
- v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
- __func__, shutter_speed, dev->exposure_mode_user,
- dev->metering_mode);
- ret = vchiq_mmal_port_parameter_set(dev->instance,
- control,
- MMAL_PARAMETER_SHUTTER_SPEED,
- &shutter_speed,
- sizeof(shutter_speed));
- ret += vchiq_mmal_port_parameter_set(dev->instance,
- control,
- MMAL_PARAMETER_EXPOSURE_MODE,
- &dev->exposure_mode_user,
- sizeof(u32));
- dev->exposure_mode_active = dev->exposure_mode_user;
- ret += vchiq_mmal_port_parameter_set(dev->instance,
- control,
- MMAL_PARAMETER_EXP_METERING_MODE,
- &dev->metering_mode,
- sizeof(u32));
- ret += set_framerate_params(dev);
- } else {
- /* Set up scene mode */
- int i;
- const struct v4l2_mmal_scene_config *scene = NULL;
- int shutter_speed;
- enum mmal_parameter_exposuremode exposure_mode;
- enum mmal_parameter_exposuremeteringmode metering_mode;
-
- for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
- if (scene_configs[i].v4l2_scene == ctrl->val) {
- scene = &scene_configs[i];
- break;
- }
- }
- if (!scene)
- return -EINVAL;
- if (i >= ARRAY_SIZE(scene_configs))
- return -EINVAL;
-
- /* Set all the values */
- dev->scene_mode = ctrl->val;
-
- if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
- shutter_speed = dev->manual_shutter_speed;
- else
- shutter_speed = 0;
- exposure_mode = scene->exposure_mode;
- metering_mode = scene->metering_mode;
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
- __func__, shutter_speed, exposure_mode, metering_mode);
-
- ret = vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_SHUTTER_SPEED,
- &shutter_speed,
- sizeof(shutter_speed));
- ret += vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_EXPOSURE_MODE,
- &exposure_mode,
- sizeof(u32));
- dev->exposure_mode_active = exposure_mode;
- ret += vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_EXPOSURE_MODE,
- &exposure_mode,
- sizeof(u32));
- ret += vchiq_mmal_port_parameter_set(dev->instance, control,
- MMAL_PARAMETER_EXP_METERING_MODE,
- &metering_mode,
- sizeof(u32));
- ret += set_framerate_params(dev);
- }
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "%s: Setting scene to %d, ret=%d\n",
- __func__, ctrl->val, ret);
- ret = -EINVAL;
- }
- return 0;
-}
-
-static int bcm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct bcm2835_mmal_dev *dev = container_of(ctrl->handler, struct bcm2835_mmal_dev,
- ctrl_handler);
- const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
- int ret;
-
- if (!mmal_ctrl || mmal_ctrl->id != ctrl->id || !mmal_ctrl->setter) {
- pr_warn("mmal_ctrl:%p ctrl id:%d\n", mmal_ctrl, ctrl->id);
- return -EINVAL;
- }
-
- ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
- if (ret)
- pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n",
- ctrl->id, mmal_ctrl->mmal_id, ret);
- return ret;
-}
-
-static const struct v4l2_ctrl_ops bcm2835_mmal_ctrl_ops = {
- .s_ctrl = bcm2835_mmal_s_ctrl,
-};
-
-static const struct bcm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
- {
- .id = V4L2_CID_SATURATION,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = -100,
- .max = 100,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_SATURATION,
- .setter = ctrl_set_rational,
- },
- {
- .id = V4L2_CID_SHARPNESS,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = -100,
- .max = 100,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_SHARPNESS,
- .setter = ctrl_set_rational,
- },
- {
- .id = V4L2_CID_CONTRAST,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = -100,
- .max = 100,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_CONTRAST,
- .setter = ctrl_set_rational,
- },
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 100,
- .def = 50,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_BRIGHTNESS,
- .setter = ctrl_set_rational,
- },
- {
- .id = V4L2_CID_ISO_SENSITIVITY,
- .type = MMAL_CONTROL_TYPE_INT_MENU,
- .min = 0,
- .max = ARRAY_SIZE(iso_qmenu) - 1,
- .def = 0,
- .step = 1,
- .imenu = iso_qmenu,
- .mmal_id = MMAL_PARAMETER_ISO,
- .setter = ctrl_set_iso,
- },
- {
- .id = V4L2_CID_ISO_SENSITIVITY_AUTO,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = 0,
- .max = V4L2_ISO_SENSITIVITY_AUTO,
- .def = V4L2_ISO_SENSITIVITY_AUTO,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_ISO,
- .setter = ctrl_set_iso,
- },
- {
- .id = V4L2_CID_IMAGE_STABILIZATION,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 1,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_VIDEO_STABILISATION,
- .setter = ctrl_set_value,
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = ~0x03,
- .max = V4L2_EXPOSURE_APERTURE_PRIORITY,
- .def = V4L2_EXPOSURE_AUTO,
- .step = 0,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_EXPOSURE_MODE,
- .setter = ctrl_set_exposure,
- },
- {
- .id = V4L2_CID_EXPOSURE_ABSOLUTE,
- .type = MMAL_CONTROL_TYPE_STD,
- /* Units of 100usecs */
- .min = 1,
- .max = 1 * 1000 * 10,
- .def = 100 * 10,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_SHUTTER_SPEED,
- .setter = ctrl_set_exposure,
- },
- {
- .id = V4L2_CID_AUTO_EXPOSURE_BIAS,
- .type = MMAL_CONTROL_TYPE_INT_MENU,
- .min = 0,
- .max = ARRAY_SIZE(ev_bias_qmenu) - 1,
- .def = (ARRAY_SIZE(ev_bias_qmenu) + 1) / 2 - 1,
- .step = 0,
- .imenu = ev_bias_qmenu,
- .mmal_id = MMAL_PARAMETER_EXPOSURE_COMP,
- .setter = ctrl_set_value_ev,
- },
- {
- .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 1,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- /* Dummy MMAL ID as it gets mapped into FPS range */
- .mmal_id = 0,
- .setter = ctrl_set_exposure,
- },
- {
- .id = V4L2_CID_EXPOSURE_METERING,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = ~0xf,
- .max = V4L2_EXPOSURE_METERING_MATRIX,
- .def = V4L2_EXPOSURE_METERING_AVERAGE,
- .step = 0,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_EXP_METERING_MODE,
- .setter = ctrl_set_metering_mode,
- },
- {
- .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = ~0x3ff,
- .max = V4L2_WHITE_BALANCE_SHADE,
- .def = V4L2_WHITE_BALANCE_AUTO,
- .step = 0,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_AWB_MODE,
- .setter = ctrl_set_awb_mode,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 1,
- .max = 7999,
- .def = 1000,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_CUSTOM_AWB_GAINS,
- .setter = ctrl_set_awb_gains,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 1,
- .max = 7999,
- .def = 1000,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_CUSTOM_AWB_GAINS,
- .setter = ctrl_set_awb_gains,
- },
- {
- .id = V4L2_CID_COLORFX,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = 0,
- .max = V4L2_COLORFX_SET_CBCR,
- .def = V4L2_COLORFX_NONE,
- .step = 0,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_IMAGE_EFFECT,
- .setter = ctrl_set_image_effect,
- },
- {
- .id = V4L2_CID_COLORFX_CBCR,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 0xffff,
- .def = 0x8080,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_COLOUR_EFFECT,
- .setter = ctrl_set_colfx,
- },
- {
- .id = V4L2_CID_ROTATE,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 360,
- .def = 0,
- .step = 90,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_ROTATION,
- .setter = ctrl_set_rotate,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 1,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_MIRROR,
- .setter = ctrl_set_flip,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 1,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_MIRROR,
- .setter = ctrl_set_flip,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = 0,
- .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
- .def = 0,
- .step = 0,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_RATECONTROL,
- .setter = ctrl_set_bitrate_mode,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_BITRATE,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 25 * 1000,
- .max = 25 * 1000 * 1000,
- .def = 10 * 1000 * 1000,
- .step = 25 * 1000,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_VIDEO_BIT_RATE,
- .setter = ctrl_set_bitrate,
- },
- {
- .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 1,
- .max = 100,
- .def = 30,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_JPEG_Q_FACTOR,
- .setter = ctrl_set_image_encode_output,
- },
- {
- .id = V4L2_CID_POWER_LINE_FREQUENCY,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = 0,
- .max = V4L2_CID_POWER_LINE_FREQUENCY_AUTO,
- .def = 1,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_FLICKER_AVOID,
- .setter = ctrl_set_flicker_avoidance,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 1,
- .def = 0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
- .setter = ctrl_set_video_encode_param_output,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
- .max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
- .def = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_PROFILE,
- .setter = ctrl_set_video_encode_profile_level,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- .min = ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0)),
- .max = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
- .def = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_PROFILE,
- .setter = ctrl_set_video_encode_profile_level,
- },
- {
- .id = V4L2_CID_SCENE_MODE,
- .type = MMAL_CONTROL_TYPE_STD_MENU,
- /* mask is computed at runtime */
- .min = -1,
- .max = V4L2_SCENE_MODE_TEXT,
- .def = V4L2_SCENE_MODE_NONE,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_PROFILE,
- .setter = ctrl_set_scene_mode,
- },
- {
- .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
- .type = MMAL_CONTROL_TYPE_STD,
- .min = 0,
- .max = 0x7FFFFFFF,
- .def = 60,
- .step = 1,
- .imenu = NULL,
- .mmal_id = MMAL_PARAMETER_INTRAPERIOD,
- .setter = ctrl_set_video_encode_param_output,
- },
-};
-
-int bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev)
-{
- int c;
- int ret = 0;
-
- for (c = 0; c < V4L2_CTRL_COUNT; c++) {
- if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) {
- ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c],
- &v4l2_ctrls[c]);
- if (ret) {
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Failed when setting default values for ctrl %d\n",
- c);
- break;
- }
- }
- }
- return ret;
-}
-
-int set_framerate_params(struct bcm2835_mmal_dev *dev)
-{
- struct mmal_parameter_fps_range fps_range;
- int ret;
-
- fps_range.fps_high.numerator = dev->capture.timeperframe.denominator;
- fps_range.fps_high.denominator = dev->capture.timeperframe.numerator;
-
- if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) &&
- (dev->exp_auto_priority)) {
- /* Variable FPS. Define min FPS as 1fps. */
- fps_range.fps_low.numerator = 1;
- fps_range.fps_low.denominator = 1;
- } else {
- /* Fixed FPS - set min and max to be the same */
- fps_range.fps_low.numerator = fps_range.fps_high.numerator;
- fps_range.fps_low.denominator = fps_range.fps_high.denominator;
- }
-
- v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Set fps range to %d/%d to %d/%d\n",
- fps_range.fps_low.numerator,
- fps_range.fps_low.denominator,
- fps_range.fps_high.numerator,
- fps_range.fps_high.denominator);
-
- ret = vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW],
- MMAL_PARAMETER_FPS_RANGE,
- &fps_range, sizeof(fps_range));
- ret += vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO],
- MMAL_PARAMETER_FPS_RANGE,
- &fps_range, sizeof(fps_range));
- ret += vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE],
- MMAL_PARAMETER_FPS_RANGE,
- &fps_range, sizeof(fps_range));
- if (ret)
- v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
- "Failed to set fps ret %d\n", ret);
-
- return ret;
-}
-
-int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_handler *hdl)
-{
- int c;
- const struct bcm2835_mmal_v4l2_ctrl *ctrl;
-
- v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT);
-
- for (c = 0; c < V4L2_CTRL_COUNT; c++) {
- ctrl = &v4l2_ctrls[c];
-
- switch (ctrl->type) {
- case MMAL_CONTROL_TYPE_STD:
- dev->ctrls[c] = v4l2_ctrl_new_std(hdl, &bcm2835_mmal_ctrl_ops,
- ctrl->id, ctrl->min, ctrl->max,
- ctrl->step, ctrl->def);
- break;
-
- case MMAL_CONTROL_TYPE_STD_MENU:
- {
- u64 mask = ctrl->min;
-
- if (ctrl->id == V4L2_CID_SCENE_MODE) {
- /* Special handling to work out the mask
- * value based on the scene_configs array
- * at runtime. Reduces the chance of
- * mismatches.
- */
- int i;
-
- mask = BIT(V4L2_SCENE_MODE_NONE);
- for (i = 0;
- i < ARRAY_SIZE(scene_configs);
- i++) {
- mask |= BIT(scene_configs[i].v4l2_scene);
- }
- mask = ~mask;
- }
-
- dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, &bcm2835_mmal_ctrl_ops,
- ctrl->id, ctrl->max, mask,
- ctrl->def);
- break;
- }
-
- case MMAL_CONTROL_TYPE_INT_MENU:
- dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, &bcm2835_mmal_ctrl_ops,
- ctrl->id, ctrl->max,
- ctrl->def, ctrl->imenu);
- break;
-
- case MMAL_CONTROL_TYPE_CLUSTER:
- /* skip this entry when constructing controls */
- continue;
- }
-
- if (hdl->error)
- break;
-
- dev->ctrls[c]->priv = (void *)ctrl;
- }
-
- if (hdl->error) {
- pr_err("error adding control %d/%d id 0x%x\n", c,
- V4L2_CTRL_COUNT, ctrl->id);
- return hdl->error;
- }
-
- for (c = 0; c < V4L2_CTRL_COUNT; c++) {
- ctrl = &v4l2_ctrls[c];
-
- switch (ctrl->type) {
- case MMAL_CONTROL_TYPE_CLUSTER:
- v4l2_ctrl_auto_cluster(ctrl->min,
- &dev->ctrls[c + 1],
- ctrl->max,
- ctrl->def);
- break;
-
- case MMAL_CONTROL_TYPE_STD:
- case MMAL_CONTROL_TYPE_STD_MENU:
- case MMAL_CONTROL_TYPE_INT_MENU:
- break;
- }
- }
-
- return 0;
-}
diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
deleted file mode 100644
index ee4469f4fc51..000000000000
--- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
-
-#ifndef VCHIQ_H
-#define VCHIQ_H
-
-#define VCHIQ_MAKE_FOURCC(x0, x1, x2, x3) \
- (((x0) << 24) | ((x1) << 16) | ((x2) << 8) | (x3))
-
-enum vchiq_reason {
- VCHIQ_SERVICE_OPENED, /* service, -, - */
- VCHIQ_SERVICE_CLOSED, /* service, -, - */
- VCHIQ_MESSAGE_AVAILABLE, /* service, header, - */
- VCHIQ_BULK_TRANSMIT_DONE, /* service, -, bulk_userdata */
- VCHIQ_BULK_RECEIVE_DONE, /* service, -, bulk_userdata */
- VCHIQ_BULK_TRANSMIT_ABORTED, /* service, -, bulk_userdata */
- VCHIQ_BULK_RECEIVE_ABORTED /* service, -, bulk_userdata */
-};
-
-enum vchiq_bulk_mode {
- VCHIQ_BULK_MODE_CALLBACK,
- VCHIQ_BULK_MODE_BLOCKING,
- VCHIQ_BULK_MODE_NOCALLBACK,
- VCHIQ_BULK_MODE_WAITING /* Reserved for internal use */
-};
-
-enum vchiq_service_option {
- VCHIQ_SERVICE_OPTION_AUTOCLOSE,
- VCHIQ_SERVICE_OPTION_SLOT_QUOTA,
- VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA,
- VCHIQ_SERVICE_OPTION_SYNCHRONOUS,
- VCHIQ_SERVICE_OPTION_TRACE
-};
-
-struct vchiq_header {
- /* The message identifier - opaque to applications. */
- int msgid;
-
- /* Size of message data. */
- unsigned int size;
-
- char data[]; /* message */
-};
-
-struct vchiq_element {
- const void __user *data;
- unsigned int size;
-};
-
-struct vchiq_instance;
-struct vchiq_state;
-
-struct vchiq_service_base {
- int fourcc;
- int (*callback)(struct vchiq_instance *instance,
- enum vchiq_reason reason,
- struct vchiq_header *header,
- unsigned int handle,
- void *cb_data, void __user *cb_userdata);
- void *userdata;
-};
-
-struct vchiq_completion_data_kernel {
- enum vchiq_reason reason;
- struct vchiq_header *header;
- void *service_userdata;
- void *cb_data;
- void __user *cb_userdata;
-};
-
-struct vchiq_service_params_kernel {
- int fourcc;
- int (*callback)(struct vchiq_instance *instance,
- enum vchiq_reason reason,
- struct vchiq_header *header,
- unsigned int handle,
- void *cb_data, void __user *cb_userdata);
- void *userdata;
- short version; /* Increment for non-trivial changes */
- short version_min; /* Update for incompatible changes */
-};
-
-extern int vchiq_initialise(struct vchiq_state *state,
- struct vchiq_instance **pinstance);
-extern int vchiq_shutdown(struct vchiq_instance *instance);
-extern int vchiq_connect(struct vchiq_instance *instance);
-extern int vchiq_open_service(struct vchiq_instance *instance,
- const struct vchiq_service_params_kernel *params,
- unsigned int *pservice);
-extern int vchiq_close_service(struct vchiq_instance *instance,
- unsigned int service);
-extern int vchiq_use_service(struct vchiq_instance *instance, unsigned int service);
-extern int vchiq_release_service(struct vchiq_instance *instance,
- unsigned int service);
-extern void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_header *header);
-extern void vchiq_release_message(struct vchiq_instance *instance, unsigned int service,
- struct vchiq_header *header);
-extern int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle,
- void *data, unsigned int size);
-extern int vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int service,
- const void *data, unsigned int size, void *userdata,
- enum vchiq_bulk_mode mode);
-extern int vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int service,
- void *data, unsigned int size, void *userdata,
- enum vchiq_bulk_mode mode);
-extern void *vchiq_get_service_userdata(struct vchiq_instance *instance, unsigned int service);
-extern int vchiq_get_peer_version(struct vchiq_instance *instance, unsigned int handle,
- short *peer_version);
-extern struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle);
-
-#endif /* VCHIQ_H */
diff --git a/drivers/staging/vc04_services/interface/TESTING b/drivers/staging/vc04_services/interface/TESTING
deleted file mode 100644
index c98f688b07e0..000000000000
--- a/drivers/staging/vc04_services/interface/TESTING
+++ /dev/null
@@ -1,125 +0,0 @@
-This document contains some hints to test the function of the VCHIQ driver
-without having additional hardware to the Raspberry Pi.
-
-* Requirements & limitations
-
-Testing the VCHIQ driver requires a Raspberry Pi with one of the following SoC:
- - BCM2835 ( e.g. Raspberry Pi Zero W )
- - BCM2836 ( e.g. Raspberry Pi 2 )
- - BCM2837 ( e.g. Raspberry Pi 3 B+ )
-
-The BCM2711 used in the Raspberry Pi 4 is currently not supported in the
-mainline kernel.
-
-There are no specific requirements to the VideoCore firmware to get VCHIQ
-working.
-
-The test scenarios described in this document based on the tool vchiq_test.
-Its source code is available here: https://github.com/raspberrypi/userland
-
-* Configuration
-
-Here are the most common kernel configurations:
-
- 1. BCM2835 target SoC (ARM 32 bit)
-
- Just use bcm2835_defconfig which already has VCHIQ enabled.
-
- 2. BCM2836/7 target SoC (ARM 32 bit)
-
- Use the multi_v7_defconfig as a base and then enable all VCHIQ options.
-
- 3. BCM2837 target SoC (ARM 64 bit)
-
- Use the defconfig which has most of the VCHIQ options enabled.
-
-* Scenarios
-
- * Initial test
-
- Check the driver is probed and /dev/vchiq is created
-
- * Functional test
-
- Command: vchiq_test -f 10
-
- Expected output:
- Functional test - iters:10
- ======== iteration 1 ========
- Testing bulk transfer for alignment.
- Testing bulk transfer at PAGE_SIZE.
- ...
-
- * Ping test
-
- Command: vchiq_test -p
-
- Expected output:
- Ping test - service:echo, iters:1000, version 3
- vchi ping (size 0) -> 57.000000us
- vchi ping (size 0, 0 async, 0 oneway) -> 122.000000us
- vchi bulk (size 0, 0 async, 0 oneway) -> 546.000000us
- vchi bulk (size 0, 0 oneway) -> 230.000000us
- vchi ping (size 0) -> 49.000000us
- vchi ping (size 0, 0 async, 0 oneway) -> 70.000000us
- vchi bulk (size 0, 0 async, 0 oneway) -> 296.000000us
- vchi bulk (size 0, 0 oneway) -> 266.000000us
- vchi ping (size 0, 1 async, 0 oneway) -> 65.000000us
- vchi bulk (size 0, 0 oneway) -> 456.000000us
- vchi ping (size 0, 2 async, 0 oneway) -> 74.000000us
- vchi bulk (size 0, 0 oneway) -> 640.000000us
- vchi ping (size 0, 10 async, 0 oneway) -> 125.000000us
- vchi bulk (size 0, 0 oneway) -> 2309.000000us
- vchi ping (size 0, 0 async, 1 oneway) -> 70.000000us
- vchi ping (size 0, 0 async, 2 oneway) -> 76.000000us
- vchi ping (size 0, 0 async, 10 oneway) -> 105.000000us
- vchi ping (size 0, 10 async, 10 oneway) -> 165.000000us
- vchi ping (size 0, 100 async, 0 oneway) -> nanus
- vchi bulk (size 0, 0 oneway) -> nanus
- vchi ping (size 0, 0 async, 100 oneway) -> nanus
- vchi ping (size 0, 100 async, 100 oneway) -> infus
- vchi ping (size 0, 200 async, 0 oneway) -> infus
- ...
-
- * Debugfs test
-
- Command: cat /sys/kernel/debug/vchiq/state
-
- Example output:
- State 0: CONNECTED
- tx_pos=0x1e8(@43b0acda), rx_pos=0x170(@05493af8)
- Version: 8 (min 3)
- Stats: ctrl_tx_count=7, ctrl_rx_count=7, error_count=0
- Slots: 30 available (29 data), 0 recyclable, 0 stalls (0 data)
- Platform: 2835 (VC master)
- Local: slots 34-64 tx_pos=0x1e8 recycle=0x1f
- Slots claimed:
- DEBUG: SLOT_HANDLER_COUNT = 20(0x14)
- DEBUG: SLOT_HANDLER_LINE = 1937(0x791)
- DEBUG: PARSE_LINE = 1864(0x748)
- DEBUG: PARSE_HEADER = -249155224(0xf1263168)
- DEBUG: PARSE_MSGID = 67362817(0x403e001)
- DEBUG: AWAIT_COMPLETION_LINE = 0(0x0)
- DEBUG: DEQUEUE_MESSAGE_LINE = 0(0x0)
- DEBUG: SERVICE_CALLBACK_LINE = 0(0x0)
- DEBUG: MSG_QUEUE_FULL_COUNT = 0(0x0)
- DEBUG: COMPLETION_QUEUE_FULL_COUNT = 0(0x0)
- Remote: slots 2-32 tx_pos=0x170 recycle=0x1f
- Slots claimed:
- 2: 10/9
- DEBUG: SLOT_HANDLER_COUNT = 20(0x14)
- DEBUG: SLOT_HANDLER_LINE = 1851(0x73b)
- DEBUG: PARSE_LINE = 1827(0x723)
- DEBUG: PARSE_HEADER = -150330912(0xf70a21e0)
- DEBUG: PARSE_MSGID = 67113022(0x400103e)
- DEBUG: AWAIT_COMPLETION_LINE = 0(0x0)
- DEBUG: DEQUEUE_MESSAGE_LINE = 0(0x0)
- DEBUG: SERVICE_CALLBACK_LINE = 0(0x0)
- DEBUG: MSG_QUEUE_FULL_COUNT = 0(0x0)
- DEBUG: COMPLETION_QUEUE_FULL_COUNT = 0(0x0)
- Service 0: LISTENING (ref 1) 'PEEK little-endian (0x4b454550)' remote n/a (msg use 0/3840, slot use 0/15)
- Bulk: tx_pending=0 (size 0), rx_pending=0 (size 0)
- Ctrl: tx_count=0, tx_bytes=0, rx_count=0, rx_bytes=0
- Bulk: tx_count=0, tx_bytes=0, rx_count=0, rx_bytes=0
- 0 quota stalls, 0 slot stalls, 0 bulk stalls, 0 aborted, 0 errors
- instance b511f60b
diff --git a/drivers/staging/vc04_services/interface/TODO b/drivers/staging/vc04_services/interface/TODO
deleted file mode 100644
index f6f24600aa86..000000000000
--- a/drivers/staging/vc04_services/interface/TODO
+++ /dev/null
@@ -1,28 +0,0 @@
-* Import drivers using VCHI.
-
-VCHI is just a tool to let drivers talk to the firmware. Here are
-some of the ones we want:
-
- - vc_mem (https://github.com/raspberrypi/linux/blob/rpi-4.4.y/drivers/char/broadcom/vc_mem.c)
-
- This driver is what the vcdbg userspace program uses to set up its
- requests to the firmware, which are transmitted across VCHIQ. vcdbg
- is really useful for debugging firmware interactions.
-
- - VCSM (https://github.com/raspberrypi/linux/tree/rpi-4.4.y/drivers/char/broadcom/vc_sm)
-
- This driver is used for talking about regions of VC memory across
- firmware protocols including VCHI. We'll want to extend this driver
- to manage these buffers as dmabufs so that we can zero-copy import
- camera images into vc4 for rendering/display.
-
-* Documentation
-
-A short top-down description of this driver's architecture (function of
-kthreads, userspace, limitations) could be very helpful for reviewers.
-
-* Reformat core code with more sane indentations
-
-The code follows the 80 characters limitation yet tends to go 3 or 4 levels of
-indentation deep making it very unpleasant to read. This is specially relevant
-in the character driver ioctl code and in the core thread functions.
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
deleted file mode 100644
index 721b15b7e13b..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ /dev/null
@@ -1,1473 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/*
- * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched/signal.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/device/bus.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/bug.h>
-#include <linux/completion.h>
-#include <linux/list.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/compat.h>
-#include <linux/dma-mapping.h>
-#include <linux/rcupdate.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <soc/bcm2835/raspberrypi-firmware.h>
-
-#include "vchiq_core.h"
-#include "vchiq_ioctl.h"
-#include "vchiq_arm.h"
-#include "vchiq_bus.h"
-#include "vchiq_debugfs.h"
-
-#define DEVICE_NAME "vchiq"
-
-#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32)
-
-#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2)
-
-#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0
-#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1
-
-#define BELL0 0x00
-
-#define ARM_DS_ACTIVE BIT(2)
-
-/* Override the default prefix, which would be vchiq_arm (from the filename) */
-#undef MODULE_PARAM_PREFIX
-#define MODULE_PARAM_PREFIX DEVICE_NAME "."
-
-#define KEEPALIVE_VER 1
-#define KEEPALIVE_VER_MIN KEEPALIVE_VER
-
-/*
- * The devices implemented in the VCHIQ firmware are not discoverable,
- * so we need to maintain a list of them in order to register them with
- * the interface.
- */
-static struct vchiq_device *bcm2835_audio;
-static struct vchiq_device *bcm2835_camera;
-
-static const struct vchiq_platform_info bcm2835_info = {
- .cache_line_size = 32,
-};
-
-static const struct vchiq_platform_info bcm2836_info = {
- .cache_line_size = 64,
-};
-
-struct vchiq_arm_state {
- /* Keepalive-related data */
- struct task_struct *ka_thread;
- struct completion ka_evt;
- atomic_t ka_use_count;
- atomic_t ka_use_ack_count;
- atomic_t ka_release_count;
-
- rwlock_t susp_res_lock;
-
- struct vchiq_state *state;
-
- /*
- * Global use count for videocore.
- * This is equal to the sum of the use counts for all services. When
- * this hits zero the videocore suspend procedure will be initiated.
- */
- int videocore_use_count;
-
- /*
- * Use count to track requests from videocore peer.
- * This use count is not associated with a service, so needs to be
- * tracked separately with the state.
- */
- int peer_use_count;
-
- /*
- * Flag to indicate that the first vchiq connect has made it through.
- * This means that both sides should be fully ready, and we should
- * be able to suspend after this point.
- */
- int first_connect;
-};
-
-static int
-vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk_params);
-
-static irqreturn_t
-vchiq_doorbell_irq(int irq, void *dev_id)
-{
- struct vchiq_state *state = dev_id;
- struct vchiq_drv_mgmt *mgmt;
- irqreturn_t ret = IRQ_NONE;
- unsigned int status;
-
- mgmt = dev_get_drvdata(state->dev);
-
- /* Read (and clear) the doorbell */
- status = readl(mgmt->regs + BELL0);
-
- if (status & ARM_DS_ACTIVE) { /* Was the doorbell rung? */
- remote_event_pollall(state);
- ret = IRQ_HANDLED;
- }
-
- return ret;
-}
-
-/*
- * This function is called by the vchiq stack once it has been connected to
- * the videocore and clients can start to use the stack.
- */
-static void vchiq_call_connected_callbacks(struct vchiq_drv_mgmt *drv_mgmt)
-{
- int i;
-
- if (mutex_lock_killable(&drv_mgmt->connected_mutex))
- return;
-
- for (i = 0; i < drv_mgmt->num_deferred_callbacks; i++)
- drv_mgmt->deferred_callback[i]();
-
- drv_mgmt->num_deferred_callbacks = 0;
- drv_mgmt->connected = true;
- mutex_unlock(&drv_mgmt->connected_mutex);
-}
-
-/*
- * This function is used to defer initialization until the vchiq stack is
- * initialized. If the stack is already initialized, then the callback will
- * be made immediately, otherwise it will be deferred until
- * vchiq_call_connected_callbacks is called.
- */
-void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)(void))
-{
- struct vchiq_drv_mgmt *drv_mgmt = device->drv_mgmt;
-
- if (mutex_lock_killable(&drv_mgmt->connected_mutex))
- return;
-
- if (drv_mgmt->connected) {
- /* We're already connected. Call the callback immediately. */
- callback();
- } else {
- if (drv_mgmt->num_deferred_callbacks >= VCHIQ_DRV_MAX_CALLBACKS) {
- dev_err(&device->dev,
- "core: deferred callbacks(%d) exceeded the maximum limit(%d)\n",
- drv_mgmt->num_deferred_callbacks, VCHIQ_DRV_MAX_CALLBACKS);
- } else {
- drv_mgmt->deferred_callback[drv_mgmt->num_deferred_callbacks] =
- callback;
- drv_mgmt->num_deferred_callbacks++;
- }
- }
- mutex_unlock(&drv_mgmt->connected_mutex);
-}
-EXPORT_SYMBOL(vchiq_add_connected_callback);
-
-static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
-{
- struct device *dev = &pdev->dev;
- struct vchiq_drv_mgmt *drv_mgmt = platform_get_drvdata(pdev);
- struct rpi_firmware *fw = drv_mgmt->fw;
- struct vchiq_slot_zero *vchiq_slot_zero;
- void *slot_mem;
- dma_addr_t slot_phys;
- u32 channelbase;
- int slot_mem_size, frag_mem_size;
- int err, irq, i;
-
- /*
- * VCHI messages between the CPU and firmware use
- * 32-bit bus addresses.
- */
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-
- if (err < 0)
- return err;
-
- drv_mgmt->fragments_size = 2 * drv_mgmt->info->cache_line_size;
-
- /* Allocate space for the channels in coherent memory */
- slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE);
- frag_mem_size = PAGE_ALIGN(drv_mgmt->fragments_size * MAX_FRAGMENTS);
-
- slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size,
- &slot_phys, GFP_KERNEL);
- if (!slot_mem) {
- dev_err(dev, "could not allocate DMA memory\n");
- return -ENOMEM;
- }
-
- WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0);
-
- vchiq_slot_zero = vchiq_init_slots(dev, slot_mem, slot_mem_size);
- if (!vchiq_slot_zero)
- return -ENOMEM;
-
- vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] =
- (int)slot_phys + slot_mem_size;
- vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] =
- MAX_FRAGMENTS;
-
- drv_mgmt->fragments_base = (char *)slot_mem + slot_mem_size;
-
- drv_mgmt->free_fragments = drv_mgmt->fragments_base;
- for (i = 0; i < (MAX_FRAGMENTS - 1); i++) {
- *(char **)&drv_mgmt->fragments_base[i * drv_mgmt->fragments_size] =
- &drv_mgmt->fragments_base[(i + 1) * drv_mgmt->fragments_size];
- }
- *(char **)&drv_mgmt->fragments_base[i * drv_mgmt->fragments_size] = NULL;
- sema_init(&drv_mgmt->free_fragments_sema, MAX_FRAGMENTS);
- sema_init(&drv_mgmt->free_fragments_mutex, 1);
-
- err = vchiq_init_state(state, vchiq_slot_zero, dev);
- if (err)
- return err;
-
- drv_mgmt->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(drv_mgmt->regs))
- return PTR_ERR(drv_mgmt->regs);
-
- irq = platform_get_irq(pdev, 0);
- if (irq <= 0)
- return irq;
-
- err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL,
- "VCHIQ doorbell", state);
- if (err) {
- dev_err(dev, "failed to register irq=%d\n", irq);
- return err;
- }
-
- /* Send the base address of the slots to VideoCore */
- channelbase = slot_phys;
- err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT,
- &channelbase, sizeof(channelbase));
- if (err) {
- dev_err(dev, "failed to send firmware property: %d\n", err);
- return err;
- }
-
- if (channelbase) {
- dev_err(dev, "failed to set channelbase (response: %x)\n",
- channelbase);
- return -ENXIO;
- }
-
- dev_dbg(&pdev->dev, "arm: vchiq_init - done (slots %p, phys %pad)\n",
- vchiq_slot_zero, &slot_phys);
-
- mutex_init(&drv_mgmt->connected_mutex);
- vchiq_call_connected_callbacks(drv_mgmt);
-
- return 0;
-}
-
-int
-vchiq_platform_init_state(struct vchiq_state *state)
-{
- struct vchiq_arm_state *platform_state;
-
- platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL);
- if (!platform_state)
- return -ENOMEM;
-
- rwlock_init(&platform_state->susp_res_lock);
-
- init_completion(&platform_state->ka_evt);
- atomic_set(&platform_state->ka_use_count, 0);
- atomic_set(&platform_state->ka_use_ack_count, 0);
- atomic_set(&platform_state->ka_release_count, 0);
-
- platform_state->state = state;
-
- state->platform_state = (struct opaque_platform_state *)platform_state;
-
- return 0;
-}
-
-static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *state)
-{
- return (struct vchiq_arm_state *)state->platform_state;
-}
-
-static void
-vchiq_platform_uninit(struct vchiq_drv_mgmt *mgmt)
-{
- struct vchiq_arm_state *arm_state;
-
- kthread_stop(mgmt->state.sync_thread);
- kthread_stop(mgmt->state.recycle_thread);
- kthread_stop(mgmt->state.slot_handler_thread);
-
- arm_state = vchiq_platform_get_arm_state(&mgmt->state);
- if (!IS_ERR_OR_NULL(arm_state->ka_thread))
- kthread_stop(arm_state->ka_thread);
-}
-
-void vchiq_dump_platform_state(struct seq_file *f)
-{
- seq_puts(f, " Platform: 2835 (VC master)\n");
-}
-
-#define VCHIQ_INIT_RETRIES 10
-int vchiq_initialise(struct vchiq_state *state, struct vchiq_instance **instance_out)
-{
- struct vchiq_instance *instance = NULL;
- int i, ret;
-
- /*
- * VideoCore may not be ready due to boot up timing.
- * It may never be ready if kernel and firmware are mismatched,so don't
- * block forever.
- */
- for (i = 0; i < VCHIQ_INIT_RETRIES; i++) {
- if (vchiq_remote_initialised(state))
- break;
- usleep_range(500, 600);
- }
- if (i == VCHIQ_INIT_RETRIES) {
- dev_err(state->dev, "core: %s: Videocore not initialized\n", __func__);
- ret = -ENOTCONN;
- goto failed;
- } else if (i > 0) {
- dev_warn(state->dev, "core: %s: videocore initialized after %d retries\n",
- __func__, i);
- }
-
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
- if (!instance) {
- ret = -ENOMEM;
- goto failed;
- }
-
- instance->connected = 0;
- instance->state = state;
- mutex_init(&instance->bulk_waiter_list_mutex);
- INIT_LIST_HEAD(&instance->bulk_waiter_list);
-
- *instance_out = instance;
-
- ret = 0;
-
-failed:
- dev_dbg(state->dev, "core: (%p): returning %d\n", instance, ret);
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_initialise);
-
-void free_bulk_waiter(struct vchiq_instance *instance)
-{
- struct bulk_waiter_node *waiter, *next;
-
- list_for_each_entry_safe(waiter, next,
- &instance->bulk_waiter_list, list) {
- list_del(&waiter->list);
- dev_dbg(instance->state->dev,
- "arm: bulk_waiter - cleaned up %p for pid %d\n",
- waiter, waiter->pid);
- kfree(waiter);
- }
-}
-
-int vchiq_shutdown(struct vchiq_instance *instance)
-{
- struct vchiq_state *state = instance->state;
- int ret = 0;
-
- mutex_lock(&state->mutex);
-
- /* Remove all services */
- vchiq_shutdown_internal(state, instance);
-
- mutex_unlock(&state->mutex);
-
- dev_dbg(state->dev, "core: (%p): returning %d\n", instance, ret);
-
- free_bulk_waiter(instance);
- kfree(instance);
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_shutdown);
-
-static int vchiq_is_connected(struct vchiq_instance *instance)
-{
- return instance->connected;
-}
-
-int vchiq_connect(struct vchiq_instance *instance)
-{
- struct vchiq_state *state = instance->state;
- int ret;
-
- if (mutex_lock_killable(&state->mutex)) {
- dev_dbg(state->dev,
- "core: call to mutex_lock failed\n");
- ret = -EAGAIN;
- goto failed;
- }
- ret = vchiq_connect_internal(state, instance);
-
- if (!ret)
- instance->connected = 1;
-
- mutex_unlock(&state->mutex);
-
-failed:
- dev_dbg(state->dev, "core: (%p): returning %d\n", instance, ret);
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_connect);
-
-static int
-vchiq_add_service(struct vchiq_instance *instance,
- const struct vchiq_service_params_kernel *params,
- unsigned int *phandle)
-{
- struct vchiq_state *state = instance->state;
- struct vchiq_service *service = NULL;
- int srvstate, ret;
-
- *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
-
- srvstate = vchiq_is_connected(instance)
- ? VCHIQ_SRVSTATE_LISTENING
- : VCHIQ_SRVSTATE_HIDDEN;
-
- service = vchiq_add_service_internal(state, params, srvstate, instance, NULL);
-
- if (service) {
- *phandle = service->handle;
- ret = 0;
- } else {
- ret = -EINVAL;
- }
-
- dev_dbg(state->dev, "core: (%p): returning %d\n", instance, ret);
-
- return ret;
-}
-
-int
-vchiq_open_service(struct vchiq_instance *instance,
- const struct vchiq_service_params_kernel *params,
- unsigned int *phandle)
-{
- struct vchiq_state *state = instance->state;
- struct vchiq_service *service = NULL;
- int ret = -EINVAL;
-
- *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
-
- if (!vchiq_is_connected(instance))
- goto failed;
-
- service = vchiq_add_service_internal(state, params, VCHIQ_SRVSTATE_OPENING, instance, NULL);
-
- if (service) {
- *phandle = service->handle;
- ret = vchiq_open_service_internal(service, current->pid);
- if (ret) {
- vchiq_remove_service(instance, service->handle);
- *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
- }
- }
-
-failed:
- dev_dbg(state->dev, "core: (%p): returning %d\n", instance, ret);
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_open_service);
-
-int
-vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const void *data,
- unsigned int size, void *userdata, enum vchiq_bulk_mode mode)
-{
- struct vchiq_bulk bulk_params = {};
- int ret;
-
- switch (mode) {
- case VCHIQ_BULK_MODE_NOCALLBACK:
- case VCHIQ_BULK_MODE_CALLBACK:
-
- bulk_params.offset = (void *)data;
- bulk_params.mode = mode;
- bulk_params.size = size;
- bulk_params.cb_data = userdata;
- bulk_params.dir = VCHIQ_BULK_TRANSMIT;
-
- ret = vchiq_bulk_xfer_callback(instance, handle, &bulk_params);
- break;
- case VCHIQ_BULK_MODE_BLOCKING:
- bulk_params.offset = (void *)data;
- bulk_params.mode = mode;
- bulk_params.size = size;
- bulk_params.dir = VCHIQ_BULK_TRANSMIT;
-
- ret = vchiq_blocking_bulk_transfer(instance, handle, &bulk_params);
- break;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_bulk_transmit);
-
-int vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle,
- void *data, unsigned int size, void *userdata,
- enum vchiq_bulk_mode mode)
-{
- struct vchiq_bulk bulk_params = {};
- int ret;
-
- switch (mode) {
- case VCHIQ_BULK_MODE_NOCALLBACK:
- case VCHIQ_BULK_MODE_CALLBACK:
-
- bulk_params.offset = (void *)data;
- bulk_params.mode = mode;
- bulk_params.size = size;
- bulk_params.cb_data = userdata;
- bulk_params.dir = VCHIQ_BULK_RECEIVE;
-
- ret = vchiq_bulk_xfer_callback(instance, handle, &bulk_params);
- break;
- case VCHIQ_BULK_MODE_BLOCKING:
- bulk_params.offset = (void *)data;
- bulk_params.mode = mode;
- bulk_params.size = size;
- bulk_params.dir = VCHIQ_BULK_RECEIVE;
-
- ret = vchiq_blocking_bulk_transfer(instance, handle, &bulk_params);
- break;
- default:
- return -EINVAL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(vchiq_bulk_receive);
-
-static int
-vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk_params)
-{
- struct vchiq_service *service;
- struct bulk_waiter_node *waiter = NULL, *iter;
- int ret;
-
- service = find_service_by_handle(instance, handle);
- if (!service)
- return -EINVAL;
-
- vchiq_service_put(service);
-
- mutex_lock(&instance->bulk_waiter_list_mutex);
- list_for_each_entry(iter, &instance->bulk_waiter_list, list) {
- if (iter->pid == current->pid) {
- list_del(&iter->list);
- waiter = iter;
- break;
- }
- }
- mutex_unlock(&instance->bulk_waiter_list_mutex);
-
- if (waiter) {
- struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk;
-
- if (bulk) {
- /* This thread has an outstanding bulk transfer. */
- /* FIXME: why compare a dma address to a pointer? */
- if ((bulk->dma_addr != (dma_addr_t)(uintptr_t)bulk_params->dma_addr) ||
- (bulk->size != bulk_params->size)) {
- /*
- * This is not a retry of the previous one.
- * Cancel the signal when the transfer completes.
- */
- spin_lock(&service->state->bulk_waiter_spinlock);
- bulk->waiter = NULL;
- spin_unlock(&service->state->bulk_waiter_spinlock);
- }
- }
- } else {
- waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
- if (!waiter)
- return -ENOMEM;
- }
-
- bulk_params->waiter = &waiter->bulk_waiter;
-
- ret = vchiq_bulk_xfer_blocking(instance, handle, bulk_params);
- if ((ret != -EAGAIN) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) {
- struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk;
-
- if (bulk) {
- /* Cancel the signal when the transfer completes. */
- spin_lock(&service->state->bulk_waiter_spinlock);
- bulk->waiter = NULL;
- spin_unlock(&service->state->bulk_waiter_spinlock);
- }
- kfree(waiter);
- } else {
- waiter->pid = current->pid;
- mutex_lock(&instance->bulk_waiter_list_mutex);
- list_add(&waiter->list, &instance->bulk_waiter_list);
- mutex_unlock(&instance->bulk_waiter_list_mutex);
- dev_dbg(instance->state->dev, "arm: saved bulk_waiter %p for pid %d\n",
- waiter, current->pid);
- }
-
- return ret;
-}
-
-static int
-add_completion(struct vchiq_instance *instance, enum vchiq_reason reason,
- struct vchiq_header *header, struct user_service *user_service,
- void *cb_data, void __user *cb_userdata)
-{
- struct vchiq_completion_data_kernel *completion;
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev);
- int insert;
-
- DEBUG_INITIALISE(mgmt->state.local);
-
- insert = instance->completion_insert;
- while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) {
- /* Out of space - wait for the client */
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- dev_dbg(instance->state->dev, "core: completion queue full\n");
- DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
- if (wait_for_completion_interruptible(&instance->remove_event)) {
- dev_dbg(instance->state->dev, "arm: service_callback interrupted\n");
- return -EAGAIN;
- } else if (instance->closing) {
- dev_dbg(instance->state->dev, "arm: service_callback closing\n");
- return 0;
- }
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- }
-
- completion = &instance->completions[insert & (MAX_COMPLETIONS - 1)];
-
- completion->header = header;
- completion->reason = reason;
- /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
- completion->service_userdata = user_service->service;
- completion->cb_data = cb_data;
- completion->cb_userdata = cb_userdata;
-
- if (reason == VCHIQ_SERVICE_CLOSED) {
- /*
- * Take an extra reference, to be held until
- * this CLOSED notification is delivered.
- */
- vchiq_service_get(user_service->service);
- if (instance->use_close_delivered)
- user_service->close_pending = 1;
- }
-
- /*
- * A write barrier is needed here to ensure that the entire completion
- * record is written out before the insert point.
- */
- wmb();
-
- if (reason == VCHIQ_MESSAGE_AVAILABLE)
- user_service->message_available_pos = insert;
-
- insert++;
- instance->completion_insert = insert;
-
- complete(&instance->insert_event);
-
- return 0;
-}
-
-static int
-service_single_message(struct vchiq_instance *instance,
- enum vchiq_reason reason, struct vchiq_service *service,
- void *cb_data, void __user *cb_userdata)
-{
- struct user_service *user_service;
-
- user_service = (struct user_service *)service->base.userdata;
-
- dev_dbg(service->state->dev, "arm: msg queue full\n");
- /*
- * If there is no MESSAGE_AVAILABLE in the completion
- * queue, add one
- */
- if ((user_service->message_available_pos -
- instance->completion_remove) < 0) {
- int ret;
-
- dev_dbg(instance->state->dev,
- "arm: Inserting extra MESSAGE_AVAILABLE\n");
- ret = add_completion(instance, reason, NULL, user_service,
- cb_data, cb_userdata);
- if (ret)
- return ret;
- }
-
- if (wait_for_completion_interruptible(&user_service->remove_event)) {
- dev_dbg(instance->state->dev, "arm: interrupted\n");
- return -EAGAIN;
- } else if (instance->closing) {
- dev_dbg(instance->state->dev, "arm: closing\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-int
-service_callback(struct vchiq_instance *instance, enum vchiq_reason reason,
- struct vchiq_header *header, unsigned int handle,
- void *cb_data, void __user *cb_userdata)
-{
- /*
- * How do we ensure the callback goes to the right client?
- * The service_user data points to a user_service record
- * containing the original callback and the user state structure, which
- * contains a circular buffer for completion records.
- */
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev);
- struct user_service *user_service;
- struct vchiq_service *service;
- bool skip_completion = false;
-
- DEBUG_INITIALISE(mgmt->state.local);
-
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- if (WARN_ON(!service)) {
- rcu_read_unlock();
- return 0;
- }
-
- user_service = (struct user_service *)service->base.userdata;
-
- if (instance->closing) {
- rcu_read_unlock();
- return 0;
- }
-
- /*
- * As hopping around different synchronization mechanism,
- * taking an extra reference results in simpler implementation.
- */
- vchiq_service_get(service);
- rcu_read_unlock();
-
- dev_dbg(service->state->dev,
- "arm: service %p(%d,%p), reason %d, header %p, instance %p, cb_data %p, cb_userdata %p\n",
- user_service, service->localport, user_service->userdata,
- reason, header, instance, cb_data, cb_userdata);
-
- if (header && user_service->is_vchi) {
- spin_lock(&service->state->msg_queue_spinlock);
- while (user_service->msg_insert ==
- (user_service->msg_remove + MSG_QUEUE_SIZE)) {
- int ret;
-
- spin_unlock(&service->state->msg_queue_spinlock);
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- DEBUG_COUNT(MSG_QUEUE_FULL_COUNT);
-
- ret = service_single_message(instance, reason, service,
- cb_data, cb_userdata);
- if (ret) {
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- vchiq_service_put(service);
- return ret;
- }
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- spin_lock(&service->state->msg_queue_spinlock);
- }
-
- user_service->msg_queue[user_service->msg_insert &
- (MSG_QUEUE_SIZE - 1)] = header;
- user_service->msg_insert++;
-
- /*
- * If there is a thread waiting in DEQUEUE_MESSAGE, or if
- * there is a MESSAGE_AVAILABLE in the completion queue then
- * bypass the completion queue.
- */
- if (((user_service->message_available_pos -
- instance->completion_remove) >= 0) ||
- user_service->dequeue_pending) {
- user_service->dequeue_pending = 0;
- skip_completion = true;
- }
-
- spin_unlock(&service->state->msg_queue_spinlock);
- complete(&user_service->insert_event);
-
- header = NULL;
- }
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
- vchiq_service_put(service);
-
- if (skip_completion)
- return 0;
-
- return add_completion(instance, reason, header, user_service,
- cb_data, cb_userdata);
-}
-
-void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f)
-{
- int i;
-
- if (!vchiq_remote_initialised(state))
- return;
-
- /*
- * There is no list of instances, so instead scan all services,
- * marking those that have been dumped.
- */
-
- rcu_read_lock();
- for (i = 0; i < state->unused_service; i++) {
- struct vchiq_service *service;
- struct vchiq_instance *instance;
-
- service = rcu_dereference(state->services[i]);
- if (!service || service->base.callback != service_callback)
- continue;
-
- instance = service->instance;
- if (instance)
- instance->mark = 0;
- }
- rcu_read_unlock();
-
- for (i = 0; i < state->unused_service; i++) {
- struct vchiq_service *service;
- struct vchiq_instance *instance;
-
- rcu_read_lock();
- service = rcu_dereference(state->services[i]);
- if (!service || service->base.callback != service_callback) {
- rcu_read_unlock();
- continue;
- }
-
- instance = service->instance;
- if (!instance || instance->mark) {
- rcu_read_unlock();
- continue;
- }
- rcu_read_unlock();
-
- seq_printf(f, "Instance %pK: pid %d,%s completions %d/%d\n",
- instance, instance->pid,
- instance->connected ? " connected, " :
- "",
- instance->completion_insert -
- instance->completion_remove,
- MAX_COMPLETIONS);
- instance->mark = 1;
- }
-}
-
-void vchiq_dump_platform_service_state(struct seq_file *f,
- struct vchiq_service *service)
-{
- struct user_service *user_service =
- (struct user_service *)service->base.userdata;
-
- seq_printf(f, " instance %pK", service->instance);
-
- if ((service->base.callback == service_callback) && user_service->is_vchi) {
- seq_printf(f, ", %d/%d messages",
- user_service->msg_insert - user_service->msg_remove,
- MSG_QUEUE_SIZE);
-
- if (user_service->dequeue_pending)
- seq_puts(f, " (dequeue pending)");
- }
-
- seq_puts(f, "\n");
-}
-
-/*
- * Autosuspend related functionality
- */
-
-static int
-vchiq_keepalive_vchiq_callback(struct vchiq_instance *instance,
- enum vchiq_reason reason,
- struct vchiq_header *header,
- unsigned int service_user,
- void *cb_data, void __user *cb_userdata)
-{
- dev_err(instance->state->dev, "suspend: %s: callback reason %d\n",
- __func__, reason);
- return 0;
-}
-
-static int
-vchiq_keepalive_thread_func(void *v)
-{
- struct vchiq_state *state = (struct vchiq_state *)v;
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- struct vchiq_instance *instance;
- unsigned int ka_handle;
- int ret;
-
- struct vchiq_service_params_kernel params = {
- .fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'),
- .callback = vchiq_keepalive_vchiq_callback,
- .version = KEEPALIVE_VER,
- .version_min = KEEPALIVE_VER_MIN
- };
-
- ret = vchiq_initialise(state, &instance);
- if (ret) {
- dev_err(state->dev, "suspend: %s: vchiq_initialise failed %d\n", __func__, ret);
- goto exit;
- }
-
- ret = vchiq_connect(instance);
- if (ret) {
- dev_err(state->dev, "suspend: %s: vchiq_connect failed %d\n", __func__, ret);
- goto shutdown;
- }
-
- ret = vchiq_add_service(instance, &params, &ka_handle);
- if (ret) {
- dev_err(state->dev, "suspend: %s: vchiq_open_service failed %d\n",
- __func__, ret);
- goto shutdown;
- }
-
- while (!kthread_should_stop()) {
- long rc = 0, uc = 0;
-
- if (wait_for_completion_interruptible(&arm_state->ka_evt)) {
- dev_dbg(state->dev, "suspend: %s: interrupted\n", __func__);
- flush_signals(current);
- continue;
- }
-
- /*
- * read and clear counters. Do release_count then use_count to
- * prevent getting more releases than uses
- */
- rc = atomic_xchg(&arm_state->ka_release_count, 0);
- uc = atomic_xchg(&arm_state->ka_use_count, 0);
-
- /*
- * Call use/release service the requisite number of times.
- * Process use before release so use counts don't go negative
- */
- while (uc--) {
- atomic_inc(&arm_state->ka_use_ack_count);
- ret = vchiq_use_service(instance, ka_handle);
- if (ret) {
- dev_err(state->dev, "suspend: %s: vchiq_use_service error %d\n",
- __func__, ret);
- }
- }
- while (rc--) {
- ret = vchiq_release_service(instance, ka_handle);
- if (ret) {
- dev_err(state->dev, "suspend: %s: vchiq_release_service error %d\n",
- __func__, ret);
- }
- }
- }
-
-shutdown:
- vchiq_shutdown(instance);
-exit:
- return 0;
-}
-
-int
-vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
- enum USE_TYPE_E use_type)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- int ret = 0;
- char entity[64];
- int *entity_uc;
- int local_uc;
-
- if (!arm_state) {
- ret = -EINVAL;
- goto out;
- }
-
- if (use_type == USE_TYPE_VCHIQ) {
- snprintf(entity, sizeof(entity), "VCHIQ: ");
- entity_uc = &arm_state->peer_use_count;
- } else if (service) {
- snprintf(entity, sizeof(entity), "%p4cc:%03d",
- &service->base.fourcc,
- service->client_id);
- entity_uc = &service->service_use_count;
- } else {
- dev_err(state->dev, "suspend: %s: null service ptr\n", __func__);
- ret = -EINVAL;
- goto out;
- }
-
- write_lock_bh(&arm_state->susp_res_lock);
- local_uc = ++arm_state->videocore_use_count;
- ++(*entity_uc);
-
- dev_dbg(state->dev, "suspend: %s count %d, state count %d\n",
- entity, *entity_uc, local_uc);
-
- write_unlock_bh(&arm_state->susp_res_lock);
-
- if (!ret) {
- int ret = 0;
- long ack_cnt = atomic_xchg(&arm_state->ka_use_ack_count, 0);
-
- while (ack_cnt && !ret) {
- /* Send the use notify to videocore */
- ret = vchiq_send_remote_use_active(state);
- if (!ret)
- ack_cnt--;
- else
- atomic_add(ack_cnt, &arm_state->ka_use_ack_count);
- }
- }
-
-out:
- dev_dbg(state->dev, "suspend: exit %d\n", ret);
- return ret;
-}
-
-int
-vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- int ret = 0;
- char entity[64];
- int *entity_uc;
-
- if (!arm_state) {
- ret = -EINVAL;
- goto out;
- }
-
- if (service) {
- snprintf(entity, sizeof(entity), "%p4cc:%03d",
- &service->base.fourcc,
- service->client_id);
- entity_uc = &service->service_use_count;
- } else {
- snprintf(entity, sizeof(entity), "PEER: ");
- entity_uc = &arm_state->peer_use_count;
- }
-
- write_lock_bh(&arm_state->susp_res_lock);
- if (!arm_state->videocore_use_count || !(*entity_uc)) {
- WARN_ON(!arm_state->videocore_use_count);
- WARN_ON(!(*entity_uc));
- ret = -EINVAL;
- goto unlock;
- }
- --arm_state->videocore_use_count;
- --(*entity_uc);
-
- dev_dbg(state->dev, "suspend: %s count %d, state count %d\n",
- entity, *entity_uc, arm_state->videocore_use_count);
-
-unlock:
- write_unlock_bh(&arm_state->susp_res_lock);
-
-out:
- dev_dbg(state->dev, "suspend: exit %d\n", ret);
- return ret;
-}
-
-void
-vchiq_on_remote_use(struct vchiq_state *state)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
-
- atomic_inc(&arm_state->ka_use_count);
- complete(&arm_state->ka_evt);
-}
-
-void
-vchiq_on_remote_release(struct vchiq_state *state)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
-
- atomic_inc(&arm_state->ka_release_count);
- complete(&arm_state->ka_evt);
-}
-
-int
-vchiq_use_service_internal(struct vchiq_service *service)
-{
- return vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
-}
-
-int
-vchiq_release_service_internal(struct vchiq_service *service)
-{
- return vchiq_release_internal(service->state, service);
-}
-
-struct vchiq_debugfs_node *
-vchiq_instance_get_debugfs_node(struct vchiq_instance *instance)
-{
- return &instance->debugfs_node;
-}
-
-int
-vchiq_instance_get_use_count(struct vchiq_instance *instance)
-{
- struct vchiq_service *service;
- int use_count = 0, i;
-
- i = 0;
- rcu_read_lock();
- while ((service = __next_service_by_instance(instance->state,
- instance, &i)))
- use_count += service->service_use_count;
- rcu_read_unlock();
- return use_count;
-}
-
-int
-vchiq_instance_get_pid(struct vchiq_instance *instance)
-{
- return instance->pid;
-}
-
-int
-vchiq_instance_get_trace(struct vchiq_instance *instance)
-{
- return instance->trace;
-}
-
-void
-vchiq_instance_set_trace(struct vchiq_instance *instance, int trace)
-{
- struct vchiq_service *service;
- int i;
-
- i = 0;
- rcu_read_lock();
- while ((service = __next_service_by_instance(instance->state,
- instance, &i)))
- service->trace = trace;
- rcu_read_unlock();
- instance->trace = (trace != 0);
-}
-
-int
-vchiq_use_service(struct vchiq_instance *instance, unsigned int handle)
-{
- int ret = -EINVAL;
- struct vchiq_service *service = find_service_by_handle(instance, handle);
-
- if (service) {
- ret = vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
- vchiq_service_put(service);
- }
- return ret;
-}
-EXPORT_SYMBOL(vchiq_use_service);
-
-int
-vchiq_release_service(struct vchiq_instance *instance, unsigned int handle)
-{
- int ret = -EINVAL;
- struct vchiq_service *service = find_service_by_handle(instance, handle);
-
- if (service) {
- ret = vchiq_release_internal(service->state, service);
- vchiq_service_put(service);
- }
- return ret;
-}
-EXPORT_SYMBOL(vchiq_release_service);
-
-struct service_data_struct {
- int fourcc;
- int clientid;
- int use_count;
-};
-
-void
-vchiq_dump_service_use_state(struct vchiq_state *state)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- struct service_data_struct *service_data;
- int i, found = 0;
- /*
- * If there's more than 64 services, only dump ones with
- * non-zero counts
- */
- int only_nonzero = 0;
- static const char *nz = "<-- preventing suspend";
-
- int peer_count;
- int vc_use_count;
- int active_services;
-
- if (!arm_state)
- return;
-
- service_data = kmalloc_array(MAX_SERVICES, sizeof(*service_data),
- GFP_KERNEL);
- if (!service_data)
- return;
-
- read_lock_bh(&arm_state->susp_res_lock);
- peer_count = arm_state->peer_use_count;
- vc_use_count = arm_state->videocore_use_count;
- active_services = state->unused_service;
- if (active_services > MAX_SERVICES)
- only_nonzero = 1;
-
- rcu_read_lock();
- for (i = 0; i < active_services; i++) {
- struct vchiq_service *service_ptr =
- rcu_dereference(state->services[i]);
-
- if (!service_ptr)
- continue;
-
- if (only_nonzero && !service_ptr->service_use_count)
- continue;
-
- if (service_ptr->srvstate == VCHIQ_SRVSTATE_FREE)
- continue;
-
- service_data[found].fourcc = service_ptr->base.fourcc;
- service_data[found].clientid = service_ptr->client_id;
- service_data[found].use_count = service_ptr->service_use_count;
- found++;
- if (found >= MAX_SERVICES)
- break;
- }
- rcu_read_unlock();
-
- read_unlock_bh(&arm_state->susp_res_lock);
-
- if (only_nonzero)
- dev_warn(state->dev,
- "suspend: Too many active services (%d). Only dumping up to first %d services with non-zero use-count\n",
- active_services, found);
-
- for (i = 0; i < found; i++) {
- dev_warn(state->dev,
- "suspend: %p4cc:%d service count %d %s\n",
- &service_data[i].fourcc,
- service_data[i].clientid, service_data[i].use_count,
- service_data[i].use_count ? nz : "");
- }
- dev_warn(state->dev, "suspend: VCHIQ use count %d\n", peer_count);
- dev_warn(state->dev, "suspend: Overall vchiq instance use count %d\n", vc_use_count);
-
- kfree(service_data);
-}
-
-int
-vchiq_check_service(struct vchiq_service *service)
-{
- struct vchiq_arm_state *arm_state;
- int ret = -EINVAL;
-
- if (!service || !service->state)
- goto out;
-
- arm_state = vchiq_platform_get_arm_state(service->state);
-
- read_lock_bh(&arm_state->susp_res_lock);
- if (service->service_use_count)
- ret = 0;
- read_unlock_bh(&arm_state->susp_res_lock);
-
- if (ret) {
- dev_err(service->state->dev,
- "suspend: %s: %p4cc:%d service count %d, state count %d\n",
- __func__, &service->base.fourcc, service->client_id,
- service->service_use_count, arm_state->videocore_use_count);
- vchiq_dump_service_use_state(service->state);
- }
-out:
- return ret;
-}
-
-void vchiq_platform_conn_state_changed(struct vchiq_state *state,
- enum vchiq_connstate oldstate,
- enum vchiq_connstate newstate)
-{
- struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
- char threadname[16];
-
- dev_dbg(state->dev, "suspend: %d: %s->%s\n",
- state->id, get_conn_state_name(oldstate), get_conn_state_name(newstate));
- if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED)
- return;
-
- write_lock_bh(&arm_state->susp_res_lock);
- if (arm_state->first_connect) {
- write_unlock_bh(&arm_state->susp_res_lock);
- return;
- }
-
- arm_state->first_connect = 1;
- write_unlock_bh(&arm_state->susp_res_lock);
- snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
- state->id);
- arm_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func,
- (void *)state,
- threadname);
- if (IS_ERR(arm_state->ka_thread)) {
- dev_err(state->dev, "suspend: Couldn't create thread %s\n",
- threadname);
- } else {
- wake_up_process(arm_state->ka_thread);
- }
-}
-
-static const struct of_device_id vchiq_of_match[] = {
- { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_info },
- { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_info },
- {},
-};
-MODULE_DEVICE_TABLE(of, vchiq_of_match);
-
-static int vchiq_probe(struct platform_device *pdev)
-{
- const struct vchiq_platform_info *info;
- struct vchiq_drv_mgmt *mgmt;
- int ret;
-
- info = of_device_get_match_data(&pdev->dev);
- if (!info)
- return -EINVAL;
-
- struct device_node *fw_node __free(device_node) =
- of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware");
- if (!fw_node) {
- dev_err(&pdev->dev, "Missing firmware node\n");
- return -ENOENT;
- }
-
- mgmt = devm_kzalloc(&pdev->dev, sizeof(*mgmt), GFP_KERNEL);
- if (!mgmt)
- return -ENOMEM;
-
- mgmt->fw = devm_rpi_firmware_get(&pdev->dev, fw_node);
- if (!mgmt->fw)
- return -EPROBE_DEFER;
-
- mgmt->info = info;
- platform_set_drvdata(pdev, mgmt);
-
- ret = vchiq_platform_init(pdev, &mgmt->state);
- if (ret) {
- dev_err(&pdev->dev, "arm: Could not initialize vchiq platform\n");
- return ret;
- }
-
- dev_dbg(&pdev->dev, "arm: platform initialised - version %d (min %d)\n",
- VCHIQ_VERSION, VCHIQ_VERSION_MIN);
-
- /*
- * Simply exit on error since the function handles cleanup in
- * cases of failure.
- */
- ret = vchiq_register_chrdev(&pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n");
- vchiq_platform_uninit(mgmt);
- return ret;
- }
-
- vchiq_debugfs_init(&mgmt->state);
-
- bcm2835_audio = vchiq_device_register(&pdev->dev, "bcm2835-audio");
- bcm2835_camera = vchiq_device_register(&pdev->dev, "bcm2835-camera");
-
- return 0;
-}
-
-static void vchiq_remove(struct platform_device *pdev)
-{
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev);
-
- vchiq_device_unregister(bcm2835_audio);
- vchiq_device_unregister(bcm2835_camera);
- vchiq_debugfs_deinit();
- vchiq_deregister_chrdev();
- vchiq_platform_uninit(mgmt);
-}
-
-static struct platform_driver vchiq_driver = {
- .driver = {
- .name = "bcm2835_vchiq",
- .of_match_table = vchiq_of_match,
- },
- .probe = vchiq_probe,
- .remove = vchiq_remove,
-};
-
-static int __init vchiq_driver_init(void)
-{
- int ret;
-
- ret = bus_register(&vchiq_bus_type);
- if (ret) {
- pr_err("Failed to register %s\n", vchiq_bus_type.name);
- return ret;
- }
-
- ret = platform_driver_register(&vchiq_driver);
- if (ret) {
- pr_err("Failed to register vchiq driver\n");
- bus_unregister(&vchiq_bus_type);
- }
-
- return ret;
-}
-module_init(vchiq_driver_init);
-
-static void __exit vchiq_driver_exit(void)
-{
- bus_unregister(&vchiq_bus_type);
- platform_driver_unregister(&vchiq_driver);
-}
-module_exit(vchiq_driver_exit);
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("Videocore VCHIQ driver");
-MODULE_AUTHOR("Broadcom Corporation");
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
deleted file mode 100644
index e32b02f99024..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/*
- * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- */
-
-#ifndef VCHIQ_ARM_H
-#define VCHIQ_ARM_H
-
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/semaphore.h>
-#include <linux/atomic.h>
-#include "vchiq_core.h"
-#include "vchiq_debugfs.h"
-
-/* Some per-instance constants */
-#define MAX_COMPLETIONS 128
-#define MAX_SERVICES 64
-#define MAX_ELEMENTS 8
-#define MSG_QUEUE_SIZE 128
-
-#define VCHIQ_DRV_MAX_CALLBACKS 10
-
-struct rpi_firmware;
-struct vchiq_device;
-
-enum USE_TYPE_E {
- USE_TYPE_SERVICE,
- USE_TYPE_VCHIQ
-};
-
-struct vchiq_platform_info {
- unsigned int cache_line_size;
-};
-
-struct vchiq_drv_mgmt {
- struct rpi_firmware *fw;
- const struct vchiq_platform_info *info;
-
- bool connected;
- int num_deferred_callbacks;
- /* Protects connected and num_deferred_callbacks */
- struct mutex connected_mutex;
-
- void (*deferred_callback[VCHIQ_DRV_MAX_CALLBACKS])(void);
-
- struct semaphore free_fragments_sema;
- struct semaphore free_fragments_mutex;
- char *fragments_base;
- char *free_fragments;
- unsigned int fragments_size;
-
- void __iomem *regs;
-
- struct vchiq_state state;
-};
-
-struct user_service {
- struct vchiq_service *service;
- void __user *userdata;
- struct vchiq_instance *instance;
- char is_vchi;
- char dequeue_pending;
- char close_pending;
- int message_available_pos;
- int msg_insert;
- int msg_remove;
- struct completion insert_event;
- struct completion remove_event;
- struct completion close_event;
- struct vchiq_header *msg_queue[MSG_QUEUE_SIZE];
-};
-
-struct bulk_waiter_node {
- struct bulk_waiter bulk_waiter;
- int pid;
- struct list_head list;
-};
-
-struct vchiq_instance {
- struct vchiq_state *state;
- struct vchiq_completion_data_kernel completions[MAX_COMPLETIONS];
- int completion_insert;
- int completion_remove;
- struct completion insert_event;
- struct completion remove_event;
- struct mutex completion_mutex;
-
- int connected;
- int closing;
- int pid;
- int mark;
- int use_close_delivered;
- int trace;
-
- struct list_head bulk_waiter_list;
- struct mutex bulk_waiter_list_mutex;
-
- struct vchiq_debugfs_node debugfs_node;
-};
-
-int
-vchiq_use_service(struct vchiq_instance *instance, unsigned int handle);
-
-extern int
-vchiq_release_service(struct vchiq_instance *instance, unsigned int handle);
-
-extern int
-vchiq_check_service(struct vchiq_service *service);
-
-extern void
-vchiq_dump_service_use_state(struct vchiq_state *state);
-
-extern int
-vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
- enum USE_TYPE_E use_type);
-extern int
-vchiq_release_internal(struct vchiq_state *state,
- struct vchiq_service *service);
-
-extern struct vchiq_debugfs_node *
-vchiq_instance_get_debugfs_node(struct vchiq_instance *instance);
-
-extern int
-vchiq_instance_get_use_count(struct vchiq_instance *instance);
-
-extern int
-vchiq_instance_get_pid(struct vchiq_instance *instance);
-
-extern int
-vchiq_instance_get_trace(struct vchiq_instance *instance);
-
-extern void
-vchiq_instance_set_trace(struct vchiq_instance *instance, int trace);
-
-extern void
-vchiq_add_connected_callback(struct vchiq_device *device,
- void (*callback)(void));
-
-#if IS_ENABLED(CONFIG_VCHIQ_CDEV)
-
-extern void
-vchiq_deregister_chrdev(void);
-
-extern int
-vchiq_register_chrdev(struct device *parent);
-
-#else
-
-static inline void vchiq_deregister_chrdev(void) { }
-static inline int vchiq_register_chrdev(struct device *parent) { return 0; }
-
-#endif /* IS_ENABLED(CONFIG_VCHIQ_CDEV) */
-
-extern int
-service_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason,
- struct vchiq_header *header, unsigned int handle,
- void *cb_data, void __user *cb_userdata);
-
-extern void
-free_bulk_waiter(struct vchiq_instance *instance);
-
-#endif /* VCHIQ_ARM_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c
deleted file mode 100644
index 41ece91ab88a..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * vchiq_device.c - VCHIQ generic device and bus-type
- *
- * Copyright (c) 2023 Ideas On Board Oy
- */
-
-#include <linux/device/bus.h>
-#include <linux/dma-mapping.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "vchiq_arm.h"
-#include "vchiq_bus.h"
-
-static int vchiq_bus_type_match(struct device *dev, const struct device_driver *drv)
-{
- if (dev->bus == &vchiq_bus_type &&
- strcmp(dev_name(dev), drv->name) == 0)
- return true;
-
- return false;
-}
-
-static int vchiq_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
-{
- const struct vchiq_device *device = container_of_const(dev, struct vchiq_device, dev);
-
- return add_uevent_var(env, "MODALIAS=vchiq:%s", dev_name(&device->dev));
-}
-
-static int vchiq_bus_probe(struct device *dev)
-{
- struct vchiq_device *device = to_vchiq_device(dev);
- struct vchiq_driver *driver = to_vchiq_driver(dev->driver);
-
- return driver->probe(device);
-}
-
-static void vchiq_bus_remove(struct device *dev)
-{
- struct vchiq_device *device = to_vchiq_device(dev);
- struct vchiq_driver *driver = to_vchiq_driver(dev->driver);
-
- if (driver->remove)
- driver->remove(device);
-}
-
-const struct bus_type vchiq_bus_type = {
- .name = "vchiq-bus",
- .match = vchiq_bus_type_match,
- .uevent = vchiq_bus_uevent,
- .probe = vchiq_bus_probe,
- .remove = vchiq_bus_remove,
-};
-
-static void vchiq_device_release(struct device *dev)
-{
- struct vchiq_device *device = to_vchiq_device(dev);
-
- kfree(device);
-}
-
-struct vchiq_device *
-vchiq_device_register(struct device *parent, const char *name)
-{
- struct vchiq_device *device;
- int ret;
-
- device = kzalloc(sizeof(*device), GFP_KERNEL);
- if (!device)
- return NULL;
-
- device->dev.init_name = name;
- device->dev.parent = parent;
- device->dev.bus = &vchiq_bus_type;
- device->dev.dma_mask = &device->dev.coherent_dma_mask;
- device->dev.release = vchiq_device_release;
-
- device->drv_mgmt = dev_get_drvdata(parent);
-
- of_dma_configure(&device->dev, parent->of_node, true);
-
- ret = device_register(&device->dev);
- if (ret) {
- dev_err(parent, "Cannot register %s: %d\n", name, ret);
- put_device(&device->dev);
- return NULL;
- }
-
- return device;
-}
-
-void vchiq_device_unregister(struct vchiq_device *vchiq_dev)
-{
- device_unregister(&vchiq_dev->dev);
-}
-
-int vchiq_driver_register(struct vchiq_driver *vchiq_drv)
-{
- vchiq_drv->driver.bus = &vchiq_bus_type;
-
- return driver_register(&vchiq_drv->driver);
-}
-EXPORT_SYMBOL_GPL(vchiq_driver_register);
-
-void vchiq_driver_unregister(struct vchiq_driver *vchiq_drv)
-{
- driver_unregister(&vchiq_drv->driver);
-}
-EXPORT_SYMBOL_GPL(vchiq_driver_unregister);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h
deleted file mode 100644
index 9de179b39f85..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2023 Ideas On Board Oy
- */
-
-#ifndef _VCHIQ_DEVICE_H
-#define _VCHIQ_DEVICE_H
-
-#include <linux/device.h>
-#include <linux/mod_devicetable.h>
-
-struct vchiq_drv_mgmt;
-
-struct vchiq_device {
- struct device dev;
- struct vchiq_drv_mgmt *drv_mgmt;
-};
-
-struct vchiq_driver {
- int (*probe)(struct vchiq_device *device);
- void (*remove)(struct vchiq_device *device);
- int (*resume)(struct vchiq_device *device);
- int (*suspend)(struct vchiq_device *device,
- pm_message_t state);
-
- const struct vchiq_device_id *id_table;
- struct device_driver driver;
-};
-
-static inline struct vchiq_device *to_vchiq_device(struct device *d)
-{
- return container_of(d, struct vchiq_device, dev);
-}
-
-static inline struct vchiq_driver *to_vchiq_driver(struct device_driver *d)
-{
- return container_of(d, struct vchiq_driver, driver);
-}
-
-extern const struct bus_type vchiq_bus_type;
-
-struct vchiq_device *
-vchiq_device_register(struct device *parent, const char *name);
-void vchiq_device_unregister(struct vchiq_device *dev);
-
-int vchiq_driver_register(struct vchiq_driver *vchiq_drv);
-void vchiq_driver_unregister(struct vchiq_driver *vchiq_drv);
-
-/**
- * module_vchiq_driver() - Helper macro for registering a vchiq driver
- * @__vchiq_driver: vchiq driver struct
- *
- * Helper macro for vchiq drivers which do not do anything special in
- * module init/exit. This eliminates a lot of boilerplate. Each module may only
- * use this macro once, and calling it replaces module_init() and module_exit()
- */
-#define module_vchiq_driver(__vchiq_driver) \
- module_driver(__vchiq_driver, vchiq_driver_register, vchiq_driver_unregister)
-
-#endif /* _VCHIQ_DEVICE_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h
deleted file mode 100644
index a16d0299996c..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2010-2014 Broadcom. All rights reserved. */
-
-#ifndef VCHIQ_CFG_H
-#define VCHIQ_CFG_H
-
-#define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V', 'C', 'H', 'I')
-/* The version of VCHIQ - change with any non-trivial change */
-#define VCHIQ_VERSION 8
-/*
- * The minimum compatible version - update to match VCHIQ_VERSION with any
- * incompatible change
- */
-#define VCHIQ_VERSION_MIN 3
-
-/* The version that introduced the VCHIQ_IOC_LIB_VERSION ioctl */
-#define VCHIQ_VERSION_LIB_VERSION 7
-
-/* The version that introduced the VCHIQ_IOC_CLOSE_DELIVERED ioctl */
-#define VCHIQ_VERSION_CLOSE_DELIVERED 7
-
-/* The version that made it safe to use SYNCHRONOUS mode */
-#define VCHIQ_VERSION_SYNCHRONOUS_MODE 8
-
-#define VCHIQ_MAX_STATES 1
-#define VCHIQ_MAX_SERVICES 4096
-#define VCHIQ_MAX_SLOTS 128
-#define VCHIQ_MAX_SLOTS_PER_SIDE 64
-
-#define VCHIQ_NUM_CURRENT_BULKS 32
-#define VCHIQ_NUM_SERVICE_BULKS 4
-
-#ifndef VCHIQ_ENABLE_DEBUG
-#define VCHIQ_ENABLE_DEBUG 1
-#endif
-
-#ifndef VCHIQ_ENABLE_STATS
-#define VCHIQ_ENABLE_STATS 1
-#endif
-
-#endif /* VCHIQ_CFG_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
deleted file mode 100644
index e2cac0898b8f..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ /dev/null
@@ -1,4016 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
-
-#include <linux/types.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/highmem.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/kref.h>
-#include <linux/rcupdate.h>
-#include <linux/sched/signal.h>
-
-#include "vchiq_arm.h"
-#include "vchiq_core.h"
-
-#define VCHIQ_SLOT_HANDLER_STACK 8192
-
-#define VCHIQ_MSG_PADDING 0 /* - */
-#define VCHIQ_MSG_CONNECT 1 /* - */
-#define VCHIQ_MSG_OPEN 2 /* + (srcport, -), fourcc, client_id */
-#define VCHIQ_MSG_OPENACK 3 /* + (srcport, dstport) */
-#define VCHIQ_MSG_CLOSE 4 /* + (srcport, dstport) */
-#define VCHIQ_MSG_DATA 5 /* + (srcport, dstport) */
-#define VCHIQ_MSG_BULK_RX 6 /* + (srcport, dstport), data, size */
-#define VCHIQ_MSG_BULK_TX 7 /* + (srcport, dstport), data, size */
-#define VCHIQ_MSG_BULK_RX_DONE 8 /* + (srcport, dstport), actual */
-#define VCHIQ_MSG_BULK_TX_DONE 9 /* + (srcport, dstport), actual */
-#define VCHIQ_MSG_PAUSE 10 /* - */
-#define VCHIQ_MSG_RESUME 11 /* - */
-#define VCHIQ_MSG_REMOTE_USE 12 /* - */
-#define VCHIQ_MSG_REMOTE_RELEASE 13 /* - */
-#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 /* - */
-
-#define TYPE_SHIFT 24
-
-#define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1)
-#define VCHIQ_PORT_FREE 0x1000
-#define VCHIQ_PORT_IS_VALID(port) ((port) < VCHIQ_PORT_FREE)
-#define VCHIQ_MAKE_MSG(type, srcport, dstport) \
- (((type) << TYPE_SHIFT) | ((srcport) << 12) | ((dstport) << 0))
-#define VCHIQ_MSG_TYPE(msgid) ((unsigned int)(msgid) >> TYPE_SHIFT)
-#define VCHIQ_MSG_SRCPORT(msgid) \
- ((unsigned short)(((unsigned int)(msgid) >> 12) & 0xfff))
-#define VCHIQ_MSG_DSTPORT(msgid) \
- ((unsigned short)(msgid) & 0xfff)
-
-#define MAKE_CONNECT (VCHIQ_MSG_CONNECT << TYPE_SHIFT)
-#define MAKE_OPEN(srcport) \
- ((VCHIQ_MSG_OPEN << TYPE_SHIFT) | ((srcport) << 12))
-#define MAKE_OPENACK(srcport, dstport) \
- ((VCHIQ_MSG_OPENACK << TYPE_SHIFT) | ((srcport) << 12) | ((dstport) << 0))
-#define MAKE_CLOSE(srcport, dstport) \
- ((VCHIQ_MSG_CLOSE << TYPE_SHIFT) | ((srcport) << 12) | ((dstport) << 0))
-#define MAKE_DATA(srcport, dstport) \
- ((VCHIQ_MSG_DATA << TYPE_SHIFT) | ((srcport) << 12) | ((dstport) << 0))
-#define MAKE_PAUSE (VCHIQ_MSG_PAUSE << TYPE_SHIFT)
-#define MAKE_RESUME (VCHIQ_MSG_RESUME << TYPE_SHIFT)
-#define MAKE_REMOTE_USE (VCHIQ_MSG_REMOTE_USE << TYPE_SHIFT)
-#define MAKE_REMOTE_USE_ACTIVE (VCHIQ_MSG_REMOTE_USE_ACTIVE << TYPE_SHIFT)
-
-#define PAGELIST_WRITE 0
-#define PAGELIST_READ 1
-#define PAGELIST_READ_WITH_FRAGMENTS 2
-
-#define BELL2 0x08
-
-/* Ensure the fields are wide enough */
-static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX)) == 0);
-static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0);
-static_assert((unsigned int)VCHIQ_PORT_MAX < (unsigned int)VCHIQ_PORT_FREE);
-
-#define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0)
-#define VCHIQ_MSGID_CLAIMED 0x40000000
-
-#define VCHIQ_FOURCC_INVALID 0x00000000
-#define VCHIQ_FOURCC_IS_LEGAL(fourcc) ((fourcc) != VCHIQ_FOURCC_INVALID)
-
-#define VCHIQ_BULK_ACTUAL_ABORTED -1
-
-#if VCHIQ_ENABLE_STATS
-#define VCHIQ_STATS_INC(state, stat) (state->stats. stat++)
-#define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat++)
-#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) \
- (service->stats. stat += addend)
-#else
-#define VCHIQ_STATS_INC(state, stat) ((void)0)
-#define VCHIQ_SERVICE_STATS_INC(service, stat) ((void)0)
-#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) ((void)0)
-#endif
-
-#define HANDLE_STATE_SHIFT 12
-
-#define SLOT_INFO_FROM_INDEX(state, index) (state->slot_info + (index))
-#define SLOT_DATA_FROM_INDEX(state, index) (state->slot_data + (index))
-#define SLOT_INDEX_FROM_DATA(state, data) \
- (((unsigned int)((char *)data - (char *)state->slot_data)) / \
- VCHIQ_SLOT_SIZE)
-#define SLOT_INDEX_FROM_INFO(state, info) \
- ((unsigned int)(info - state->slot_info))
-#define SLOT_QUEUE_INDEX_FROM_POS(pos) \
- ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE))
-#define SLOT_QUEUE_INDEX_FROM_POS_MASKED(pos) \
- (SLOT_QUEUE_INDEX_FROM_POS(pos) & VCHIQ_SLOT_QUEUE_MASK)
-
-#define BULK_INDEX(x) ((x) & (VCHIQ_NUM_SERVICE_BULKS - 1))
-
-#define NO_CLOSE_RECVD 0
-#define CLOSE_RECVD 1
-
-#define NO_RETRY_POLL 0
-#define RETRY_POLL 1
-
-struct vchiq_open_payload {
- int fourcc;
- int client_id;
- short version;
- short version_min;
-};
-
-struct vchiq_openack_payload {
- short version;
-};
-
-enum {
- QMFLAGS_IS_BLOCKING = BIT(0),
- QMFLAGS_NO_MUTEX_LOCK = BIT(1),
- QMFLAGS_NO_MUTEX_UNLOCK = BIT(2)
-};
-
-enum {
- VCHIQ_POLL_TERMINATE,
- VCHIQ_POLL_REMOVE,
- VCHIQ_POLL_TXNOTIFY,
- VCHIQ_POLL_RXNOTIFY,
- VCHIQ_POLL_COUNT
-};
-
-/* we require this for consistency between endpoints */
-static_assert(sizeof(struct vchiq_header) == 8);
-static_assert(VCHIQ_VERSION >= VCHIQ_VERSION_MIN);
-
-static inline void check_sizes(void)
-{
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_SLOT_SIZE);
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_MAX_SLOTS);
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_MAX_SLOTS_PER_SIDE);
- BUILD_BUG_ON_NOT_POWER_OF_2(sizeof(struct vchiq_header));
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_NUM_CURRENT_BULKS);
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_NUM_SERVICE_BULKS);
- BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_MAX_SERVICES);
-}
-
-static unsigned int handle_seq;
-
-static const char *const srvstate_names[] = {
- "FREE",
- "HIDDEN",
- "LISTENING",
- "OPENING",
- "OPEN",
- "OPENSYNC",
- "CLOSESENT",
- "CLOSERECVD",
- "CLOSEWAIT",
- "CLOSED"
-};
-
-static const char *const reason_names[] = {
- "SERVICE_OPENED",
- "SERVICE_CLOSED",
- "MESSAGE_AVAILABLE",
- "BULK_TRANSMIT_DONE",
- "BULK_RECEIVE_DONE",
- "BULK_TRANSMIT_ABORTED",
- "BULK_RECEIVE_ABORTED"
-};
-
-static const char *const conn_state_names[] = {
- "DISCONNECTED",
- "CONNECTING",
- "CONNECTED",
- "PAUSING",
- "PAUSE_SENT",
- "PAUSED",
- "RESUMING",
- "PAUSE_TIMEOUT",
- "RESUME_TIMEOUT"
-};
-
-static void
-release_message_sync(struct vchiq_state *state, struct vchiq_header *header);
-
-static const char *msg_type_str(unsigned int msg_type)
-{
- switch (msg_type) {
- case VCHIQ_MSG_PADDING: return "PADDING";
- case VCHIQ_MSG_CONNECT: return "CONNECT";
- case VCHIQ_MSG_OPEN: return "OPEN";
- case VCHIQ_MSG_OPENACK: return "OPENACK";
- case VCHIQ_MSG_CLOSE: return "CLOSE";
- case VCHIQ_MSG_DATA: return "DATA";
- case VCHIQ_MSG_BULK_RX: return "BULK_RX";
- case VCHIQ_MSG_BULK_TX: return "BULK_TX";
- case VCHIQ_MSG_BULK_RX_DONE: return "BULK_RX_DONE";
- case VCHIQ_MSG_BULK_TX_DONE: return "BULK_TX_DONE";
- case VCHIQ_MSG_PAUSE: return "PAUSE";
- case VCHIQ_MSG_RESUME: return "RESUME";
- case VCHIQ_MSG_REMOTE_USE: return "REMOTE_USE";
- case VCHIQ_MSG_REMOTE_RELEASE: return "REMOTE_RELEASE";
- case VCHIQ_MSG_REMOTE_USE_ACTIVE: return "REMOTE_USE_ACTIVE";
- }
- return "???";
-}
-
-static inline void
-set_service_state(struct vchiq_service *service, int newstate)
-{
- dev_dbg(service->state->dev, "core: %d: srv:%d %s->%s\n",
- service->state->id, service->localport,
- srvstate_names[service->srvstate],
- srvstate_names[newstate]);
- service->srvstate = newstate;
-}
-
-struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigned int handle)
-{
- int idx = handle & (VCHIQ_MAX_SERVICES - 1);
-
- return rcu_dereference(instance->state->services[idx]);
-}
-
-struct vchiq_service *
-find_service_by_handle(struct vchiq_instance *instance, unsigned int handle)
-{
- struct vchiq_service *service;
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
- service->handle == handle &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- rcu_read_unlock();
- dev_dbg(instance->state->dev, "core: Invalid service handle 0x%x\n", handle);
- return NULL;
-}
-
-struct vchiq_service *
-find_service_by_port(struct vchiq_state *state, unsigned int localport)
-{
- if (localport <= VCHIQ_PORT_MAX) {
- struct vchiq_service *service;
-
- rcu_read_lock();
- service = rcu_dereference(state->services[localport]);
- if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- rcu_read_unlock();
- }
- dev_dbg(state->dev, "core: Invalid port %u\n", localport);
- return NULL;
-}
-
-struct vchiq_service *
-find_service_for_instance(struct vchiq_instance *instance, unsigned int handle)
-{
- struct vchiq_service *service;
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
- service->handle == handle &&
- service->instance == instance &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- rcu_read_unlock();
- dev_dbg(instance->state->dev, "core: Invalid service handle 0x%x\n", handle);
- return NULL;
-}
-
-struct vchiq_service *
-find_closed_service_for_instance(struct vchiq_instance *instance, unsigned int handle)
-{
- struct vchiq_service *service;
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- if (service &&
- (service->srvstate == VCHIQ_SRVSTATE_FREE ||
- service->srvstate == VCHIQ_SRVSTATE_CLOSED) &&
- service->handle == handle &&
- service->instance == instance &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- rcu_read_unlock();
- dev_dbg(instance->state->dev, "core: Invalid service handle 0x%x\n", handle);
- return service;
-}
-
-struct vchiq_service *
-__next_service_by_instance(struct vchiq_state *state,
- struct vchiq_instance *instance,
- int *pidx)
-{
- struct vchiq_service *service = NULL;
- int idx = *pidx;
-
- while (idx < state->unused_service) {
- struct vchiq_service *srv;
-
- srv = rcu_dereference(state->services[idx]);
- idx++;
- if (srv && srv->srvstate != VCHIQ_SRVSTATE_FREE &&
- srv->instance == instance) {
- service = srv;
- break;
- }
- }
-
- *pidx = idx;
- return service;
-}
-
-struct vchiq_service *
-next_service_by_instance(struct vchiq_state *state,
- struct vchiq_instance *instance,
- int *pidx)
-{
- struct vchiq_service *service;
-
- rcu_read_lock();
- while (1) {
- service = __next_service_by_instance(state, instance, pidx);
- if (!service)
- break;
- if (kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- break;
- }
- }
- rcu_read_unlock();
- return service;
-}
-
-void
-vchiq_service_get(struct vchiq_service *service)
-{
- if (!service) {
- WARN(1, "%s service is NULL\n", __func__);
- return;
- }
- kref_get(&service->ref_count);
-}
-
-static void service_release(struct kref *kref)
-{
- struct vchiq_service *service =
- container_of(kref, struct vchiq_service, ref_count);
- struct vchiq_state *state = service->state;
-
- WARN_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
- rcu_assign_pointer(state->services[service->localport], NULL);
- if (service->userdata_term)
- service->userdata_term(service->base.userdata);
- kfree_rcu(service, rcu);
-}
-
-void
-vchiq_service_put(struct vchiq_service *service)
-{
- if (!service) {
- WARN(1, "%s: service is NULL\n", __func__);
- return;
- }
- kref_put(&service->ref_count, service_release);
-}
-
-int
-vchiq_get_client_id(struct vchiq_instance *instance, unsigned int handle)
-{
- struct vchiq_service *service;
- int id;
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- id = service ? service->client_id : 0;
- rcu_read_unlock();
- return id;
-}
-
-void *
-vchiq_get_service_userdata(struct vchiq_instance *instance, unsigned int handle)
-{
- void *userdata;
- struct vchiq_service *service;
-
- rcu_read_lock();
- service = handle_to_service(instance, handle);
- userdata = service ? service->base.userdata : NULL;
- rcu_read_unlock();
- return userdata;
-}
-EXPORT_SYMBOL(vchiq_get_service_userdata);
-
-static void
-mark_service_closing_internal(struct vchiq_service *service, int sh_thread)
-{
- struct vchiq_state *state = service->state;
- struct vchiq_service_quota *quota;
-
- service->closing = 1;
-
- /* Synchronise with other threads. */
- mutex_lock(&state->recycle_mutex);
- mutex_unlock(&state->recycle_mutex);
- if (!sh_thread || (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT)) {
- /*
- * If we're pausing then the slot_mutex is held until resume
- * by the slot handler. Therefore don't try to acquire this
- * mutex if we're the slot handler and in the pause sent state.
- * We don't need to in this case anyway.
- */
- mutex_lock(&state->slot_mutex);
- mutex_unlock(&state->slot_mutex);
- }
-
- /* Unblock any sending thread. */
- quota = &state->service_quotas[service->localport];
- complete(&quota->quota_event);
-}
-
-static void
-mark_service_closing(struct vchiq_service *service)
-{
- mark_service_closing_internal(service, 0);
-}
-
-static inline int
-make_service_callback(struct vchiq_service *service, enum vchiq_reason reason,
- struct vchiq_header *header, struct vchiq_bulk *bulk)
-{
- void *cb_data = NULL;
- void __user *cb_userdata = NULL;
- int status;
-
- /*
- * If a bulk transfer is in progress, pass bulk->cb_*data to the
- * callback function.
- */
- if (bulk) {
- cb_data = bulk->cb_data;
- cb_userdata = bulk->cb_userdata;
- }
-
- dev_dbg(service->state->dev, "core: %d: callback:%d (%s, %p, %p %p)\n",
- service->state->id, service->localport, reason_names[reason],
- header, cb_data, cb_userdata);
- status = service->base.callback(service->instance, reason, header, service->handle,
- cb_data, cb_userdata);
- if (status && (status != -EAGAIN)) {
- dev_warn(service->state->dev,
- "core: %d: ignoring ERROR from callback to service %x\n",
- service->state->id, service->handle);
- status = 0;
- }
-
- if (reason != VCHIQ_MESSAGE_AVAILABLE)
- vchiq_release_message(service->instance, service->handle, header);
-
- return status;
-}
-
-inline void
-vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newstate)
-{
- enum vchiq_connstate oldstate = state->conn_state;
-
- dev_dbg(state->dev, "core: %d: %s->%s\n",
- state->id, conn_state_names[oldstate], conn_state_names[newstate]);
- state->conn_state = newstate;
- vchiq_platform_conn_state_changed(state, oldstate, newstate);
-}
-
-/* This initialises a single remote_event, and the associated wait_queue. */
-static inline void
-remote_event_create(wait_queue_head_t *wq, struct remote_event *event)
-{
- event->armed = 0;
- /*
- * Don't clear the 'fired' flag because it may already have been set
- * by the other side.
- */
- init_waitqueue_head(wq);
-}
-
-/*
- * All the event waiting routines in VCHIQ used a custom semaphore
- * implementation that filtered most signals. This achieved a behaviour similar
- * to the "killable" family of functions. While cleaning up this code all the
- * routines where switched to the "interruptible" family of functions, as the
- * former was deemed unjustified and the use "killable" set all VCHIQ's
- * threads in D state.
- *
- * Returns: 0 on success, a negative error code on failure
- */
-static inline int
-remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
-{
- int ret = 0;
-
- if (!event->fired) {
- event->armed = 1;
- dsb(sy);
- ret = wait_event_interruptible(*wq, event->fired);
- if (ret) {
- event->armed = 0;
- return ret;
- }
- event->armed = 0;
- /* Ensure that the peer sees that we are not waiting (armed == 0). */
- wmb();
- }
-
- event->fired = 0;
- return ret;
-}
-
-static void
-remote_event_signal(struct vchiq_state *state, struct remote_event *event)
-{
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(state->dev);
-
- /*
- * Ensure that all writes to shared data structures have completed
- * before signalling the peer.
- */
- wmb();
-
- event->fired = 1;
-
- dsb(sy); /* data barrier operation */
-
- if (event->armed)
- writel(0, mgmt->regs + BELL2); /* trigger vc interrupt */
-}
-
-/*
- * Acknowledge that the event has been signalled, and wake any waiters. Usually
- * called as a result of the doorbell being rung.
- */
-static inline void
-remote_event_signal_local(wait_queue_head_t *wq, struct remote_event *event)
-{
- event->fired = 1;
- event->armed = 0;
- wake_up_all(wq);
-}
-
-/* Check if a single event has been signalled, waking the waiters if it has. */
-static inline void
-remote_event_poll(wait_queue_head_t *wq, struct remote_event *event)
-{
- if (event->fired && event->armed)
- remote_event_signal_local(wq, event);
-}
-
-/*
- * VCHIQ used a small, fixed number of remote events. It is simplest to
- * enumerate them here for polling.
- */
-void
-remote_event_pollall(struct vchiq_state *state)
-{
- remote_event_poll(&state->sync_trigger_event, &state->local->sync_trigger);
- remote_event_poll(&state->sync_release_event, &state->local->sync_release);
- remote_event_poll(&state->trigger_event, &state->local->trigger);
- remote_event_poll(&state->recycle_event, &state->local->recycle);
-}
-
-/*
- * Round up message sizes so that any space at the end of a slot is always big
- * enough for a header. This relies on header size being a power of two, which
- * has been verified earlier by a static assertion.
- */
-
-static inline size_t
-calc_stride(size_t size)
-{
- /* Allow room for the header */
- size += sizeof(struct vchiq_header);
-
- /* Round up */
- return (size + sizeof(struct vchiq_header) - 1) &
- ~(sizeof(struct vchiq_header) - 1);
-}
-
-/* Called by the slot handler thread */
-static struct vchiq_service *
-get_listening_service(struct vchiq_state *state, int fourcc)
-{
- int i;
-
- WARN_ON(fourcc == VCHIQ_FOURCC_INVALID);
-
- rcu_read_lock();
- for (i = 0; i < state->unused_service; i++) {
- struct vchiq_service *service;
-
- service = rcu_dereference(state->services[i]);
- if (service &&
- service->public_fourcc == fourcc &&
- (service->srvstate == VCHIQ_SRVSTATE_LISTENING ||
- (service->srvstate == VCHIQ_SRVSTATE_OPEN &&
- service->remoteport == VCHIQ_PORT_FREE)) &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- }
- rcu_read_unlock();
- return NULL;
-}
-
-/* Called by the slot handler thread */
-static struct vchiq_service *
-get_connected_service(struct vchiq_state *state, unsigned int port)
-{
- int i;
-
- rcu_read_lock();
- for (i = 0; i < state->unused_service; i++) {
- struct vchiq_service *service =
- rcu_dereference(state->services[i]);
-
- if (service && service->srvstate == VCHIQ_SRVSTATE_OPEN &&
- service->remoteport == port &&
- kref_get_unless_zero(&service->ref_count)) {
- service = rcu_pointer_handoff(service);
- rcu_read_unlock();
- return service;
- }
- }
- rcu_read_unlock();
- return NULL;
-}
-
-inline void
-request_poll(struct vchiq_state *state, struct vchiq_service *service,
- int poll_type)
-{
- u32 value;
- int index;
-
- if (!service)
- goto skip_service;
-
- do {
- value = atomic_read(&service->poll_flags);
- } while (atomic_cmpxchg(&service->poll_flags, value,
- value | BIT(poll_type)) != value);
-
- index = BITSET_WORD(service->localport);
- do {
- value = atomic_read(&state->poll_services[index]);
- } while (atomic_cmpxchg(&state->poll_services[index],
- value, value | BIT(service->localport & 0x1f)) != value);
-
-skip_service:
- state->poll_needed = 1;
- /* Ensure the slot handler thread sees the poll_needed flag. */
- wmb();
-
- /* ... and ensure the slot handler runs. */
- remote_event_signal_local(&state->trigger_event, &state->local->trigger);
-}
-
-/*
- * Called from queue_message, by the slot handler and application threads,
- * with slot_mutex held
- */
-static struct vchiq_header *
-reserve_space(struct vchiq_state *state, size_t space, int is_blocking)
-{
- struct vchiq_shared_state *local = state->local;
- int tx_pos = state->local_tx_pos;
- int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK);
-
- if (space > slot_space) {
- struct vchiq_header *header;
- /* Fill the remaining space with padding */
- WARN_ON(!state->tx_data);
- header = (struct vchiq_header *)
- (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
- header->msgid = VCHIQ_MSGID_PADDING;
- header->size = slot_space - sizeof(struct vchiq_header);
-
- tx_pos += slot_space;
- }
-
- /* If necessary, get the next slot. */
- if ((tx_pos & VCHIQ_SLOT_MASK) == 0) {
- int slot_index;
-
- /* If there is no free slot... */
-
- if (!try_wait_for_completion(&state->slot_available_event)) {
- /* ...wait for one. */
-
- VCHIQ_STATS_INC(state, slot_stalls);
-
- /* But first, flush through the last slot. */
- state->local_tx_pos = tx_pos;
- local->tx_pos = tx_pos;
- remote_event_signal(state, &state->remote->trigger);
-
- if (!is_blocking ||
- (wait_for_completion_interruptible(&state->slot_available_event)))
- return NULL; /* No space available */
- }
-
- if (tx_pos == (state->slot_queue_available * VCHIQ_SLOT_SIZE)) {
- complete(&state->slot_available_event);
- dev_warn(state->dev, "%s: invalid tx_pos: %d\n",
- __func__, tx_pos);
- return NULL;
- }
-
- slot_index = local->slot_queue[SLOT_QUEUE_INDEX_FROM_POS_MASKED(tx_pos)];
- state->tx_data =
- (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
- }
-
- state->local_tx_pos = tx_pos + space;
-
- return (struct vchiq_header *)(state->tx_data +
- (tx_pos & VCHIQ_SLOT_MASK));
-}
-
-static void
-process_free_data_message(struct vchiq_state *state, u32 *service_found,
- struct vchiq_header *header)
-{
- int msgid = header->msgid;
- int port = VCHIQ_MSG_SRCPORT(msgid);
- struct vchiq_service_quota *quota = &state->service_quotas[port];
- int count;
-
- spin_lock(&state->quota_spinlock);
- count = quota->message_use_count;
- if (count > 0)
- quota->message_use_count = count - 1;
- spin_unlock(&state->quota_spinlock);
-
- if (count == quota->message_quota) {
- /*
- * Signal the service that it
- * has dropped below its quota
- */
- complete(&quota->quota_event);
- } else if (count == 0) {
- dev_err(state->dev,
- "core: service %d message_use_count=%d (header %p, msgid %x, header->msgid %x, header->size %x)\n",
- port, quota->message_use_count, header, msgid,
- header->msgid, header->size);
- WARN(1, "invalid message use count\n");
- }
- if (!BITSET_IS_SET(service_found, port)) {
- /* Set the found bit for this service */
- BITSET_SET(service_found, port);
-
- spin_lock(&state->quota_spinlock);
- count = quota->slot_use_count;
- if (count > 0)
- quota->slot_use_count = count - 1;
- spin_unlock(&state->quota_spinlock);
-
- if (count > 0) {
- /*
- * Signal the service in case
- * it has dropped below its quota
- */
- complete(&quota->quota_event);
- dev_dbg(state->dev, "core: %d: pfq:%d %x@%p - slot_use->%d\n",
- state->id, port, header->size, header, count - 1);
- } else {
- dev_err(state->dev,
- "core: service %d slot_use_count=%d (header %p, msgid %x, header->msgid %x, header->size %x)\n",
- port, count, header, msgid, header->msgid, header->size);
- WARN(1, "bad slot use count\n");
- }
- }
-}
-
-/* Called by the recycle thread. */
-static void
-process_free_queue(struct vchiq_state *state, u32 *service_found,
- size_t length)
-{
- struct vchiq_shared_state *local = state->local;
- int slot_queue_available;
-
- /*
- * Find slots which have been freed by the other side, and return them
- * to the available queue.
- */
- slot_queue_available = state->slot_queue_available;
-
- /*
- * Use a memory barrier to ensure that any state that may have been
- * modified by another thread is not masked by stale prefetched
- * values.
- */
- mb();
-
- while (slot_queue_available != local->slot_queue_recycle) {
- unsigned int pos;
- int slot_index = local->slot_queue[slot_queue_available &
- VCHIQ_SLOT_QUEUE_MASK];
- char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
- int data_found = 0;
-
- slot_queue_available++;
- /*
- * Beware of the address dependency - data is calculated
- * using an index written by the other side.
- */
- rmb();
-
- dev_dbg(state->dev, "core: %d: pfq %d=%p %x %x\n",
- state->id, slot_index, data, local->slot_queue_recycle,
- slot_queue_available);
-
- /* Initialise the bitmask for services which have used this slot */
- memset(service_found, 0, length);
-
- pos = 0;
-
- while (pos < VCHIQ_SLOT_SIZE) {
- struct vchiq_header *header =
- (struct vchiq_header *)(data + pos);
- int msgid = header->msgid;
-
- if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) {
- process_free_data_message(state, service_found,
- header);
- data_found = 1;
- }
-
- pos += calc_stride(header->size);
- if (pos > VCHIQ_SLOT_SIZE) {
- dev_err(state->dev,
- "core: pfq - pos %x: header %p, msgid %x, header->msgid %x, header->size %x\n",
- pos, header, msgid, header->msgid, header->size);
- WARN(1, "invalid slot position\n");
- }
- }
-
- if (data_found) {
- int count;
-
- spin_lock(&state->quota_spinlock);
- count = state->data_use_count;
- if (count > 0)
- state->data_use_count = count - 1;
- spin_unlock(&state->quota_spinlock);
- if (count == state->data_quota)
- complete(&state->data_quota_event);
- }
-
- /*
- * Don't allow the slot to be reused until we are no
- * longer interested in it.
- */
- mb();
-
- state->slot_queue_available = slot_queue_available;
- complete(&state->slot_available_event);
- }
-}
-
-static ssize_t
-memcpy_copy_callback(void *context, void *dest, size_t offset, size_t maxsize)
-{
- memcpy(dest + offset, context + offset, maxsize);
- return maxsize;
-}
-
-static ssize_t
-copy_message_data(ssize_t (*copy_callback)(void *context, void *dest, size_t offset,
- size_t maxsize),
- void *context,
- void *dest,
- size_t size)
-{
- size_t pos = 0;
-
- while (pos < size) {
- ssize_t callback_result;
- size_t max_bytes = size - pos;
-
- callback_result = copy_callback(context, dest + pos, pos,
- max_bytes);
-
- if (callback_result < 0)
- return callback_result;
-
- if (!callback_result)
- return -EIO;
-
- if (callback_result > max_bytes)
- return -EIO;
-
- pos += callback_result;
- }
-
- return size;
-}
-
-/* Called by the slot handler and application threads */
-static int
-queue_message(struct vchiq_state *state, struct vchiq_service *service,
- int msgid,
- ssize_t (*copy_callback)(void *context, void *dest,
- size_t offset, size_t maxsize),
- void *context, size_t size, int flags)
-{
- struct vchiq_shared_state *local;
- struct vchiq_service_quota *quota = NULL;
- struct vchiq_header *header;
- int type = VCHIQ_MSG_TYPE(msgid);
- int svc_fourcc;
-
- size_t stride;
-
- local = state->local;
-
- stride = calc_stride(size);
-
- WARN_ON(stride > VCHIQ_SLOT_SIZE);
-
- if (!(flags & QMFLAGS_NO_MUTEX_LOCK) &&
- mutex_lock_killable(&state->slot_mutex))
- return -EINTR;
-
- if (type == VCHIQ_MSG_DATA) {
- int tx_end_index;
-
- if (!service) {
- WARN(1, "%s: service is NULL\n", __func__);
- mutex_unlock(&state->slot_mutex);
- return -EINVAL;
- }
-
- WARN_ON(flags & (QMFLAGS_NO_MUTEX_LOCK |
- QMFLAGS_NO_MUTEX_UNLOCK));
-
- if (service->closing) {
- /* The service has been closed */
- mutex_unlock(&state->slot_mutex);
- return -EHOSTDOWN;
- }
-
- quota = &state->service_quotas[service->localport];
-
- spin_lock(&state->quota_spinlock);
-
- /*
- * Ensure this service doesn't use more than its quota of
- * messages or slots
- */
- tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
-
- /*
- * Ensure data messages don't use more than their quota of
- * slots
- */
- while ((tx_end_index != state->previous_data_index) &&
- (state->data_use_count == state->data_quota)) {
- VCHIQ_STATS_INC(state, data_stalls);
- spin_unlock(&state->quota_spinlock);
- mutex_unlock(&state->slot_mutex);
-
- if (wait_for_completion_killable(&state->data_quota_event))
- return -EINTR;
-
- mutex_lock(&state->slot_mutex);
- spin_lock(&state->quota_spinlock);
- tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
- if ((tx_end_index == state->previous_data_index) ||
- (state->data_use_count < state->data_quota)) {
- /* Pass the signal on to other waiters */
- complete(&state->data_quota_event);
- break;
- }
- }
-
- while ((quota->message_use_count == quota->message_quota) ||
- ((tx_end_index != quota->previous_tx_index) &&
- (quota->slot_use_count == quota->slot_quota))) {
- spin_unlock(&state->quota_spinlock);
- dev_dbg(state->dev,
- "core: %d: qm:%d %s,%zx - quota stall (msg %d, slot %d)\n",
- state->id, service->localport, msg_type_str(type), size,
- quota->message_use_count, quota->slot_use_count);
- VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
- mutex_unlock(&state->slot_mutex);
- if (wait_for_completion_killable(&quota->quota_event))
- return -EINTR;
- if (service->closing)
- return -EHOSTDOWN;
- if (mutex_lock_killable(&state->slot_mutex))
- return -EINTR;
- if (service->srvstate != VCHIQ_SRVSTATE_OPEN) {
- /* The service has been closed */
- mutex_unlock(&state->slot_mutex);
- return -EHOSTDOWN;
- }
- spin_lock(&state->quota_spinlock);
- tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
- }
-
- spin_unlock(&state->quota_spinlock);
- }
-
- header = reserve_space(state, stride, flags & QMFLAGS_IS_BLOCKING);
-
- if (!header) {
- if (service)
- VCHIQ_SERVICE_STATS_INC(service, slot_stalls);
- /*
- * In the event of a failure, return the mutex to the
- * state it was in
- */
- if (!(flags & QMFLAGS_NO_MUTEX_LOCK))
- mutex_unlock(&state->slot_mutex);
- return -EAGAIN;
- }
-
- if (type == VCHIQ_MSG_DATA) {
- ssize_t callback_result;
- int tx_end_index;
- int slot_use_count;
-
- dev_dbg(state->dev, "core: %d: qm %s@%p,%zx (%d->%d)\n",
- state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
- VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
-
- WARN_ON(flags & (QMFLAGS_NO_MUTEX_LOCK |
- QMFLAGS_NO_MUTEX_UNLOCK));
-
- callback_result =
- copy_message_data(copy_callback, context,
- header->data, size);
-
- if (callback_result < 0) {
- mutex_unlock(&state->slot_mutex);
- VCHIQ_SERVICE_STATS_INC(service, error_count);
- return -EINVAL;
- }
-
- vchiq_log_dump_mem(state->dev, "Sent", 0,
- header->data,
- min_t(size_t, 16, callback_result));
-
- spin_lock(&state->quota_spinlock);
- quota->message_use_count++;
-
- tx_end_index =
- SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1);
-
- /*
- * If this transmission can't fit in the last slot used by any
- * service, the data_use_count must be increased.
- */
- if (tx_end_index != state->previous_data_index) {
- state->previous_data_index = tx_end_index;
- state->data_use_count++;
- }
-
- /*
- * If this isn't the same slot last used by this service,
- * the service's slot_use_count must be increased.
- */
- if (tx_end_index != quota->previous_tx_index) {
- quota->previous_tx_index = tx_end_index;
- slot_use_count = ++quota->slot_use_count;
- } else {
- slot_use_count = 0;
- }
-
- spin_unlock(&state->quota_spinlock);
-
- if (slot_use_count)
- dev_dbg(state->dev, "core: %d: qm:%d %s,%zx - slot_use->%d (hdr %p)\n",
- state->id, service->localport, msg_type_str(VCHIQ_MSG_TYPE(msgid)),
- size, slot_use_count, header);
-
- VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
- VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
- } else {
- dev_dbg(state->dev, "core: %d: qm %s@%p,%zx (%d->%d)\n",
- state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
- VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
- if (size != 0) {
- /*
- * It is assumed for now that this code path
- * only happens from calls inside this file.
- *
- * External callers are through the vchiq_queue_message
- * path which always sets the type to be VCHIQ_MSG_DATA
- *
- * At first glance this appears to be correct but
- * more review is needed.
- */
- copy_message_data(copy_callback, context,
- header->data, size);
- }
- VCHIQ_STATS_INC(state, ctrl_tx_count);
- }
-
- header->msgid = msgid;
- header->size = size;
-
- svc_fourcc = service ? service->base.fourcc
- : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
-
- dev_dbg(state->dev, "core_msg: Sent Msg %s(%u) to %p4cc s:%u d:%d len:%zu\n",
- msg_type_str(VCHIQ_MSG_TYPE(msgid)),
- VCHIQ_MSG_TYPE(msgid), &svc_fourcc,
- VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid), size);
-
- /* Make sure the new header is visible to the peer. */
- wmb();
-
- /* Make the new tx_pos visible to the peer. */
- local->tx_pos = state->local_tx_pos;
- wmb();
-
- if (service && (type == VCHIQ_MSG_CLOSE))
- set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
-
- if (!(flags & QMFLAGS_NO_MUTEX_UNLOCK))
- mutex_unlock(&state->slot_mutex);
-
- remote_event_signal(state, &state->remote->trigger);
-
- return 0;
-}
-
-/* Called by the slot handler and application threads */
-static int
-queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
- int msgid,
- ssize_t (*copy_callback)(void *context, void *dest,
- size_t offset, size_t maxsize),
- void *context, int size)
-{
- struct vchiq_shared_state *local;
- struct vchiq_header *header;
- ssize_t callback_result;
- int svc_fourcc;
- int ret;
-
- local = state->local;
-
- if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME &&
- mutex_lock_killable(&state->sync_mutex))
- return -EAGAIN;
-
- ret = remote_event_wait(&state->sync_release_event, &local->sync_release);
- if (ret)
- return ret;
-
- /* Ensure that reads don't overtake the remote_event_wait. */
- rmb();
-
- header = (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
- local->slot_sync);
-
- {
- int oldmsgid = header->msgid;
-
- if (oldmsgid != VCHIQ_MSGID_PADDING)
- dev_err(state->dev, "core: %d: qms - msgid %x, not PADDING\n",
- state->id, oldmsgid);
- }
-
- dev_dbg(state->dev, "sync: %d: qms %s@%p,%x (%d->%d)\n",
- state->id, msg_type_str(VCHIQ_MSG_TYPE(msgid)), header, size,
- VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid));
-
- callback_result = copy_message_data(copy_callback, context,
- header->data, size);
-
- if (callback_result < 0) {
- mutex_unlock(&state->slot_mutex);
- VCHIQ_SERVICE_STATS_INC(service, error_count);
- return -EINVAL;
- }
-
- if (service) {
- vchiq_log_dump_mem(state->dev, "Sent", 0,
- header->data,
- min_t(size_t, 16, callback_result));
-
- VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
- VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
- } else {
- VCHIQ_STATS_INC(state, ctrl_tx_count);
- }
-
- header->size = size;
- header->msgid = msgid;
-
- svc_fourcc = service ? service->base.fourcc
- : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
-
- dev_dbg(state->dev,
- "sync: Sent Sync Msg %s(%u) to %p4cc s:%u d:%d len:%d\n",
- msg_type_str(VCHIQ_MSG_TYPE(msgid)), VCHIQ_MSG_TYPE(msgid),
- &svc_fourcc, VCHIQ_MSG_SRCPORT(msgid),
- VCHIQ_MSG_DSTPORT(msgid), size);
-
- remote_event_signal(state, &state->remote->sync_trigger);
-
- if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
- mutex_unlock(&state->sync_mutex);
-
- return 0;
-}
-
-static inline void
-claim_slot(struct vchiq_slot_info *slot)
-{
- slot->use_count++;
-}
-
-static void
-release_slot(struct vchiq_state *state, struct vchiq_slot_info *slot_info,
- struct vchiq_header *header, struct vchiq_service *service)
-{
- mutex_lock(&state->recycle_mutex);
-
- if (header) {
- int msgid = header->msgid;
-
- if (((msgid & VCHIQ_MSGID_CLAIMED) == 0) || (service && service->closing)) {
- mutex_unlock(&state->recycle_mutex);
- return;
- }
-
- /* Rewrite the message header to prevent a double release */
- header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
- }
-
- slot_info->release_count++;
-
- if (slot_info->release_count == slot_info->use_count) {
- int slot_queue_recycle;
- /* Add to the freed queue */
-
- /*
- * A read barrier is necessary here to prevent speculative
- * fetches of remote->slot_queue_recycle from overtaking the
- * mutex.
- */
- rmb();
-
- slot_queue_recycle = state->remote->slot_queue_recycle;
- state->remote->slot_queue[slot_queue_recycle &
- VCHIQ_SLOT_QUEUE_MASK] =
- SLOT_INDEX_FROM_INFO(state, slot_info);
- state->remote->slot_queue_recycle = slot_queue_recycle + 1;
- dev_dbg(state->dev, "core: %d: %d - recycle->%x\n",
- state->id, SLOT_INDEX_FROM_INFO(state, slot_info),
- state->remote->slot_queue_recycle);
-
- /*
- * A write barrier is necessary, but remote_event_signal
- * contains one.
- */
- remote_event_signal(state, &state->remote->recycle);
- }
-
- mutex_unlock(&state->recycle_mutex);
-}
-
-static inline enum vchiq_reason
-get_bulk_reason(struct vchiq_bulk *bulk)
-{
- if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
- if (bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED)
- return VCHIQ_BULK_TRANSMIT_ABORTED;
-
- return VCHIQ_BULK_TRANSMIT_DONE;
- }
-
- if (bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED)
- return VCHIQ_BULK_RECEIVE_ABORTED;
-
- return VCHIQ_BULK_RECEIVE_DONE;
-}
-
-static int service_notify_bulk(struct vchiq_service *service,
- struct vchiq_bulk *bulk)
-{
- if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) {
- if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
- VCHIQ_SERVICE_STATS_INC(service, bulk_tx_count);
- VCHIQ_SERVICE_STATS_ADD(service, bulk_tx_bytes,
- bulk->actual);
- } else {
- VCHIQ_SERVICE_STATS_INC(service, bulk_rx_count);
- VCHIQ_SERVICE_STATS_ADD(service, bulk_rx_bytes,
- bulk->actual);
- }
- } else {
- VCHIQ_SERVICE_STATS_INC(service, bulk_aborted_count);
- }
-
- if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) {
- struct bulk_waiter *waiter;
-
- spin_lock(&service->state->bulk_waiter_spinlock);
- waiter = bulk->waiter;
- if (waiter) {
- waiter->actual = bulk->actual;
- complete(&waiter->event);
- }
- spin_unlock(&service->state->bulk_waiter_spinlock);
- } else if (bulk->mode == VCHIQ_BULK_MODE_CALLBACK) {
- enum vchiq_reason reason = get_bulk_reason(bulk);
-
- return make_service_callback(service, reason, NULL, bulk);
- }
-
- return 0;
-}
-
-/* Called by the slot handler - don't hold the bulk mutex */
-static int
-notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue,
- int retry_poll)
-{
- int status = 0;
-
- dev_dbg(service->state->dev,
- "core: %d: nb:%d %cx - p=%x rn=%x r=%x\n",
- service->state->id, service->localport,
- (queue == &service->bulk_tx) ? 't' : 'r',
- queue->process, queue->remote_notify, queue->remove);
-
- queue->remote_notify = queue->process;
-
- while (queue->remove != queue->remote_notify) {
- struct vchiq_bulk *bulk =
- &queue->bulks[BULK_INDEX(queue->remove)];
-
- /*
- * Only generate callbacks for non-dummy bulk
- * requests, and non-terminated services
- */
- if (bulk->dma_addr && service->instance) {
- status = service_notify_bulk(service, bulk);
- if (status == -EAGAIN)
- break;
- }
-
- queue->remove++;
- complete(&service->bulk_remove_event);
- }
- if (!retry_poll)
- status = 0;
-
- if (status == -EAGAIN)
- request_poll(service->state, service, (queue == &service->bulk_tx) ?
- VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
-
- return status;
-}
-
-static void
-poll_services_of_group(struct vchiq_state *state, int group)
-{
- u32 flags = atomic_xchg(&state->poll_services[group], 0);
- int i;
-
- for (i = 0; flags; i++) {
- struct vchiq_service *service;
- u32 service_flags;
-
- if ((flags & BIT(i)) == 0)
- continue;
-
- service = find_service_by_port(state, (group << 5) + i);
- flags &= ~BIT(i);
-
- if (!service)
- continue;
-
- service_flags = atomic_xchg(&service->poll_flags, 0);
- if (service_flags & BIT(VCHIQ_POLL_REMOVE)) {
- dev_dbg(state->dev, "core: %d: ps - remove %d<->%d\n",
- state->id, service->localport, service->remoteport);
-
- /*
- * Make it look like a client, because
- * it must be removed and not left in
- * the LISTENING state.
- */
- service->public_fourcc = VCHIQ_FOURCC_INVALID;
-
- if (vchiq_close_service_internal(service, NO_CLOSE_RECVD))
- request_poll(state, service, VCHIQ_POLL_REMOVE);
- } else if (service_flags & BIT(VCHIQ_POLL_TERMINATE)) {
- dev_dbg(state->dev, "core: %d: ps - terminate %d<->%d\n",
- state->id, service->localport, service->remoteport);
- if (vchiq_close_service_internal(service, NO_CLOSE_RECVD))
- request_poll(state, service, VCHIQ_POLL_TERMINATE);
- }
- if (service_flags & BIT(VCHIQ_POLL_TXNOTIFY))
- notify_bulks(service, &service->bulk_tx, RETRY_POLL);
- if (service_flags & BIT(VCHIQ_POLL_RXNOTIFY))
- notify_bulks(service, &service->bulk_rx, RETRY_POLL);
- vchiq_service_put(service);
- }
-}
-
-/* Called by the slot handler thread */
-static void
-poll_services(struct vchiq_state *state)
-{
- int group;
-
- for (group = 0; group < BITSET_SIZE(state->unused_service); group++)
- poll_services_of_group(state, group);
-}
-
-static void
-cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo)
-{
- if (pagelistinfo->scatterlist_mapped) {
- dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
- pagelistinfo->num_pages, pagelistinfo->dma_dir);
- }
-
- if (pagelistinfo->pages_need_release)
- unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages);
-
- dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size,
- pagelistinfo->pagelist, pagelistinfo->dma_addr);
-}
-
-static inline bool
-is_adjacent_block(u32 *addrs, dma_addr_t addr, unsigned int k)
-{
- u32 tmp;
-
- if (!k)
- return false;
-
- tmp = (addrs[k - 1] & PAGE_MASK) +
- (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT);
-
- return tmp == (addr & PAGE_MASK);
-}
-
-/* There is a potential problem with partial cache lines (pages?)
- * at the ends of the block when reading. If the CPU accessed anything in
- * the same line (page?) then it may have pulled old data into the cache,
- * obscuring the new data underneath. We can solve this by transferring the
- * partial cache lines separately, and allowing the ARM to copy into the
- * cached area.
- */
-static struct vchiq_pagelist_info *
-create_pagelist(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
-{
- struct vchiq_drv_mgmt *drv_mgmt;
- struct pagelist *pagelist;
- struct vchiq_pagelist_info *pagelistinfo;
- struct page **pages;
- u32 *addrs;
- unsigned int num_pages, offset, i, k;
- int actual_pages;
- size_t pagelist_size;
- struct scatterlist *scatterlist, *sg;
- int dma_buffers;
- unsigned int cache_line_size;
- dma_addr_t dma_addr;
- size_t count = bulk->size;
- unsigned short type = (bulk->dir == VCHIQ_BULK_RECEIVE)
- ? PAGELIST_READ : PAGELIST_WRITE;
-
- if (count >= INT_MAX - PAGE_SIZE)
- return NULL;
-
- drv_mgmt = dev_get_drvdata(instance->state->dev);
-
- if (bulk->offset)
- offset = (uintptr_t)bulk->offset & (PAGE_SIZE - 1);
- else
- offset = (uintptr_t)bulk->uoffset & (PAGE_SIZE - 1);
- num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE);
-
- if ((size_t)num_pages > (SIZE_MAX - sizeof(struct pagelist) -
- sizeof(struct vchiq_pagelist_info)) /
- (sizeof(u32) + sizeof(pages[0]) +
- sizeof(struct scatterlist)))
- return NULL;
-
- pagelist_size = sizeof(struct pagelist) +
- (num_pages * sizeof(u32)) +
- (num_pages * sizeof(pages[0]) +
- (num_pages * sizeof(struct scatterlist))) +
- sizeof(struct vchiq_pagelist_info);
-
- /* Allocate enough storage to hold the page pointers and the page
- * list
- */
- pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr,
- GFP_KERNEL);
-
- dev_dbg(instance->state->dev, "arm: %p\n", pagelist);
-
- if (!pagelist)
- return NULL;
-
- addrs = pagelist->addrs;
- pages = (struct page **)(addrs + num_pages);
- scatterlist = (struct scatterlist *)(pages + num_pages);
- pagelistinfo = (struct vchiq_pagelist_info *)
- (scatterlist + num_pages);
-
- pagelist->length = count;
- pagelist->type = type;
- pagelist->offset = offset;
-
- /* Populate the fields of the pagelistinfo structure */
- pagelistinfo->pagelist = pagelist;
- pagelistinfo->pagelist_buffer_size = pagelist_size;
- pagelistinfo->dma_addr = dma_addr;
- pagelistinfo->dma_dir = (type == PAGELIST_WRITE) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
- pagelistinfo->num_pages = num_pages;
- pagelistinfo->pages_need_release = 0;
- pagelistinfo->pages = pages;
- pagelistinfo->scatterlist = scatterlist;
- pagelistinfo->scatterlist_mapped = 0;
-
- if (bulk->offset) {
- unsigned long length = count;
- unsigned int off = offset;
-
- for (actual_pages = 0; actual_pages < num_pages;
- actual_pages++) {
- struct page *pg =
- vmalloc_to_page(((unsigned int *)bulk->offset +
- (actual_pages * PAGE_SIZE)));
- size_t bytes = PAGE_SIZE - off;
-
- if (!pg) {
- cleanup_pagelistinfo(instance, pagelistinfo);
- return NULL;
- }
-
- if (bytes > length)
- bytes = length;
- pages[actual_pages] = pg;
- length -= bytes;
- off = 0;
- }
- /* do not try and release vmalloc pages */
- } else {
- actual_pages =
- pin_user_pages_fast((unsigned long)bulk->uoffset & PAGE_MASK, num_pages,
- type == PAGELIST_READ, pages);
-
- if (actual_pages != num_pages) {
- dev_dbg(instance->state->dev, "arm: Only %d/%d pages locked\n",
- actual_pages, num_pages);
-
- /* This is probably due to the process being killed */
- if (actual_pages > 0)
- unpin_user_pages(pages, actual_pages);
- cleanup_pagelistinfo(instance, pagelistinfo);
- return NULL;
- }
- /* release user pages */
- pagelistinfo->pages_need_release = 1;
- }
-
- /*
- * Initialize the scatterlist so that the magic cookie
- * is filled if debugging is enabled
- */
- sg_init_table(scatterlist, num_pages);
- /* Now set the pages for each scatterlist */
- for (i = 0; i < num_pages; i++) {
- unsigned int len = PAGE_SIZE - offset;
-
- if (len > count)
- len = count;
- sg_set_page(scatterlist + i, pages[i], len, offset);
- offset = 0;
- count -= len;
- }
-
- dma_buffers = dma_map_sg(instance->state->dev,
- scatterlist,
- num_pages,
- pagelistinfo->dma_dir);
-
- if (dma_buffers == 0) {
- cleanup_pagelistinfo(instance, pagelistinfo);
- return NULL;
- }
-
- pagelistinfo->scatterlist_mapped = 1;
-
- /* Combine adjacent blocks for performance */
- k = 0;
- for_each_sg(scatterlist, sg, dma_buffers, i) {
- unsigned int len = sg_dma_len(sg);
- dma_addr_t addr = sg_dma_address(sg);
-
- /* Note: addrs is the address + page_count - 1
- * The firmware expects blocks after the first to be page-
- * aligned and a multiple of the page size
- */
- WARN_ON(len == 0);
- WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
- WARN_ON(i && (addr & ~PAGE_MASK));
- if (is_adjacent_block(addrs, addr, k))
- addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT);
- else
- addrs[k++] = (addr & PAGE_MASK) |
- (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1);
- }
-
- /* Partial cache lines (fragments) require special measures */
- cache_line_size = drv_mgmt->info->cache_line_size;
- if ((type == PAGELIST_READ) &&
- ((pagelist->offset & (cache_line_size - 1)) ||
- ((pagelist->offset + pagelist->length) & (cache_line_size - 1)))) {
- char *fragments;
-
- if (down_interruptible(&drv_mgmt->free_fragments_sema)) {
- cleanup_pagelistinfo(instance, pagelistinfo);
- return NULL;
- }
-
- WARN_ON(!drv_mgmt->free_fragments);
-
- down(&drv_mgmt->free_fragments_mutex);
- fragments = drv_mgmt->free_fragments;
- WARN_ON(!fragments);
- drv_mgmt->free_fragments = *(char **)drv_mgmt->free_fragments;
- up(&drv_mgmt->free_fragments_mutex);
- pagelist->type = PAGELIST_READ_WITH_FRAGMENTS +
- (fragments - drv_mgmt->fragments_base) / drv_mgmt->fragments_size;
- }
-
- return pagelistinfo;
-}
-
-static void
-free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo,
- int actual)
-{
- struct vchiq_drv_mgmt *drv_mgmt;
- struct pagelist *pagelist = pagelistinfo->pagelist;
- struct page **pages = pagelistinfo->pages;
- unsigned int num_pages = pagelistinfo->num_pages;
- unsigned int cache_line_size;
-
- dev_dbg(instance->state->dev, "arm: %p, %d\n", pagelistinfo->pagelist, actual);
-
- drv_mgmt = dev_get_drvdata(instance->state->dev);
-
- /*
- * NOTE: dma_unmap_sg must be called before the
- * cpu can touch any of the data/pages.
- */
- dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
- pagelistinfo->num_pages, pagelistinfo->dma_dir);
- pagelistinfo->scatterlist_mapped = 0;
-
- /* Deal with any partial cache lines (fragments) */
- cache_line_size = drv_mgmt->info->cache_line_size;
- if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS && drv_mgmt->fragments_base) {
- char *fragments = drv_mgmt->fragments_base +
- (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) *
- drv_mgmt->fragments_size;
- int head_bytes, tail_bytes;
-
- head_bytes = (cache_line_size - pagelist->offset) &
- (cache_line_size - 1);
- tail_bytes = (pagelist->offset + actual) &
- (cache_line_size - 1);
-
- if ((actual >= 0) && (head_bytes != 0)) {
- if (head_bytes > actual)
- head_bytes = actual;
-
- memcpy_to_page(pages[0], pagelist->offset,
- fragments, head_bytes);
- }
- if ((actual >= 0) && (head_bytes < actual) &&
- (tail_bytes != 0))
- memcpy_to_page(pages[num_pages - 1],
- (pagelist->offset + actual) &
- (PAGE_SIZE - 1) & ~(cache_line_size - 1),
- fragments + cache_line_size,
- tail_bytes);
-
- down(&drv_mgmt->free_fragments_mutex);
- *(char **)fragments = drv_mgmt->free_fragments;
- drv_mgmt->free_fragments = fragments;
- up(&drv_mgmt->free_fragments_mutex);
- up(&drv_mgmt->free_fragments_sema);
- }
-
- /* Need to mark all the pages dirty. */
- if (pagelist->type != PAGELIST_WRITE &&
- pagelistinfo->pages_need_release) {
- unsigned int i;
-
- for (i = 0; i < num_pages; i++)
- set_page_dirty(pages[i]);
- }
-
- cleanup_pagelistinfo(instance, pagelistinfo);
-}
-
-static int
-vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
-{
- struct vchiq_pagelist_info *pagelistinfo;
-
- pagelistinfo = create_pagelist(instance, bulk);
-
- if (!pagelistinfo)
- return -ENOMEM;
-
- bulk->dma_addr = pagelistinfo->dma_addr;
-
- /*
- * Store the pagelistinfo address in remote_data,
- * which isn't used by the slave.
- */
- bulk->remote_data = pagelistinfo;
-
- return 0;
-}
-
-static void
-vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
-{
- if (bulk && bulk->remote_data && bulk->actual)
- free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data,
- bulk->actual);
-}
-
-/* Called with the bulk_mutex held */
-static void
-abort_outstanding_bulks(struct vchiq_service *service,
- struct vchiq_bulk_queue *queue)
-{
- int is_tx = (queue == &service->bulk_tx);
-
- dev_dbg(service->state->dev,
- "core: %d: aob:%d %cx - li=%x ri=%x p=%x\n",
- service->state->id, service->localport,
- is_tx ? 't' : 'r', queue->local_insert,
- queue->remote_insert, queue->process);
-
- WARN_ON((int)(queue->local_insert - queue->process) < 0);
- WARN_ON((int)(queue->remote_insert - queue->process) < 0);
-
- while ((queue->process != queue->local_insert) ||
- (queue->process != queue->remote_insert)) {
- struct vchiq_bulk *bulk = &queue->bulks[BULK_INDEX(queue->process)];
-
- if (queue->process == queue->remote_insert) {
- /* fabricate a matching dummy bulk */
- bulk->remote_data = NULL;
- bulk->remote_size = 0;
- queue->remote_insert++;
- }
-
- if (queue->process != queue->local_insert) {
- vchiq_complete_bulk(service->instance, bulk);
-
- dev_dbg(service->state->dev,
- "core_msg: %s %p4cc d:%d ABORTED - tx len:%d, rx len:%d\n",
- is_tx ? "Send Bulk to" : "Recv Bulk from",
- &service->base.fourcc,
- service->remoteport, bulk->size, bulk->remote_size);
- } else {
- /* fabricate a matching dummy bulk */
- bulk->dma_addr = 0;
- bulk->size = 0;
- bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
- bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT :
- VCHIQ_BULK_RECEIVE;
- queue->local_insert++;
- }
-
- queue->process++;
- }
-}
-
-static int
-parse_open(struct vchiq_state *state, struct vchiq_header *header)
-{
- const struct vchiq_open_payload *payload;
- struct vchiq_openack_payload ack_payload;
- struct vchiq_service *service = NULL;
- int msgid, size;
- int openack_id;
- unsigned int localport, remoteport, fourcc;
- short version, version_min;
-
- msgid = header->msgid;
- size = header->size;
- localport = VCHIQ_MSG_DSTPORT(msgid);
- remoteport = VCHIQ_MSG_SRCPORT(msgid);
- if (size < sizeof(struct vchiq_open_payload))
- goto fail_open;
-
- payload = (struct vchiq_open_payload *)header->data;
- fourcc = payload->fourcc;
- dev_dbg(state->dev, "core: %d: prs OPEN@%p (%d->'%p4cc')\n",
- state->id, header, localport, &fourcc);
-
- service = get_listening_service(state, fourcc);
- if (!service)
- goto fail_open;
-
- /* A matching service exists */
- version = payload->version;
- version_min = payload->version_min;
-
- if ((service->version < version_min) || (version < service->version_min)) {
- /* Version mismatch */
- dev_err(state->dev, "%d: service %d (%p4cc) version mismatch - local (%d, min %d) vs. remote (%d, min %d)",
- state->id, service->localport, &fourcc,
- service->version, service->version_min, version, version_min);
- vchiq_service_put(service);
- service = NULL;
- goto fail_open;
- }
- service->peer_version = version;
-
- if (service->srvstate != VCHIQ_SRVSTATE_LISTENING)
- goto done;
-
- ack_payload.version = service->version;
- openack_id = MAKE_OPENACK(service->localport, remoteport);
-
- if (state->version_common < VCHIQ_VERSION_SYNCHRONOUS_MODE)
- service->sync = 0;
-
- /* Acknowledge the OPEN */
- if (service->sync) {
- if (queue_message_sync(state, NULL, openack_id,
- memcpy_copy_callback,
- &ack_payload,
- sizeof(ack_payload)) == -EAGAIN)
- goto bail_not_ready;
-
- /* The service is now open */
- set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC);
- } else {
- if (queue_message(state, NULL, openack_id,
- memcpy_copy_callback, &ack_payload,
- sizeof(ack_payload), 0) == -EINTR)
- goto bail_not_ready;
-
- /* The service is now open */
- set_service_state(service, VCHIQ_SRVSTATE_OPEN);
- }
-
-done:
- /* Success - the message has been dealt with */
- vchiq_service_put(service);
- return 1;
-
-fail_open:
- /* No available service, or an invalid request - send a CLOSE */
- if (queue_message(state, NULL, MAKE_CLOSE(0, VCHIQ_MSG_SRCPORT(msgid)),
- NULL, NULL, 0, 0) == -EINTR)
- goto bail_not_ready;
-
- return 1;
-
-bail_not_ready:
- if (service)
- vchiq_service_put(service);
-
- return 0;
-}
-
-/**
- * parse_message() - parses a single message from the rx slot
- * @state: vchiq state struct
- * @header: message header
- *
- * Context: Process context
- *
- * Return:
- * * >= 0 - size of the parsed message payload (without header)
- * * -EINVAL - fatal error occurred, bail out is required
- */
-static int
-parse_message(struct vchiq_state *state, struct vchiq_header *header)
-{
- struct vchiq_service *service = NULL;
- unsigned int localport, remoteport;
- int msgid, size, type, ret = -EINVAL;
- int svc_fourcc;
-
- DEBUG_INITIALISE(state->local);
-
- DEBUG_VALUE(PARSE_HEADER, (int)(long)header);
- msgid = header->msgid;
- DEBUG_VALUE(PARSE_MSGID, msgid);
- size = header->size;
- type = VCHIQ_MSG_TYPE(msgid);
- localport = VCHIQ_MSG_DSTPORT(msgid);
- remoteport = VCHIQ_MSG_SRCPORT(msgid);
-
- if (type != VCHIQ_MSG_DATA)
- VCHIQ_STATS_INC(state, ctrl_rx_count);
-
- switch (type) {
- case VCHIQ_MSG_OPENACK:
- case VCHIQ_MSG_CLOSE:
- case VCHIQ_MSG_DATA:
- case VCHIQ_MSG_BULK_RX:
- case VCHIQ_MSG_BULK_TX:
- case VCHIQ_MSG_BULK_RX_DONE:
- case VCHIQ_MSG_BULK_TX_DONE:
- service = find_service_by_port(state, localport);
- if ((!service ||
- ((service->remoteport != remoteport) &&
- (service->remoteport != VCHIQ_PORT_FREE))) &&
- (localport == 0) &&
- (type == VCHIQ_MSG_CLOSE)) {
- /*
- * This could be a CLOSE from a client which
- * hadn't yet received the OPENACK - look for
- * the connected service
- */
- if (service)
- vchiq_service_put(service);
- service = get_connected_service(state, remoteport);
- if (service)
- dev_warn(state->dev,
- "core: %d: prs %s@%p (%d->%d) - found connected service %d\n",
- state->id, msg_type_str(type), header,
- remoteport, localport, service->localport);
- }
-
- if (!service) {
- dev_err(state->dev,
- "core: %d: prs %s@%p (%d->%d) - invalid/closed service %d\n",
- state->id, msg_type_str(type), header, remoteport,
- localport, localport);
- goto skip_message;
- }
- break;
- default:
- break;
- }
-
- svc_fourcc = service ? service->base.fourcc
- : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
-
- dev_dbg(state->dev, "core_msg: Rcvd Msg %s(%u) from %p4cc s:%d d:%d len:%d\n",
- msg_type_str(type), type, &svc_fourcc, remoteport, localport, size);
- if (size > 0)
- vchiq_log_dump_mem(state->dev, "Rcvd", 0, header->data, min(16, size));
-
- if (((unsigned long)header & VCHIQ_SLOT_MASK) +
- calc_stride(size) > VCHIQ_SLOT_SIZE) {
- dev_err(state->dev, "core: header %p (msgid %x) - size %x too big for slot\n",
- header, (unsigned int)msgid, (unsigned int)size);
- WARN(1, "oversized for slot\n");
- }
-
- switch (type) {
- case VCHIQ_MSG_OPEN:
- WARN_ON(VCHIQ_MSG_DSTPORT(msgid));
- if (!parse_open(state, header))
- goto bail_not_ready;
- break;
- case VCHIQ_MSG_OPENACK:
- if (size >= sizeof(struct vchiq_openack_payload)) {
- const struct vchiq_openack_payload *payload =
- (struct vchiq_openack_payload *)
- header->data;
- service->peer_version = payload->version;
- }
- dev_dbg(state->dev,
- "core: %d: prs OPENACK@%p,%x (%d->%d) v:%d\n",
- state->id, header, size, remoteport, localport,
- service->peer_version);
- if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
- service->remoteport = remoteport;
- set_service_state(service, VCHIQ_SRVSTATE_OPEN);
- complete(&service->remove_event);
- } else {
- dev_err(state->dev, "core: OPENACK received in state %s\n",
- srvstate_names[service->srvstate]);
- }
- break;
- case VCHIQ_MSG_CLOSE:
- WARN_ON(size); /* There should be no data */
-
- dev_dbg(state->dev, "core: %d: prs CLOSE@%p (%d->%d)\n",
- state->id, header, remoteport, localport);
-
- mark_service_closing_internal(service, 1);
-
- if (vchiq_close_service_internal(service, CLOSE_RECVD) == -EAGAIN)
- goto bail_not_ready;
-
- dev_dbg(state->dev, "core: Close Service %p4cc s:%u d:%d\n",
- &service->base.fourcc, service->localport, service->remoteport);
- break;
- case VCHIQ_MSG_DATA:
- dev_dbg(state->dev, "core: %d: prs DATA@%p,%x (%d->%d)\n",
- state->id, header, size, remoteport, localport);
-
- if ((service->remoteport == remoteport) &&
- (service->srvstate == VCHIQ_SRVSTATE_OPEN)) {
- header->msgid = msgid | VCHIQ_MSGID_CLAIMED;
- claim_slot(state->rx_info);
- DEBUG_TRACE(PARSE_LINE);
- if (make_service_callback(service, VCHIQ_MESSAGE_AVAILABLE, header,
- NULL) == -EAGAIN) {
- DEBUG_TRACE(PARSE_LINE);
- goto bail_not_ready;
- }
- VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count);
- VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes, size);
- } else {
- VCHIQ_STATS_INC(state, error_count);
- }
- break;
- case VCHIQ_MSG_CONNECT:
- dev_dbg(state->dev, "core: %d: prs CONNECT@%p\n",
- state->id, header);
- state->version_common = ((struct vchiq_slot_zero *)
- state->slot_data)->version;
- complete(&state->connect);
- break;
- case VCHIQ_MSG_BULK_RX:
- case VCHIQ_MSG_BULK_TX:
- /*
- * We should never receive a bulk request from the
- * other side since we're not setup to perform as the
- * master.
- */
- WARN_ON(1);
- break;
- case VCHIQ_MSG_BULK_RX_DONE:
- case VCHIQ_MSG_BULK_TX_DONE:
- if ((service->remoteport == remoteport) &&
- (service->srvstate != VCHIQ_SRVSTATE_FREE)) {
- struct vchiq_bulk_queue *queue;
- struct vchiq_bulk *bulk;
-
- queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
- &service->bulk_rx : &service->bulk_tx;
-
- DEBUG_TRACE(PARSE_LINE);
- if (mutex_lock_killable(&service->bulk_mutex)) {
- DEBUG_TRACE(PARSE_LINE);
- goto bail_not_ready;
- }
- if ((int)(queue->remote_insert -
- queue->local_insert) >= 0) {
- dev_err(state->dev,
- "core: %d: prs %s@%p (%d->%d) unexpected (ri=%d,li=%d)\n",
- state->id, msg_type_str(type), header, remoteport,
- localport, queue->remote_insert, queue->local_insert);
- mutex_unlock(&service->bulk_mutex);
- break;
- }
- if (queue->process != queue->remote_insert) {
- dev_err(state->dev, "%s: p %x != ri %x\n",
- __func__, queue->process,
- queue->remote_insert);
- mutex_unlock(&service->bulk_mutex);
- goto bail_not_ready;
- }
-
- bulk = &queue->bulks[BULK_INDEX(queue->remote_insert)];
- bulk->actual = *(int *)header->data;
- queue->remote_insert++;
-
- dev_dbg(state->dev, "core: %d: prs %s@%p (%d->%d) %x@%pad\n",
- state->id, msg_type_str(type), header, remoteport,
- localport, bulk->actual, &bulk->dma_addr);
-
- dev_dbg(state->dev, "core: %d: prs:%d %cx li=%x ri=%x p=%x\n",
- state->id, localport,
- (type == VCHIQ_MSG_BULK_RX_DONE) ? 'r' : 't',
- queue->local_insert, queue->remote_insert, queue->process);
-
- DEBUG_TRACE(PARSE_LINE);
- WARN_ON(queue->process == queue->local_insert);
- vchiq_complete_bulk(service->instance, bulk);
- queue->process++;
- mutex_unlock(&service->bulk_mutex);
- DEBUG_TRACE(PARSE_LINE);
- notify_bulks(service, queue, RETRY_POLL);
- DEBUG_TRACE(PARSE_LINE);
- }
- break;
- case VCHIQ_MSG_PADDING:
- dev_dbg(state->dev, "core: %d: prs PADDING@%p,%x\n",
- state->id, header, size);
- break;
- case VCHIQ_MSG_PAUSE:
- /* If initiated, signal the application thread */
- dev_dbg(state->dev, "core: %d: prs PAUSE@%p,%x\n",
- state->id, header, size);
- if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
- dev_err(state->dev, "core: %d: PAUSE received in state PAUSED\n",
- state->id);
- break;
- }
- if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) {
- /* Send a PAUSE in response */
- if (queue_message(state, NULL, MAKE_PAUSE, NULL, NULL, 0,
- QMFLAGS_NO_MUTEX_UNLOCK) == -EINTR)
- goto bail_not_ready;
- }
- /* At this point slot_mutex is held */
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
- break;
- case VCHIQ_MSG_RESUME:
- dev_dbg(state->dev, "core: %d: prs RESUME@%p,%x\n",
- state->id, header, size);
- /* Release the slot mutex */
- mutex_unlock(&state->slot_mutex);
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
- break;
-
- case VCHIQ_MSG_REMOTE_USE:
- vchiq_on_remote_use(state);
- break;
- case VCHIQ_MSG_REMOTE_RELEASE:
- vchiq_on_remote_release(state);
- break;
- case VCHIQ_MSG_REMOTE_USE_ACTIVE:
- break;
-
- default:
- dev_err(state->dev, "core: %d: prs invalid msgid %x@%p,%x\n",
- state->id, msgid, header, size);
- WARN(1, "invalid message\n");
- break;
- }
-
-skip_message:
- ret = size;
-
-bail_not_ready:
- if (service)
- vchiq_service_put(service);
-
- return ret;
-}
-
-/* Called by the slot handler thread */
-static void
-parse_rx_slots(struct vchiq_state *state)
-{
- struct vchiq_shared_state *remote = state->remote;
- int tx_pos;
-
- DEBUG_INITIALISE(state->local);
-
- tx_pos = remote->tx_pos;
-
- while (state->rx_pos != tx_pos) {
- struct vchiq_header *header;
- int size;
-
- DEBUG_TRACE(PARSE_LINE);
- if (!state->rx_data) {
- int rx_index;
-
- WARN_ON(state->rx_pos & VCHIQ_SLOT_MASK);
- rx_index = remote->slot_queue[
- SLOT_QUEUE_INDEX_FROM_POS_MASKED(state->rx_pos)];
- state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state,
- rx_index);
- state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
-
- /*
- * Initialise use_count to one, and increment
- * release_count at the end of the slot to avoid
- * releasing the slot prematurely.
- */
- state->rx_info->use_count = 1;
- state->rx_info->release_count = 0;
- }
-
- header = (struct vchiq_header *)(state->rx_data +
- (state->rx_pos & VCHIQ_SLOT_MASK));
- size = parse_message(state, header);
- if (size < 0)
- return;
-
- state->rx_pos += calc_stride(size);
-
- DEBUG_TRACE(PARSE_LINE);
- /*
- * Perform some housekeeping when the end of the slot is
- * reached.
- */
- if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0) {
- /* Remove the extra reference count. */
- release_slot(state, state->rx_info, NULL, NULL);
- state->rx_data = NULL;
- }
- }
-}
-
-/**
- * handle_poll() - handle service polling and other rare conditions
- * @state: vchiq state struct
- *
- * Context: Process context
- *
- * Return:
- * * 0 - poll handled successful
- * * -EAGAIN - retry later
- */
-static int
-handle_poll(struct vchiq_state *state)
-{
- switch (state->conn_state) {
- case VCHIQ_CONNSTATE_CONNECTED:
- /* Poll the services as requested */
- poll_services(state);
- break;
-
- case VCHIQ_CONNSTATE_PAUSING:
- if (queue_message(state, NULL, MAKE_PAUSE, NULL, NULL, 0,
- QMFLAGS_NO_MUTEX_UNLOCK) != -EINTR) {
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSE_SENT);
- } else {
- /* Retry later */
- return -EAGAIN;
- }
- break;
-
- case VCHIQ_CONNSTATE_RESUMING:
- if (queue_message(state, NULL, MAKE_RESUME, NULL, NULL, 0,
- QMFLAGS_NO_MUTEX_LOCK) != -EINTR) {
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
- } else {
- /*
- * This should really be impossible,
- * since the PAUSE should have flushed
- * through outstanding messages.
- */
- dev_err(state->dev, "core: Failed to send RESUME message\n");
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/* Called by the slot handler thread */
-static int
-slot_handler_func(void *v)
-{
- struct vchiq_state *state = v;
- struct vchiq_shared_state *local = state->local;
- int ret;
-
- DEBUG_INITIALISE(local);
-
- while (!kthread_should_stop()) {
- DEBUG_COUNT(SLOT_HANDLER_COUNT);
- DEBUG_TRACE(SLOT_HANDLER_LINE);
- ret = remote_event_wait(&state->trigger_event, &local->trigger);
- if (ret)
- return ret;
-
- /* Ensure that reads don't overtake the remote_event_wait. */
- rmb();
-
- DEBUG_TRACE(SLOT_HANDLER_LINE);
- if (state->poll_needed) {
- state->poll_needed = 0;
-
- /*
- * Handle service polling and other rare conditions here
- * out of the mainline code
- */
- if (handle_poll(state) == -EAGAIN)
- state->poll_needed = 1;
- }
-
- DEBUG_TRACE(SLOT_HANDLER_LINE);
- parse_rx_slots(state);
- }
- return 0;
-}
-
-/* Called by the recycle thread */
-static int
-recycle_func(void *v)
-{
- struct vchiq_state *state = v;
- struct vchiq_shared_state *local = state->local;
- u32 *found;
- size_t length;
- int ret;
-
- length = sizeof(*found) * BITSET_SIZE(VCHIQ_MAX_SERVICES);
-
- found = kmalloc_array(BITSET_SIZE(VCHIQ_MAX_SERVICES), sizeof(*found),
- GFP_KERNEL);
- if (!found)
- return -ENOMEM;
-
- while (!kthread_should_stop()) {
- ret = remote_event_wait(&state->recycle_event, &local->recycle);
- if (ret)
- return ret;
-
- process_free_queue(state, found, length);
- }
- return 0;
-}
-
-/* Called by the sync thread */
-static int
-sync_func(void *v)
-{
- struct vchiq_state *state = v;
- struct vchiq_shared_state *local = state->local;
- struct vchiq_header *header =
- (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
- state->remote->slot_sync);
- int svc_fourcc;
- int ret;
-
- while (!kthread_should_stop()) {
- struct vchiq_service *service;
- int msgid, size;
- int type;
- unsigned int localport, remoteport;
-
- ret = remote_event_wait(&state->sync_trigger_event, &local->sync_trigger);
- if (ret)
- return ret;
-
- /* Ensure that reads don't overtake the remote_event_wait. */
- rmb();
-
- msgid = header->msgid;
- size = header->size;
- type = VCHIQ_MSG_TYPE(msgid);
- localport = VCHIQ_MSG_DSTPORT(msgid);
- remoteport = VCHIQ_MSG_SRCPORT(msgid);
-
- service = find_service_by_port(state, localport);
-
- if (!service) {
- dev_err(state->dev,
- "sync: %d: sf %s@%p (%d->%d) - invalid/closed service %d\n",
- state->id, msg_type_str(type), header, remoteport,
- localport, localport);
- release_message_sync(state, header);
- continue;
- }
-
- svc_fourcc = service->base.fourcc;
-
- dev_dbg(state->dev, "sync: Rcvd Msg %s from %p4cc s:%d d:%d len:%d\n",
- msg_type_str(type), &svc_fourcc, remoteport, localport, size);
- if (size > 0)
- vchiq_log_dump_mem(state->dev, "Rcvd", 0, header->data, min(16, size));
-
- switch (type) {
- case VCHIQ_MSG_OPENACK:
- if (size >= sizeof(struct vchiq_openack_payload)) {
- const struct vchiq_openack_payload *payload =
- (struct vchiq_openack_payload *)
- header->data;
- service->peer_version = payload->version;
- }
- dev_err(state->dev, "sync: %d: sf OPENACK@%p,%x (%d->%d) v:%d\n",
- state->id, header, size, remoteport, localport,
- service->peer_version);
- if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
- service->remoteport = remoteport;
- set_service_state(service, VCHIQ_SRVSTATE_OPENSYNC);
- service->sync = 1;
- complete(&service->remove_event);
- }
- release_message_sync(state, header);
- break;
-
- case VCHIQ_MSG_DATA:
- dev_dbg(state->dev, "sync: %d: sf DATA@%p,%x (%d->%d)\n",
- state->id, header, size, remoteport, localport);
-
- if ((service->remoteport == remoteport) &&
- (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC)) {
- if (make_service_callback(service, VCHIQ_MESSAGE_AVAILABLE, header,
- NULL) == -EAGAIN)
- dev_err(state->dev,
- "sync: error: synchronous callback to service %d returns -EAGAIN\n",
- localport);
- }
- break;
-
- default:
- dev_err(state->dev, "sync: error: %d: sf unexpected msgid %x@%p,%x\n",
- state->id, msgid, header, size);
- release_message_sync(state, header);
- break;
- }
-
- vchiq_service_put(service);
- }
-
- return 0;
-}
-
-inline const char *
-get_conn_state_name(enum vchiq_connstate conn_state)
-{
- return conn_state_names[conn_state];
-}
-
-struct vchiq_slot_zero *
-vchiq_init_slots(struct device *dev, void *mem_base, int mem_size)
-{
- int mem_align =
- (int)((VCHIQ_SLOT_SIZE - (long)mem_base) & VCHIQ_SLOT_MASK);
- struct vchiq_slot_zero *slot_zero =
- (struct vchiq_slot_zero *)(mem_base + mem_align);
- int num_slots = (mem_size - mem_align) / VCHIQ_SLOT_SIZE;
- int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS;
-
- check_sizes();
-
- /* Ensure there is enough memory to run an absolutely minimum system */
- num_slots -= first_data_slot;
-
- if (num_slots < 4) {
- dev_err(dev, "core: %s: Insufficient memory %x bytes\n",
- __func__, mem_size);
- return NULL;
- }
-
- memset(slot_zero, 0, sizeof(struct vchiq_slot_zero));
-
- slot_zero->magic = VCHIQ_MAGIC;
- slot_zero->version = VCHIQ_VERSION;
- slot_zero->version_min = VCHIQ_VERSION_MIN;
- slot_zero->slot_zero_size = sizeof(struct vchiq_slot_zero);
- slot_zero->slot_size = VCHIQ_SLOT_SIZE;
- slot_zero->max_slots = VCHIQ_MAX_SLOTS;
- slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE;
-
- slot_zero->master.slot_sync = first_data_slot;
- slot_zero->master.slot_first = first_data_slot + 1;
- slot_zero->master.slot_last = first_data_slot + (num_slots / 2) - 1;
- slot_zero->slave.slot_sync = first_data_slot + (num_slots / 2);
- slot_zero->slave.slot_first = first_data_slot + (num_slots / 2) + 1;
- slot_zero->slave.slot_last = first_data_slot + num_slots - 1;
-
- return slot_zero;
-}
-
-int
-vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, struct device *dev)
-{
- struct vchiq_shared_state *local;
- struct vchiq_shared_state *remote;
- char threadname[16];
- int i, ret;
-
- local = &slot_zero->slave;
- remote = &slot_zero->master;
-
- if (local->initialised) {
- if (remote->initialised)
- dev_err(dev, "local state has already been initialised\n");
- else
- dev_err(dev, "master/slave mismatch two slaves\n");
-
- return -EINVAL;
- }
-
- memset(state, 0, sizeof(struct vchiq_state));
-
- state->dev = dev;
-
- /*
- * initialize shared state pointers
- */
-
- state->local = local;
- state->remote = remote;
- state->slot_data = (struct vchiq_slot *)slot_zero;
-
- /*
- * initialize events and mutexes
- */
-
- init_completion(&state->connect);
- mutex_init(&state->mutex);
- mutex_init(&state->slot_mutex);
- mutex_init(&state->recycle_mutex);
- mutex_init(&state->sync_mutex);
-
- spin_lock_init(&state->msg_queue_spinlock);
- spin_lock_init(&state->bulk_waiter_spinlock);
- spin_lock_init(&state->quota_spinlock);
-
- init_completion(&state->slot_available_event);
- init_completion(&state->data_quota_event);
-
- state->slot_queue_available = 0;
-
- for (i = 0; i < VCHIQ_MAX_SERVICES; i++) {
- struct vchiq_service_quota *quota = &state->service_quotas[i];
-
- init_completion(&quota->quota_event);
- }
-
- for (i = local->slot_first; i <= local->slot_last; i++) {
- local->slot_queue[state->slot_queue_available] = i;
- state->slot_queue_available++;
- complete(&state->slot_available_event);
- }
-
- state->default_slot_quota = state->slot_queue_available / 2;
- state->default_message_quota =
- min_t(unsigned short, state->default_slot_quota * 256, ~0);
-
- state->previous_data_index = -1;
- state->data_use_count = 0;
- state->data_quota = state->slot_queue_available - 1;
-
- remote_event_create(&state->trigger_event, &local->trigger);
- local->tx_pos = 0;
- remote_event_create(&state->recycle_event, &local->recycle);
- local->slot_queue_recycle = state->slot_queue_available;
- remote_event_create(&state->sync_trigger_event, &local->sync_trigger);
- remote_event_create(&state->sync_release_event, &local->sync_release);
-
- /* At start-of-day, the slot is empty and available */
- ((struct vchiq_header *)
- SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid =
- VCHIQ_MSGID_PADDING;
- remote_event_signal_local(&state->sync_release_event, &local->sync_release);
-
- local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
-
- ret = vchiq_platform_init_state(state);
- if (ret)
- return ret;
-
- /*
- * bring up slot handler thread
- */
- snprintf(threadname, sizeof(threadname), "vchiq-slot/%d", state->id);
- state->slot_handler_thread = kthread_create(&slot_handler_func, (void *)state, threadname);
-
- if (IS_ERR(state->slot_handler_thread)) {
- dev_err(state->dev, "couldn't create thread %s\n", threadname);
- return PTR_ERR(state->slot_handler_thread);
- }
- set_user_nice(state->slot_handler_thread, -19);
-
- snprintf(threadname, sizeof(threadname), "vchiq-recy/%d", state->id);
- state->recycle_thread = kthread_create(&recycle_func, (void *)state, threadname);
- if (IS_ERR(state->recycle_thread)) {
- dev_err(state->dev, "couldn't create thread %s\n", threadname);
- ret = PTR_ERR(state->recycle_thread);
- goto fail_free_handler_thread;
- }
- set_user_nice(state->recycle_thread, -19);
-
- snprintf(threadname, sizeof(threadname), "vchiq-sync/%d", state->id);
- state->sync_thread = kthread_create(&sync_func, (void *)state, threadname);
- if (IS_ERR(state->sync_thread)) {
- dev_err(state->dev, "couldn't create thread %s\n", threadname);
- ret = PTR_ERR(state->sync_thread);
- goto fail_free_recycle_thread;
- }
- set_user_nice(state->sync_thread, -20);
-
- wake_up_process(state->slot_handler_thread);
- wake_up_process(state->recycle_thread);
- wake_up_process(state->sync_thread);
-
- /* Indicate readiness to the other side */
- local->initialised = 1;
-
- return 0;
-
-fail_free_recycle_thread:
- kthread_stop(state->recycle_thread);
-fail_free_handler_thread:
- kthread_stop(state->slot_handler_thread);
-
- return ret;
-}
-
-void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_header *header)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int pos;
-
- if (!service)
- return;
-
- while (service->msg_queue_write == service->msg_queue_read +
- VCHIQ_MAX_SLOTS) {
- if (wait_for_completion_interruptible(&service->msg_queue_pop))
- flush_signals(current);
- }
-
- pos = service->msg_queue_write & (VCHIQ_MAX_SLOTS - 1);
- service->msg_queue_write++;
- service->msg_queue[pos] = header;
-
- complete(&service->msg_queue_push);
-}
-EXPORT_SYMBOL(vchiq_msg_queue_push);
-
-struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- struct vchiq_header *header;
- int pos;
-
- if (!service)
- return NULL;
-
- if (service->msg_queue_write == service->msg_queue_read)
- return NULL;
-
- while (service->msg_queue_write == service->msg_queue_read) {
- if (wait_for_completion_interruptible(&service->msg_queue_push))
- flush_signals(current);
- }
-
- pos = service->msg_queue_read & (VCHIQ_MAX_SLOTS - 1);
- service->msg_queue_read++;
- header = service->msg_queue[pos];
-
- complete(&service->msg_queue_pop);
-
- return header;
-}
-EXPORT_SYMBOL(vchiq_msg_hold);
-
-static int vchiq_validate_params(struct vchiq_state *state,
- const struct vchiq_service_params_kernel *params)
-{
- if (!params->callback || !params->fourcc) {
- dev_err(state->dev, "Can't add service, invalid params\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Called from application thread when a client or server service is created. */
-struct vchiq_service *
-vchiq_add_service_internal(struct vchiq_state *state,
- const struct vchiq_service_params_kernel *params,
- int srvstate, struct vchiq_instance *instance,
- void (*userdata_term)(void *userdata))
-{
- struct vchiq_service *service;
- struct vchiq_service __rcu **pservice = NULL;
- struct vchiq_service_quota *quota;
- int ret;
- int i;
-
- ret = vchiq_validate_params(state, params);
- if (ret)
- return NULL;
-
- service = kzalloc(sizeof(*service), GFP_KERNEL);
- if (!service)
- return service;
-
- service->base.fourcc = params->fourcc;
- service->base.callback = params->callback;
- service->base.userdata = params->userdata;
- service->handle = VCHIQ_SERVICE_HANDLE_INVALID;
- kref_init(&service->ref_count);
- service->srvstate = VCHIQ_SRVSTATE_FREE;
- service->userdata_term = userdata_term;
- service->localport = VCHIQ_PORT_FREE;
- service->remoteport = VCHIQ_PORT_FREE;
-
- service->public_fourcc = (srvstate == VCHIQ_SRVSTATE_OPENING) ?
- VCHIQ_FOURCC_INVALID : params->fourcc;
- service->auto_close = 1;
- atomic_set(&service->poll_flags, 0);
- service->version = params->version;
- service->version_min = params->version_min;
- service->state = state;
- service->instance = instance;
- init_completion(&service->remove_event);
- init_completion(&service->bulk_remove_event);
- init_completion(&service->msg_queue_pop);
- init_completion(&service->msg_queue_push);
- mutex_init(&service->bulk_mutex);
-
- /*
- * Although it is perfectly possible to use a spinlock
- * to protect the creation of services, it is overkill as it
- * disables interrupts while the array is searched.
- * The only danger is of another thread trying to create a
- * service - service deletion is safe.
- * Therefore it is preferable to use state->mutex which,
- * although slower to claim, doesn't block interrupts while
- * it is held.
- */
-
- mutex_lock(&state->mutex);
-
- /* Prepare to use a previously unused service */
- if (state->unused_service < VCHIQ_MAX_SERVICES)
- pservice = &state->services[state->unused_service];
-
- if (srvstate == VCHIQ_SRVSTATE_OPENING) {
- for (i = 0; i < state->unused_service; i++) {
- if (!rcu_access_pointer(state->services[i])) {
- pservice = &state->services[i];
- break;
- }
- }
- } else {
- rcu_read_lock();
- for (i = (state->unused_service - 1); i >= 0; i--) {
- struct vchiq_service *srv;
-
- srv = rcu_dereference(state->services[i]);
- if (!srv) {
- pservice = &state->services[i];
- } else if ((srv->public_fourcc == params->fourcc) &&
- ((srv->instance != instance) ||
- (srv->base.callback != params->callback))) {
- /*
- * There is another server using this
- * fourcc which doesn't match.
- */
- pservice = NULL;
- break;
- }
- }
- rcu_read_unlock();
- }
-
- if (pservice) {
- service->localport = (pservice - state->services);
- if (!handle_seq)
- handle_seq = VCHIQ_MAX_STATES *
- VCHIQ_MAX_SERVICES;
- service->handle = handle_seq |
- (state->id * VCHIQ_MAX_SERVICES) |
- service->localport;
- handle_seq += VCHIQ_MAX_STATES * VCHIQ_MAX_SERVICES;
- rcu_assign_pointer(*pservice, service);
- if (pservice == &state->services[state->unused_service])
- state->unused_service++;
- }
-
- mutex_unlock(&state->mutex);
-
- if (!pservice) {
- kfree(service);
- return NULL;
- }
-
- quota = &state->service_quotas[service->localport];
- quota->slot_quota = state->default_slot_quota;
- quota->message_quota = state->default_message_quota;
- if (quota->slot_use_count == 0)
- quota->previous_tx_index =
- SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos)
- - 1;
-
- /* Bring this service online */
- set_service_state(service, srvstate);
-
- dev_dbg(state->dev, "core_msg: %s Service %p4cc SrcPort:%d\n",
- (srvstate == VCHIQ_SRVSTATE_OPENING) ? "Open" : "Add",
- &params->fourcc, service->localport);
-
- /* Don't unlock the service - leave it with a ref_count of 1. */
-
- return service;
-}
-
-int
-vchiq_open_service_internal(struct vchiq_service *service, int client_id)
-{
- struct vchiq_open_payload payload = {
- service->base.fourcc,
- client_id,
- service->version,
- service->version_min
- };
- int status = 0;
-
- service->client_id = client_id;
- vchiq_use_service_internal(service);
- status = queue_message(service->state,
- NULL, MAKE_OPEN(service->localport),
- memcpy_copy_callback,
- &payload,
- sizeof(payload),
- QMFLAGS_IS_BLOCKING);
-
- if (status)
- return status;
-
- /* Wait for the ACK/NAK */
- if (wait_for_completion_interruptible(&service->remove_event)) {
- status = -EAGAIN;
- vchiq_release_service_internal(service);
- } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) &&
- (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) {
- if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT)
- dev_err(service->state->dev,
- "core: %d: osi - srvstate = %s (ref %u)\n",
- service->state->id, srvstate_names[service->srvstate],
- kref_read(&service->ref_count));
- status = -EINVAL;
- VCHIQ_SERVICE_STATS_INC(service, error_count);
- vchiq_release_service_internal(service);
- }
-
- return status;
-}
-
-static void
-release_service_messages(struct vchiq_service *service)
-{
- struct vchiq_state *state = service->state;
- int slot_last = state->remote->slot_last;
- int i;
-
- /* Release any claimed messages aimed at this service */
-
- if (service->sync) {
- struct vchiq_header *header =
- (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
- state->remote->slot_sync);
- if (VCHIQ_MSG_DSTPORT(header->msgid) == service->localport)
- release_message_sync(state, header);
-
- return;
- }
-
- for (i = state->remote->slot_first; i <= slot_last; i++) {
- struct vchiq_slot_info *slot_info =
- SLOT_INFO_FROM_INDEX(state, i);
- unsigned int pos, end;
- char *data;
-
- if (slot_info->release_count == slot_info->use_count)
- continue;
-
- data = (char *)SLOT_DATA_FROM_INDEX(state, i);
- end = VCHIQ_SLOT_SIZE;
- if (data == state->rx_data)
- /*
- * This buffer is still being read from - stop
- * at the current read position
- */
- end = state->rx_pos & VCHIQ_SLOT_MASK;
-
- pos = 0;
-
- while (pos < end) {
- struct vchiq_header *header =
- (struct vchiq_header *)(data + pos);
- int msgid = header->msgid;
- int port = VCHIQ_MSG_DSTPORT(msgid);
-
- if ((port == service->localport) && (msgid & VCHIQ_MSGID_CLAIMED)) {
- dev_dbg(state->dev, "core: fsi - hdr %p\n", header);
- release_slot(state, slot_info, header, NULL);
- }
- pos += calc_stride(header->size);
- if (pos > VCHIQ_SLOT_SIZE) {
- dev_err(state->dev,
- "core: fsi - pos %x: header %p, msgid %x, header->msgid %x, header->size %x\n",
- pos, header, msgid, header->msgid, header->size);
- WARN(1, "invalid slot position\n");
- }
- }
- }
-}
-
-static int
-do_abort_bulks(struct vchiq_service *service)
-{
- int status;
-
- /* Abort any outstanding bulk transfers */
- if (mutex_lock_killable(&service->bulk_mutex))
- return 0;
- abort_outstanding_bulks(service, &service->bulk_tx);
- abort_outstanding_bulks(service, &service->bulk_rx);
- mutex_unlock(&service->bulk_mutex);
-
- status = notify_bulks(service, &service->bulk_tx, NO_RETRY_POLL);
- if (status)
- return 0;
-
- status = notify_bulks(service, &service->bulk_rx, NO_RETRY_POLL);
- return !status;
-}
-
-static int
-close_service_complete(struct vchiq_service *service, int failstate)
-{
- int status;
- int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
- int newstate;
-
- switch (service->srvstate) {
- case VCHIQ_SRVSTATE_OPEN:
- case VCHIQ_SRVSTATE_CLOSESENT:
- case VCHIQ_SRVSTATE_CLOSERECVD:
- if (is_server) {
- if (service->auto_close) {
- service->client_id = 0;
- service->remoteport = VCHIQ_PORT_FREE;
- newstate = VCHIQ_SRVSTATE_LISTENING;
- } else {
- newstate = VCHIQ_SRVSTATE_CLOSEWAIT;
- }
- } else {
- newstate = VCHIQ_SRVSTATE_CLOSED;
- }
- set_service_state(service, newstate);
- break;
- case VCHIQ_SRVSTATE_LISTENING:
- break;
- default:
- dev_err(service->state->dev, "core: (%x) called in state %s\n",
- service->handle, srvstate_names[service->srvstate]);
- WARN(1, "%s in unexpected state\n", __func__);
- return -EINVAL;
- }
-
- status = make_service_callback(service, VCHIQ_SERVICE_CLOSED, NULL, NULL);
-
- if (status != -EAGAIN) {
- int uc = service->service_use_count;
- int i;
- /* Complete the close process */
- for (i = 0; i < uc; i++)
- /*
- * cater for cases where close is forced and the
- * client may not close all it's handles
- */
- vchiq_release_service_internal(service);
-
- service->client_id = 0;
- service->remoteport = VCHIQ_PORT_FREE;
-
- if (service->srvstate == VCHIQ_SRVSTATE_CLOSED) {
- vchiq_free_service_internal(service);
- } else if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) {
- if (is_server)
- service->closing = 0;
-
- complete(&service->remove_event);
- }
- } else {
- set_service_state(service, failstate);
- }
-
- return status;
-}
-
-/*
- * Prepares a bulk transfer to be queued. The function is interruptible and is
- * intended to be called from user threads. It may return -EAGAIN to indicate
- * that a signal has been received and the call should be retried after being
- * returned to user context.
- */
-static int
-vchiq_bulk_xfer_queue_msg_killable(struct vchiq_service *service,
- struct vchiq_bulk *bulk_params)
-{
- struct vchiq_bulk_queue *queue;
- struct bulk_waiter *bulk_waiter = NULL;
- struct vchiq_bulk *bulk;
- struct vchiq_state *state = service->state;
- const char dir_char = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r';
- const int dir_msgtype = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ?
- VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX;
- int status = -EINVAL;
- int payload[2];
-
- if (bulk_params->mode == VCHIQ_BULK_MODE_BLOCKING) {
- bulk_waiter = bulk_params->waiter;
- init_completion(&bulk_waiter->event);
- bulk_waiter->actual = 0;
- bulk_waiter->bulk = NULL;
- }
-
- queue = (bulk_params->dir == VCHIQ_BULK_TRANSMIT) ?
- &service->bulk_tx : &service->bulk_rx;
-
- if (mutex_lock_killable(&service->bulk_mutex))
- return -EINTR;
-
- if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) {
- VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
- do {
- mutex_unlock(&service->bulk_mutex);
- if (wait_for_completion_killable(&service->bulk_remove_event))
- return -EINTR;
- if (mutex_lock_killable(&service->bulk_mutex))
- return -EINTR;
- } while (queue->local_insert == queue->remove +
- VCHIQ_NUM_SERVICE_BULKS);
- }
-
- bulk = &queue->bulks[BULK_INDEX(queue->local_insert)];
-
- /* Initiliaze the 'bulk' slot with bulk parameters passed in. */
- bulk->mode = bulk_params->mode;
- bulk->dir = bulk_params->dir;
- bulk->waiter = bulk_params->waiter;
- bulk->cb_data = bulk_params->cb_data;
- bulk->cb_userdata = bulk_params->cb_userdata;
- bulk->size = bulk_params->size;
- bulk->offset = bulk_params->offset;
- bulk->uoffset = bulk_params->uoffset;
- bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
-
- if (vchiq_prepare_bulk_data(service->instance, bulk))
- goto unlock_error_exit;
-
- /*
- * Ensure that the bulk data record is visible to the peer
- * before proceeding.
- */
- wmb();
-
- dev_dbg(state->dev, "core: %d: bt (%d->%d) %cx %x@%pad %p\n",
- state->id, service->localport, service->remoteport,
- dir_char, bulk->size, &bulk->dma_addr, bulk->cb_data);
-
- /*
- * The slot mutex must be held when the service is being closed, so
- * claim it here to ensure that isn't happening
- */
- if (mutex_lock_killable(&state->slot_mutex)) {
- status = -EINTR;
- goto cancel_bulk_error_exit;
- }
-
- if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
- goto unlock_both_error_exit;
-
- payload[0] = lower_32_bits(bulk->dma_addr);
- payload[1] = bulk->size;
- status = queue_message(state,
- NULL,
- VCHIQ_MAKE_MSG(dir_msgtype,
- service->localport,
- service->remoteport),
- memcpy_copy_callback,
- &payload,
- sizeof(payload),
- QMFLAGS_IS_BLOCKING |
- QMFLAGS_NO_MUTEX_LOCK |
- QMFLAGS_NO_MUTEX_UNLOCK);
- if (status)
- goto unlock_both_error_exit;
-
- queue->local_insert++;
-
- mutex_unlock(&state->slot_mutex);
- mutex_unlock(&service->bulk_mutex);
-
- dev_dbg(state->dev, "core: %d: bt:%d %cx li=%x ri=%x p=%x\n",
- state->id, service->localport, dir_char, queue->local_insert,
- queue->remote_insert, queue->process);
-
- if (bulk_waiter) {
- bulk_waiter->bulk = bulk;
- if (wait_for_completion_killable(&bulk_waiter->event))
- status = -EINTR;
- else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
- status = -EINVAL;
- }
-
- return status;
-
-unlock_both_error_exit:
- mutex_unlock(&state->slot_mutex);
-cancel_bulk_error_exit:
- vchiq_complete_bulk(service->instance, bulk);
-unlock_error_exit:
- mutex_unlock(&service->bulk_mutex);
-
- return status;
-}
-
-/* Called by the slot handler */
-int
-vchiq_close_service_internal(struct vchiq_service *service, int close_recvd)
-{
- struct vchiq_state *state = service->state;
- int status = 0;
- int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
- int close_id = MAKE_CLOSE(service->localport,
- VCHIQ_MSG_DSTPORT(service->remoteport));
-
- dev_dbg(state->dev, "core: %d: csi:%d,%d (%s)\n",
- service->state->id, service->localport, close_recvd,
- srvstate_names[service->srvstate]);
-
- switch (service->srvstate) {
- case VCHIQ_SRVSTATE_CLOSED:
- case VCHIQ_SRVSTATE_HIDDEN:
- case VCHIQ_SRVSTATE_LISTENING:
- case VCHIQ_SRVSTATE_CLOSEWAIT:
- if (close_recvd) {
- dev_err(state->dev, "core: (1) called in state %s\n",
- srvstate_names[service->srvstate]);
- break;
- } else if (!is_server) {
- vchiq_free_service_internal(service);
- break;
- }
-
- if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
- status = -EINVAL;
- } else {
- service->client_id = 0;
- service->remoteport = VCHIQ_PORT_FREE;
- if (service->srvstate == VCHIQ_SRVSTATE_CLOSEWAIT)
- set_service_state(service, VCHIQ_SRVSTATE_LISTENING);
- }
- complete(&service->remove_event);
- break;
- case VCHIQ_SRVSTATE_OPENING:
- if (close_recvd) {
- /* The open was rejected - tell the user */
- set_service_state(service, VCHIQ_SRVSTATE_CLOSEWAIT);
- complete(&service->remove_event);
- } else {
- /* Shutdown mid-open - let the other side know */
- status = queue_message(state, service, close_id, NULL, NULL, 0, 0);
- }
- break;
-
- case VCHIQ_SRVSTATE_OPENSYNC:
- mutex_lock(&state->sync_mutex);
- fallthrough;
- case VCHIQ_SRVSTATE_OPEN:
- if (close_recvd) {
- if (!do_abort_bulks(service))
- status = -EAGAIN;
- }
-
- release_service_messages(service);
-
- if (!status)
- status = queue_message(state, service, close_id, NULL,
- NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK);
-
- if (status) {
- if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC)
- mutex_unlock(&state->sync_mutex);
- break;
- }
-
- if (!close_recvd) {
- /* Change the state while the mutex is still held */
- set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
- mutex_unlock(&state->slot_mutex);
- if (service->sync)
- mutex_unlock(&state->sync_mutex);
- break;
- }
-
- /* Change the state while the mutex is still held */
- set_service_state(service, VCHIQ_SRVSTATE_CLOSERECVD);
- mutex_unlock(&state->slot_mutex);
- if (service->sync)
- mutex_unlock(&state->sync_mutex);
-
- status = close_service_complete(service, VCHIQ_SRVSTATE_CLOSERECVD);
- break;
-
- case VCHIQ_SRVSTATE_CLOSESENT:
- if (!close_recvd)
- /* This happens when a process is killed mid-close */
- break;
-
- if (!do_abort_bulks(service)) {
- status = -EAGAIN;
- break;
- }
-
- if (!status)
- status = close_service_complete(service, VCHIQ_SRVSTATE_CLOSERECVD);
- break;
-
- case VCHIQ_SRVSTATE_CLOSERECVD:
- if (!close_recvd && is_server)
- /* Force into LISTENING mode */
- set_service_state(service, VCHIQ_SRVSTATE_LISTENING);
- status = close_service_complete(service, VCHIQ_SRVSTATE_CLOSERECVD);
- break;
-
- default:
- dev_err(state->dev, "core: (%d) called in state %s\n",
- close_recvd, srvstate_names[service->srvstate]);
- break;
- }
-
- return status;
-}
-
-/* Called from the application process upon process death */
-void
-vchiq_terminate_service_internal(struct vchiq_service *service)
-{
- struct vchiq_state *state = service->state;
-
- dev_dbg(state->dev, "core: %d: tsi - (%d<->%d)\n",
- state->id, service->localport, service->remoteport);
-
- mark_service_closing(service);
-
- /* Mark the service for removal by the slot handler */
- request_poll(state, service, VCHIQ_POLL_REMOVE);
-}
-
-/* Called from the slot handler */
-void
-vchiq_free_service_internal(struct vchiq_service *service)
-{
- struct vchiq_state *state = service->state;
-
- dev_dbg(state->dev, "core: %d: fsi - (%d)\n", state->id, service->localport);
-
- switch (service->srvstate) {
- case VCHIQ_SRVSTATE_OPENING:
- case VCHIQ_SRVSTATE_CLOSED:
- case VCHIQ_SRVSTATE_HIDDEN:
- case VCHIQ_SRVSTATE_LISTENING:
- case VCHIQ_SRVSTATE_CLOSEWAIT:
- break;
- default:
- dev_err(state->dev, "core: %d: fsi - (%d) in state %s\n",
- state->id, service->localport, srvstate_names[service->srvstate]);
- return;
- }
-
- set_service_state(service, VCHIQ_SRVSTATE_FREE);
-
- complete(&service->remove_event);
-
- /* Release the initial lock */
- vchiq_service_put(service);
-}
-
-int
-vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance)
-{
- struct vchiq_service *service;
- int status = 0;
- int i;
-
- /* Find all services registered to this client and enable them. */
- i = 0;
- while ((service = next_service_by_instance(state, instance, &i)) != NULL) {
- if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)
- set_service_state(service, VCHIQ_SRVSTATE_LISTENING);
- vchiq_service_put(service);
- }
-
- if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
- status = queue_message(state, NULL, MAKE_CONNECT, NULL, NULL, 0,
- QMFLAGS_IS_BLOCKING);
- if (status)
- return status;
-
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING);
- }
-
- if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) {
- if (wait_for_completion_interruptible(&state->connect))
- return -EAGAIN;
-
- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
- complete(&state->connect);
- }
-
- return status;
-}
-
-void
-vchiq_shutdown_internal(struct vchiq_state *state, struct vchiq_instance *instance)
-{
- struct vchiq_service *service;
- int i;
-
- /* Find all services registered to this client and remove them. */
- i = 0;
- while ((service = next_service_by_instance(state, instance, &i)) != NULL) {
- (void)vchiq_remove_service(instance, service->handle);
- vchiq_service_put(service);
- }
-}
-
-int
-vchiq_close_service(struct vchiq_instance *instance, unsigned int handle)
-{
- /* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int status = 0;
-
- if (!service)
- return -EINVAL;
-
- dev_dbg(service->state->dev, "core: %d: close_service:%d\n",
- service->state->id, service->localport);
-
- if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
- (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
- (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)) {
- vchiq_service_put(service);
- return -EINVAL;
- }
-
- mark_service_closing(service);
-
- if (current == service->state->slot_handler_thread) {
- status = vchiq_close_service_internal(service, NO_CLOSE_RECVD);
- WARN_ON(status == -EAGAIN);
- } else {
- /* Mark the service for termination by the slot handler */
- request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
- }
-
- while (1) {
- if (wait_for_completion_interruptible(&service->remove_event)) {
- status = -EAGAIN;
- break;
- }
-
- if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
- (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
- (service->srvstate == VCHIQ_SRVSTATE_OPEN))
- break;
-
- dev_warn(service->state->dev,
- "core: %d: close_service:%d - waiting in state %s\n",
- service->state->id, service->localport,
- srvstate_names[service->srvstate]);
- }
-
- if (!status &&
- (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
- (service->srvstate != VCHIQ_SRVSTATE_LISTENING))
- status = -EINVAL;
-
- vchiq_service_put(service);
-
- return status;
-}
-EXPORT_SYMBOL(vchiq_close_service);
-
-int
-vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle)
-{
- /* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int status = 0;
-
- if (!service)
- return -EINVAL;
-
- dev_dbg(service->state->dev, "core: %d: remove_service:%d\n",
- service->state->id, service->localport);
-
- if (service->srvstate == VCHIQ_SRVSTATE_FREE) {
- vchiq_service_put(service);
- return -EINVAL;
- }
-
- mark_service_closing(service);
-
- if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
- (current == service->state->slot_handler_thread)) {
- /*
- * Make it look like a client, because it must be removed and
- * not left in the LISTENING state.
- */
- service->public_fourcc = VCHIQ_FOURCC_INVALID;
-
- status = vchiq_close_service_internal(service, NO_CLOSE_RECVD);
- WARN_ON(status == -EAGAIN);
- } else {
- /* Mark the service for removal by the slot handler */
- request_poll(service->state, service, VCHIQ_POLL_REMOVE);
- }
- while (1) {
- if (wait_for_completion_interruptible(&service->remove_event)) {
- status = -EAGAIN;
- break;
- }
-
- if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
- (service->srvstate == VCHIQ_SRVSTATE_OPEN))
- break;
-
- dev_warn(service->state->dev,
- "core: %d: remove_service:%d - waiting in state %s\n",
- service->state->id, service->localport,
- srvstate_names[service->srvstate]);
- }
-
- if (!status && (service->srvstate != VCHIQ_SRVSTATE_FREE))
- status = -EINVAL;
-
- vchiq_service_put(service);
-
- return status;
-}
-
-int
-vchiq_bulk_xfer_blocking(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk_params)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int status = -EINVAL;
-
- if (!service)
- return -EINVAL;
-
- if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
- goto error_exit;
-
- if (!bulk_params->offset && !bulk_params->uoffset)
- goto error_exit;
-
- if (vchiq_check_service(service))
- goto error_exit;
-
- status = vchiq_bulk_xfer_queue_msg_killable(service, bulk_params);
-
-error_exit:
- vchiq_service_put(service);
-
- return status;
-}
-
-int
-vchiq_bulk_xfer_callback(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk_params)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int status = -EINVAL;
-
- if (!service)
- return -EINVAL;
-
- if (bulk_params->mode != VCHIQ_BULK_MODE_CALLBACK &&
- bulk_params->mode != VCHIQ_BULK_MODE_NOCALLBACK)
- goto error_exit;
-
- if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
- goto error_exit;
-
- if (!bulk_params->offset && !bulk_params->uoffset)
- goto error_exit;
-
- if (vchiq_check_service(service))
- goto error_exit;
-
- status = vchiq_bulk_xfer_queue_msg_killable(service, bulk_params);
-
-error_exit:
- vchiq_service_put(service);
-
- return status;
-}
-
-/*
- * This function is called by VCHIQ ioctl interface and is interruptible.
- * It may receive -EAGAIN to indicate that a signal has been received
- * and the call should be retried after being returned to user context.
- */
-int
-vchiq_bulk_xfer_waiting(struct vchiq_instance *instance,
- unsigned int handle, struct bulk_waiter *waiter)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- struct bulk_waiter *bulk_waiter;
- int status = -EINVAL;
-
- if (!service)
- return -EINVAL;
-
- if (!waiter)
- goto error_exit;
-
- if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
- goto error_exit;
-
- if (vchiq_check_service(service))
- goto error_exit;
-
- bulk_waiter = waiter;
-
- vchiq_service_put(service);
-
- status = 0;
-
- if (wait_for_completion_killable(&bulk_waiter->event))
- return -EINTR;
- else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
- return -EINVAL;
-
- return status;
-
-error_exit:
- vchiq_service_put(service);
-
- return status;
-}
-
-int
-vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
- ssize_t (*copy_callback)(void *context, void *dest,
- size_t offset, size_t maxsize),
- void *context,
- size_t size)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- int status = -EINVAL;
- int data_id;
-
- if (!service)
- goto error_exit;
-
- if (vchiq_check_service(service))
- goto error_exit;
-
- if (!size) {
- VCHIQ_SERVICE_STATS_INC(service, error_count);
- goto error_exit;
- }
-
- if (size > VCHIQ_MAX_MSG_SIZE) {
- VCHIQ_SERVICE_STATS_INC(service, error_count);
- goto error_exit;
- }
-
- data_id = MAKE_DATA(service->localport, service->remoteport);
-
- switch (service->srvstate) {
- case VCHIQ_SRVSTATE_OPEN:
- status = queue_message(service->state, service, data_id,
- copy_callback, context, size,
- QMFLAGS_IS_BLOCKING);
- break;
- case VCHIQ_SRVSTATE_OPENSYNC:
- status = queue_message_sync(service->state, service, data_id,
- copy_callback, context, size);
- break;
- default:
- status = -EINVAL;
- break;
- }
-
-error_exit:
- if (service)
- vchiq_service_put(service);
-
- return status;
-}
-
-int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle, void *data,
- unsigned int size)
-{
- return vchiq_queue_message(instance, handle, memcpy_copy_callback,
- data, size);
-}
-EXPORT_SYMBOL(vchiq_queue_kernel_message);
-
-void
-vchiq_release_message(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_header *header)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- struct vchiq_shared_state *remote;
- struct vchiq_state *state;
- int slot_index;
-
- if (!service)
- return;
-
- state = service->state;
- remote = state->remote;
-
- slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header);
-
- if ((slot_index >= remote->slot_first) &&
- (slot_index <= remote->slot_last)) {
- int msgid = header->msgid;
-
- if (msgid & VCHIQ_MSGID_CLAIMED) {
- struct vchiq_slot_info *slot_info =
- SLOT_INFO_FROM_INDEX(state, slot_index);
-
- release_slot(state, slot_info, header, service);
- }
- } else if (slot_index == remote->slot_sync) {
- release_message_sync(state, header);
- }
-
- vchiq_service_put(service);
-}
-EXPORT_SYMBOL(vchiq_release_message);
-
-static void
-release_message_sync(struct vchiq_state *state, struct vchiq_header *header)
-{
- header->msgid = VCHIQ_MSGID_PADDING;
- remote_event_signal(state, &state->remote->sync_release);
-}
-
-int
-vchiq_get_peer_version(struct vchiq_instance *instance, unsigned int handle, short *peer_version)
-{
- int status = -EINVAL;
- struct vchiq_service *service = find_service_by_handle(instance, handle);
-
- if (!service)
- goto exit;
-
- if (vchiq_check_service(service))
- goto exit;
-
- if (!peer_version)
- goto exit;
-
- *peer_version = service->peer_version;
- status = 0;
-
-exit:
- if (service)
- vchiq_service_put(service);
- return status;
-}
-EXPORT_SYMBOL(vchiq_get_peer_version);
-
-void vchiq_get_config(struct vchiq_config *config)
-{
- config->max_msg_size = VCHIQ_MAX_MSG_SIZE;
- config->bulk_threshold = VCHIQ_MAX_MSG_SIZE;
- config->max_outstanding_bulks = VCHIQ_NUM_SERVICE_BULKS;
- config->max_services = VCHIQ_MAX_SERVICES;
- config->version = VCHIQ_VERSION;
- config->version_min = VCHIQ_VERSION_MIN;
-}
-
-int
-vchiq_set_service_option(struct vchiq_instance *instance, unsigned int handle,
- enum vchiq_service_option option, int value)
-{
- struct vchiq_service *service = find_service_by_handle(instance, handle);
- struct vchiq_service_quota *quota;
- int ret = -EINVAL;
-
- if (!service)
- return -EINVAL;
-
- switch (option) {
- case VCHIQ_SERVICE_OPTION_AUTOCLOSE:
- service->auto_close = value;
- ret = 0;
- break;
-
- case VCHIQ_SERVICE_OPTION_SLOT_QUOTA:
- quota = &service->state->service_quotas[service->localport];
- if (value == 0)
- value = service->state->default_slot_quota;
- if ((value >= quota->slot_use_count) &&
- (value < (unsigned short)~0)) {
- quota->slot_quota = value;
- if ((value >= quota->slot_use_count) &&
- (quota->message_quota >= quota->message_use_count))
- /*
- * Signal the service that it may have
- * dropped below its quota
- */
- complete(&quota->quota_event);
- ret = 0;
- }
- break;
-
- case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA:
- quota = &service->state->service_quotas[service->localport];
- if (value == 0)
- value = service->state->default_message_quota;
- if ((value >= quota->message_use_count) &&
- (value < (unsigned short)~0)) {
- quota->message_quota = value;
- if ((value >= quota->message_use_count) &&
- (quota->slot_quota >= quota->slot_use_count))
- /*
- * Signal the service that it may have
- * dropped below its quota
- */
- complete(&quota->quota_event);
- ret = 0;
- }
- break;
-
- case VCHIQ_SERVICE_OPTION_SYNCHRONOUS:
- if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
- (service->srvstate == VCHIQ_SRVSTATE_LISTENING)) {
- service->sync = value;
- ret = 0;
- }
- break;
-
- case VCHIQ_SERVICE_OPTION_TRACE:
- service->trace = value;
- ret = 0;
- break;
-
- default:
- break;
- }
- vchiq_service_put(service);
-
- return ret;
-}
-
-static void
-vchiq_dump_shared_state(struct seq_file *f, struct vchiq_state *state,
- struct vchiq_shared_state *shared, const char *label)
-{
- static const char *const debug_names[] = {
- "<entries>",
- "SLOT_HANDLER_COUNT",
- "SLOT_HANDLER_LINE",
- "PARSE_LINE",
- "PARSE_HEADER",
- "PARSE_MSGID",
- "AWAIT_COMPLETION_LINE",
- "DEQUEUE_MESSAGE_LINE",
- "SERVICE_CALLBACK_LINE",
- "MSG_QUEUE_FULL_COUNT",
- "COMPLETION_QUEUE_FULL_COUNT"
- };
- int i;
-
- seq_printf(f, " %s: slots %d-%d tx_pos=0x%x recycle=0x%x\n",
- label, shared->slot_first, shared->slot_last,
- shared->tx_pos, shared->slot_queue_recycle);
-
- seq_puts(f, " Slots claimed:\n");
-
- for (i = shared->slot_first; i <= shared->slot_last; i++) {
- struct vchiq_slot_info slot_info =
- *SLOT_INFO_FROM_INDEX(state, i);
- if (slot_info.use_count != slot_info.release_count) {
- seq_printf(f, " %d: %d/%d\n", i, slot_info.use_count,
- slot_info.release_count);
- }
- }
-
- for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) {
- seq_printf(f, " DEBUG: %s = %d(0x%x)\n",
- debug_names[i], shared->debug[i], shared->debug[i]);
- }
-}
-
-static void
-vchiq_dump_service_state(struct seq_file *f, struct vchiq_service *service)
-{
- unsigned int ref_count;
-
- /*Don't include the lock just taken*/
- ref_count = kref_read(&service->ref_count) - 1;
- seq_printf(f, "Service %u: %s (ref %u)", service->localport,
- srvstate_names[service->srvstate], ref_count);
-
- if (service->srvstate != VCHIQ_SRVSTATE_FREE) {
- char remoteport[30];
- struct vchiq_service_quota *quota =
- &service->state->service_quotas[service->localport];
- int fourcc = service->base.fourcc;
- int tx_pending, rx_pending, tx_size = 0, rx_size = 0;
-
- if (service->remoteport != VCHIQ_PORT_FREE) {
- int len2 = scnprintf(remoteport, sizeof(remoteport),
- "%u", service->remoteport);
-
- if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
- scnprintf(remoteport + len2, sizeof(remoteport) - len2,
- " (client 0x%x)", service->client_id);
- } else {
- strscpy(remoteport, "n/a", sizeof(remoteport));
- }
-
- seq_printf(f, " '%p4cc' remote %s (msg use %d/%d, slot use %d/%d)\n",
- &fourcc, remoteport,
- quota->message_use_count, quota->message_quota,
- quota->slot_use_count, quota->slot_quota);
-
- tx_pending = service->bulk_tx.local_insert -
- service->bulk_tx.remote_insert;
- if (tx_pending) {
- unsigned int i = BULK_INDEX(service->bulk_tx.remove);
-
- tx_size = service->bulk_tx.bulks[i].size;
- }
-
- rx_pending = service->bulk_rx.local_insert -
- service->bulk_rx.remote_insert;
- if (rx_pending) {
- unsigned int i = BULK_INDEX(service->bulk_rx.remove);
-
- rx_size = service->bulk_rx.bulks[i].size;
- }
-
- seq_printf(f, " Bulk: tx_pending=%d (size %d), rx_pending=%d (size %d)\n",
- tx_pending, tx_size, rx_pending, rx_size);
-
- if (VCHIQ_ENABLE_STATS) {
- seq_printf(f, " Ctrl: tx_count=%d, tx_bytes=%llu, rx_count=%d, rx_bytes=%llu\n",
- service->stats.ctrl_tx_count,
- service->stats.ctrl_tx_bytes,
- service->stats.ctrl_rx_count,
- service->stats.ctrl_rx_bytes);
-
- seq_printf(f, " Bulk: tx_count=%d, tx_bytes=%llu, rx_count=%d, rx_bytes=%llu\n",
- service->stats.bulk_tx_count,
- service->stats.bulk_tx_bytes,
- service->stats.bulk_rx_count,
- service->stats.bulk_rx_bytes);
-
- seq_printf(f, " %d quota stalls, %d slot stalls, %d bulk stalls, %d aborted, %d errors\n",
- service->stats.quota_stalls,
- service->stats.slot_stalls,
- service->stats.bulk_stalls,
- service->stats.bulk_aborted_count,
- service->stats.error_count);
- }
- }
-
- vchiq_dump_platform_service_state(f, service);
-}
-
-void vchiq_dump_state(struct seq_file *f, struct vchiq_state *state)
-{
- int i;
-
- seq_printf(f, "State %d: %s\n", state->id,
- conn_state_names[state->conn_state]);
-
- seq_printf(f, " tx_pos=0x%x(@%pK), rx_pos=0x%x(@%pK)\n",
- state->local->tx_pos,
- state->tx_data + (state->local_tx_pos & VCHIQ_SLOT_MASK),
- state->rx_pos,
- state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK));
-
- seq_printf(f, " Version: %d (min %d)\n", VCHIQ_VERSION,
- VCHIQ_VERSION_MIN);
-
- if (VCHIQ_ENABLE_STATS) {
- seq_printf(f, " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, error_count=%d\n",
- state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
- state->stats.error_count);
- }
-
- seq_printf(f, " Slots: %d available (%d data), %d recyclable, %d stalls (%d data)\n",
- ((state->slot_queue_available * VCHIQ_SLOT_SIZE) -
- state->local_tx_pos) / VCHIQ_SLOT_SIZE,
- state->data_quota - state->data_use_count,
- state->local->slot_queue_recycle - state->slot_queue_available,
- state->stats.slot_stalls, state->stats.data_stalls);
-
- vchiq_dump_platform_state(f);
-
- vchiq_dump_shared_state(f, state, state->local, "Local");
-
- vchiq_dump_shared_state(f, state, state->remote, "Remote");
-
- vchiq_dump_platform_instances(state, f);
-
- for (i = 0; i < state->unused_service; i++) {
- struct vchiq_service *service = find_service_by_port(state, i);
-
- if (service) {
- vchiq_dump_service_state(f, service);
- vchiq_service_put(service);
- }
- }
-}
-
-int vchiq_send_remote_use(struct vchiq_state *state)
-{
- if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED)
- return -ENOTCONN;
-
- return queue_message(state, NULL, MAKE_REMOTE_USE, NULL, NULL, 0, 0);
-}
-
-int vchiq_send_remote_use_active(struct vchiq_state *state)
-{
- if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED)
- return -ENOTCONN;
-
- return queue_message(state, NULL, MAKE_REMOTE_USE_ACTIVE,
- NULL, NULL, 0, 0);
-}
-
-void vchiq_log_dump_mem(struct device *dev, const char *label, u32 addr,
- const void *void_mem, size_t num_bytes)
-{
- const u8 *mem = void_mem;
- size_t offset;
- char line_buf[100];
- char *s;
-
- while (num_bytes > 0) {
- s = line_buf;
-
- for (offset = 0; offset < 16; offset++) {
- if (offset < num_bytes)
- s += scnprintf(s, 4, "%02x ", mem[offset]);
- else
- s += scnprintf(s, 4, " ");
- }
-
- for (offset = 0; offset < 16; offset++) {
- if (offset < num_bytes) {
- u8 ch = mem[offset];
-
- if ((ch < ' ') || (ch > '~'))
- ch = '.';
- *s++ = (char)ch;
- }
- }
- *s++ = '\0';
-
- if (label && (*label != '\0'))
- dev_dbg(dev, "core: %s: %08x: %s\n", label, addr, line_buf);
- else
- dev_dbg(dev, "core: %s: %08x: %s\n", label, addr, line_buf);
-
- addr += 16;
- mem += 16;
- if (num_bytes > 16)
- num_bytes -= 16;
- else
- num_bytes = 0;
- }
-}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
deleted file mode 100644
index 9b4e766990a4..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ /dev/null
@@ -1,596 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
-
-#ifndef VCHIQ_CORE_H
-#define VCHIQ_CORE_H
-
-#include <linux/mutex.h>
-#include <linux/completion.h>
-#include <linux/dma-mapping.h>
-#include <linux/dev_printk.h>
-#include <linux/kthread.h>
-#include <linux/kref.h>
-#include <linux/rcupdate.h>
-#include <linux/seq_file.h>
-#include <linux/spinlock_types.h>
-#include <linux/wait.h>
-
-#include "../../include/linux/raspberrypi/vchiq.h"
-#include "vchiq_cfg.h"
-
-/* Do this so that we can test-build the code on non-rpi systems */
-#if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
-
-#else
-
-#ifndef dsb
-#define dsb(a)
-#endif
-
-#endif /* IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) */
-
-#define VCHIQ_SERVICE_HANDLE_INVALID 0
-
-#define VCHIQ_SLOT_SIZE 4096
-#define VCHIQ_MAX_MSG_SIZE (VCHIQ_SLOT_SIZE - sizeof(struct vchiq_header))
-
-#define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1)
-#define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1)
-#define VCHIQ_SLOT_ZERO_SLOTS DIV_ROUND_UP(sizeof(struct vchiq_slot_zero), \
- VCHIQ_SLOT_SIZE)
-
-#define BITSET_SIZE(b) ((b + 31) >> 5)
-#define BITSET_WORD(b) (b >> 5)
-#define BITSET_BIT(b) (1 << (b & 31))
-#define BITSET_IS_SET(bs, b) (bs[BITSET_WORD(b)] & BITSET_BIT(b))
-#define BITSET_SET(bs, b) (bs[BITSET_WORD(b)] |= BITSET_BIT(b))
-
-enum {
- DEBUG_ENTRIES,
-#if VCHIQ_ENABLE_DEBUG
- DEBUG_SLOT_HANDLER_COUNT,
- DEBUG_SLOT_HANDLER_LINE,
- DEBUG_PARSE_LINE,
- DEBUG_PARSE_HEADER,
- DEBUG_PARSE_MSGID,
- DEBUG_AWAIT_COMPLETION_LINE,
- DEBUG_DEQUEUE_MESSAGE_LINE,
- DEBUG_SERVICE_CALLBACK_LINE,
- DEBUG_MSG_QUEUE_FULL_COUNT,
- DEBUG_COMPLETION_QUEUE_FULL_COUNT,
-#endif
- DEBUG_MAX
-};
-
-#if VCHIQ_ENABLE_DEBUG
-
-#define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug
-#define DEBUG_TRACE(d) \
- do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(sy); } while (0)
-#define DEBUG_VALUE(d, v) \
- do { debug_ptr[DEBUG_ ## d] = (v); dsb(sy); } while (0)
-#define DEBUG_COUNT(d) \
- do { debug_ptr[DEBUG_ ## d]++; dsb(sy); } while (0)
-
-#else /* VCHIQ_ENABLE_DEBUG */
-
-#define DEBUG_INITIALISE(local)
-#define DEBUG_TRACE(d)
-#define DEBUG_VALUE(d, v)
-#define DEBUG_COUNT(d)
-
-#endif /* VCHIQ_ENABLE_DEBUG */
-
-enum vchiq_connstate {
- VCHIQ_CONNSTATE_DISCONNECTED,
- VCHIQ_CONNSTATE_CONNECTING,
- VCHIQ_CONNSTATE_CONNECTED,
- VCHIQ_CONNSTATE_PAUSING,
- VCHIQ_CONNSTATE_PAUSE_SENT,
- VCHIQ_CONNSTATE_PAUSED,
- VCHIQ_CONNSTATE_RESUMING,
- VCHIQ_CONNSTATE_PAUSE_TIMEOUT,
- VCHIQ_CONNSTATE_RESUME_TIMEOUT
-};
-
-enum {
- VCHIQ_SRVSTATE_FREE,
- VCHIQ_SRVSTATE_HIDDEN,
- VCHIQ_SRVSTATE_LISTENING,
- VCHIQ_SRVSTATE_OPENING,
- VCHIQ_SRVSTATE_OPEN,
- VCHIQ_SRVSTATE_OPENSYNC,
- VCHIQ_SRVSTATE_CLOSESENT,
- VCHIQ_SRVSTATE_CLOSERECVD,
- VCHIQ_SRVSTATE_CLOSEWAIT,
- VCHIQ_SRVSTATE_CLOSED
-};
-
-enum vchiq_bulk_dir {
- VCHIQ_BULK_TRANSMIT,
- VCHIQ_BULK_RECEIVE
-};
-
-struct vchiq_bulk {
- short mode;
- short dir;
- void *cb_data;
- void __user *cb_userdata;
- struct bulk_waiter *waiter;
- dma_addr_t dma_addr;
- int size;
- void *remote_data;
- int remote_size;
- int actual;
- void *offset;
- void __user *uoffset;
-};
-
-struct vchiq_bulk_queue {
- int local_insert; /* Where to insert the next local bulk */
- int remote_insert; /* Where to insert the next remote bulk (master) */
- int process; /* Bulk to transfer next */
- int remote_notify; /* Bulk to notify the remote client of next (mstr) */
- int remove; /* Bulk to notify the local client of, and remove, next */
- struct vchiq_bulk bulks[VCHIQ_NUM_SERVICE_BULKS];
-};
-
-/*
- * Remote events provide a way of presenting several virtual doorbells to a
- * peer (ARM host to VPU) using only one physical doorbell. They can be thought
- * of as a way for the peer to signal a semaphore, in this case implemented as
- * a workqueue.
- *
- * Remote events remain signalled until acknowledged by the receiver, and they
- * are non-counting. They are designed in such a way as to minimise the number
- * of interrupts and avoid unnecessary waiting.
- *
- * A remote_event is as small data structures that live in shared memory. It
- * comprises two booleans - armed and fired:
- *
- * The sender sets fired when they signal the receiver.
- * If fired is set, the receiver has been signalled and need not wait.
- * The receiver sets the armed field before they begin to wait.
- * If armed is set, the receiver is waiting and wishes to be woken by interrupt.
- */
-struct remote_event {
- int armed;
- int fired;
- u32 __unused;
-};
-
-struct opaque_platform_state;
-
-struct vchiq_slot {
- char data[VCHIQ_SLOT_SIZE];
-};
-
-struct vchiq_slot_info {
- /* Use two counters rather than one to avoid the need for a mutex. */
- short use_count;
- short release_count;
-};
-
-struct vchiq_service {
- struct vchiq_service_base base;
- unsigned int handle;
- struct kref ref_count;
- struct rcu_head rcu;
- int srvstate;
- void (*userdata_term)(void *userdata);
- unsigned int localport;
- unsigned int remoteport;
- int public_fourcc;
- int client_id;
- char auto_close;
- char sync;
- char closing;
- char trace;
- atomic_t poll_flags;
- short version;
- short version_min;
- short peer_version;
-
- struct vchiq_state *state;
- struct vchiq_instance *instance;
-
- int service_use_count;
-
- struct vchiq_bulk_queue bulk_tx;
- struct vchiq_bulk_queue bulk_rx;
-
- struct completion remove_event;
- struct completion bulk_remove_event;
- struct mutex bulk_mutex;
-
- struct service_stats_struct {
- int quota_stalls;
- int slot_stalls;
- int bulk_stalls;
- int error_count;
- int ctrl_tx_count;
- int ctrl_rx_count;
- int bulk_tx_count;
- int bulk_rx_count;
- int bulk_aborted_count;
- u64 ctrl_tx_bytes;
- u64 ctrl_rx_bytes;
- u64 bulk_tx_bytes;
- u64 bulk_rx_bytes;
- } stats;
-
- int msg_queue_read;
- int msg_queue_write;
- struct completion msg_queue_pop;
- struct completion msg_queue_push;
- struct vchiq_header *msg_queue[VCHIQ_MAX_SLOTS];
-};
-
-/*
- * The quota information is outside struct vchiq_service so that it can
- * be statically allocated, since for accounting reasons a service's slot
- * usage is carried over between users of the same port number.
- */
-struct vchiq_service_quota {
- unsigned short slot_quota;
- unsigned short slot_use_count;
- unsigned short message_quota;
- unsigned short message_use_count;
- struct completion quota_event;
- int previous_tx_index;
-};
-
-struct vchiq_shared_state {
- /* A non-zero value here indicates that the content is valid. */
- int initialised;
-
- /* The first and last (inclusive) slots allocated to the owner. */
- int slot_first;
- int slot_last;
-
- /* The slot allocated to synchronous messages from the owner. */
- int slot_sync;
-
- /*
- * Signalling this event indicates that owner's slot handler thread
- * should run.
- */
- struct remote_event trigger;
-
- /*
- * Indicates the byte position within the stream where the next message
- * will be written. The least significant bits are an index into the
- * slot. The next bits are the index of the slot in slot_queue.
- */
- int tx_pos;
-
- /* This event should be signalled when a slot is recycled. */
- struct remote_event recycle;
-
- /* The slot_queue index where the next recycled slot will be written. */
- int slot_queue_recycle;
-
- /* This event should be signalled when a synchronous message is sent. */
- struct remote_event sync_trigger;
-
- /*
- * This event should be signalled when a synchronous message has been
- * released.
- */
- struct remote_event sync_release;
-
- /* A circular buffer of slot indexes. */
- int slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE];
-
- /* Debugging state */
- int debug[DEBUG_MAX];
-};
-
-struct vchiq_slot_zero {
- int magic;
- short version;
- short version_min;
- int slot_zero_size;
- int slot_size;
- int max_slots;
- int max_slots_per_side;
- int platform_data[2];
- struct vchiq_shared_state master;
- struct vchiq_shared_state slave;
- struct vchiq_slot_info slots[VCHIQ_MAX_SLOTS];
-};
-
-struct vchiq_state {
- struct device *dev;
- int id;
- int initialised;
- enum vchiq_connstate conn_state;
- short version_common;
-
- struct vchiq_shared_state *local;
- struct vchiq_shared_state *remote;
- struct vchiq_slot *slot_data;
-
- unsigned short default_slot_quota;
- unsigned short default_message_quota;
-
- /* Event indicating connect message received */
- struct completion connect;
-
- /* Mutex protecting services */
- struct mutex mutex;
- struct vchiq_instance **instance;
-
- /* Processes incoming messages */
- struct task_struct *slot_handler_thread;
-
- /* Processes recycled slots */
- struct task_struct *recycle_thread;
-
- /* Processes synchronous messages */
- struct task_struct *sync_thread;
-
- /* Local implementation of the trigger remote event */
- wait_queue_head_t trigger_event;
-
- /* Local implementation of the recycle remote event */
- wait_queue_head_t recycle_event;
-
- /* Local implementation of the sync trigger remote event */
- wait_queue_head_t sync_trigger_event;
-
- /* Local implementation of the sync release remote event */
- wait_queue_head_t sync_release_event;
-
- char *tx_data;
- char *rx_data;
- struct vchiq_slot_info *rx_info;
-
- struct mutex slot_mutex;
-
- struct mutex recycle_mutex;
-
- struct mutex sync_mutex;
-
- spinlock_t msg_queue_spinlock;
-
- spinlock_t bulk_waiter_spinlock;
-
- spinlock_t quota_spinlock;
-
- /*
- * Indicates the byte position within the stream from where the next
- * message will be read. The least significant bits are an index into
- * the slot.The next bits are the index of the slot in
- * remote->slot_queue.
- */
- int rx_pos;
-
- /*
- * A cached copy of local->tx_pos. Only write to local->tx_pos, and read
- * from remote->tx_pos.
- */
- int local_tx_pos;
-
- /* The slot_queue index of the slot to become available next. */
- int slot_queue_available;
-
- /* A flag to indicate if any poll has been requested */
- int poll_needed;
-
- /* Ths index of the previous slot used for data messages. */
- int previous_data_index;
-
- /* The number of slots occupied by data messages. */
- unsigned short data_use_count;
-
- /* The maximum number of slots to be occupied by data messages. */
- unsigned short data_quota;
-
- /* An array of bit sets indicating which services must be polled. */
- atomic_t poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
-
- /* The number of the first unused service */
- int unused_service;
-
- /* Signalled when a free slot becomes available. */
- struct completion slot_available_event;
-
- /* Signalled when a free data slot becomes available. */
- struct completion data_quota_event;
-
- struct state_stats_struct {
- int slot_stalls;
- int data_stalls;
- int ctrl_tx_count;
- int ctrl_rx_count;
- int error_count;
- } stats;
-
- struct vchiq_service __rcu *services[VCHIQ_MAX_SERVICES];
- struct vchiq_service_quota service_quotas[VCHIQ_MAX_SERVICES];
- struct vchiq_slot_info slot_info[VCHIQ_MAX_SLOTS];
-
- struct opaque_platform_state *platform_state;
-};
-
-struct pagelist {
- u32 length;
- u16 type;
- u16 offset;
- u32 addrs[1]; /* N.B. 12 LSBs hold the number
- * of following pages at consecutive
- * addresses.
- */
-};
-
-struct vchiq_pagelist_info {
- struct pagelist *pagelist;
- size_t pagelist_buffer_size;
- dma_addr_t dma_addr;
- enum dma_data_direction dma_dir;
- unsigned int num_pages;
- unsigned int pages_need_release;
- struct page **pages;
- struct scatterlist *scatterlist;
- unsigned int scatterlist_mapped;
-};
-
-static inline bool vchiq_remote_initialised(const struct vchiq_state *state)
-{
- return state->remote && state->remote->initialised;
-}
-
-struct bulk_waiter {
- struct vchiq_bulk *bulk;
- struct completion event;
- int actual;
-};
-
-struct vchiq_config {
- unsigned int max_msg_size;
- unsigned int bulk_threshold; /* The message size above which it
- * is better to use a bulk transfer
- * (<= max_msg_size)
- */
- unsigned int max_outstanding_bulks;
- unsigned int max_services;
- short version; /* The version of VCHIQ */
- short version_min; /* The minimum compatible version of VCHIQ */
-};
-
-extern spinlock_t bulk_waiter_spinlock;
-
-extern const char *
-get_conn_state_name(enum vchiq_connstate conn_state);
-
-extern struct vchiq_slot_zero *
-vchiq_init_slots(struct device *dev, void *mem_base, int mem_size);
-
-extern int
-vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, struct device *dev);
-
-extern int
-vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance);
-
-struct vchiq_service *
-vchiq_add_service_internal(struct vchiq_state *state,
- const struct vchiq_service_params_kernel *params,
- int srvstate, struct vchiq_instance *instance,
- void (*userdata_term)(void *userdata));
-
-extern int
-vchiq_open_service_internal(struct vchiq_service *service, int client_id);
-
-extern int
-vchiq_close_service_internal(struct vchiq_service *service, int close_recvd);
-
-extern void
-vchiq_terminate_service_internal(struct vchiq_service *service);
-
-extern void
-vchiq_free_service_internal(struct vchiq_service *service);
-
-extern void
-vchiq_shutdown_internal(struct vchiq_state *state, struct vchiq_instance *instance);
-
-extern void
-remote_event_pollall(struct vchiq_state *state);
-
-extern int
-vchiq_bulk_xfer_waiting(struct vchiq_instance *instance, unsigned int handle,
- struct bulk_waiter *userdata);
-
-extern int
-vchiq_bulk_xfer_blocking(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk);
-
-extern int
-vchiq_bulk_xfer_callback(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_bulk *bulk);
-
-extern void
-vchiq_dump_state(struct seq_file *f, struct vchiq_state *state);
-
-extern void
-request_poll(struct vchiq_state *state, struct vchiq_service *service,
- int poll_type);
-
-struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigned int handle);
-
-extern struct vchiq_service *
-find_service_by_handle(struct vchiq_instance *instance, unsigned int handle);
-
-extern struct vchiq_service *
-find_service_by_port(struct vchiq_state *state, unsigned int localport);
-
-extern struct vchiq_service *
-find_service_for_instance(struct vchiq_instance *instance, unsigned int handle);
-
-extern struct vchiq_service *
-find_closed_service_for_instance(struct vchiq_instance *instance, unsigned int handle);
-
-extern struct vchiq_service *
-__next_service_by_instance(struct vchiq_state *state,
- struct vchiq_instance *instance,
- int *pidx);
-
-extern struct vchiq_service *
-next_service_by_instance(struct vchiq_state *state,
- struct vchiq_instance *instance,
- int *pidx);
-
-extern void
-vchiq_service_get(struct vchiq_service *service);
-
-extern void
-vchiq_service_put(struct vchiq_service *service);
-
-extern int
-vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
- ssize_t (*copy_callback)(void *context, void *dest,
- size_t offset, size_t maxsize),
- void *context,
- size_t size);
-
-void vchiq_dump_platform_state(struct seq_file *f);
-
-void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f);
-
-void vchiq_dump_platform_service_state(struct seq_file *f, struct vchiq_service *service);
-
-int vchiq_use_service_internal(struct vchiq_service *service);
-
-int vchiq_release_service_internal(struct vchiq_service *service);
-
-void vchiq_on_remote_use(struct vchiq_state *state);
-
-void vchiq_on_remote_release(struct vchiq_state *state);
-
-int vchiq_platform_init_state(struct vchiq_state *state);
-
-int vchiq_check_service(struct vchiq_service *service);
-
-int vchiq_send_remote_use(struct vchiq_state *state);
-
-int vchiq_send_remote_use_active(struct vchiq_state *state);
-
-void vchiq_platform_conn_state_changed(struct vchiq_state *state,
- enum vchiq_connstate oldstate,
- enum vchiq_connstate newstate);
-
-void vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newstate);
-
-void vchiq_log_dump_mem(struct device *dev, const char *label, u32 addr,
- const void *void_mem, size_t num_bytes);
-
-int vchiq_remove_service(struct vchiq_instance *instance, unsigned int service);
-
-int vchiq_get_client_id(struct vchiq_instance *instance, unsigned int service);
-
-void vchiq_get_config(struct vchiq_config *config);
-
-int vchiq_set_service_option(struct vchiq_instance *instance, unsigned int service,
- enum vchiq_service_option option, int value);
-
-#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c
deleted file mode 100644
index d5f7f61c5626..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c
+++ /dev/null
@@ -1,157 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/*
- * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- */
-
-#include <linux/debugfs.h>
-#include "vchiq_core.h"
-#include "vchiq_arm.h"
-#include "vchiq_debugfs.h"
-
-#ifdef CONFIG_DEBUG_FS
-
-#define DEBUGFS_WRITE_BUF_SIZE 256
-
-/* Global 'vchiq' debugfs and clients entry used by all instances */
-static struct dentry *vchiq_dbg_dir;
-static struct dentry *vchiq_dbg_clients;
-
-static int debugfs_usecount_show(struct seq_file *f, void *offset)
-{
- struct vchiq_instance *instance = f->private;
- int use_count;
-
- use_count = vchiq_instance_get_use_count(instance);
- seq_printf(f, "%d\n", use_count);
-
- return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(debugfs_usecount);
-
-static int debugfs_trace_show(struct seq_file *f, void *offset)
-{
- struct vchiq_instance *instance = f->private;
- int trace;
-
- trace = vchiq_instance_get_trace(instance);
- seq_printf(f, "%s\n", trace ? "Y" : "N");
-
- return 0;
-}
-
-static int vchiq_dump_show(struct seq_file *f, void *offset)
-{
- struct vchiq_state *state = f->private;
-
- vchiq_dump_state(f, state);
-
- return 0;
-}
-DEFINE_SHOW_ATTRIBUTE(vchiq_dump);
-
-static int debugfs_trace_open(struct inode *inode, struct file *file)
-{
- return single_open(file, debugfs_trace_show, inode->i_private);
-}
-
-static ssize_t debugfs_trace_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct seq_file *f = (struct seq_file *)file->private_data;
- struct vchiq_instance *instance = f->private;
- char firstchar;
-
- if (copy_from_user(&firstchar, buffer, 1))
- return -EFAULT;
-
- switch (firstchar) {
- case 'Y':
- case 'y':
- case '1':
- vchiq_instance_set_trace(instance, 1);
- break;
- case 'N':
- case 'n':
- case '0':
- vchiq_instance_set_trace(instance, 0);
- break;
- default:
- break;
- }
-
- *ppos += count;
-
- return count;
-}
-
-static const struct file_operations debugfs_trace_fops = {
- .owner = THIS_MODULE,
- .open = debugfs_trace_open,
- .write = debugfs_trace_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/* add an instance (process) to the debugfs entries */
-void vchiq_debugfs_add_instance(struct vchiq_instance *instance)
-{
- char pidstr[16];
- struct dentry *top;
-
- snprintf(pidstr, sizeof(pidstr), "%d",
- vchiq_instance_get_pid(instance));
-
- top = debugfs_create_dir(pidstr, vchiq_dbg_clients);
-
- debugfs_create_file("use_count", 0444, top, instance,
- &debugfs_usecount_fops);
- debugfs_create_file("trace", 0644, top, instance, &debugfs_trace_fops);
-
- vchiq_instance_get_debugfs_node(instance)->dentry = top;
-}
-
-void vchiq_debugfs_remove_instance(struct vchiq_instance *instance)
-{
- struct vchiq_debugfs_node *node =
- vchiq_instance_get_debugfs_node(instance);
-
- debugfs_remove_recursive(node->dentry);
-}
-
-void vchiq_debugfs_init(struct vchiq_state *state)
-{
- vchiq_dbg_dir = debugfs_create_dir("vchiq", NULL);
- vchiq_dbg_clients = debugfs_create_dir("clients", vchiq_dbg_dir);
-
- debugfs_create_file("state", S_IFREG | 0444, vchiq_dbg_dir, state,
- &vchiq_dump_fops);
-}
-
-/* remove all the debugfs entries */
-void vchiq_debugfs_deinit(void)
-{
- debugfs_remove_recursive(vchiq_dbg_dir);
-}
-
-#else /* CONFIG_DEBUG_FS */
-
-void vchiq_debugfs_init(struct vchiq_state *state)
-{
-}
-
-void vchiq_debugfs_deinit(void)
-{
-}
-
-void vchiq_debugfs_add_instance(struct vchiq_instance *instance)
-{
-}
-
-void vchiq_debugfs_remove_instance(struct vchiq_instance *instance)
-{
-}
-
-#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
deleted file mode 100644
index b29e6693c949..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. */
-
-#ifndef VCHIQ_DEBUGFS_H
-#define VCHIQ_DEBUGFS_H
-
-struct vchiq_state;
-struct vchiq_instance;
-
-struct vchiq_debugfs_node {
- struct dentry *dentry;
-};
-
-void vchiq_debugfs_init(struct vchiq_state *state);
-
-void vchiq_debugfs_deinit(void);
-
-void vchiq_debugfs_add_instance(struct vchiq_instance *instance);
-
-void vchiq_debugfs_remove_instance(struct vchiq_instance *instance);
-
-#endif /* VCHIQ_DEBUGFS_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
deleted file mode 100644
index 3b20ba5c7362..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/*
- * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
- * Copyright (c) 2010-2012 Broadcom. All rights reserved.
- */
-
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/compat.h>
-#include <linux/miscdevice.h>
-
-#include "vchiq_core.h"
-#include "vchiq_ioctl.h"
-#include "vchiq_arm.h"
-#include "vchiq_debugfs.h"
-
-static const char *const ioctl_names[] = {
- "CONNECT",
- "SHUTDOWN",
- "CREATE_SERVICE",
- "REMOVE_SERVICE",
- "QUEUE_MESSAGE",
- "QUEUE_BULK_TRANSMIT",
- "QUEUE_BULK_RECEIVE",
- "AWAIT_COMPLETION",
- "DEQUEUE_MESSAGE",
- "GET_CLIENT_ID",
- "GET_CONFIG",
- "CLOSE_SERVICE",
- "USE_SERVICE",
- "RELEASE_SERVICE",
- "SET_SERVICE_OPTION",
- "DUMP_PHYS_MEM",
- "LIB_VERSION",
- "CLOSE_DELIVERED"
-};
-
-static_assert(ARRAY_SIZE(ioctl_names) == (VCHIQ_IOC_MAX + 1));
-
-static void
-user_service_free(void *userdata)
-{
- kfree(userdata);
-}
-
-static void close_delivered(struct user_service *user_service)
-{
- dev_dbg(user_service->service->state->dev,
- "arm: (handle=%x)\n", user_service->service->handle);
-
- if (user_service->close_pending) {
- /* Allow the underlying service to be culled */
- vchiq_service_put(user_service->service);
-
- /* Wake the user-thread blocked in close_ or remove_service */
- complete(&user_service->close_event);
-
- user_service->close_pending = 0;
- }
-}
-
-struct vchiq_io_copy_callback_context {
- struct vchiq_element *element;
- size_t element_offset;
- unsigned long elements_to_go;
-};
-
-static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest,
- size_t offset, size_t maxsize)
-{
- struct vchiq_io_copy_callback_context *cc = context;
- size_t total_bytes_copied = 0;
- size_t bytes_this_round;
-
- while (total_bytes_copied < maxsize) {
- if (!cc->elements_to_go)
- return total_bytes_copied;
-
- if (!cc->element->size) {
- cc->elements_to_go--;
- cc->element++;
- cc->element_offset = 0;
- continue;
- }
-
- bytes_this_round = min(cc->element->size - cc->element_offset,
- maxsize - total_bytes_copied);
-
- if (copy_from_user(dest + total_bytes_copied,
- cc->element->data + cc->element_offset,
- bytes_this_round))
- return -EFAULT;
-
- cc->element_offset += bytes_this_round;
- total_bytes_copied += bytes_this_round;
-
- if (cc->element_offset == cc->element->size) {
- cc->elements_to_go--;
- cc->element++;
- cc->element_offset = 0;
- }
- }
-
- return maxsize;
-}
-
-static int
-vchiq_ioc_queue_message(struct vchiq_instance *instance, unsigned int handle,
- struct vchiq_element *elements, unsigned long count)
-{
- struct vchiq_io_copy_callback_context context;
- int status = 0;
- unsigned long i;
- size_t total_size = 0;
-
- context.element = elements;
- context.element_offset = 0;
- context.elements_to_go = count;
-
- for (i = 0; i < count; i++) {
- if (!elements[i].data && elements[i].size != 0)
- return -EFAULT;
-
- total_size += elements[i].size;
- }
-
- status = vchiq_queue_message(instance, handle, vchiq_ioc_copy_element_data,
- &context, total_size);
-
- if (status == -EINVAL)
- return -EIO;
- else if (status == -EAGAIN)
- return -EINTR;
- return 0;
-}
-
-static int vchiq_ioc_create_service(struct vchiq_instance *instance,
- struct vchiq_create_service *args)
-{
- struct user_service *user_service = NULL;
- struct vchiq_service *service;
- int status = 0;
- struct vchiq_service_params_kernel params;
- int srvstate;
-
- if (args->is_open && !instance->connected)
- return -ENOTCONN;
-
- user_service = kmalloc(sizeof(*user_service), GFP_KERNEL);
- if (!user_service)
- return -ENOMEM;
-
- if (args->is_open) {
- srvstate = VCHIQ_SRVSTATE_OPENING;
- } else {
- srvstate = instance->connected ?
- VCHIQ_SRVSTATE_LISTENING : VCHIQ_SRVSTATE_HIDDEN;
- }
-
- params = (struct vchiq_service_params_kernel) {
- .fourcc = args->params.fourcc,
- .callback = service_callback,
- .userdata = user_service,
- .version = args->params.version,
- .version_min = args->params.version_min,
- };
- service = vchiq_add_service_internal(instance->state, &params,
- srvstate, instance,
- user_service_free);
- if (!service) {
- kfree(user_service);
- return -EEXIST;
- }
-
- user_service->service = service;
- user_service->userdata = args->params.userdata;
- user_service->instance = instance;
- user_service->is_vchi = (args->is_vchi != 0);
- user_service->dequeue_pending = 0;
- user_service->close_pending = 0;
- user_service->message_available_pos = instance->completion_remove - 1;
- user_service->msg_insert = 0;
- user_service->msg_remove = 0;
- init_completion(&user_service->insert_event);
- init_completion(&user_service->remove_event);
- init_completion(&user_service->close_event);
-
- if (args->is_open) {
- status = vchiq_open_service_internal(service, instance->pid);
- if (status) {
- vchiq_remove_service(instance, service->handle);
- return (status == -EAGAIN) ?
- -EINTR : -EIO;
- }
- }
- args->handle = service->handle;
-
- return 0;
-}
-
-static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance,
- struct vchiq_dequeue_message *args)
-{
- struct user_service *user_service;
- struct vchiq_service *service;
- struct vchiq_header *header;
- int ret;
-
- DEBUG_INITIALISE(instance->state->local);
- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
- service = find_service_for_instance(instance, args->handle);
- if (!service)
- return -EINVAL;
-
- user_service = (struct user_service *)service->base.userdata;
- if (user_service->is_vchi == 0) {
- ret = -EINVAL;
- goto out;
- }
-
- spin_lock(&service->state->msg_queue_spinlock);
- if (user_service->msg_remove == user_service->msg_insert) {
- if (!args->blocking) {
- spin_unlock(&service->state->msg_queue_spinlock);
- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
- ret = -EWOULDBLOCK;
- goto out;
- }
- user_service->dequeue_pending = 1;
- ret = 0;
- do {
- spin_unlock(&service->state->msg_queue_spinlock);
- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
- if (wait_for_completion_interruptible(&user_service->insert_event)) {
- dev_dbg(service->state->dev, "arm: DEQUEUE_MESSAGE interrupted\n");
- ret = -EINTR;
- break;
- }
- spin_lock(&service->state->msg_queue_spinlock);
- } while (user_service->msg_remove == user_service->msg_insert);
-
- if (ret)
- goto out;
- }
-
- if (WARN_ON_ONCE((int)(user_service->msg_insert -
- user_service->msg_remove) < 0)) {
- spin_unlock(&service->state->msg_queue_spinlock);
- ret = -EINVAL;
- goto out;
- }
-
- header = user_service->msg_queue[user_service->msg_remove &
- (MSG_QUEUE_SIZE - 1)];
- user_service->msg_remove++;
- spin_unlock(&service->state->msg_queue_spinlock);
-
- complete(&user_service->remove_event);
- if (!header) {
- ret = -ENOTCONN;
- } else if (header->size <= args->bufsize) {
- /* Copy to user space if msgbuf is not NULL */
- if (!args->buf || (copy_to_user(args->buf, header->data, header->size) == 0)) {
- ret = header->size;
- vchiq_release_message(instance, service->handle, header);
- } else {
- ret = -EFAULT;
- }
- } else {
- dev_err(service->state->dev,
- "arm: header %p: bufsize %x < size %x\n",
- header, args->bufsize, header->size);
- WARN(1, "invalid size\n");
- ret = -EMSGSIZE;
- }
- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
-out:
- vchiq_service_put(service);
- return ret;
-}
-
-static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
- struct vchiq_queue_bulk_transfer *args,
- enum vchiq_bulk_dir dir,
- enum vchiq_bulk_mode __user *mode)
-{
- struct vchiq_service *service;
- struct bulk_waiter_node *waiter = NULL, *iter;
- struct vchiq_bulk bulk_params = {};
- int status = 0;
- int ret;
-
- service = find_service_for_instance(instance, args->handle);
- if (!service)
- return -EINVAL;
-
- if (args->mode == VCHIQ_BULK_MODE_BLOCKING) {
- waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
- if (!waiter) {
- ret = -ENOMEM;
- goto out;
- }
-
- bulk_params.uoffset = args->data;
- bulk_params.mode = args->mode;
- bulk_params.size = args->size;
- bulk_params.dir = dir;
- bulk_params.waiter = &waiter->bulk_waiter;
-
- status = vchiq_bulk_xfer_blocking(instance, args->handle,
- &bulk_params);
- } else if (args->mode == VCHIQ_BULK_MODE_WAITING) {
- mutex_lock(&instance->bulk_waiter_list_mutex);
- list_for_each_entry(iter, &instance->bulk_waiter_list,
- list) {
- if (iter->pid == current->pid) {
- list_del(&iter->list);
- waiter = iter;
- break;
- }
- }
- mutex_unlock(&instance->bulk_waiter_list_mutex);
- if (!waiter) {
- dev_err(service->state->dev,
- "arm: no bulk_waiter found for pid %d\n", current->pid);
- ret = -ESRCH;
- goto out;
- }
- dev_dbg(service->state->dev, "arm: found bulk_waiter %p for pid %d\n",
- waiter, current->pid);
-
- status = vchiq_bulk_xfer_waiting(instance, args->handle,
- &waiter->bulk_waiter);
- } else {
- bulk_params.uoffset = args->data;
- bulk_params.mode = args->mode;
- bulk_params.size = args->size;
- bulk_params.dir = dir;
- bulk_params.cb_userdata = args->userdata;
-
- status = vchiq_bulk_xfer_callback(instance, args->handle,
- &bulk_params);
- }
-
- if (!waiter) {
- ret = 0;
- goto out;
- }
-
- if ((status != -EAGAIN) || fatal_signal_pending(current) ||
- !waiter->bulk_waiter.bulk) {
- if (waiter->bulk_waiter.bulk) {
- /* Cancel the signal when the transfer completes. */
- spin_lock(&service->state->bulk_waiter_spinlock);
- waiter->bulk_waiter.bulk->waiter = NULL;
- spin_unlock(&service->state->bulk_waiter_spinlock);
- }
- kfree(waiter);
- ret = 0;
- } else {
- const enum vchiq_bulk_mode mode_waiting =
- VCHIQ_BULK_MODE_WAITING;
- waiter->pid = current->pid;
- mutex_lock(&instance->bulk_waiter_list_mutex);
- list_add(&waiter->list, &instance->bulk_waiter_list);
- mutex_unlock(&instance->bulk_waiter_list_mutex);
- dev_dbg(service->state->dev, "arm: saved bulk_waiter %p for pid %d\n",
- waiter, current->pid);
-
- ret = put_user(mode_waiting, mode);
- }
-out:
- vchiq_service_put(service);
- if (ret)
- return ret;
- else if (status == -EINVAL)
- return -EIO;
- else if (status == -EAGAIN)
- return -EINTR;
- return 0;
-}
-
-/* read a user pointer value from an array pointers in user space */
-static inline int vchiq_get_user_ptr(void __user **buf, void __user *ubuf, int index)
-{
- int ret;
-
- if (in_compat_syscall()) {
- compat_uptr_t ptr32;
- compat_uptr_t __user *uptr = ubuf;
-
- ret = get_user(ptr32, uptr + index);
- if (ret)
- return ret;
-
- *buf = compat_ptr(ptr32);
- } else {
- uintptr_t ptr, __user *uptr = ubuf;
-
- ret = get_user(ptr, uptr + index);
-
- if (ret)
- return ret;
-
- *buf = (void __user *)ptr;
- }
-
- return 0;
-}
-
-struct vchiq_completion_data32 {
- enum vchiq_reason reason;
- compat_uptr_t header;
- compat_uptr_t service_userdata;
- compat_uptr_t cb_data;
-};
-
-static int vchiq_put_completion(struct vchiq_completion_data __user *buf,
- struct vchiq_completion_data *completion,
- int index)
-{
- struct vchiq_completion_data32 __user *buf32 = (void __user *)buf;
-
- if (in_compat_syscall()) {
- struct vchiq_completion_data32 tmp = {
- .reason = completion->reason,
- .header = ptr_to_compat(completion->header),
- .service_userdata = ptr_to_compat(completion->service_userdata),
- .cb_data = ptr_to_compat(completion->cb_userdata),
- };
- if (copy_to_user(&buf32[index], &tmp, sizeof(tmp)))
- return -EFAULT;
- } else {
- if (copy_to_user(&buf[index], completion, sizeof(*completion)))
- return -EFAULT;
- }
-
- return 0;
-}
-
-static int vchiq_ioc_await_completion(struct vchiq_instance *instance,
- struct vchiq_await_completion *args,
- int __user *msgbufcountp)
-{
- int msgbufcount;
- int remove;
- int ret;
-
- DEBUG_INITIALISE(instance->state->local);
-
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
- if (!instance->connected)
- return -ENOTCONN;
-
- mutex_lock(&instance->completion_mutex);
-
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
- while ((instance->completion_remove == instance->completion_insert) && !instance->closing) {
- int rc;
-
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
- mutex_unlock(&instance->completion_mutex);
- rc = wait_for_completion_interruptible(&instance->insert_event);
- mutex_lock(&instance->completion_mutex);
- if (rc) {
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
- dev_dbg(instance->state->dev, "arm: AWAIT_COMPLETION interrupted\n");
- ret = -EINTR;
- goto out;
- }
- }
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
-
- msgbufcount = args->msgbufcount;
- remove = instance->completion_remove;
-
- for (ret = 0; ret < args->count; ret++) {
- struct vchiq_completion_data_kernel *completion;
- struct vchiq_completion_data user_completion;
- struct vchiq_service *service;
- struct user_service *user_service;
- struct vchiq_header *header;
-
- if (remove == instance->completion_insert)
- break;
-
- completion = &instance->completions[remove & (MAX_COMPLETIONS - 1)];
-
- /*
- * A read memory barrier is needed to stop
- * prefetch of a stale completion record
- */
- rmb();
-
- service = completion->service_userdata;
- user_service = service->base.userdata;
-
- memset(&user_completion, 0, sizeof(user_completion));
- user_completion = (struct vchiq_completion_data) {
- .reason = completion->reason,
- .service_userdata = user_service->userdata,
- };
-
- header = completion->header;
- if (header) {
- void __user *msgbuf;
- int msglen;
-
- msglen = header->size + sizeof(struct vchiq_header);
- /* This must be a VCHIQ-style service */
- if (args->msgbufsize < msglen) {
- dev_err(service->state->dev,
- "arm: header %p: msgbufsize %x < msglen %x\n",
- header, args->msgbufsize, msglen);
- WARN(1, "invalid message size\n");
- if (ret == 0)
- ret = -EMSGSIZE;
- break;
- }
- if (msgbufcount <= 0)
- /* Stall here for lack of a buffer for the message. */
- break;
- /* Get the pointer from user space */
- msgbufcount--;
- if (vchiq_get_user_ptr(&msgbuf, args->msgbufs,
- msgbufcount)) {
- if (ret == 0)
- ret = -EFAULT;
- break;
- }
-
- /* Copy the message to user space */
- if (copy_to_user(msgbuf, header, msglen)) {
- if (ret == 0)
- ret = -EFAULT;
- break;
- }
-
- /* Now it has been copied, the message can be released. */
- vchiq_release_message(instance, service->handle, header);
-
- /* The completion must point to the msgbuf. */
- user_completion.header = msgbuf;
- }
-
- if ((completion->reason == VCHIQ_SERVICE_CLOSED) &&
- !instance->use_close_delivered)
- vchiq_service_put(service);
-
- user_completion.cb_userdata = completion->cb_userdata;
-
- if (vchiq_put_completion(args->buf, &user_completion, ret)) {
- if (ret == 0)
- ret = -EFAULT;
- break;
- }
-
- /*
- * Ensure that the above copy has completed
- * before advancing the remove pointer.
- */
- mb();
- remove++;
- instance->completion_remove = remove;
- }
-
- if (msgbufcount != args->msgbufcount) {
- if (put_user(msgbufcount, msgbufcountp))
- ret = -EFAULT;
- }
-out:
- if (ret)
- complete(&instance->remove_event);
- mutex_unlock(&instance->completion_mutex);
- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
-
- return ret;
-}
-
-static long
-vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct vchiq_instance *instance = file->private_data;
- int status = 0;
- struct vchiq_service *service = NULL;
- long ret = 0;
- int i, rc;
-
- dev_dbg(instance->state->dev, "arm: instance %p, cmd %s, arg %lx\n", instance,
- ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
- ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
-
- switch (cmd) {
- case VCHIQ_IOC_SHUTDOWN:
- if (!instance->connected)
- break;
-
- /* Remove all services */
- i = 0;
- while ((service = next_service_by_instance(instance->state,
- instance, &i))) {
- status = vchiq_remove_service(instance, service->handle);
- vchiq_service_put(service);
- if (status)
- break;
- }
- service = NULL;
-
- if (!status) {
- /* Wake the completion thread and ask it to exit */
- instance->closing = 1;
- complete(&instance->insert_event);
- }
-
- break;
-
- case VCHIQ_IOC_CONNECT:
- if (instance->connected) {
- ret = -EINVAL;
- break;
- }
- rc = mutex_lock_killable(&instance->state->mutex);
- if (rc) {
- dev_err(instance->state->dev,
- "arm: vchiq: connect: could not lock mutex for state %d: %d\n",
- instance->state->id, rc);
- ret = -EINTR;
- break;
- }
- status = vchiq_connect_internal(instance->state, instance);
- mutex_unlock(&instance->state->mutex);
-
- if (!status)
- instance->connected = 1;
- else
- dev_err(instance->state->dev,
- "arm: vchiq: could not connect: %d\n", status);
- break;
-
- case VCHIQ_IOC_CREATE_SERVICE: {
- struct vchiq_create_service __user *argp;
- struct vchiq_create_service args;
-
- argp = (void __user *)arg;
- if (copy_from_user(&args, argp, sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- ret = vchiq_ioc_create_service(instance, &args);
- if (ret < 0)
- break;
-
- if (put_user(args.handle, &argp->handle)) {
- vchiq_remove_service(instance, args.handle);
- ret = -EFAULT;
- }
- } break;
-
- case VCHIQ_IOC_CLOSE_SERVICE:
- case VCHIQ_IOC_REMOVE_SERVICE: {
- unsigned int handle = (unsigned int)arg;
- struct user_service *user_service;
-
- service = find_service_for_instance(instance, handle);
- if (!service) {
- ret = -EINVAL;
- break;
- }
-
- user_service = service->base.userdata;
-
- /*
- * close_pending is false on first entry, and when the
- * wait in vchiq_close_service has been interrupted.
- */
- if (!user_service->close_pending) {
- status = (cmd == VCHIQ_IOC_CLOSE_SERVICE) ?
- vchiq_close_service(instance, service->handle) :
- vchiq_remove_service(instance, service->handle);
- if (status)
- break;
- }
-
- /*
- * close_pending is true once the underlying service
- * has been closed until the client library calls the
- * CLOSE_DELIVERED ioctl, signalling close_event.
- */
- if (user_service->close_pending &&
- wait_for_completion_interruptible(&user_service->close_event))
- status = -EAGAIN;
- break;
- }
-
- case VCHIQ_IOC_USE_SERVICE:
- case VCHIQ_IOC_RELEASE_SERVICE: {
- unsigned int handle = (unsigned int)arg;
-
- service = find_service_for_instance(instance, handle);
- if (service) {
- ret = (cmd == VCHIQ_IOC_USE_SERVICE) ?
- vchiq_use_service_internal(service) :
- vchiq_release_service_internal(service);
- if (ret) {
- dev_err(instance->state->dev,
- "suspend: cmd %s returned error %ld for service %p4cc:%03d\n",
- (cmd == VCHIQ_IOC_USE_SERVICE) ?
- "VCHIQ_IOC_USE_SERVICE" :
- "VCHIQ_IOC_RELEASE_SERVICE",
- ret, &service->base.fourcc,
- service->client_id);
- }
- } else {
- ret = -EINVAL;
- }
- } break;
-
- case VCHIQ_IOC_QUEUE_MESSAGE: {
- struct vchiq_queue_message args;
-
- if (copy_from_user(&args, (const void __user *)arg,
- sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- service = find_service_for_instance(instance, args.handle);
-
- if (service && (args.count <= MAX_ELEMENTS)) {
- /* Copy elements into kernel space */
- struct vchiq_element elements[MAX_ELEMENTS];
-
- if (copy_from_user(elements, args.elements,
- args.count * sizeof(struct vchiq_element)) == 0)
- ret = vchiq_ioc_queue_message(instance, args.handle, elements,
- args.count);
- else
- ret = -EFAULT;
- } else {
- ret = -EINVAL;
- }
- } break;
-
- case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
- case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
- struct vchiq_queue_bulk_transfer args;
- struct vchiq_queue_bulk_transfer __user *argp;
-
- enum vchiq_bulk_dir dir =
- (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
- VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
-
- argp = (void __user *)arg;
- if (copy_from_user(&args, argp, sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- ret = vchiq_irq_queue_bulk_tx_rx(instance, &args,
- dir, &argp->mode);
- } break;
-
- case VCHIQ_IOC_AWAIT_COMPLETION: {
- struct vchiq_await_completion args;
- struct vchiq_await_completion __user *argp;
-
- argp = (void __user *)arg;
- if (copy_from_user(&args, argp, sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- ret = vchiq_ioc_await_completion(instance, &args,
- &argp->msgbufcount);
- } break;
-
- case VCHIQ_IOC_DEQUEUE_MESSAGE: {
- struct vchiq_dequeue_message args;
-
- if (copy_from_user(&args, (const void __user *)arg,
- sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- ret = vchiq_ioc_dequeue_message(instance, &args);
- } break;
-
- case VCHIQ_IOC_GET_CLIENT_ID: {
- unsigned int handle = (unsigned int)arg;
-
- ret = vchiq_get_client_id(instance, handle);
- } break;
-
- case VCHIQ_IOC_GET_CONFIG: {
- struct vchiq_get_config args;
- struct vchiq_config config;
-
- if (copy_from_user(&args, (const void __user *)arg,
- sizeof(args))) {
- ret = -EFAULT;
- break;
- }
- if (args.config_size > sizeof(config)) {
- ret = -EINVAL;
- break;
- }
-
- vchiq_get_config(&config);
- if (copy_to_user(args.pconfig, &config, args.config_size)) {
- ret = -EFAULT;
- break;
- }
- } break;
-
- case VCHIQ_IOC_SET_SERVICE_OPTION: {
- struct vchiq_set_service_option args;
-
- if (copy_from_user(&args, (const void __user *)arg,
- sizeof(args))) {
- ret = -EFAULT;
- break;
- }
-
- service = find_service_for_instance(instance, args.handle);
- if (!service) {
- ret = -EINVAL;
- break;
- }
-
- ret = vchiq_set_service_option(instance, args.handle, args.option,
- args.value);
- } break;
-
- case VCHIQ_IOC_LIB_VERSION: {
- unsigned int lib_version = (unsigned int)arg;
-
- if (lib_version < VCHIQ_VERSION_MIN)
- ret = -EINVAL;
- else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
- instance->use_close_delivered = 1;
- } break;
-
- case VCHIQ_IOC_CLOSE_DELIVERED: {
- unsigned int handle = (unsigned int)arg;
-
- service = find_closed_service_for_instance(instance, handle);
- if (service) {
- struct user_service *user_service =
- (struct user_service *)service->base.userdata;
- close_delivered(user_service);
- } else {
- ret = -EINVAL;
- }
- } break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- if (service)
- vchiq_service_put(service);
-
- if (ret == 0) {
- if (status == -EINVAL)
- ret = -EIO;
- else if (status == -EAGAIN)
- ret = -EINTR;
- }
-
- if (!status && (ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK)) {
- dev_dbg(instance->state->dev,
- "arm: ioctl instance %p, cmd %s -> status %d, %ld\n",
- instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
- ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
- } else {
- dev_dbg(instance->state->dev,
- "arm: ioctl instance %p, cmd %s -> status %d\n, %ld\n",
- instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
- ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
- }
-
- return ret;
-}
-
-#if defined(CONFIG_COMPAT)
-
-struct vchiq_service_params32 {
- int fourcc;
- compat_uptr_t callback;
- compat_uptr_t userdata;
- short version; /* Increment for non-trivial changes */
- short version_min; /* Update for incompatible changes */
-};
-
-struct vchiq_create_service32 {
- struct vchiq_service_params32 params;
- int is_open;
- int is_vchi;
- unsigned int handle; /* OUT */
-};
-
-#define VCHIQ_IOC_CREATE_SERVICE32 \
- _IOWR(VCHIQ_IOC_MAGIC, 2, struct vchiq_create_service32)
-
-static long
-vchiq_compat_ioctl_create_service(struct file *file, unsigned int cmd,
- struct vchiq_create_service32 __user *ptrargs32)
-{
- struct vchiq_create_service args;
- struct vchiq_create_service32 args32;
- struct vchiq_instance *instance = file->private_data;
- long ret;
-
- if (copy_from_user(&args32, ptrargs32, sizeof(args32)))
- return -EFAULT;
-
- args = (struct vchiq_create_service) {
- .params = {
- .fourcc = args32.params.fourcc,
- .callback = compat_ptr(args32.params.callback),
- .userdata = compat_ptr(args32.params.userdata),
- .version = args32.params.version,
- .version_min = args32.params.version_min,
- },
- .is_open = args32.is_open,
- .is_vchi = args32.is_vchi,
- .handle = args32.handle,
- };
-
- ret = vchiq_ioc_create_service(instance, &args);
- if (ret < 0)
- return ret;
-
- if (put_user(args.handle, &ptrargs32->handle)) {
- vchiq_remove_service(instance, args.handle);
- return -EFAULT;
- }
-
- return 0;
-}
-
-struct vchiq_element32 {
- compat_uptr_t data;
- unsigned int size;
-};
-
-struct vchiq_queue_message32 {
- unsigned int handle;
- unsigned int count;
- compat_uptr_t elements;
-};
-
-#define VCHIQ_IOC_QUEUE_MESSAGE32 \
- _IOW(VCHIQ_IOC_MAGIC, 4, struct vchiq_queue_message32)
-
-static long
-vchiq_compat_ioctl_queue_message(struct file *file,
- unsigned int cmd,
- struct vchiq_queue_message32 __user *arg)
-{
- struct vchiq_queue_message args;
- struct vchiq_queue_message32 args32;
- struct vchiq_service *service;
- struct vchiq_instance *instance = file->private_data;
- int ret;
-
- if (copy_from_user(&args32, arg, sizeof(args32)))
- return -EFAULT;
-
- args = (struct vchiq_queue_message) {
- .handle = args32.handle,
- .count = args32.count,
- .elements = compat_ptr(args32.elements),
- };
-
- if (args32.count > MAX_ELEMENTS)
- return -EINVAL;
-
- service = find_service_for_instance(instance, args.handle);
- if (!service)
- return -EINVAL;
-
- if (args32.elements && args32.count) {
- struct vchiq_element32 element32[MAX_ELEMENTS];
- struct vchiq_element elements[MAX_ELEMENTS];
- unsigned int count;
-
- if (copy_from_user(&element32, args.elements,
- sizeof(element32))) {
- vchiq_service_put(service);
- return -EFAULT;
- }
-
- for (count = 0; count < args32.count; count++) {
- elements[count].data =
- compat_ptr(element32[count].data);
- elements[count].size = element32[count].size;
- }
- ret = vchiq_ioc_queue_message(instance, args.handle, elements,
- args.count);
- } else {
- ret = -EINVAL;
- }
- vchiq_service_put(service);
-
- return ret;
-}
-
-struct vchiq_queue_bulk_transfer32 {
- unsigned int handle;
- compat_uptr_t data;
- unsigned int size;
- compat_uptr_t userdata;
- enum vchiq_bulk_mode mode;
-};
-
-#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 \
- _IOWR(VCHIQ_IOC_MAGIC, 5, struct vchiq_queue_bulk_transfer32)
-#define VCHIQ_IOC_QUEUE_BULK_RECEIVE32 \
- _IOWR(VCHIQ_IOC_MAGIC, 6, struct vchiq_queue_bulk_transfer32)
-
-static long
-vchiq_compat_ioctl_queue_bulk(struct file *file,
- unsigned int cmd,
- struct vchiq_queue_bulk_transfer32 __user *argp)
-{
- struct vchiq_queue_bulk_transfer32 args32;
- struct vchiq_queue_bulk_transfer args;
- enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32) ?
- VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
-
- if (copy_from_user(&args32, argp, sizeof(args32)))
- return -EFAULT;
-
- args = (struct vchiq_queue_bulk_transfer) {
- .handle = args32.handle,
- .data = compat_ptr(args32.data),
- .size = args32.size,
- .userdata = compat_ptr(args32.userdata),
- .mode = args32.mode,
- };
-
- return vchiq_irq_queue_bulk_tx_rx(file->private_data, &args,
- dir, &argp->mode);
-}
-
-struct vchiq_await_completion32 {
- unsigned int count;
- compat_uptr_t buf;
- unsigned int msgbufsize;
- unsigned int msgbufcount; /* IN/OUT */
- compat_uptr_t msgbufs;
-};
-
-#define VCHIQ_IOC_AWAIT_COMPLETION32 \
- _IOWR(VCHIQ_IOC_MAGIC, 7, struct vchiq_await_completion32)
-
-static long
-vchiq_compat_ioctl_await_completion(struct file *file,
- unsigned int cmd,
- struct vchiq_await_completion32 __user *argp)
-{
- struct vchiq_await_completion args;
- struct vchiq_await_completion32 args32;
-
- if (copy_from_user(&args32, argp, sizeof(args32)))
- return -EFAULT;
-
- args = (struct vchiq_await_completion) {
- .count = args32.count,
- .buf = compat_ptr(args32.buf),
- .msgbufsize = args32.msgbufsize,
- .msgbufcount = args32.msgbufcount,
- .msgbufs = compat_ptr(args32.msgbufs),
- };
-
- return vchiq_ioc_await_completion(file->private_data, &args,
- &argp->msgbufcount);
-}
-
-struct vchiq_dequeue_message32 {
- unsigned int handle;
- int blocking;
- unsigned int bufsize;
- compat_uptr_t buf;
-};
-
-#define VCHIQ_IOC_DEQUEUE_MESSAGE32 \
- _IOWR(VCHIQ_IOC_MAGIC, 8, struct vchiq_dequeue_message32)
-
-static long
-vchiq_compat_ioctl_dequeue_message(struct file *file,
- unsigned int cmd,
- struct vchiq_dequeue_message32 __user *arg)
-{
- struct vchiq_dequeue_message32 args32;
- struct vchiq_dequeue_message args;
-
- if (copy_from_user(&args32, arg, sizeof(args32)))
- return -EFAULT;
-
- args = (struct vchiq_dequeue_message) {
- .handle = args32.handle,
- .blocking = args32.blocking,
- .bufsize = args32.bufsize,
- .buf = compat_ptr(args32.buf),
- };
-
- return vchiq_ioc_dequeue_message(file->private_data, &args);
-}
-
-struct vchiq_get_config32 {
- unsigned int config_size;
- compat_uptr_t pconfig;
-};
-
-#define VCHIQ_IOC_GET_CONFIG32 \
- _IOWR(VCHIQ_IOC_MAGIC, 10, struct vchiq_get_config32)
-
-static long
-vchiq_compat_ioctl_get_config(struct file *file,
- unsigned int cmd,
- struct vchiq_get_config32 __user *arg)
-{
- struct vchiq_get_config32 args32;
- struct vchiq_config config;
- void __user *ptr;
-
- if (copy_from_user(&args32, arg, sizeof(args32)))
- return -EFAULT;
- if (args32.config_size > sizeof(config))
- return -EINVAL;
-
- vchiq_get_config(&config);
- ptr = compat_ptr(args32.pconfig);
- if (copy_to_user(ptr, &config, args32.config_size))
- return -EFAULT;
-
- return 0;
-}
-
-static long
-vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- void __user *argp = compat_ptr(arg);
-
- switch (cmd) {
- case VCHIQ_IOC_CREATE_SERVICE32:
- return vchiq_compat_ioctl_create_service(file, cmd, argp);
- case VCHIQ_IOC_QUEUE_MESSAGE32:
- return vchiq_compat_ioctl_queue_message(file, cmd, argp);
- case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32:
- case VCHIQ_IOC_QUEUE_BULK_RECEIVE32:
- return vchiq_compat_ioctl_queue_bulk(file, cmd, argp);
- case VCHIQ_IOC_AWAIT_COMPLETION32:
- return vchiq_compat_ioctl_await_completion(file, cmd, argp);
- case VCHIQ_IOC_DEQUEUE_MESSAGE32:
- return vchiq_compat_ioctl_dequeue_message(file, cmd, argp);
- case VCHIQ_IOC_GET_CONFIG32:
- return vchiq_compat_ioctl_get_config(file, cmd, argp);
- default:
- return vchiq_ioctl(file, cmd, (unsigned long)argp);
- }
-}
-
-#endif
-
-static int vchiq_open(struct inode *inode, struct file *file)
-{
- struct miscdevice *vchiq_miscdev = file->private_data;
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(vchiq_miscdev->parent);
- struct vchiq_state *state = &mgmt->state;
- struct vchiq_instance *instance;
-
- dev_dbg(state->dev, "arm: vchiq open\n");
-
- if (!vchiq_remote_initialised(state)) {
- dev_dbg(state->dev, "arm: vchiq has no connection to VideoCore\n");
- return -ENOTCONN;
- }
-
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
- if (!instance)
- return -ENOMEM;
-
- instance->state = state;
- instance->pid = current->tgid;
-
- vchiq_debugfs_add_instance(instance);
-
- init_completion(&instance->insert_event);
- init_completion(&instance->remove_event);
- mutex_init(&instance->completion_mutex);
- mutex_init(&instance->bulk_waiter_list_mutex);
- INIT_LIST_HEAD(&instance->bulk_waiter_list);
-
- file->private_data = instance;
-
- return 0;
-}
-
-static int vchiq_release(struct inode *inode, struct file *file)
-{
- struct vchiq_instance *instance = file->private_data;
- struct vchiq_state *state = instance->state;
- struct vchiq_service *service;
- int ret = 0;
- int i;
-
- dev_dbg(state->dev, "arm: instance=%p\n", instance);
-
- if (!vchiq_remote_initialised(state)) {
- ret = -EPERM;
- goto out;
- }
-
- /* Ensure videocore is awake to allow termination. */
- vchiq_use_internal(instance->state, NULL, USE_TYPE_VCHIQ);
-
- mutex_lock(&instance->completion_mutex);
-
- /* Wake the completion thread and ask it to exit */
- instance->closing = 1;
- complete(&instance->insert_event);
-
- mutex_unlock(&instance->completion_mutex);
-
- /* Wake the slot handler if the completion queue is full. */
- complete(&instance->remove_event);
-
- /* Mark all services for termination... */
- i = 0;
- while ((service = next_service_by_instance(state, instance, &i))) {
- struct user_service *user_service = service->base.userdata;
-
- /* Wake the slot handler if the msg queue is full. */
- complete(&user_service->remove_event);
-
- vchiq_terminate_service_internal(service);
- vchiq_service_put(service);
- }
-
- /* ...and wait for them to die */
- i = 0;
- while ((service = next_service_by_instance(state, instance, &i))) {
- struct user_service *user_service = service->base.userdata;
-
- wait_for_completion(&service->remove_event);
-
- if (WARN_ON(service->srvstate != VCHIQ_SRVSTATE_FREE)) {
- vchiq_service_put(service);
- break;
- }
-
- spin_lock(&service->state->msg_queue_spinlock);
-
- while (user_service->msg_remove != user_service->msg_insert) {
- struct vchiq_header *header;
- int m = user_service->msg_remove & (MSG_QUEUE_SIZE - 1);
-
- header = user_service->msg_queue[m];
- user_service->msg_remove++;
- spin_unlock(&service->state->msg_queue_spinlock);
-
- if (header)
- vchiq_release_message(instance, service->handle, header);
- spin_lock(&service->state->msg_queue_spinlock);
- }
-
- spin_unlock(&service->state->msg_queue_spinlock);
-
- vchiq_service_put(service);
- }
-
- /* Release any closed services */
- while (instance->completion_remove != instance->completion_insert) {
- struct vchiq_completion_data_kernel *completion;
- struct vchiq_service *service;
-
- completion = &instance->completions[instance->completion_remove
- & (MAX_COMPLETIONS - 1)];
- service = completion->service_userdata;
- if (completion->reason == VCHIQ_SERVICE_CLOSED) {
- struct user_service *user_service =
- service->base.userdata;
-
- /* Wake any blocked user-thread */
- if (instance->use_close_delivered)
- complete(&user_service->close_event);
- vchiq_service_put(service);
- }
- instance->completion_remove++;
- }
-
- /* Release the PEER service count. */
- vchiq_release_internal(instance->state, NULL);
-
- free_bulk_waiter(instance);
-
- vchiq_debugfs_remove_instance(instance);
-
- kfree(instance);
- file->private_data = NULL;
-
-out:
- return ret;
-}
-
-static const struct file_operations
-vchiq_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = vchiq_ioctl,
-#if defined(CONFIG_COMPAT)
- .compat_ioctl = vchiq_compat_ioctl,
-#endif
- .open = vchiq_open,
- .release = vchiq_release,
-};
-
-static struct miscdevice vchiq_miscdev = {
- .fops = &vchiq_fops,
- .minor = MISC_DYNAMIC_MINOR,
- .name = "vchiq",
-
-};
-
-/**
- * vchiq_register_chrdev - Register the char driver for vchiq
- * and create the necessary class and
- * device files in userspace.
- * @parent: The parent of the char device.
- *
- * Returns 0 on success else returns the error code.
- */
-int vchiq_register_chrdev(struct device *parent)
-{
- vchiq_miscdev.parent = parent;
-
- return misc_register(&vchiq_miscdev);
-}
-
-/**
- * vchiq_deregister_chrdev - Deregister and cleanup the vchiq char
- * driver and device files
- */
-void vchiq_deregister_chrdev(void)
-{
- misc_deregister(&vchiq_miscdev);
-}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
deleted file mode 100644
index afb71a83cfe7..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
-
-#ifndef VCHIQ_IOCTLS_H
-#define VCHIQ_IOCTLS_H
-
-#include <linux/ioctl.h>
-
-#include "../../include/linux/raspberrypi/vchiq.h"
-
-#define VCHIQ_IOC_MAGIC 0xc4
-#define VCHIQ_INVALID_HANDLE (~0)
-
-struct vchiq_service_params {
- int fourcc;
- int __user (*callback)(enum vchiq_reason reason,
- struct vchiq_header *header,
- unsigned int handle,
- void *bulk_userdata);
- void __user *userdata;
- short version; /* Increment for non-trivial changes */
- short version_min; /* Update for incompatible changes */
-};
-
-struct vchiq_create_service {
- struct vchiq_service_params params;
- int is_open;
- int is_vchi;
- unsigned int handle; /* OUT */
-};
-
-struct vchiq_queue_message {
- unsigned int handle;
- unsigned int count;
- const struct vchiq_element __user *elements;
-};
-
-struct vchiq_queue_bulk_transfer {
- unsigned int handle;
- void __user *data;
- unsigned int size;
- void __user *userdata;
- enum vchiq_bulk_mode mode;
-};
-
-struct vchiq_completion_data {
- enum vchiq_reason reason;
- struct vchiq_header __user *header;
- void __user *service_userdata;
- void __user *cb_userdata;
-};
-
-struct vchiq_await_completion {
- unsigned int count;
- struct vchiq_completion_data __user *buf;
- unsigned int msgbufsize;
- unsigned int msgbufcount; /* IN/OUT */
- void * __user *msgbufs;
-};
-
-struct vchiq_dequeue_message {
- unsigned int handle;
- int blocking;
- unsigned int bufsize;
- void __user *buf;
-};
-
-struct vchiq_get_config {
- unsigned int config_size;
- struct vchiq_config __user *pconfig;
-};
-
-struct vchiq_set_service_option {
- unsigned int handle;
- enum vchiq_service_option option;
- int value;
-};
-
-struct vchiq_dump_mem {
- void __user *virt_addr;
- size_t num_bytes;
-};
-
-#define VCHIQ_IOC_CONNECT _IO(VCHIQ_IOC_MAGIC, 0)
-#define VCHIQ_IOC_SHUTDOWN _IO(VCHIQ_IOC_MAGIC, 1)
-#define VCHIQ_IOC_CREATE_SERVICE \
- _IOWR(VCHIQ_IOC_MAGIC, 2, struct vchiq_create_service)
-#define VCHIQ_IOC_REMOVE_SERVICE _IO(VCHIQ_IOC_MAGIC, 3)
-#define VCHIQ_IOC_QUEUE_MESSAGE \
- _IOW(VCHIQ_IOC_MAGIC, 4, struct vchiq_queue_message)
-#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT \
- _IOWR(VCHIQ_IOC_MAGIC, 5, struct vchiq_queue_bulk_transfer)
-#define VCHIQ_IOC_QUEUE_BULK_RECEIVE \
- _IOWR(VCHIQ_IOC_MAGIC, 6, struct vchiq_queue_bulk_transfer)
-#define VCHIQ_IOC_AWAIT_COMPLETION \
- _IOWR(VCHIQ_IOC_MAGIC, 7, struct vchiq_await_completion)
-#define VCHIQ_IOC_DEQUEUE_MESSAGE \
- _IOWR(VCHIQ_IOC_MAGIC, 8, struct vchiq_dequeue_message)
-#define VCHIQ_IOC_GET_CLIENT_ID _IO(VCHIQ_IOC_MAGIC, 9)
-#define VCHIQ_IOC_GET_CONFIG \
- _IOWR(VCHIQ_IOC_MAGIC, 10, struct vchiq_get_config)
-#define VCHIQ_IOC_CLOSE_SERVICE _IO(VCHIQ_IOC_MAGIC, 11)
-#define VCHIQ_IOC_USE_SERVICE _IO(VCHIQ_IOC_MAGIC, 12)
-#define VCHIQ_IOC_RELEASE_SERVICE _IO(VCHIQ_IOC_MAGIC, 13)
-#define VCHIQ_IOC_SET_SERVICE_OPTION \
- _IOW(VCHIQ_IOC_MAGIC, 14, struct vchiq_set_service_option)
-#define VCHIQ_IOC_DUMP_PHYS_MEM \
- _IOW(VCHIQ_IOC_MAGIC, 15, struct vchiq_dump_mem)
-#define VCHIQ_IOC_LIB_VERSION _IO(VCHIQ_IOC_MAGIC, 16)
-#define VCHIQ_IOC_CLOSE_DELIVERED _IO(VCHIQ_IOC_MAGIC, 17)
-#define VCHIQ_IOC_MAX 17
-
-#endif
diff --git a/drivers/staging/vc04_services/vchiq-mmal/Kconfig b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
deleted file mode 100644
index c99525a0bb45..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config BCM2835_VCHIQ_MMAL
- tristate "BCM2835 MMAL VCHIQ service"
- depends on BCM2835_VCHIQ
- help
- Enables the MMAL API over VCHIQ interface as used for the
- majority of the multimedia services on VideoCore.
- Defaults to Y when the Broadcomd BCM2835 camera host is selected.
diff --git a/drivers/staging/vc04_services/vchiq-mmal/Makefile b/drivers/staging/vc04_services/vchiq-mmal/Makefile
deleted file mode 100644
index 6937f6534c26..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-bcm2835-mmal-vchiq-objs := mmal-vchiq.o
-
-obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += bcm2835-mmal-vchiq.o
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
deleted file mode 100644
index b33129403a30..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- *
- * MMAL structures
- *
- */
-#ifndef MMAL_COMMON_H
-#define MMAL_COMMON_H
-
-#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24))
-#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l')
-
-/** Special value signalling that time is not known */
-#define MMAL_TIME_UNKNOWN BIT_ULL(63)
-
-struct mmal_msg_context;
-
-/* mapping between v4l and mmal video modes */
-struct mmal_fmt {
- u32 fourcc; /* v4l2 format id */
- int flags; /* v4l2 flags field */
- u32 mmal;
- int depth;
- u32 mmal_component; /* MMAL component index to be used to encode */
- u32 ybbp; /* depth of first Y plane for planar formats */
- bool remove_padding; /* Does the GPU have to remove padding,
- * or can we do hide padding via bytesperline.
- */
-};
-
-/* buffer for one video frame */
-struct mmal_buffer {
- /* v4l buffer data -- must be first */
- struct vb2_v4l2_buffer vb;
-
- /* list of buffers available */
- struct list_head list;
-
- void *buffer; /* buffer pointer */
- unsigned long buffer_size; /* size of allocated buffer */
-
- struct mmal_msg_context *msg_context;
-
- unsigned long length;
- u32 mmal_flags;
- s64 dts;
- s64 pts;
-};
-
-/* */
-struct mmal_colourfx {
- s32 enable;
- u32 u;
- u32 v;
-};
-#endif
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
deleted file mode 100644
index e15ae7b24f73..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-#ifndef MMAL_ENCODINGS_H
-#define MMAL_ENCODINGS_H
-
-#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4')
-#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3')
-#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V')
-#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V')
-#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V')
-#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3')
-#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2')
-#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1')
-#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1')
-#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ')
-#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ')
-#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ')
-#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O')
-#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K')
-#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G')
-
-#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G')
-#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ')
-#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ')
-#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ')
-#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ')
-#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ')
-
-#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0')
-#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0')
-#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2')
-#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2')
-#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2')
-#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V')
-#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U')
-#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y')
-#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y')
-#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2')
-#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1')
-#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B')
-#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A')
-#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R')
-#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A')
-#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2')
-#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3')
-#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4')
-#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2')
-#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3')
-#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4')
-
-/** SAND Video (YUVUV128) format, native format understood by VideoCore.
- * This format is *not* opaque - if requested you will receive full frames
- * of YUV_UV video.
- */
-#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D')
-
-/** VideoCore opaque image format, image handles are returned to
- * the host but not the actual image data.
- */
-#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V')
-
-/** An EGL image handle
- */
-#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I')
-
-/* }@ */
-
-/** \name Pre-defined audio encodings */
-/* @{ */
-#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U')
-#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u')
-#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S')
-#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's')
-#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F')
-#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f')
-
-/* Pre-defined H264 encoding variants */
-
-/** ISO 14496-10 Annex B byte stream format */
-#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0
-/** ISO 14496-15 AVC stream format */
-#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1')
-/** Implicitly delineated NAL units without emulation prevention */
-#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ')
-
-/** \defgroup MmalColorSpace List of pre-defined video color spaces
- * This defines a list of common color spaces. This list isn't exhaustive and
- * is only provided as a convenience to avoid clients having to use FourCC
- * codes directly. However components are allowed to define and use their own
- * FourCC codes.
- */
-/* @{ */
-
-/** Unknown color space */
-#define MMAL_COLOR_SPACE_UNKNOWN 0
-/** ITU-R BT.601-5 [SDTV] */
-#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1')
-/** ITU-R BT.709-3 [HDTV] */
-#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9')
-/** JPEG JFIF */
-#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I')
-/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */
-#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C')
-/** Society of Motion Picture and Television Engineers 240M (1999) */
-#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0')
-/** ITU-R BT.470-2 System M */
-#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M')
-/** ITU-R BT.470-2 System BG */
-#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G')
-/** JPEG JFIF, but with 16..255 luma */
-#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6')
-/* @} MmalColorSpace List */
-
-#endif /* MMAL_ENCODINGS_H */
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
deleted file mode 100644
index 492d4c5dca08..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-#ifndef MMAL_MSG_COMMON_H
-#define MMAL_MSG_COMMON_H
-
-#include <linux/types.h>
-
-enum mmal_msg_status {
- MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */
- MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */
- MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */
- MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */
- MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */
- MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */
- MMAL_MSG_STATUS_ENXIO, /**< No such device or address */
- MMAL_MSG_STATUS_EIO, /**< I/O error */
- MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */
- MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */
- MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */
- MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */
- MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */
- MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */
- MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */
- MMAL_MSG_STATUS_EFAULT, /**< Bad address */
-};
-
-struct mmal_rect {
- s32 x; /**< x coordinate (from left) */
- s32 y; /**< y coordinate (from top) */
- s32 width; /**< width */
- s32 height; /**< height */
-};
-
-#endif /* MMAL_MSG_COMMON_H */
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
deleted file mode 100644
index 5569876d8c7d..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-#ifndef MMAL_MSG_FORMAT_H
-#define MMAL_MSG_FORMAT_H
-
-#include <linux/math.h>
-
-#include "mmal-msg-common.h"
-
-/* MMAL_ES_FORMAT_T */
-
-struct mmal_audio_format {
- u32 channels; /* Number of audio channels */
- u32 sample_rate; /* Sample rate */
-
- u32 bits_per_sample; /* Bits per sample */
- u32 block_align; /* Size of a block of data */
-};
-
-struct mmal_video_format {
- u32 width; /* Width of frame in pixels */
- u32 height; /* Height of frame in rows of pixels */
- struct mmal_rect crop; /* Visible region of the frame */
- struct s32_fract frame_rate; /* Frame rate */
- struct s32_fract par; /* Pixel aspect ratio */
-
- /*
- * FourCC specifying the color space of the video stream. See the
- * MmalColorSpace "pre-defined color spaces" for some examples.
- */
- u32 color_space;
-};
-
-struct mmal_subpicture_format {
- u32 x_offset;
- u32 y_offset;
-};
-
-union mmal_es_specific_format {
- struct mmal_audio_format audio;
- struct mmal_video_format video;
- struct mmal_subpicture_format subpicture;
-};
-
-/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */
-struct mmal_es_format_local {
- u32 type; /* enum mmal_es_type */
-
- u32 encoding; /* FourCC specifying encoding of the elementary
- * stream.
- */
- u32 encoding_variant; /* FourCC specifying the specific
- * encoding variant of the elementary
- * stream.
- */
-
- union mmal_es_specific_format *es; /* Type specific
- * information for the
- * elementary stream
- */
-
- u32 bitrate; /* Bitrate in bits per second */
- u32 flags; /* Flags describing properties of the elementary
- * stream.
- */
-
- u32 extradata_size; /* Size of the codec specific data */
- u8 *extradata; /* Codec specific data */
-};
-
-/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */
-struct mmal_es_format {
- u32 type; /* enum mmal_es_type */
-
- u32 encoding; /* FourCC specifying encoding of the elementary
- * stream.
- */
- u32 encoding_variant; /* FourCC specifying the specific
- * encoding variant of the elementary
- * stream.
- */
-
- u32 es; /* Type specific
- * information for the
- * elementary stream
- */
-
- u32 bitrate; /* Bitrate in bits per second */
- u32 flags; /* Flags describing properties of the elementary
- * stream.
- */
-
- u32 extradata_size; /* Size of the codec specific data */
- u32 extradata; /* Codec specific data */
-};
-
-#endif /* MMAL_MSG_FORMAT_H */
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
deleted file mode 100644
index 6ee4c1ed7f19..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-/* MMAL_PORT_TYPE_T */
-enum mmal_port_type {
- MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */
- MMAL_PORT_TYPE_CONTROL, /* Control port */
- MMAL_PORT_TYPE_INPUT, /* Input port */
- MMAL_PORT_TYPE_OUTPUT, /* Output port */
- MMAL_PORT_TYPE_CLOCK, /* Clock port */
-};
-
-/* The port is pass-through and doesn't need buffer headers allocated */
-#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01
-/*
- *The port wants to allocate the buffer payloads.
- * This signals a preference that payload allocation should be done
- * on this port for efficiency reasons.
- */
-#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02
-/*
- * The port supports format change events.
- * This applies to input ports and is used to let the client know
- * whether the port supports being reconfigured via a format
- * change event (i.e. without having to disable the port).
- */
-#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04
-
-/*
- * mmal port structure (MMAL_PORT_T)
- *
- * most elements are informational only, the pointer values for
- * interogation messages are generally provided as additional
- * structures within the message. When used to set values only the
- * buffer_num, buffer_size and userdata parameters are writable.
- */
-struct mmal_port {
- u32 priv; /* Private member used by the framework */
- u32 name; /* Port name. Used for debugging purposes (RO) */
-
- u32 type; /* Type of the port (RO) enum mmal_port_type */
- u16 index; /* Index of the port in its type list (RO) */
- u16 index_all; /* Index of the port in the list of all ports (RO) */
-
- u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */
- u32 format; /* Format of the elementary stream */
-
- u32 buffer_num_min; /* Minimum number of buffers the port
- * requires (RO). This is set by the
- * component.
- */
-
- u32 buffer_size_min; /* Minimum size of buffers the port
- * requires (RO). This is set by the
- * component.
- */
-
- u32 buffer_alignment_min;/* Minimum alignment requirement for
- * the buffers (RO). A value of
- * zero means no special alignment
- * requirements. This is set by the
- * component.
- */
-
- u32 buffer_num_recommended; /* Number of buffers the port
- * recommends for optimal
- * performance (RO). A value of
- * zero means no special
- * recommendation. This is set
- * by the component.
- */
-
- u32 buffer_size_recommended; /* Size of buffers the port
- * recommends for optimal
- * performance (RO). A value of
- * zero means no special
- * recommendation. This is set
- * by the component.
- */
-
- u32 buffer_num; /* Actual number of buffers the port will use.
- * This is set by the client.
- */
-
- u32 buffer_size; /* Actual maximum size of the buffers that
- * will be sent to the port. This is set by
- * the client.
- */
-
- u32 component; /* Component this port belongs to (Read Only) */
-
- u32 userdata; /* Field reserved for use by the client */
-
- u32 capabilities; /* Flags describing the capabilities of a
- * port (RO). Bitwise combination of \ref
- * portcapabilities "Port capabilities"
- * values.
- */
-};
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
deleted file mode 100644
index 1889494425eb..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-/*
- * all the data structures which serialise the MMAL protocol. note
- * these are directly mapped onto the received message data.
- *
- * BEWARE: They seem to *assume* pointers are u32 and that there is no
- * structure padding!
- *
- * NOTE: this implementation uses kernel types to ensure sizes. Rather
- * than assigning values to enums to force their size the
- * implementation uses fixed size types and not the enums (though the
- * comments have the actual enum type
- */
-#ifndef MMAL_MSG_H
-#define MMAL_MSG_H
-
-#define VC_MMAL_VER 15
-#define VC_MMAL_MIN_VER 10
-
-/* max total message size is 512 bytes */
-#define MMAL_MSG_MAX_SIZE 512
-/* with six 32bit header elements max payload is therefore 488 bytes */
-#define MMAL_MSG_MAX_PAYLOAD 488
-
-#include "mmal-msg-common.h"
-#include "mmal-msg-format.h"
-#include "mmal-msg-port.h"
-#include "mmal-vchiq.h"
-
-enum mmal_msg_type {
- MMAL_MSG_TYPE_QUIT = 1,
- MMAL_MSG_TYPE_SERVICE_CLOSED,
- MMAL_MSG_TYPE_GET_VERSION,
- MMAL_MSG_TYPE_COMPONENT_CREATE,
- MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */
- MMAL_MSG_TYPE_COMPONENT_ENABLE,
- MMAL_MSG_TYPE_COMPONENT_DISABLE,
- MMAL_MSG_TYPE_PORT_INFO_GET,
- MMAL_MSG_TYPE_PORT_INFO_SET,
- MMAL_MSG_TYPE_PORT_ACTION, /* 10 */
- MMAL_MSG_TYPE_BUFFER_FROM_HOST,
- MMAL_MSG_TYPE_BUFFER_TO_HOST,
- MMAL_MSG_TYPE_GET_STATS,
- MMAL_MSG_TYPE_PORT_PARAMETER_SET,
- MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */
- MMAL_MSG_TYPE_EVENT_TO_HOST,
- MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT,
- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR,
- MMAL_MSG_TYPE_CONSUME_MEM,
- MMAL_MSG_TYPE_LMK, /* 20 */
- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC,
- MMAL_MSG_TYPE_DRM_GET_LHS32,
- MMAL_MSG_TYPE_DRM_GET_TIME,
- MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN,
- MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */
- MMAL_MSG_TYPE_HOST_LOG,
- MMAL_MSG_TYPE_MSG_LAST
-};
-
-/* port action request messages differ depending on the action type */
-enum mmal_msg_port_action_type {
- MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */
- MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */
- MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */
- MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */
- MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */
- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */
- MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/
-};
-
-struct mmal_msg_header {
- u32 magic;
- u32 type; /* enum mmal_msg_type */
-
- /* Opaque handle to the control service */
- u32 control_service;
-
- u32 context; /* a u32 per message context */
- u32 status; /* The status of the vchiq operation */
- u32 padding;
-};
-
-/* Send from VC to host to report version */
-struct mmal_msg_version {
- u32 flags;
- u32 major;
- u32 minor;
- u32 minimum;
-};
-
-/* request to VC to create component */
-struct mmal_msg_component_create {
- u32 client_component; /* component context */
- char name[128];
- u32 pid; /* For debug */
-};
-
-/* reply from VC to component creation request */
-struct mmal_msg_component_create_reply {
- u32 status; /* enum mmal_msg_status - how does this differ to
- * the one in the header?
- */
- u32 component_handle; /* VideoCore handle for component */
- u32 input_num; /* Number of input ports */
- u32 output_num; /* Number of output ports */
- u32 clock_num; /* Number of clock ports */
-};
-
-/* request to VC to destroy a component */
-struct mmal_msg_component_destroy {
- u32 component_handle;
-};
-
-struct mmal_msg_component_destroy_reply {
- u32 status; /* The component destruction status */
-};
-
-/* request and reply to VC to enable a component */
-struct mmal_msg_component_enable {
- u32 component_handle;
-};
-
-struct mmal_msg_component_enable_reply {
- u32 status; /* The component enable status */
-};
-
-/* request and reply to VC to disable a component */
-struct mmal_msg_component_disable {
- u32 component_handle;
-};
-
-struct mmal_msg_component_disable_reply {
- u32 status; /* The component disable status */
-};
-
-/* request to VC to get port information */
-struct mmal_msg_port_info_get {
- u32 component_handle; /* component handle port is associated with */
- u32 port_type; /* enum mmal_msg_port_type */
- u32 index; /* port index to query */
-};
-
-/* reply from VC to get port info request */
-struct mmal_msg_port_info_get_reply {
- u32 status; /* enum mmal_msg_status */
- u32 component_handle; /* component handle port is associated with */
- u32 port_type; /* enum mmal_msg_port_type */
- u32 port_index; /* port indexed in query */
- s32 found; /* unused */
- u32 port_handle; /* Handle to use for this port */
- struct mmal_port port;
- struct mmal_es_format format; /* elementary stream format */
- union mmal_es_specific_format es; /* es type specific data */
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */
-};
-
-/* request to VC to set port information */
-struct mmal_msg_port_info_set {
- u32 component_handle;
- u32 port_type; /* enum mmal_msg_port_type */
- u32 port_index; /* port indexed in query */
- struct mmal_port port;
- struct mmal_es_format format;
- union mmal_es_specific_format es;
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
-};
-
-/* reply from VC to port info set request */
-struct mmal_msg_port_info_set_reply {
- u32 status;
- u32 component_handle; /* component handle port is associated with */
- u32 port_type; /* enum mmal_msg_port_type */
- u32 index; /* port indexed in query */
- s32 found; /* unused */
- u32 port_handle; /* Handle to use for this port */
- struct mmal_port port;
- struct mmal_es_format format;
- union mmal_es_specific_format es;
- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
-};
-
-/* port action requests that take a mmal_port as a parameter */
-struct mmal_msg_port_action_port {
- u32 component_handle;
- u32 port_handle;
- u32 action; /* enum mmal_msg_port_action_type */
- struct mmal_port port;
-};
-
-/* port action requests that take handles as a parameter */
-struct mmal_msg_port_action_handle {
- u32 component_handle;
- u32 port_handle;
- u32 action; /* enum mmal_msg_port_action_type */
- u32 connect_component_handle;
- u32 connect_port_handle;
-};
-
-struct mmal_msg_port_action_reply {
- u32 status; /* The port action operation status */
-};
-
-/* MMAL buffer transfer */
-
-/* Size of space reserved in a buffer message for short messages. */
-#define MMAL_VC_SHORT_DATA 128
-
-/* Signals that the current payload is the end of the stream of data */
-#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0)
-/* Signals that the start of the current payload starts a frame */
-#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1)
-/* Signals that the end of the current payload ends a frame */
-#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2)
-/* Signals that the current payload contains only complete frames (>1) */
-#define MMAL_BUFFER_HEADER_FLAG_FRAME \
- (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \
- MMAL_BUFFER_HEADER_FLAG_FRAME_END)
-/* Signals that the current payload is a keyframe (i.e. self decodable) */
-#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3)
-/*
- * Signals a discontinuity in the stream of data (e.g. after a seek).
- * Can be used for instance by a decoder to reset its state
- */
-#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4)
-/*
- * Signals a buffer containing some kind of config data for the component
- * (e.g. codec config data)
- */
-#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5)
-/* Signals an encrypted payload */
-#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6)
-/* Signals a buffer containing side information */
-#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7)
-/*
- * Signals a buffer which is the snapshot/postview image from a stills
- * capture
- */
-#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8)
-/* Signals a buffer which contains data known to be corrupted */
-#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9)
-/* Signals that a buffer failed to be transmitted */
-#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10)
-
-struct mmal_driver_buffer {
- u32 magic;
- u32 component_handle;
- u32 port_handle;
- u32 client_context;
-};
-
-/* buffer header */
-struct mmal_buffer_header {
- u32 next; /* next header */
- u32 priv; /* framework private data */
- u32 cmd;
- u32 data;
- u32 alloc_size;
- u32 length;
- u32 offset;
- u32 flags;
- s64 pts;
- s64 dts;
- u32 type;
- u32 user_data;
-};
-
-struct mmal_buffer_header_type_specific {
- union {
- struct {
- u32 planes;
- u32 offset[4];
- u32 pitch[4];
- u32 flags;
- } video;
- } u;
-};
-
-struct mmal_msg_buffer_from_host {
- /*
- *The front 32 bytes of the buffer header are copied
- * back to us in the reply to allow for context. This
- * area is used to store two mmal_driver_buffer structures to
- * allow for multiple concurrent service users.
- */
- /* control data */
- struct mmal_driver_buffer drvbuf;
-
- /* referenced control data for passthrough buffer management */
- struct mmal_driver_buffer drvbuf_ref;
- struct mmal_buffer_header buffer_header; /* buffer header itself */
- struct mmal_buffer_header_type_specific buffer_header_type_specific;
- s32 is_zero_copy;
- s32 has_reference;
-
- /* allows short data to be xfered in control message */
- u32 payload_in_message;
- u8 short_data[MMAL_VC_SHORT_DATA];
-};
-
-/* port parameter setting */
-
-#define MMAL_WORKER_PORT_PARAMETER_SPACE 96
-
-struct mmal_msg_port_parameter_set {
- u32 component_handle; /* component */
- u32 port_handle; /* port */
- u32 id; /* Parameter ID */
- u32 size; /* Parameter size */
- u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
-};
-
-struct mmal_msg_port_parameter_set_reply {
- u32 status; /* enum mmal_msg_status todo: how does this
- * differ to the one in the header?
- */
-};
-
-/* port parameter getting */
-
-struct mmal_msg_port_parameter_get {
- u32 component_handle; /* component */
- u32 port_handle; /* port */
- u32 id; /* Parameter ID */
- u32 size; /* Parameter size */
-};
-
-struct mmal_msg_port_parameter_get_reply {
- u32 status; /* Status of mmal_port_parameter_get call */
- u32 id; /* Parameter ID */
- u32 size; /* Parameter size */
- u32 value[MMAL_WORKER_PORT_PARAMETER_SPACE];
-};
-
-/* event messages */
-#define MMAL_WORKER_EVENT_SPACE 256
-
-struct mmal_msg_event_to_host {
- u32 client_component; /* component context */
-
- u32 port_type;
- u32 port_num;
-
- u32 cmd;
- u32 length;
- u8 data[MMAL_WORKER_EVENT_SPACE];
- u32 delayed_buffer;
-};
-
-/* all mmal messages are serialised through this structure */
-struct mmal_msg {
- /* header */
- struct mmal_msg_header h;
- /* payload */
- union {
- struct mmal_msg_version version;
-
- struct mmal_msg_component_create component_create;
- struct mmal_msg_component_create_reply component_create_reply;
-
- struct mmal_msg_component_destroy component_destroy;
- struct mmal_msg_component_destroy_reply component_destroy_reply;
-
- struct mmal_msg_component_enable component_enable;
- struct mmal_msg_component_enable_reply component_enable_reply;
-
- struct mmal_msg_component_disable component_disable;
- struct mmal_msg_component_disable_reply component_disable_reply;
-
- struct mmal_msg_port_info_get port_info_get;
- struct mmal_msg_port_info_get_reply port_info_get_reply;
-
- struct mmal_msg_port_info_set port_info_set;
- struct mmal_msg_port_info_set_reply port_info_set_reply;
-
- struct mmal_msg_port_action_port port_action_port;
- struct mmal_msg_port_action_handle port_action_handle;
- struct mmal_msg_port_action_reply port_action_reply;
-
- struct mmal_msg_buffer_from_host buffer_from_host;
-
- struct mmal_msg_port_parameter_set port_parameter_set;
- struct mmal_msg_port_parameter_set_reply
- port_parameter_set_reply;
- struct mmal_msg_port_parameter_get
- port_parameter_get;
- struct mmal_msg_port_parameter_get_reply
- port_parameter_get_reply;
-
- struct mmal_msg_event_to_host event_to_host;
-
- u8 payload[MMAL_MSG_MAX_PAYLOAD];
- } u;
-};
-#endif
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
deleted file mode 100644
index a0cdd28101f2..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
+++ /dev/null
@@ -1,752 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- */
-
-/* common parameters */
-
-/** @name Parameter groups
- * Parameters are divided into groups, and then allocated sequentially within
- * a group using an enum.
- * @{
- */
-
-#ifndef MMAL_PARAMETERS_H
-#define MMAL_PARAMETERS_H
-
-#include <linux/math.h>
-
-/** Common parameter ID group, used with many types of component. */
-#define MMAL_PARAMETER_GROUP_COMMON (0 << 16)
-/** Camera-specific parameter ID group. */
-#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16)
-/** Video-specific parameter ID group. */
-#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16)
-/** Audio-specific parameter ID group. */
-#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16)
-/** Clock-specific parameter ID group. */
-#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16)
-/** Miracast-specific parameter ID group. */
-#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16)
-
-/* Common parameters */
-enum mmal_parameter_common_type {
- /**< Never a valid parameter ID */
- MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON,
-
- /**< MMAL_PARAMETER_ENCODING_T */
- MMAL_PARAMETER_SUPPORTED_ENCODINGS,
- /**< MMAL_PARAMETER_URI_T */
- MMAL_PARAMETER_URI,
- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */
- MMAL_PARAMETER_CHANGE_EVENT_REQUEST,
- /** MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_ZERO_COPY,
- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */
- MMAL_PARAMETER_BUFFER_REQUIREMENTS,
- /**< MMAL_PARAMETER_STATISTICS_T */
- MMAL_PARAMETER_STATISTICS,
- /**< MMAL_PARAMETER_CORE_STATISTICS_T */
- MMAL_PARAMETER_CORE_STATISTICS,
- /**< MMAL_PARAMETER_MEM_USAGE_T */
- MMAL_PARAMETER_MEM_USAGE,
- /**< MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_BUFFER_FLAG_FILTER,
- /**< MMAL_PARAMETER_SEEK_T */
- MMAL_PARAMETER_SEEK,
- /**< MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_POWERMON_ENABLE,
- /**< MMAL_PARAMETER_LOGGING_T */
- MMAL_PARAMETER_LOGGING,
- /**< MMAL_PARAMETER_UINT64_T */
- MMAL_PARAMETER_SYSTEM_TIME,
- /**< MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_NO_IMAGE_PADDING,
-};
-
-/* camera parameters */
-
-enum mmal_parameter_camera_type {
- /* 0 */
- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */
- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION =
- MMAL_PARAMETER_GROUP_CAMERA,
- /**< Unused? */
- MMAL_PARAMETER_CAPTURE_QUALITY,
- /**< @ref MMAL_PARAMETER_INT32_T */
- MMAL_PARAMETER_ROTATION,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_EXIF_DISABLE,
- /**< @ref MMAL_PARAMETER_EXIF_T */
- MMAL_PARAMETER_EXIF,
- /**< @ref MMAL_PARAM_AWBMODE_T */
- MMAL_PARAMETER_AWB_MODE,
- /**< @ref MMAL_PARAMETER_IMAGEFX_T */
- MMAL_PARAMETER_IMAGE_EFFECT,
- /**< @ref MMAL_PARAMETER_COLOURFX_T */
- MMAL_PARAMETER_COLOUR_EFFECT,
- /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */
- MMAL_PARAMETER_FLICKER_AVOID,
- /**< @ref MMAL_PARAMETER_FLASH_T */
- MMAL_PARAMETER_FLASH,
- /**< @ref MMAL_PARAMETER_REDEYE_T */
- MMAL_PARAMETER_REDEYE,
- /**< @ref MMAL_PARAMETER_FOCUS_T */
- MMAL_PARAMETER_FOCUS,
- /**< Unused? */
- MMAL_PARAMETER_FOCAL_LENGTHS,
- /**< @ref MMAL_PARAMETER_INT32_T */
- MMAL_PARAMETER_EXPOSURE_COMP,
- /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */
- MMAL_PARAMETER_ZOOM,
- /**< @ref MMAL_PARAMETER_MIRROR_T */
- MMAL_PARAMETER_MIRROR,
-
- /* 0x10 */
- /**< @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_CAMERA_NUM,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_CAPTURE,
- /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */
- MMAL_PARAMETER_EXPOSURE_MODE,
- /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */
- MMAL_PARAMETER_EXP_METERING_MODE,
- /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */
- MMAL_PARAMETER_FOCUS_STATUS,
- /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */
- MMAL_PARAMETER_CAMERA_CONFIG,
- /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */
- MMAL_PARAMETER_CAPTURE_STATUS,
- /**< @ref MMAL_PARAMETER_FACE_TRACK_T */
- MMAL_PARAMETER_FACE_TRACK,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS,
- /**< @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_JPEG_Q_FACTOR,
- /**< @ref MMAL_PARAMETER_FRAME_RATE_T */
- MMAL_PARAMETER_FRAME_RATE,
- /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */
- MMAL_PARAMETER_USE_STC,
- /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */
- MMAL_PARAMETER_CAMERA_INFO,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_STABILISATION,
- /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */
- MMAL_PARAMETER_FACE_TRACK_RESULTS,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_ENABLE_RAW_CAPTURE,
-
- /* 0x20 */
- /**< @ref MMAL_PARAMETER_URI_T */
- MMAL_PARAMETER_DPF_FILE,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_ENABLE_DPF_FILE,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_DPF_FAIL_IS_FATAL,
- /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */
- MMAL_PARAMETER_CAPTURE_MODE,
- /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */
- MMAL_PARAMETER_FOCUS_REGIONS,
- /**< @ref MMAL_PARAMETER_INPUT_CROP_T */
- MMAL_PARAMETER_INPUT_CROP,
- /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */
- MMAL_PARAMETER_SENSOR_INFORMATION,
- /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */
- MMAL_PARAMETER_FLASH_SELECT,
- /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */
- MMAL_PARAMETER_FIELD_OF_VIEW,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE,
- /**< @ref MMAL_PARAMETER_DRC_T */
- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION,
- /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */
- MMAL_PARAMETER_ALGORITHM_CONTROL,
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
- MMAL_PARAMETER_SHARPNESS,
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
- MMAL_PARAMETER_CONTRAST,
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
- MMAL_PARAMETER_BRIGHTNESS,
- /**< @ref MMAL_PARAMETER_RATIONAL_T */
- MMAL_PARAMETER_SATURATION,
-
- /* 0x30 */
- /**< @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_ISO,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_ANTISHAKE,
- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */
- MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_CAMERA_BURST_CAPTURE,
- /** @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_CAMERA_MIN_ISO,
- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */
- MMAL_PARAMETER_CAMERA_USE_CASE,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_CAPTURE_STATS_PASS,
- /** @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG,
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_ENABLE_REGISTER_FILE,
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL,
- /** @ref MMAL_PARAMETER_CONFIGFILE_T */
- MMAL_PARAMETER_CONFIGFILE_REGISTERS,
- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */
- MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_JPEG_ATTACH_LOG,
- /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */
- MMAL_PARAMETER_ZERO_SHUTTER_LAG,
- /**< @ref MMAL_PARAMETER_FPS_RANGE_T */
- MMAL_PARAMETER_FPS_RANGE,
- /**< @ref MMAL_PARAMETER_INT32_T */
- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP,
-
- /* 0x40 */
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_SW_SHARPEN_DISABLE,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_FLASH_REQUIRED,
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_SW_SATURATION_DISABLE,
- /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_SHUTTER_SPEED,
- /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */
- MMAL_PARAMETER_CUSTOM_AWB_GAINS,
-};
-
-enum mmal_parameter_camera_config_timestamp_mode {
- MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */
- MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value
- * for the frame timestamp
- */
- MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp
- * but subtract the
- * timestamp of the first
- * frame sent to give a
- * zero based timestamp.
- */
-};
-
-struct mmal_parameter_fps_range {
- /**< Low end of the permitted framerate range */
- struct s32_fract fps_low;
- /**< High end of the permitted framerate range */
- struct s32_fract fps_high;
-};
-
-/* camera configuration parameter */
-struct mmal_parameter_camera_config {
- /* Parameters for setting up the image pools */
- u32 max_stills_w; /* Max size of stills capture */
- u32 max_stills_h;
- u32 stills_yuv422; /* Allow YUV422 stills capture */
- u32 one_shot_stills; /* Continuous or one shot stills captures. */
-
- u32 max_preview_video_w; /* Max size of the preview or video
- * capture frames
- */
- u32 max_preview_video_h;
- u32 num_preview_video_frames;
-
- /** Sets the height of the circular buffer for stills capture. */
- u32 stills_capture_circular_buffer_height;
-
- /** Allows preview/encode to resume as fast as possible after the stills
- * input frame has been received, and then processes the still frame in
- * the background whilst preview/encode has resumed.
- * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE.
- */
- u32 fast_preview_resume;
-
- /** Selects algorithm for timestamping frames if
- * there is no clock component connected.
- * enum mmal_parameter_camera_config_timestamp_mode
- */
- s32 use_stc_timestamp;
-};
-
-enum mmal_parameter_exposuremode {
- MMAL_PARAM_EXPOSUREMODE_OFF,
- MMAL_PARAM_EXPOSUREMODE_AUTO,
- MMAL_PARAM_EXPOSUREMODE_NIGHT,
- MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW,
- MMAL_PARAM_EXPOSUREMODE_BACKLIGHT,
- MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT,
- MMAL_PARAM_EXPOSUREMODE_SPORTS,
- MMAL_PARAM_EXPOSUREMODE_SNOW,
- MMAL_PARAM_EXPOSUREMODE_BEACH,
- MMAL_PARAM_EXPOSUREMODE_VERYLONG,
- MMAL_PARAM_EXPOSUREMODE_FIXEDFPS,
- MMAL_PARAM_EXPOSUREMODE_ANTISHAKE,
- MMAL_PARAM_EXPOSUREMODE_FIREWORKS,
-};
-
-enum mmal_parameter_exposuremeteringmode {
- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE,
- MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT,
- MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT,
- MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX,
-};
-
-enum mmal_parameter_awbmode {
- MMAL_PARAM_AWBMODE_OFF,
- MMAL_PARAM_AWBMODE_AUTO,
- MMAL_PARAM_AWBMODE_SUNLIGHT,
- MMAL_PARAM_AWBMODE_CLOUDY,
- MMAL_PARAM_AWBMODE_SHADE,
- MMAL_PARAM_AWBMODE_TUNGSTEN,
- MMAL_PARAM_AWBMODE_FLUORESCENT,
- MMAL_PARAM_AWBMODE_INCANDESCENT,
- MMAL_PARAM_AWBMODE_FLASH,
- MMAL_PARAM_AWBMODE_HORIZON,
-};
-
-enum mmal_parameter_imagefx {
- MMAL_PARAM_IMAGEFX_NONE,
- MMAL_PARAM_IMAGEFX_NEGATIVE,
- MMAL_PARAM_IMAGEFX_SOLARIZE,
- MMAL_PARAM_IMAGEFX_POSTERIZE,
- MMAL_PARAM_IMAGEFX_WHITEBOARD,
- MMAL_PARAM_IMAGEFX_BLACKBOARD,
- MMAL_PARAM_IMAGEFX_SKETCH,
- MMAL_PARAM_IMAGEFX_DENOISE,
- MMAL_PARAM_IMAGEFX_EMBOSS,
- MMAL_PARAM_IMAGEFX_OILPAINT,
- MMAL_PARAM_IMAGEFX_HATCH,
- MMAL_PARAM_IMAGEFX_GPEN,
- MMAL_PARAM_IMAGEFX_PASTEL,
- MMAL_PARAM_IMAGEFX_WATERCOLOUR,
- MMAL_PARAM_IMAGEFX_FILM,
- MMAL_PARAM_IMAGEFX_BLUR,
- MMAL_PARAM_IMAGEFX_SATURATION,
- MMAL_PARAM_IMAGEFX_COLOURSWAP,
- MMAL_PARAM_IMAGEFX_WASHEDOUT,
- MMAL_PARAM_IMAGEFX_POSTERISE,
- MMAL_PARAM_IMAGEFX_COLOURPOINT,
- MMAL_PARAM_IMAGEFX_COLOURBALANCE,
- MMAL_PARAM_IMAGEFX_CARTOON,
-};
-
-enum MMAL_PARAM_FLICKERAVOID {
- MMAL_PARAM_FLICKERAVOID_OFF,
- MMAL_PARAM_FLICKERAVOID_AUTO,
- MMAL_PARAM_FLICKERAVOID_50HZ,
- MMAL_PARAM_FLICKERAVOID_60HZ,
- MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF
-};
-
-struct mmal_parameter_awbgains {
- struct s32_fract r_gain; /**< Red gain */
- struct s32_fract b_gain; /**< Blue gain */
-};
-
-/** Manner of video rate control */
-enum mmal_parameter_rate_control_mode {
- MMAL_VIDEO_RATECONTROL_DEFAULT,
- MMAL_VIDEO_RATECONTROL_VARIABLE,
- MMAL_VIDEO_RATECONTROL_CONSTANT,
- MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES,
- MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES
-};
-
-enum mmal_video_profile {
- MMAL_VIDEO_PROFILE_H263_BASELINE,
- MMAL_VIDEO_PROFILE_H263_H320CODING,
- MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE,
- MMAL_VIDEO_PROFILE_H263_ISWV2,
- MMAL_VIDEO_PROFILE_H263_ISWV3,
- MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION,
- MMAL_VIDEO_PROFILE_H263_INTERNET,
- MMAL_VIDEO_PROFILE_H263_INTERLACE,
- MMAL_VIDEO_PROFILE_H263_HIGHLATENCY,
- MMAL_VIDEO_PROFILE_MP4V_SIMPLE,
- MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE,
- MMAL_VIDEO_PROFILE_MP4V_CORE,
- MMAL_VIDEO_PROFILE_MP4V_MAIN,
- MMAL_VIDEO_PROFILE_MP4V_NBIT,
- MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE,
- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE,
- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA,
- MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED,
- MMAL_VIDEO_PROFILE_MP4V_HYBRID,
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME,
- MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE,
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING,
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE,
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE,
- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE,
- MMAL_VIDEO_PROFILE_H264_BASELINE,
- MMAL_VIDEO_PROFILE_H264_MAIN,
- MMAL_VIDEO_PROFILE_H264_EXTENDED,
- MMAL_VIDEO_PROFILE_H264_HIGH,
- MMAL_VIDEO_PROFILE_H264_HIGH10,
- MMAL_VIDEO_PROFILE_H264_HIGH422,
- MMAL_VIDEO_PROFILE_H264_HIGH444,
- MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
- MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF
-};
-
-enum mmal_video_level {
- MMAL_VIDEO_LEVEL_H263_10,
- MMAL_VIDEO_LEVEL_H263_20,
- MMAL_VIDEO_LEVEL_H263_30,
- MMAL_VIDEO_LEVEL_H263_40,
- MMAL_VIDEO_LEVEL_H263_45,
- MMAL_VIDEO_LEVEL_H263_50,
- MMAL_VIDEO_LEVEL_H263_60,
- MMAL_VIDEO_LEVEL_H263_70,
- MMAL_VIDEO_LEVEL_MP4V_0,
- MMAL_VIDEO_LEVEL_MP4V_0b,
- MMAL_VIDEO_LEVEL_MP4V_1,
- MMAL_VIDEO_LEVEL_MP4V_2,
- MMAL_VIDEO_LEVEL_MP4V_3,
- MMAL_VIDEO_LEVEL_MP4V_4,
- MMAL_VIDEO_LEVEL_MP4V_4a,
- MMAL_VIDEO_LEVEL_MP4V_5,
- MMAL_VIDEO_LEVEL_MP4V_6,
- MMAL_VIDEO_LEVEL_H264_1,
- MMAL_VIDEO_LEVEL_H264_1b,
- MMAL_VIDEO_LEVEL_H264_11,
- MMAL_VIDEO_LEVEL_H264_12,
- MMAL_VIDEO_LEVEL_H264_13,
- MMAL_VIDEO_LEVEL_H264_2,
- MMAL_VIDEO_LEVEL_H264_21,
- MMAL_VIDEO_LEVEL_H264_22,
- MMAL_VIDEO_LEVEL_H264_3,
- MMAL_VIDEO_LEVEL_H264_31,
- MMAL_VIDEO_LEVEL_H264_32,
- MMAL_VIDEO_LEVEL_H264_4,
- MMAL_VIDEO_LEVEL_H264_41,
- MMAL_VIDEO_LEVEL_H264_42,
- MMAL_VIDEO_LEVEL_H264_5,
- MMAL_VIDEO_LEVEL_H264_51,
- MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF
-};
-
-struct mmal_parameter_video_profile {
- enum mmal_video_profile profile;
- enum mmal_video_level level;
-};
-
-/* video parameters */
-
-enum mmal_parameter_video_type {
- /** @ref MMAL_DISPLAYREGION_T */
- MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO,
-
- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
- MMAL_PARAMETER_SUPPORTED_PROFILES,
-
- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */
- MMAL_PARAMETER_PROFILE,
-
- /** @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_INTRAPERIOD,
-
- /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */
- MMAL_PARAMETER_RATECONTROL,
-
- /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */
- MMAL_PARAMETER_NALUNITFORMAT,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
-
- /** @ref MMAL_PARAMETER_UINT32_T.
- * Setting the value to zero resets to the default (one slice per
- * frame).
- */
- MMAL_PARAMETER_MB_ROWS_PER_SLICE,
-
- /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */
- MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION,
-
- /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */
- MMAL_PARAMETER_VIDEO_EEDE_ENABLE,
-
- /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */
- MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */
- MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME,
- /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */
- MMAL_PARAMETER_VIDEO_INTRA_REFRESH,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
- MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
-
- /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */
- MMAL_PARAMETER_VIDEO_BIT_RATE,
-
- /** @ref MMAL_PARAMETER_FRAME_RATE_T */
- MMAL_PARAMETER_VIDEO_FRAME_RATE,
-
- /** @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT,
-
- /** @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT,
-
- /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL,
-
- MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */
- /** @ref MMAL_PARAMETER_UINT32_T.
- * Changing this parameter from the default can reduce frame rate
- * because image buffers need to be re-pitched.
- */
- MMAL_PARAMETER_VIDEO_ALIGN_HORIZ,
-
- /** @ref MMAL_PARAMETER_UINT32_T.
- * Changing this parameter from the default can reduce frame rate
- * because image buffers need to be re-pitched.
- */
- MMAL_PARAMETER_VIDEO_ALIGN_VERT,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
- MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES,
-
- /** @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT,
-
- /**< @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_QP_P,
-
- /**< @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT,
-
- /** @ref MMAL_PARAMETER_UINT32_T */
- MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS,
-
- /** @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE,
-
- /* H264 specific parameters */
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS,
-
- /** @ref MMAL_PARAMETER_UINT32_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC,
-
- /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP,
-
- /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */
- MMAL_PARAMETER_VIDEO_DRM_INIT_INFO,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO,
-
- /** @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT,
-
- /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */
- MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER,
-
- /** @ref MMAL_PARAMETER_BYTES_T */
- MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3,
-
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS,
-
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG,
-
- /**< @ref MMAL_PARAMETER_BOOLEAN_T */
- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER
-};
-
-/** Valid mirror modes */
-enum mmal_parameter_mirror {
- MMAL_PARAM_MIRROR_NONE,
- MMAL_PARAM_MIRROR_VERTICAL,
- MMAL_PARAM_MIRROR_HORIZONTAL,
- MMAL_PARAM_MIRROR_BOTH,
-};
-
-enum mmal_parameter_displaytransform {
- MMAL_DISPLAY_ROT0 = 0,
- MMAL_DISPLAY_MIRROR_ROT0 = 1,
- MMAL_DISPLAY_MIRROR_ROT180 = 2,
- MMAL_DISPLAY_ROT180 = 3,
- MMAL_DISPLAY_MIRROR_ROT90 = 4,
- MMAL_DISPLAY_ROT270 = 5,
- MMAL_DISPLAY_ROT90 = 6,
- MMAL_DISPLAY_MIRROR_ROT270 = 7,
-};
-
-enum mmal_parameter_displaymode {
- MMAL_DISPLAY_MODE_FILL = 0,
- MMAL_DISPLAY_MODE_LETTERBOX = 1,
-};
-
-enum mmal_parameter_displayset {
- MMAL_DISPLAY_SET_NONE = 0,
- MMAL_DISPLAY_SET_NUM = 1,
- MMAL_DISPLAY_SET_FULLSCREEN = 2,
- MMAL_DISPLAY_SET_TRANSFORM = 4,
- MMAL_DISPLAY_SET_DEST_RECT = 8,
- MMAL_DISPLAY_SET_SRC_RECT = 0x10,
- MMAL_DISPLAY_SET_MODE = 0x20,
- MMAL_DISPLAY_SET_PIXEL = 0x40,
- MMAL_DISPLAY_SET_NOASPECT = 0x80,
- MMAL_DISPLAY_SET_LAYER = 0x100,
- MMAL_DISPLAY_SET_COPYPROTECT = 0x200,
- MMAL_DISPLAY_SET_ALPHA = 0x400,
-};
-
-/* rectangle, used lots so it gets its own struct */
-struct vchiq_mmal_rect {
- s32 x;
- s32 y;
- s32 width;
- s32 height;
-};
-
-struct mmal_parameter_displayregion {
- /** Bitfield that indicates which fields are set and should be
- * used. All other fields will maintain their current value.
- * \ref MMAL_DISPLAYSET_T defines the bits that can be
- * combined.
- */
- u32 set;
-
- /** Describes the display output device, with 0 typically
- * being a directly connected LCD display. The actual values
- * will depend on the hardware. Code using hard-wired numbers
- * (e.g. 2) is certain to fail.
- */
-
- u32 display_num;
- /** Indicates that we are using the full device screen area,
- * rather than a window of the display. If zero, then
- * dest_rect is used to specify a region of the display to
- * use.
- */
-
- s32 fullscreen;
- /** Indicates any rotation or flipping used to map frames onto
- * the natural display orientation.
- */
- u32 transform; /* enum mmal_parameter_displaytransform */
-
- /** Where to display the frame within the screen, if
- * fullscreen is zero.
- */
- struct vchiq_mmal_rect dest_rect;
-
- /** Indicates which area of the frame to display. If all
- * values are zero, the whole frame will be used.
- */
- struct vchiq_mmal_rect src_rect;
-
- /** If set to non-zero, indicates that any display scaling
- * should disregard the aspect ratio of the frame region being
- * displayed.
- */
- s32 noaspect;
-
- /** Indicates how the image should be scaled to fit the
- * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates
- * that the image should fill the screen by potentially
- * cropping the frames. Setting \code mode \endcode to \code
- * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the
- * source region should be displayed and black bars added if
- * necessary.
- */
- u32 mode; /* enum mmal_parameter_displaymode */
-
- /** If non-zero, defines the width of a source pixel relative
- * to \code pixel_y \endcode. If zero, then pixels default to
- * being square.
- */
- u32 pixel_x;
-
- /** If non-zero, defines the height of a source pixel relative
- * to \code pixel_x \endcode. If zero, then pixels default to
- * being square.
- */
- u32 pixel_y;
-
- /** Sets the relative depth of the images, with greater values
- * being in front of smaller values.
- */
- u32 layer;
-
- /** Set to non-zero to ensure copy protection is used on
- * output.
- */
- s32 copyprotect_required;
-
- /** Level of opacity of the layer, where zero is fully
- * transparent and 255 is fully opaque.
- */
- u32 alpha;
-};
-
-#define MMAL_MAX_IMAGEFX_PARAMETERS 5
-
-struct mmal_parameter_imagefx_parameters {
- enum mmal_parameter_imagefx effect;
- u32 num_effect_params;
- u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS];
-};
-
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2
-#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16
-
-struct mmal_parameter_camera_info_camera {
- u32 port_id;
- u32 max_width;
- u32 max_height;
- u32 lens_present;
- u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN];
-};
-
-enum mmal_parameter_camera_info_flash_type {
- /* Make values explicit to ensure they match values in config ini */
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0,
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1,
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2,
- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF
-};
-
-struct mmal_parameter_camera_info_flash {
- enum mmal_parameter_camera_info_flash_type flash_type;
-};
-
-struct mmal_parameter_camera_info {
- u32 num_cameras;
- u32 num_flashes;
- struct mmal_parameter_camera_info_camera
- cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS];
- struct mmal_parameter_camera_info_flash
- flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES];
-};
-
-#endif
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
deleted file mode 100644
index c2b5a37915f2..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ /dev/null
@@ -1,1948 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- *
- * V4L2 driver MMAL vchiq interface code
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/completion.h>
-#include <linux/vmalloc.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include "../include/linux/raspberrypi/vchiq.h"
-#include "../interface/vchiq_arm/vchiq_arm.h"
-#include "mmal-common.h"
-#include "mmal-vchiq.h"
-#include "mmal-msg.h"
-
-/*
- * maximum number of components supported.
- * This matches the maximum permitted by default on the VPU
- */
-#define VCHIQ_MMAL_MAX_COMPONENTS 64
-
-/*
- * Timeout for synchronous msg responses in seconds.
- * Helpful to increase this if stopping in the VPU debugger.
- */
-#define SYNC_MSG_TIMEOUT 3
-
-/*#define FULL_MSG_DUMP 1*/
-
-#ifdef DEBUG
-static const char *const msg_type_names[] = {
- "UNKNOWN",
- "QUIT",
- "SERVICE_CLOSED",
- "GET_VERSION",
- "COMPONENT_CREATE",
- "COMPONENT_DESTROY",
- "COMPONENT_ENABLE",
- "COMPONENT_DISABLE",
- "PORT_INFO_GET",
- "PORT_INFO_SET",
- "PORT_ACTION",
- "BUFFER_FROM_HOST",
- "BUFFER_TO_HOST",
- "GET_STATS",
- "PORT_PARAMETER_SET",
- "PORT_PARAMETER_GET",
- "EVENT_TO_HOST",
- "GET_CORE_STATS_FOR_PORT",
- "OPAQUE_ALLOCATOR",
- "CONSUME_MEM",
- "LMK",
- "OPAQUE_ALLOCATOR_DESC",
- "DRM_GET_LHS32",
- "DRM_GET_TIME",
- "BUFFER_FROM_HOST_ZEROLEN",
- "PORT_FLUSH",
- "HOST_LOG",
-};
-#endif
-
-static const char *const port_action_type_names[] = {
- "UNKNOWN",
- "ENABLE",
- "DISABLE",
- "FLUSH",
- "CONNECT",
- "DISCONNECT",
- "SET_REQUIREMENTS",
-};
-
-#if defined(DEBUG)
-#if defined(FULL_MSG_DUMP)
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
- do { \
- pr_debug(TITLE" type:%s(%d) length:%d\n", \
- msg_type_names[(MSG)->h.type], \
- (MSG)->h.type, (MSG_LEN)); \
- print_hex_dump(KERN_DEBUG, "<<h: ", DUMP_PREFIX_OFFSET, \
- 16, 4, (MSG), \
- sizeof(struct mmal_msg_header), 1); \
- print_hex_dump(KERN_DEBUG, "<<p: ", DUMP_PREFIX_OFFSET, \
- 16, 4, \
- ((u8 *)(MSG)) + sizeof(struct mmal_msg_header),\
- (MSG_LEN) - sizeof(struct mmal_msg_header), 1); \
- } while (0)
-#else
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \
- { \
- pr_debug(TITLE" type:%s(%d) length:%d\n", \
- msg_type_names[(MSG)->h.type], \
- (MSG)->h.type, (MSG_LEN)); \
- }
-#endif
-#else
-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE)
-#endif
-
-struct vchiq_mmal_instance;
-
-/* normal message context */
-struct mmal_msg_context {
- struct vchiq_mmal_instance *instance;
-
- /* Index in the context_map idr so that we can find the
- * mmal_msg_context again when servicing the VCHI reply.
- */
- int handle;
-
- union {
- struct {
- /* work struct for buffer_cb callback */
- struct work_struct work;
- /* work struct for deferred callback */
- struct work_struct buffer_to_host_work;
- /* mmal instance */
- struct vchiq_mmal_instance *instance;
- /* mmal port */
- struct vchiq_mmal_port *port;
- /* actual buffer used to store bulk reply */
- struct mmal_buffer *buffer;
- /* amount of buffer used */
- unsigned long buffer_used;
- /* MMAL buffer flags */
- u32 mmal_flags;
- /* Presentation and Decode timestamps */
- s64 pts;
- s64 dts;
-
- int status; /* context status */
-
- } bulk; /* bulk data */
-
- struct {
- /* message handle to release */
- struct vchiq_header *msg_handle;
- /* pointer to received message */
- struct mmal_msg *msg;
- /* received message length */
- u32 msg_len;
- /* completion upon reply */
- struct completion cmplt;
- } sync; /* synchronous response */
- } u;
-
-};
-
-struct vchiq_mmal_instance {
- unsigned int service_handle;
-
- /* ensure serialised access to service */
- struct mutex vchiq_mutex;
-
- struct idr context_map;
- /* protect accesses to context_map */
- struct mutex context_map_lock;
-
- struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS];
-
- /* ordered workqueue to process all bulk operations */
- struct workqueue_struct *bulk_wq;
-
- /* handle for a vchiq instance */
- struct vchiq_instance *vchiq_instance;
-};
-
-static struct mmal_msg_context *
-get_msg_context(struct vchiq_mmal_instance *instance)
-{
- struct mmal_msg_context *msg_context;
- int handle;
-
- /* todo: should this be allocated from a pool to avoid kzalloc */
- msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL);
-
- if (!msg_context)
- return ERR_PTR(-ENOMEM);
-
- /* Create an ID that will be passed along with our message so
- * that when we service the VCHI reply, we can look up what
- * message is being replied to.
- */
- mutex_lock(&instance->context_map_lock);
- handle = idr_alloc(&instance->context_map, msg_context,
- 0, 0, GFP_KERNEL);
- mutex_unlock(&instance->context_map_lock);
-
- if (handle < 0) {
- kfree(msg_context);
- return ERR_PTR(handle);
- }
-
- msg_context->instance = instance;
- msg_context->handle = handle;
-
- return msg_context;
-}
-
-static struct mmal_msg_context *
-lookup_msg_context(struct vchiq_mmal_instance *instance, int handle)
-{
- return idr_find(&instance->context_map, handle);
-}
-
-static void
-release_msg_context(struct mmal_msg_context *msg_context)
-{
- struct vchiq_mmal_instance *instance = msg_context->instance;
-
- mutex_lock(&instance->context_map_lock);
- idr_remove(&instance->context_map, msg_context->handle);
- mutex_unlock(&instance->context_map_lock);
- kfree(msg_context);
-}
-
-/* deals with receipt of event to host message */
-static void event_to_host_cb(struct vchiq_mmal_instance *instance,
- struct mmal_msg *msg, u32 msg_len)
-{
- pr_debug("unhandled event\n");
- pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n",
- msg->u.event_to_host.client_component,
- msg->u.event_to_host.port_type,
- msg->u.event_to_host.port_num,
- msg->u.event_to_host.cmd, msg->u.event_to_host.length);
-}
-
-/* workqueue scheduled callback
- *
- * we do this because it is important we do not call any other vchiq
- * sync calls from within the message delivery thread
- */
-static void buffer_work_cb(struct work_struct *work)
-{
- struct mmal_msg_context *msg_context =
- container_of(work, struct mmal_msg_context, u.bulk.work);
- struct mmal_buffer *buffer = msg_context->u.bulk.buffer;
-
- if (!buffer) {
- pr_err("%s: ctx: %p, No mmal buffer to pass details\n",
- __func__, msg_context);
- return;
- }
-
- buffer->length = msg_context->u.bulk.buffer_used;
- buffer->mmal_flags = msg_context->u.bulk.mmal_flags;
- buffer->dts = msg_context->u.bulk.dts;
- buffer->pts = msg_context->u.bulk.pts;
-
- atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu);
-
- msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance,
- msg_context->u.bulk.port,
- msg_context->u.bulk.status,
- msg_context->u.bulk.buffer);
-}
-
-/* workqueue scheduled callback to handle receiving buffers
- *
- * VCHI will allow up to 4 bulk receives to be scheduled before blocking.
- * If we block in the service_callback context then we can't process the
- * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked
- * vchiq_bulk_receive() call to complete.
- */
-static void buffer_to_host_work_cb(struct work_struct *work)
-{
- struct mmal_msg_context *msg_context =
- container_of(work, struct mmal_msg_context,
- u.bulk.buffer_to_host_work);
- struct vchiq_mmal_instance *instance = msg_context->instance;
- unsigned long len = msg_context->u.bulk.buffer_used;
- int ret;
-
- if (!len)
- /* Dummy receive to ensure the buffers remain in order */
- len = 8;
- /* queue the bulk submission */
- vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- ret = vchiq_bulk_receive(instance->vchiq_instance, instance->service_handle,
- msg_context->u.bulk.buffer->buffer,
- /* Actual receive needs to be a multiple
- * of 4 bytes
- */
- (len + 3) & ~3,
- msg_context,
- VCHIQ_BULK_MODE_CALLBACK);
-
- vchiq_release_service(instance->vchiq_instance, instance->service_handle);
-
- if (ret != 0)
- pr_err("%s: ctx: %p, vchiq_bulk_receive failed %d\n",
- __func__, msg_context, ret);
-}
-
-/* enqueue a bulk receive for a given message context */
-static int bulk_receive(struct vchiq_mmal_instance *instance,
- struct mmal_msg *msg,
- struct mmal_msg_context *msg_context)
-{
- unsigned long rd_len;
-
- rd_len = msg->u.buffer_from_host.buffer_header.length;
-
- if (!msg_context->u.bulk.buffer) {
- pr_err("bulk.buffer not configured - error in buffer_from_host\n");
-
- /* todo: this is a serious error, we should never have
- * committed a buffer_to_host operation to the mmal
- * port without the buffer to back it up (underflow
- * handling) and there is no obvious way to deal with
- * this - how is the mmal service going to react when
- * we fail to do the xfer and reschedule a buffer when
- * it arrives? perhaps a starved flag to indicate a
- * waiting bulk receive?
- */
-
- return -EINVAL;
- }
-
- /* ensure we do not overrun the available buffer */
- if (rd_len > msg_context->u.bulk.buffer->buffer_size) {
- rd_len = msg_context->u.bulk.buffer->buffer_size;
- pr_warn("short read as not enough receive buffer space\n");
- /* todo: is this the correct response, what happens to
- * the rest of the message data?
- */
- }
-
- /* store length */
- msg_context->u.bulk.buffer_used = rd_len;
- msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
- msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
-
- queue_work(msg_context->instance->bulk_wq,
- &msg_context->u.bulk.buffer_to_host_work);
-
- return 0;
-}
-
-/* data in message, memcpy from packet into output buffer */
-static int inline_receive(struct vchiq_mmal_instance *instance,
- struct mmal_msg *msg,
- struct mmal_msg_context *msg_context)
-{
- memcpy(msg_context->u.bulk.buffer->buffer,
- msg->u.buffer_from_host.short_data,
- msg->u.buffer_from_host.payload_in_message);
-
- msg_context->u.bulk.buffer_used =
- msg->u.buffer_from_host.payload_in_message;
-
- return 0;
-}
-
-/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */
-static int
-buffer_from_host(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port, struct mmal_buffer *buf)
-{
- struct mmal_msg_context *msg_context;
- struct mmal_msg m;
- int ret;
-
- if (!port->enabled)
- return -EINVAL;
-
- pr_debug("instance:%u buffer:%p\n", instance->service_handle, buf);
-
- /* get context */
- if (!buf->msg_context) {
- pr_err("%s: msg_context not allocated, buf %p\n", __func__,
- buf);
- return -EINVAL;
- }
- msg_context = buf->msg_context;
-
- /* store bulk message context for when data arrives */
- msg_context->u.bulk.instance = instance;
- msg_context->u.bulk.port = port;
- msg_context->u.bulk.buffer = buf;
- msg_context->u.bulk.buffer_used = 0;
-
- /* initialise work structure ready to schedule callback */
- INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb);
- INIT_WORK(&msg_context->u.bulk.buffer_to_host_work,
- buffer_to_host_work_cb);
-
- atomic_inc(&port->buffers_with_vpu);
-
- /* prep the buffer from host message */
- memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */
-
- m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST;
- m.h.magic = MMAL_MAGIC;
- m.h.context = msg_context->handle;
- m.h.status = 0;
-
- /* drvbuf is our private data passed back */
- m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC;
- m.u.buffer_from_host.drvbuf.component_handle = port->component->handle;
- m.u.buffer_from_host.drvbuf.port_handle = port->handle;
- m.u.buffer_from_host.drvbuf.client_context = msg_context->handle;
-
- /* buffer header */
- m.u.buffer_from_host.buffer_header.cmd = 0;
- m.u.buffer_from_host.buffer_header.data =
- (u32)(unsigned long)buf->buffer;
- m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
- m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */
- m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */
- m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */
- m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN;
- m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN;
-
- /* clear buffer type specific data */
- memset(&m.u.buffer_from_host.buffer_header_type_specific, 0,
- sizeof(m.u.buffer_from_host.buffer_header_type_specific));
-
- /* no payload in message */
- m.u.buffer_from_host.payload_in_message = 0;
-
- vchiq_use_service(instance->vchiq_instance, instance->service_handle);
-
- ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, &m,
- sizeof(struct mmal_msg_header) +
- sizeof(m.u.buffer_from_host));
- if (ret)
- atomic_dec(&port->buffers_with_vpu);
-
- vchiq_release_service(instance->vchiq_instance, instance->service_handle);
-
- return ret;
-}
-
-/* deals with receipt of buffer to host message */
-static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
- struct mmal_msg *msg, u32 msg_len)
-{
- struct mmal_msg_context *msg_context;
- u32 handle;
-
- pr_debug("%s: instance:%p msg:%p msg_len:%d\n",
- __func__, instance, msg, msg_len);
-
- if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) {
- handle = msg->u.buffer_from_host.drvbuf.client_context;
- msg_context = lookup_msg_context(instance, handle);
-
- if (!msg_context) {
- pr_err("drvbuf.client_context(%u) is invalid\n",
- handle);
- return;
- }
- } else {
- pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n");
- return;
- }
-
- msg_context->u.bulk.mmal_flags =
- msg->u.buffer_from_host.buffer_header.flags;
-
- if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
- /* message reception had an error */
- pr_warn("error %d in reply\n", msg->h.status);
-
- msg_context->u.bulk.status = msg->h.status;
-
- } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
- /* empty buffer */
- if (msg->u.buffer_from_host.buffer_header.flags &
- MMAL_BUFFER_HEADER_FLAG_EOS) {
- msg_context->u.bulk.status =
- bulk_receive(instance, msg, msg_context);
- if (msg_context->u.bulk.status == 0)
- return; /* successful bulk submission, bulk
- * completion will trigger callback
- */
- } else {
- /* do callback with empty buffer - not EOS though */
- msg_context->u.bulk.status = 0;
- msg_context->u.bulk.buffer_used = 0;
- }
- } else if (msg->u.buffer_from_host.payload_in_message == 0) {
- /* data is not in message, queue a bulk receive */
- msg_context->u.bulk.status =
- bulk_receive(instance, msg, msg_context);
- if (msg_context->u.bulk.status == 0)
- return; /* successful bulk submission, bulk
- * completion will trigger callback
- */
-
- /* failed to submit buffer, this will end badly */
- pr_err("error %d on bulk submission\n",
- msg_context->u.bulk.status);
-
- } else if (msg->u.buffer_from_host.payload_in_message <=
- MMAL_VC_SHORT_DATA) {
- /* data payload within message */
- msg_context->u.bulk.status = inline_receive(instance, msg,
- msg_context);
- } else {
- pr_err("message with invalid short payload\n");
-
- /* signal error */
- msg_context->u.bulk.status = -EINVAL;
- msg_context->u.bulk.buffer_used =
- msg->u.buffer_from_host.payload_in_message;
- }
-
- /* schedule the port callback */
- schedule_work(&msg_context->u.bulk.work);
-}
-
-static void bulk_receive_cb(struct vchiq_mmal_instance *instance,
- struct mmal_msg_context *msg_context)
-{
- msg_context->u.bulk.status = 0;
-
- /* schedule the port callback */
- schedule_work(&msg_context->u.bulk.work);
-}
-
-static void bulk_abort_cb(struct vchiq_mmal_instance *instance,
- struct mmal_msg_context *msg_context)
-{
- pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context);
-
- msg_context->u.bulk.status = -EINTR;
-
- schedule_work(&msg_context->u.bulk.work);
-}
-
-/* incoming event service callback */
-static int mmal_service_callback(struct vchiq_instance *vchiq_instance,
- enum vchiq_reason reason, struct vchiq_header *header,
- unsigned int handle, void *cb_data,
- void __user *cb_userdata)
-{
- struct vchiq_mmal_instance *instance = vchiq_get_service_userdata(vchiq_instance, handle);
- u32 msg_len;
- struct mmal_msg *msg;
- struct mmal_msg_context *msg_context;
-
- if (!instance) {
- pr_err("Message callback passed NULL instance\n");
- return 0;
- }
-
- switch (reason) {
- case VCHIQ_MESSAGE_AVAILABLE:
- msg = (void *)header->data;
- msg_len = header->size;
-
- DBG_DUMP_MSG(msg, msg_len, "<<< reply message");
-
- /* handling is different for buffer messages */
- switch (msg->h.type) {
- case MMAL_MSG_TYPE_BUFFER_FROM_HOST:
- vchiq_release_message(vchiq_instance, handle, header);
- break;
-
- case MMAL_MSG_TYPE_EVENT_TO_HOST:
- event_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(vchiq_instance, handle, header);
-
- break;
-
- case MMAL_MSG_TYPE_BUFFER_TO_HOST:
- buffer_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(vchiq_instance, handle, header);
- break;
-
- default:
- /* messages dependent on header context to complete */
- if (!msg->h.context) {
- pr_err("received message context was null!\n");
- vchiq_release_message(vchiq_instance, handle, header);
- break;
- }
-
- msg_context = lookup_msg_context(instance,
- msg->h.context);
- if (!msg_context) {
- pr_err("received invalid message context %u!\n",
- msg->h.context);
- vchiq_release_message(vchiq_instance, handle, header);
- break;
- }
-
- /* fill in context values */
- msg_context->u.sync.msg_handle = header;
- msg_context->u.sync.msg = msg;
- msg_context->u.sync.msg_len = msg_len;
-
- /* todo: should this check (completion_done()
- * == 1) for no one waiting? or do we need a
- * flag to tell us the completion has been
- * interrupted so we can free the message and
- * its context. This probably also solves the
- * message arriving after interruption todo
- * below
- */
-
- /* complete message so caller knows it happened */
- complete(&msg_context->u.sync.cmplt);
- break;
- }
-
- break;
-
- case VCHIQ_BULK_RECEIVE_DONE:
- bulk_receive_cb(instance, cb_data);
- break;
-
- case VCHIQ_BULK_RECEIVE_ABORTED:
- bulk_abort_cb(instance, cb_data);
- break;
-
- case VCHIQ_SERVICE_CLOSED:
- /* TODO: consider if this requires action if received when
- * driver is not explicitly closing the service
- */
- break;
-
- default:
- pr_err("Received unhandled message reason %d\n", reason);
- break;
- }
-
- return 0;
-}
-
-static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance,
- struct mmal_msg *msg,
- unsigned int payload_len,
- struct mmal_msg **msg_out,
- struct vchiq_header **msg_handle)
-{
- struct mmal_msg_context *msg_context;
- int ret;
- unsigned long time_left;
-
- /* payload size must not cause message to exceed max size */
- if (payload_len >
- (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) {
- pr_err("payload length %d exceeds max:%d\n", payload_len,
- (int)(MMAL_MSG_MAX_SIZE -
- sizeof(struct mmal_msg_header)));
- return -EINVAL;
- }
-
- msg_context = get_msg_context(instance);
- if (IS_ERR(msg_context))
- return PTR_ERR(msg_context);
-
- init_completion(&msg_context->u.sync.cmplt);
-
- msg->h.magic = MMAL_MAGIC;
- msg->h.context = msg_context->handle;
- msg->h.status = 0;
-
- DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len),
- ">>> sync message");
-
- vchiq_use_service(instance->vchiq_instance, instance->service_handle);
-
- ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, msg,
- sizeof(struct mmal_msg_header) +
- payload_len);
-
- vchiq_release_service(instance->vchiq_instance, instance->service_handle);
-
- if (ret) {
- pr_err("error %d queuing message\n", ret);
- release_msg_context(msg_context);
- return ret;
- }
-
- time_left = wait_for_completion_timeout(&msg_context->u.sync.cmplt,
- SYNC_MSG_TIMEOUT * HZ);
- if (time_left == 0) {
- pr_err("timed out waiting for sync completion\n");
- ret = -ETIME;
- /* todo: what happens if the message arrives after aborting */
- release_msg_context(msg_context);
- return ret;
- }
-
- *msg_out = msg_context->u.sync.msg;
- *msg_handle = msg_context->u.sync.msg_handle;
- release_msg_context(msg_context);
-
- return 0;
-}
-
-static void dump_port_info(struct vchiq_mmal_port *port)
-{
- pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled);
-
- pr_debug("buffer minimum num:%d size:%d align:%d\n",
- port->minimum_buffer.num,
- port->minimum_buffer.size, port->minimum_buffer.alignment);
-
- pr_debug("buffer recommended num:%d size:%d align:%d\n",
- port->recommended_buffer.num,
- port->recommended_buffer.size,
- port->recommended_buffer.alignment);
-
- pr_debug("buffer current values num:%d size:%d align:%d\n",
- port->current_buffer.num,
- port->current_buffer.size, port->current_buffer.alignment);
-
- pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n",
- port->format.type,
- port->format.encoding, port->format.encoding_variant);
-
- pr_debug(" bitrate:%d flags:0x%x\n",
- port->format.bitrate, port->format.flags);
-
- if (port->format.type == MMAL_ES_TYPE_VIDEO) {
- pr_debug
- ("es video format: width:%d height:%d colourspace:0x%x\n",
- port->es.video.width, port->es.video.height,
- port->es.video.color_space);
-
- pr_debug(" : crop xywh %d,%d,%d,%d\n",
- port->es.video.crop.x,
- port->es.video.crop.y,
- port->es.video.crop.width, port->es.video.crop.height);
- pr_debug(" : framerate %d/%d aspect %d/%d\n",
- port->es.video.frame_rate.numerator,
- port->es.video.frame_rate.denominator,
- port->es.video.par.numerator, port->es.video.par.denominator);
- }
-}
-
-static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p)
-{
- /* todo do readonly fields need setting at all? */
- p->type = port->type;
- p->index = port->index;
- p->index_all = 0;
- p->is_enabled = port->enabled;
- p->buffer_num_min = port->minimum_buffer.num;
- p->buffer_size_min = port->minimum_buffer.size;
- p->buffer_alignment_min = port->minimum_buffer.alignment;
- p->buffer_num_recommended = port->recommended_buffer.num;
- p->buffer_size_recommended = port->recommended_buffer.size;
-
- /* only three writable fields in a port */
- p->buffer_num = port->current_buffer.num;
- p->buffer_size = port->current_buffer.size;
- p->userdata = (u32)(unsigned long)port;
-}
-
-static int port_info_set(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- pr_debug("setting port info port %p\n", port);
- if (!port)
- return -1;
- dump_port_info(port);
-
- m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET;
-
- m.u.port_info_set.component_handle = port->component->handle;
- m.u.port_info_set.port_type = port->type;
- m.u.port_info_set.port_index = port->index;
-
- port_to_mmal_msg(port, &m.u.port_info_set.port);
-
- /* elementary stream format setup */
- m.u.port_info_set.format.type = port->format.type;
- m.u.port_info_set.format.encoding = port->format.encoding;
- m.u.port_info_set.format.encoding_variant =
- port->format.encoding_variant;
- m.u.port_info_set.format.bitrate = port->format.bitrate;
- m.u.port_info_set.format.flags = port->format.flags;
-
- memcpy(&m.u.port_info_set.es, &port->es,
- sizeof(union mmal_es_specific_format));
-
- m.u.port_info_set.format.extradata_size = port->format.extradata_size;
- memcpy(&m.u.port_info_set.extradata, port->format.extradata,
- port->format.extradata_size);
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.port_info_set),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- /* return operation status */
- ret = -rmsg->u.port_info_get_reply.status;
-
- pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret,
- port->component->handle, port->handle);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* use port info get message to retrieve port information */
-static int port_info_get(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- /* port info time */
- m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET;
- m.u.port_info_get.component_handle = port->component->handle;
- m.u.port_info_get.port_type = port->type;
- m.u.port_info_get.index = port->index;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.port_info_get),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- /* return operation status */
- ret = -rmsg->u.port_info_get_reply.status;
- if (ret != MMAL_MSG_STATUS_SUCCESS)
- goto release_msg;
-
- if (rmsg->u.port_info_get_reply.port.is_enabled == 0)
- port->enabled = false;
- else
- port->enabled = true;
-
- /* copy the values out of the message */
- port->handle = rmsg->u.port_info_get_reply.port_handle;
-
- /* port type and index cached to use on port info set because
- * it does not use a port handle
- */
- port->type = rmsg->u.port_info_get_reply.port_type;
- port->index = rmsg->u.port_info_get_reply.port_index;
-
- port->minimum_buffer.num =
- rmsg->u.port_info_get_reply.port.buffer_num_min;
- port->minimum_buffer.size =
- rmsg->u.port_info_get_reply.port.buffer_size_min;
- port->minimum_buffer.alignment =
- rmsg->u.port_info_get_reply.port.buffer_alignment_min;
-
- port->recommended_buffer.alignment =
- rmsg->u.port_info_get_reply.port.buffer_alignment_min;
- port->recommended_buffer.num =
- rmsg->u.port_info_get_reply.port.buffer_num_recommended;
-
- port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num;
- port->current_buffer.size =
- rmsg->u.port_info_get_reply.port.buffer_size;
-
- /* stream format */
- port->format.type = rmsg->u.port_info_get_reply.format.type;
- port->format.encoding = rmsg->u.port_info_get_reply.format.encoding;
- port->format.encoding_variant =
- rmsg->u.port_info_get_reply.format.encoding_variant;
- port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate;
- port->format.flags = rmsg->u.port_info_get_reply.format.flags;
-
- /* elementary stream format */
- memcpy(&port->es,
- &rmsg->u.port_info_get_reply.es,
- sizeof(union mmal_es_specific_format));
- port->format.es = &port->es;
-
- port->format.extradata_size =
- rmsg->u.port_info_get_reply.format.extradata_size;
- memcpy(port->format.extradata,
- rmsg->u.port_info_get_reply.extradata,
- port->format.extradata_size);
-
- pr_debug("received port info\n");
- dump_port_info(port);
-
-release_msg:
-
- pr_debug("%s:result:%d component:0x%x port:%d\n",
- __func__, ret, port->component->handle, port->handle);
-
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* create component on vc */
-static int create_component(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component,
- const char *name)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- /* build component create message */
- m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE;
- m.u.component_create.client_component = component->client_component;
- strscpy_pad(m.u.component_create.name, name,
- sizeof(m.u.component_create.name));
- m.u.component_create.pid = 0;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.component_create),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != m.h.type) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.component_create_reply.status;
- if (ret != MMAL_MSG_STATUS_SUCCESS)
- goto release_msg;
-
- /* a valid component response received */
- component->handle = rmsg->u.component_create_reply.component_handle;
- component->inputs = rmsg->u.component_create_reply.input_num;
- component->outputs = rmsg->u.component_create_reply.output_num;
- component->clocks = rmsg->u.component_create_reply.clock_num;
-
- pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n",
- component->handle,
- component->inputs, component->outputs, component->clocks);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* destroys a component on vc */
-static int destroy_component(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY;
- m.u.component_destroy.component_handle = component->handle;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.component_destroy),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != m.h.type) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.component_destroy_reply.status;
-
-release_msg:
-
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* enable a component on vc */
-static int enable_component(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE;
- m.u.component_enable.component_handle = component->handle;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.component_enable),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != m.h.type) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.component_enable_reply.status;
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* disable a component on vc */
-static int disable_component(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE;
- m.u.component_disable.component_handle = component->handle;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.component_disable),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != m.h.type) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.component_disable_reply.status;
-
-release_msg:
-
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* get version of mmal implementation */
-static int get_version(struct vchiq_mmal_instance *instance,
- u32 *major_out, u32 *minor_out)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_GET_VERSION;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.version),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != m.h.type) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- *major_out = rmsg->u.version.major;
- *minor_out = rmsg->u.version.minor;
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* do a port action with a port as a parameter */
-static int port_action_port(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- enum mmal_msg_port_action_type action_type)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
- m.u.port_action_port.component_handle = port->component->handle;
- m.u.port_action_port.port_handle = port->handle;
- m.u.port_action_port.action = action_type;
-
- port_to_mmal_msg(port, &m.u.port_action_port.port);
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.port_action_port),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.port_action_reply.status;
-
- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n",
- __func__,
- ret, port->component->handle, port->handle,
- port_action_type_names[action_type], action_type);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* do a port action with handles as parameters */
-static int port_action_handle(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- enum mmal_msg_port_action_type action_type,
- u32 connect_component_handle,
- u32 connect_port_handle)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_PORT_ACTION;
-
- m.u.port_action_handle.component_handle = port->component->handle;
- m.u.port_action_handle.port_handle = port->handle;
- m.u.port_action_handle.action = action_type;
-
- m.u.port_action_handle.connect_component_handle =
- connect_component_handle;
- m.u.port_action_handle.connect_port_handle = connect_port_handle;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(m.u.port_action_handle),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.port_action_reply.status;
-
- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n",
- __func__,
- ret, port->component->handle, port->handle,
- port_action_type_names[action_type],
- action_type, connect_component_handle, connect_port_handle);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-static int port_parameter_set(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter_id, void *value, u32 value_size)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET;
-
- m.u.port_parameter_set.component_handle = port->component->handle;
- m.u.port_parameter_set.port_handle = port->handle;
- m.u.port_parameter_set.id = parameter_id;
- m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size;
- memcpy(&m.u.port_parameter_set.value, value, value_size);
-
- ret = send_synchronous_mmal_msg(instance, &m,
- (4 * sizeof(u32)) + value_size,
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) {
- /* got an unexpected message type in reply */
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = -rmsg->u.port_parameter_set_reply.status;
-
- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n",
- __func__,
- ret, port->component->handle, port->handle, parameter_id);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-static int port_parameter_get(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter_id, void *value, u32 *value_size)
-{
- int ret;
- struct mmal_msg m;
- struct mmal_msg *rmsg;
- struct vchiq_header *rmsg_handle;
-
- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET;
-
- m.u.port_parameter_get.component_handle = port->component->handle;
- m.u.port_parameter_get.port_handle = port->handle;
- m.u.port_parameter_get.id = parameter_id;
- m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size;
-
- ret = send_synchronous_mmal_msg(instance, &m,
- sizeof(struct
- mmal_msg_port_parameter_get),
- &rmsg, &rmsg_handle);
- if (ret)
- return ret;
-
- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) {
- /* got an unexpected message type in reply */
- pr_err("Incorrect reply type %d\n", rmsg->h.type);
- ret = -EINVAL;
- goto release_msg;
- }
-
- ret = rmsg->u.port_parameter_get_reply.status;
-
- /* port_parameter_get_reply.size includes the header,
- * whilst *value_size doesn't.
- */
- rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32));
-
- if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) {
- /* Copy only as much as we have space for
- * but report true size of parameter
- */
- memcpy(value, &rmsg->u.port_parameter_get_reply.value,
- *value_size);
- } else {
- memcpy(value, &rmsg->u.port_parameter_get_reply.value,
- rmsg->u.port_parameter_get_reply.size);
- }
- /* Always report the size of the returned parameter to the caller */
- *value_size = rmsg->u.port_parameter_get_reply.size;
-
- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__,
- ret, port->component->handle, port->handle, parameter_id);
-
-release_msg:
- vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
-
- return ret;
-}
-
-/* disables a port and drains buffers from it */
-static int port_disable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- int ret;
- struct list_head *q, *buf_head;
- unsigned long flags = 0;
-
- if (!port->enabled)
- return 0;
-
- port->enabled = false;
-
- ret = port_action_port(instance, port,
- MMAL_MSG_PORT_ACTION_TYPE_DISABLE);
- if (ret == 0) {
- /*
- * Drain all queued buffers on port. This should only
- * apply to buffers that have been queued before the port
- * has been enabled. If the port has been enabled and buffers
- * passed, then the buffers should have been removed from this
- * list, and we should get the relevant callbacks via VCHIQ
- * to release the buffers.
- */
- spin_lock_irqsave(&port->slock, flags);
-
- list_for_each_safe(buf_head, q, &port->buffers) {
- struct mmal_buffer *mmalbuf;
-
- mmalbuf = list_entry(buf_head, struct mmal_buffer,
- list);
- list_del(buf_head);
- if (port->buffer_cb) {
- mmalbuf->length = 0;
- mmalbuf->mmal_flags = 0;
- mmalbuf->dts = MMAL_TIME_UNKNOWN;
- mmalbuf->pts = MMAL_TIME_UNKNOWN;
- port->buffer_cb(instance,
- port, 0, mmalbuf);
- }
- }
-
- spin_unlock_irqrestore(&port->slock, flags);
-
- ret = port_info_get(instance, port);
- }
-
- return ret;
-}
-
-/* enable a port */
-static int port_enable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- unsigned int hdr_count;
- struct list_head *q, *buf_head;
- int ret;
-
- if (port->enabled)
- return 0;
-
- ret = port_action_port(instance, port,
- MMAL_MSG_PORT_ACTION_TYPE_ENABLE);
- if (ret)
- goto done;
-
- port->enabled = true;
-
- if (port->buffer_cb) {
- /* send buffer headers to videocore */
- hdr_count = 1;
- list_for_each_safe(buf_head, q, &port->buffers) {
- struct mmal_buffer *mmalbuf;
-
- mmalbuf = list_entry(buf_head, struct mmal_buffer,
- list);
- ret = buffer_from_host(instance, port, mmalbuf);
- if (ret)
- goto done;
-
- list_del(buf_head);
- hdr_count++;
- if (hdr_count > port->current_buffer.num)
- break;
- }
- }
-
- ret = port_info_get(instance, port);
-
-done:
- return ret;
-}
-
-/* ------------------------------------------------------------------
- * Exported API
- *------------------------------------------------------------------
- */
-
-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- ret = port_info_set(instance, port);
- if (ret)
- goto release_unlock;
-
- /* read what has actually been set */
- ret = port_info_get(instance, port);
-
-release_unlock:
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_set_format);
-
-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter, void *value, u32 value_size)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- ret = port_parameter_set(instance, port, parameter, value, value_size);
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
-
-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter, void *value, u32 *value_size)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- ret = port_parameter_get(instance, port, parameter, value, value_size);
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_get);
-
-/* enable a port
- *
- * enables a port and queues buffers for satisfying callbacks if we
- * provide a callback handler
- */
-int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- vchiq_mmal_buffer_cb buffer_cb)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- /* already enabled - noop */
- if (port->enabled) {
- ret = 0;
- goto unlock;
- }
-
- port->buffer_cb = buffer_cb;
-
- ret = port_enable(instance, port);
-
-unlock:
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_enable);
-
-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- if (!port->enabled) {
- mutex_unlock(&instance->vchiq_mutex);
- return 0;
- }
-
- ret = port_disable(instance, port);
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_disable);
-
-/* ports will be connected in a tunneled manner so data buffers
- * are not handled by client.
- */
-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *src,
- struct vchiq_mmal_port *dst)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- /* disconnect ports if connected */
- if (src->connected) {
- ret = port_disable(instance, src);
- if (ret) {
- pr_err("failed disabling src port(%d)\n", ret);
- goto release_unlock;
- }
-
- /* do not need to disable the destination port as they
- * are connected and it is done automatically
- */
-
- ret = port_action_handle(instance, src,
- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT,
- src->connected->component->handle,
- src->connected->handle);
- if (ret < 0) {
- pr_err("failed disconnecting src port\n");
- goto release_unlock;
- }
- src->connected->enabled = false;
- src->connected = NULL;
- }
-
- if (!dst) {
- /* do not make new connection */
- ret = 0;
- pr_debug("not making new connection\n");
- goto release_unlock;
- }
-
- /* copy src port format to dst */
- dst->format.encoding = src->format.encoding;
- dst->es.video.width = src->es.video.width;
- dst->es.video.height = src->es.video.height;
- dst->es.video.crop.x = src->es.video.crop.x;
- dst->es.video.crop.y = src->es.video.crop.y;
- dst->es.video.crop.width = src->es.video.crop.width;
- dst->es.video.crop.height = src->es.video.crop.height;
- dst->es.video.frame_rate.numerator = src->es.video.frame_rate.numerator;
- dst->es.video.frame_rate.denominator = src->es.video.frame_rate.denominator;
-
- /* set new format */
- ret = port_info_set(instance, dst);
- if (ret) {
- pr_debug("setting port info failed\n");
- goto release_unlock;
- }
-
- /* read what has actually been set */
- ret = port_info_get(instance, dst);
- if (ret) {
- pr_debug("read back port info failed\n");
- goto release_unlock;
- }
-
- /* connect two ports together */
- ret = port_action_handle(instance, src,
- MMAL_MSG_PORT_ACTION_TYPE_CONNECT,
- dst->component->handle, dst->handle);
- if (ret < 0) {
- pr_debug("connecting port %d:%d to %d:%d failed\n",
- src->component->handle, src->handle,
- dst->component->handle, dst->handle);
- goto release_unlock;
- }
- src->connected = dst;
-
-release_unlock:
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_port_connect_tunnel);
-
-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- struct mmal_buffer *buffer)
-{
- unsigned long flags = 0;
- int ret;
-
- ret = buffer_from_host(instance, port, buffer);
- if (ret == -EINVAL) {
- /* Port is disabled. Queue for when it is enabled. */
- spin_lock_irqsave(&port->slock, flags);
- list_add_tail(&buffer->list, &port->buffers);
- spin_unlock_irqrestore(&port->slock, flags);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_submit_buffer);
-
-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
- struct mmal_buffer *buf)
-{
- struct mmal_msg_context *msg_context = get_msg_context(instance);
-
- if (IS_ERR(msg_context))
- return (PTR_ERR(msg_context));
-
- buf->msg_context = msg_context;
- return 0;
-}
-EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
-
-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
-{
- struct mmal_msg_context *msg_context = buf->msg_context;
-
- if (msg_context)
- release_msg_context(msg_context);
- buf->msg_context = NULL;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
-
-/* Initialise a mmal component and its ports
- *
- */
-int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
- const char *name,
- struct vchiq_mmal_component **component_out)
-{
- int ret;
- int idx; /* port index */
- struct vchiq_mmal_component *component = NULL;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- for (idx = 0; idx < VCHIQ_MMAL_MAX_COMPONENTS; idx++) {
- if (!instance->component[idx].in_use) {
- component = &instance->component[idx];
- component->in_use = true;
- break;
- }
- }
-
- if (!component) {
- ret = -EINVAL; /* todo is this correct error? */
- goto unlock;
- }
-
- /* We need a handle to reference back to our component structure.
- * Use the array index in instance->component rather than rolling
- * another IDR.
- */
- component->client_component = idx;
-
- ret = create_component(instance, component, name);
- if (ret < 0) {
- pr_err("%s: failed to create component %d (Not enough GPU mem?)\n",
- __func__, ret);
- goto unlock;
- }
-
- /* ports info needs gathering */
- component->control.type = MMAL_PORT_TYPE_CONTROL;
- component->control.index = 0;
- component->control.component = component;
- spin_lock_init(&component->control.slock);
- INIT_LIST_HEAD(&component->control.buffers);
- ret = port_info_get(instance, &component->control);
- if (ret < 0)
- goto release_component;
-
- for (idx = 0; idx < component->inputs; idx++) {
- component->input[idx].type = MMAL_PORT_TYPE_INPUT;
- component->input[idx].index = idx;
- component->input[idx].component = component;
- spin_lock_init(&component->input[idx].slock);
- INIT_LIST_HEAD(&component->input[idx].buffers);
- ret = port_info_get(instance, &component->input[idx]);
- if (ret < 0)
- goto release_component;
- }
-
- for (idx = 0; idx < component->outputs; idx++) {
- component->output[idx].type = MMAL_PORT_TYPE_OUTPUT;
- component->output[idx].index = idx;
- component->output[idx].component = component;
- spin_lock_init(&component->output[idx].slock);
- INIT_LIST_HEAD(&component->output[idx].buffers);
- ret = port_info_get(instance, &component->output[idx]);
- if (ret < 0)
- goto release_component;
- }
-
- for (idx = 0; idx < component->clocks; idx++) {
- component->clock[idx].type = MMAL_PORT_TYPE_CLOCK;
- component->clock[idx].index = idx;
- component->clock[idx].component = component;
- spin_lock_init(&component->clock[idx].slock);
- INIT_LIST_HEAD(&component->clock[idx].buffers);
- ret = port_info_get(instance, &component->clock[idx]);
- if (ret < 0)
- goto release_component;
- }
-
- *component_out = component;
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return 0;
-
-release_component:
- destroy_component(instance, component);
-unlock:
- if (component)
- component->in_use = false;
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_component_init);
-
-/*
- * cause a mmal component to be destroyed
- */
-int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- if (component->enabled)
- ret = disable_component(instance, component);
-
- ret = destroy_component(instance, component);
-
- component->in_use = false;
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_component_finalise);
-
-/*
- * cause a mmal component to be enabled
- */
-int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- if (component->enabled) {
- mutex_unlock(&instance->vchiq_mutex);
- return 0;
- }
-
- ret = enable_component(instance, component);
- if (ret == 0)
- component->enabled = true;
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_component_enable);
-
-/*
- * cause a mmal component to be enabled
- */
-int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- if (!component->enabled) {
- mutex_unlock(&instance->vchiq_mutex);
- return 0;
- }
-
- ret = disable_component(instance, component);
- if (ret == 0)
- component->enabled = false;
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_component_disable);
-
-int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
- u32 *major_out, u32 *minor_out)
-{
- int ret;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- ret = get_version(instance, major_out, minor_out);
-
- mutex_unlock(&instance->vchiq_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_version);
-
-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
-{
- int status = 0;
-
- if (!instance)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&instance->vchiq_mutex))
- return -EINTR;
-
- vchiq_use_service(instance->vchiq_instance, instance->service_handle);
-
- status = vchiq_close_service(instance->vchiq_instance, instance->service_handle);
- if (status != 0)
- pr_err("mmal-vchiq: VCHIQ close failed\n");
-
- mutex_unlock(&instance->vchiq_mutex);
-
- vchiq_shutdown(instance->vchiq_instance);
- destroy_workqueue(instance->bulk_wq);
-
- idr_destroy(&instance->context_map);
-
- kfree(instance);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_finalise);
-
-int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance)
-{
- int status;
- int err = -ENODEV;
- struct vchiq_mmal_instance *instance;
- struct vchiq_instance *vchiq_instance;
- struct vchiq_service_params_kernel params = {
- .version = VC_MMAL_VER,
- .version_min = VC_MMAL_MIN_VER,
- .fourcc = VCHIQ_MAKE_FOURCC('m', 'm', 'a', 'l'),
- .callback = mmal_service_callback,
- .userdata = NULL,
- };
- struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(dev->parent);
-
- /* compile time checks to ensure structure size as they are
- * directly (de)serialised from memory.
- */
-
- /* ensure the header structure has packed to the correct size */
- BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24);
-
- /* ensure message structure does not exceed maximum length */
- BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE);
-
- /* mmal port struct is correct size */
- BUILD_BUG_ON(sizeof(struct mmal_port) != 64);
-
- /* create a vchi instance */
- status = vchiq_initialise(&mgmt->state, &vchiq_instance);
- if (status) {
- pr_err("Failed to initialise VCHI instance (status=%d)\n",
- status);
- return -EIO;
- }
-
- status = vchiq_connect(vchiq_instance);
- if (status) {
- pr_err("Failed to connect VCHI instance (status=%d)\n", status);
- err = -EIO;
- goto err_shutdown_vchiq;
- }
-
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
-
- if (!instance) {
- err = -ENOMEM;
- goto err_shutdown_vchiq;
- }
-
- mutex_init(&instance->vchiq_mutex);
-
- instance->vchiq_instance = vchiq_instance;
-
- mutex_init(&instance->context_map_lock);
- idr_init_base(&instance->context_map, 1);
-
- params.userdata = instance;
-
- instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq",
- WQ_MEM_RECLAIM);
- if (!instance->bulk_wq)
- goto err_free;
-
- status = vchiq_open_service(vchiq_instance, &params,
- &instance->service_handle);
- if (status) {
- pr_err("Failed to open VCHI service connection (status=%d)\n",
- status);
- goto err_close_services;
- }
-
- vchiq_release_service(instance->vchiq_instance, instance->service_handle);
-
- *out_instance = instance;
-
- return 0;
-
-err_close_services:
- vchiq_close_service(instance->vchiq_instance, instance->service_handle);
- destroy_workqueue(instance->bulk_wq);
-err_free:
- kfree(instance);
-err_shutdown_vchiq:
- vchiq_shutdown(vchiq_instance);
- return err;
-}
-EXPORT_SYMBOL_GPL(vchiq_mmal_init);
-
-MODULE_DESCRIPTION("BCM2835 MMAL VCHIQ interface");
-MODULE_AUTHOR("Dave Stevenson, <dave.stevenson@raspberrypi.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
deleted file mode 100644
index 8c3959f6f97f..000000000000
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Broadcom BCM2835 V4L2 driver
- *
- * Copyright © 2013 Raspberry Pi (Trading) Ltd.
- *
- * Authors: Vincent Sanders @ Collabora
- * Dave Stevenson @ Broadcom
- * (now dave.stevenson@raspberrypi.org)
- * Simon Mellor @ Broadcom
- * Luke Diamand @ Broadcom
- *
- * MMAL interface to VCHIQ message passing
- */
-
-#ifndef MMAL_VCHIQ_H
-#define MMAL_VCHIQ_H
-
-#include "mmal-common.h"
-#include "mmal-msg-format.h"
-
-#define MAX_PORT_COUNT 4
-
-/* Maximum size of the format extradata. */
-#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128
-
-struct vchiq_mmal_instance;
-struct device;
-
-enum vchiq_mmal_es_type {
- MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */
- MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */
- MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */
- MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */
- MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */
-};
-
-struct vchiq_mmal_port_buffer {
- unsigned int num; /* number of buffers */
- u32 size; /* size of buffers */
- u32 alignment; /* alignment of buffers */
-};
-
-struct vchiq_mmal_port;
-
-typedef void (*vchiq_mmal_buffer_cb)(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- int status, struct mmal_buffer *buffer);
-
-struct vchiq_mmal_port {
- bool enabled;
- u32 handle;
- u32 type; /* port type, cached to use on port info set */
- u32 index; /* port index, cached to use on port info set */
-
- /* component port belongs to, allows simple deref */
- struct vchiq_mmal_component *component;
-
- struct vchiq_mmal_port *connected; /* port connected to */
-
- /* buffer info */
- struct vchiq_mmal_port_buffer minimum_buffer;
- struct vchiq_mmal_port_buffer recommended_buffer;
- struct vchiq_mmal_port_buffer current_buffer;
-
- /* stream format */
- struct mmal_es_format_local format;
- /* elementary stream format */
- union mmal_es_specific_format es;
-
- /* data buffers to fill */
- struct list_head buffers;
- /* lock to serialise adding and removing buffers from list */
- spinlock_t slock;
-
- /* Count of buffers the VPU has yet to return */
- atomic_t buffers_with_vpu;
- /* callback on buffer completion */
- vchiq_mmal_buffer_cb buffer_cb;
- /* callback context */
- void *cb_ctx;
-};
-
-struct vchiq_mmal_component {
- bool in_use;
- bool enabled;
- u32 handle; /* VideoCore handle for component */
- u32 inputs; /* Number of input ports */
- u32 outputs; /* Number of output ports */
- u32 clocks; /* Number of clock ports */
- struct vchiq_mmal_port control; /* control port */
- struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */
- struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */
- struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */
- u32 client_component; /* Used to ref back to client struct */
-};
-
-int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance);
-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance);
-
-/* Initialise a mmal component and its ports
- *
- */
-int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance,
- const char *name, struct vchiq_mmal_component **component_out);
-
-int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component);
-
-int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component);
-
-int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_component *component);
-
-/* enable a mmal port
- *
- * enables a port and, if a buffer callback provided, enqueues buffer
- * headers as appropriate for the port.
- */
-int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- vchiq_mmal_buffer_cb buffer_cb);
-
-/* disable a port
- *
- * disable a port will dequeue any pending buffers
- */
-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port);
-
-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter,
- void *value,
- u32 value_size);
-
-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- u32 parameter,
- void *value,
- u32 *value_size);
-
-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port);
-
-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *src,
- struct vchiq_mmal_port *dst);
-
-int vchiq_mmal_version(struct vchiq_mmal_instance *instance,
- u32 *major_out,
- u32 *minor_out);
-
-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
- struct vchiq_mmal_port *port,
- struct mmal_buffer *buf);
-
-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
- struct mmal_buffer *buf);
-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);
-#endif /* MMAL_VCHIQ_H */