aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-06 19:41:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-06 19:41:06 -0500
commit1071ec7bc2dabd0a9d12a1ae5570f4fd3ba944ca (patch)
tree3f889877ae180066a8e682d915680f240fbfd6ec
parentc287322c3aadf45ee15339bffdbc2e9117b9cc7a (diff)
parent425792266a40189e0b3fec02cb59a69935d8c58c (diff)
Merge tag 'char-misc-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc patches from Greg KH: "Here's the big char/misc driver patchset for 3.13-rc1. Lots of stuff in here, including some new drivers for Intel's "MIC" co-processor devices, and a new eeprom driver. Other things include the driver attribute cleanups, extcon driver updates, hyperv updates, and a raft of other miscellaneous driver fixes. All of these have been in linux-next for a while" * tag 'char-misc-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (121 commits) misc: mic: Fixes for randconfig build errors and warnings. tifm: fix error return code in tifm_7xx1_probe() w1-gpio: Use devm_* functions w1-gpio: Detect of_gpio_error for first gpio uio: Pass pointers to virt_to_page(), not integers uio: fix memory leak misc/at24: avoid infinite loop on write() misc/93xx46: avoid infinite loop on write() misc: atmel_pwm: add deferred-probing support mei: wd: host_init propagate error codes from called functions mei: replace stray pr_debug with dev_dbg mei: bus: propagate error code returned by mei_me_cl_by_id mei: mei_cl_link remove duplicated check for open_handle_count mei: print correct device state during unexpected reset mei: nfc: fix memory leak in error path lkdtm: add tests for additional page permissions lkdtm: adjust recursion size to avoid warnings lkdtm: isolate stack corruption test mei: move host_clients_map cleanup to device init mei: me: downgrade two errors to debug level ...
-rw-r--r--Documentation/ABI/testing/sysfs-class-mic.txt157
-rw-r--r--Documentation/ABI/testing/sysfs-driver-sunxi-sid22
-rw-r--r--Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt17
-rw-r--r--Documentation/devicetree/bindings/misc/ti,dac7512.txt20
-rw-r--r--Documentation/extcon/porting-android-switch-class6
-rw-r--r--Documentation/mic/mic_overview.txt51
-rw-r--r--Documentation/mic/mpssd/.gitignore1
-rw-r--r--Documentation/mic/mpssd/Makefile19
-rwxr-xr-xDocumentation/mic/mpssd/micctrl173
-rwxr-xr-xDocumentation/mic/mpssd/mpss202
-rw-r--r--Documentation/mic/mpssd/mpssd.c1721
-rw-r--r--Documentation/mic/mpssd/mpssd.h102
-rw-r--r--Documentation/mic/mpssd/sysfs.c102
-rw-r--r--drivers/char/hpet.c5
-rw-r--r--drivers/char/misc.c8
-rw-r--r--drivers/char/nwbutton.c2
-rw-r--r--drivers/char/rtc.c5
-rw-r--r--drivers/char/snsc.c3
-rw-r--r--drivers/char/snsc_event.c3
-rw-r--r--drivers/char/tlclk.c2
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c3
-rw-r--r--drivers/extcon/extcon-adc-jack.c27
-rw-r--r--drivers/extcon/extcon-arizona.c55
-rw-r--r--drivers/extcon/extcon-class.c102
-rw-r--r--drivers/extcon/extcon-gpio.c19
-rw-r--r--drivers/extcon/extcon-max77693.c136
-rw-r--r--drivers/extcon/extcon-max8997.c11
-rw-r--r--drivers/extcon/extcon-palmas.c5
-rw-r--r--drivers/hv/channel.c50
-rw-r--r--drivers/hv/channel_mgmt.c5
-rw-r--r--drivers/hv/connection.c21
-rw-r--r--drivers/hv/hv.c2
-rw-r--r--drivers/hv/hv_util.c2
-rw-r--r--drivers/hv/hyperv_vmbus.h9
-rw-r--r--drivers/hv/vmbus_drv.c488
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/arm-charlcd.c2
-rw-r--r--drivers/misc/atmel_pwm.c6
-rw-r--r--drivers/misc/bh1780gli.c11
-rw-r--r--drivers/misc/bmp085.c2
-rw-r--r--drivers/misc/cb710/core.c2
-rw-r--r--drivers/misc/eeprom/Kconfig13
-rw-r--r--drivers/misc/eeprom/Makefile1
-rw-r--r--drivers/misc/eeprom/at24.c3
-rw-r--r--drivers/misc/eeprom/at25.c7
-rw-r--r--drivers/misc/eeprom/eeprom_93xx46.c2
-rw-r--r--drivers/misc/eeprom/sunxi_sid.c158
-rw-r--r--drivers/misc/ibmasm/module.c4
-rw-r--r--drivers/misc/lkdtm.c107
-rw-r--r--drivers/misc/mei/amthif.c49
-rw-r--r--drivers/misc/mei/bus.c2
-rw-r--r--drivers/misc/mei/client.c129
-rw-r--r--drivers/misc/mei/client.h9
-rw-r--r--drivers/misc/mei/hbm.c9
-rw-r--r--drivers/misc/mei/hw-me-regs.h1
-rw-r--r--drivers/misc/mei/init.c21
-rw-r--r--drivers/misc/mei/interrupt.c47
-rw-r--r--drivers/misc/mei/main.c65
-rw-r--r--drivers/misc/mei/mei_dev.h1
-rw-r--r--drivers/misc/mei/nfc.c10
-rw-r--r--drivers/misc/mei/pci-me.c8
-rw-r--r--drivers/misc/mei/wd.c12
-rw-r--r--drivers/misc/mic/Kconfig39
-rw-r--r--drivers/misc/mic/Makefile6
-rw-r--r--drivers/misc/mic/card/Makefile11
-rw-r--r--drivers/misc/mic/card/mic_debugfs.c130
-rw-r--r--drivers/misc/mic/card/mic_device.c305
-rw-r--r--drivers/misc/mic/card/mic_device.h133
-rw-r--r--drivers/misc/mic/card/mic_virtio.c630
-rw-r--r--drivers/misc/mic/card/mic_virtio.h77
-rw-r--r--drivers/misc/mic/card/mic_x100.c256
-rw-r--r--drivers/misc/mic/card/mic_x100.h48
-rw-r--r--drivers/misc/mic/common/mic_dev.h51
-rw-r--r--drivers/misc/mic/host/Makefile14
-rw-r--r--drivers/misc/mic/host/mic_boot.c300
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c491
-rw-r--r--drivers/misc/mic/host/mic_device.h203
-rw-r--r--drivers/misc/mic/host/mic_fops.c222
-rw-r--r--drivers/misc/mic/host/mic_fops.h32
-rw-r--r--drivers/misc/mic/host/mic_intr.c630
-rw-r--r--drivers/misc/mic/host/mic_intr.h137
-rw-r--r--drivers/misc/mic/host/mic_main.c537
-rw-r--r--drivers/misc/mic/host/mic_smpt.c442
-rw-r--r--drivers/misc/mic/host/mic_smpt.h98
-rw-r--r--drivers/misc/mic/host/mic_sysfs.c459
-rw-r--r--drivers/misc/mic/host/mic_virtio.c700
-rw-r--r--drivers/misc/mic/host/mic_virtio.h138
-rw-r--r--drivers/misc/mic/host/mic_x100.c570
-rw-r--r--drivers/misc/mic/host/mic_x100.h98
-rw-r--r--drivers/misc/phantom.c2
-rw-r--r--drivers/misc/pti.c1
-rw-r--r--drivers/misc/ti_dac7512.c23
-rw-r--r--drivers/misc/tifm_7xx1.c7
-rw-r--r--drivers/misc/vmw_vmci/vmci_guest.c2
-rw-r--r--drivers/misc/vmw_vmci/vmci_host.c6
-rw-r--r--drivers/misc/vmw_vmci/vmci_queue_pair.c21
-rw-r--r--drivers/pcmcia/pd6729.c13
-rw-r--r--drivers/pcmcia/yenta_socket.c16
-rw-r--r--drivers/uio/uio.c38
-rw-r--r--drivers/uio/uio_aec.c1
-rw-r--r--drivers/uio/uio_cif.c1
-rw-r--r--drivers/uio/uio_mf624.c5
-rw-r--r--drivers/uio/uio_netx.c1
-rw-r--r--drivers/uio/uio_pdrv_genirq.c34
-rw-r--r--drivers/uio/uio_sercos3.c1
-rw-r--r--drivers/w1/masters/ds1wm.c2
-rw-r--r--drivers/w1/masters/omap_hdq.c3
-rw-r--r--drivers/w1/masters/w1-gpio.c35
-rw-r--r--include/linux/extcon.h72
-rw-r--r--include/linux/extcon/extcon-adc-jack.h42
-rw-r--r--include/linux/extcon/extcon-gpio.h20
-rw-r--r--include/linux/hyperv.h37
-rw-r--r--include/uapi/linux/Kbuild2
-rw-r--r--include/uapi/linux/mic_common.h240
-rw-r--r--include/uapi/linux/mic_ioctl.h76
-rw-r--r--tools/hv/hv_kvp_daemon.c29
-rw-r--r--tools/hv/hv_vss_daemon.c8
118 files changed, 10904 insertions, 830 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mic.txt b/Documentation/ABI/testing/sysfs-class-mic.txt
new file mode 100644
index 000000000000..13f48afc534f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-mic.txt
@@ -0,0 +1,157 @@
1What: /sys/class/mic/
2Date: October 2013
3KernelVersion: 3.13
4Contact: Sudeep Dutt <sudeep.dutt@intel.com>
5Description:
6 The mic class directory belongs to Intel MIC devices and
7 provides information per MIC device. An Intel MIC device is a
8 PCIe form factor add-in Coprocessor card based on the Intel Many
9 Integrated Core (MIC) architecture that runs a Linux OS.
10
11What: /sys/class/mic/mic(x)
12Date: October 2013
13KernelVersion: 3.13
14Contact: Sudeep Dutt <sudeep.dutt@intel.com>
15Description:
16 The directories /sys/class/mic/mic0, /sys/class/mic/mic1 etc.,
17 represent MIC devices (0,1,..etc). Each directory has
18 information specific to that MIC device.
19
20What: /sys/class/mic/mic(x)/family
21Date: October 2013
22KernelVersion: 3.13
23Contact: Sudeep Dutt <sudeep.dutt@intel.com>
24Description:
25 Provides information about the Coprocessor family for an Intel
26 MIC device. For example - "x100"
27
28What: /sys/class/mic/mic(x)/stepping
29Date: October 2013
30KernelVersion: 3.13
31Contact: Sudeep Dutt <sudeep.dutt@intel.com>
32Description:
33 Provides information about the silicon stepping for an Intel
34 MIC device. For example - "A0" or "B0"
35
36What: /sys/class/mic/mic(x)/state
37Date: October 2013
38KernelVersion: 3.13
39Contact: Sudeep Dutt <sudeep.dutt@intel.com>
40Description:
41 When read, this entry provides the current state of an Intel
42 MIC device in the context of the card OS. Possible values that
43 will be read are:
44 "offline" - The MIC device is ready to boot the card OS. On
45 reading this entry after an OSPM resume, a "boot" has to be
46 written to this entry if the card was previously shutdown
47 during OSPM suspend.
48 "online" - The MIC device has initiated booting a card OS.
49 "shutting_down" - The card OS is shutting down.
50 "reset_failed" - The MIC device has failed to reset.
51 "suspending" - The MIC device is currently being prepared for
52 suspend. On reading this entry, a "suspend" has to be written
53 to the state sysfs entry to ensure the card is shutdown during
54 OSPM suspend.
55 "suspended" - The MIC device has been suspended.
56
57 When written, this sysfs entry triggers different state change
58 operations depending upon the current state of the card OS.
59 Acceptable values are:
60 "boot" - Boot the card OS image specified by the combination
61 of firmware, ramdisk, cmdline and bootmode
62 sysfs entries.
63 "reset" - Initiates device reset.
64 "shutdown" - Initiates card OS shutdown.
65 "suspend" - Initiates card OS shutdown and also marks the card
66 as suspended.
67
68What: /sys/class/mic/mic(x)/shutdown_status
69Date: October 2013
70KernelVersion: 3.13
71Contact: Sudeep Dutt <sudeep.dutt@intel.com>
72Description:
73 An Intel MIC device runs a Linux OS during its operation. This
74 OS can shutdown because of various reasons. When read, this
75 entry provides the status on why the card OS was shutdown.
76 Possible values are:
77 "nop" - shutdown status is not applicable, when the card OS is
78 "online"
79 "crashed" - Shutdown because of a HW or SW crash.
80 "halted" - Shutdown because of a halt command.
81 "poweroff" - Shutdown because of a poweroff command.
82 "restart" - Shutdown because of a restart command.
83
84What: /sys/class/mic/mic(x)/cmdline
85Date: October 2013
86KernelVersion: 3.13
87Contact: Sudeep Dutt <sudeep.dutt@intel.com>
88Description:
89 An Intel MIC device runs a Linux OS during its operation. Before
90 booting this card OS, it is possible to pass kernel command line
91 options to configure various features in it, similar to
92 self-bootable machines. When read, this entry provides
93 information about the current kernel command line options set to
94 boot the card OS. This entry can be written to change the
95 existing kernel command line options. Typically, the user would
96 want to read the current command line options, append new ones
97 or modify existing ones and then write the whole kernel command
98 line back to this entry.
99
100What: /sys/class/mic/mic(x)/firmware
101Date: October 2013
102KernelVersion: 3.13
103Contact: Sudeep Dutt <sudeep.dutt@intel.com>
104Description:
105 When read, this sysfs entry provides the path name under
106 /lib/firmware/ where the firmware image to be booted on the
107 card can be found. The entry can be written to change the
108 firmware image location under /lib/firmware/.
109
110What: /sys/class/mic/mic(x)/ramdisk
111Date: October 2013
112KernelVersion: 3.13
113Contact: Sudeep Dutt <sudeep.dutt@intel.com>
114Description:
115 When read, this sysfs entry provides the path name under
116 /lib/firmware/ where the ramdisk image to be used during card
117 OS boot can be found. The entry can be written to change
118 the ramdisk image location under /lib/firmware/.
119
120What: /sys/class/mic/mic(x)/bootmode
121Date: October 2013
122KernelVersion: 3.13
123Contact: Sudeep Dutt <sudeep.dutt@intel.com>
124Description:
125 When read, this sysfs entry provides the current bootmode for
126 the card. This sysfs entry can be written with the following
127 valid strings:
128 a) linux - Boot a Linux image.
129 b) elf - Boot an elf image for flash updates.
130
131What: /sys/class/mic/mic(x)/log_buf_addr
132Date: October 2013
133KernelVersion: 3.13
134Contact: Sudeep Dutt <sudeep.dutt@intel.com>
135Description:
136 An Intel MIC device runs a Linux OS during its operation. For
137 debugging purpose and early kernel boot messages, the user can
138 access the card OS log buffer via debugfs. When read, this entry
139 provides the kernel virtual address of the buffer where the card
140 OS log buffer can be read. This entry is written by the host
141 configuration daemon to set the log buffer address. The correct
142 log buffer address to be written can be found in the System.map
143 file of the card OS.
144
145What: /sys/class/mic/mic(x)/log_buf_len
146Date: October 2013
147KernelVersion: 3.13
148Contact: Sudeep Dutt <sudeep.dutt@intel.com>
149Description:
150 An Intel MIC device runs a Linux OS during its operation. For
151 debugging purpose and early kernel boot messages, the user can
152 access the card OS log buffer via debugfs. When read, this entry
153 provides the kernel virtual address where the card OS log buffer
154 length can be read. This entry is written by host configuration
155 daemon to set the log buffer length address. The correct log
156 buffer length address to be written can be found in the
157 System.map file of the card OS.
diff --git a/Documentation/ABI/testing/sysfs-driver-sunxi-sid b/Documentation/ABI/testing/sysfs-driver-sunxi-sid
new file mode 100644
index 000000000000..ffb9536f6ecc
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-sunxi-sid
@@ -0,0 +1,22 @@
1What: /sys/devices/*/<our-device>/eeprom
2Date: August 2013
3Contact: Oliver Schinagl <oliver@schinagl.nl>
4Description: read-only access to the SID (Security-ID) on current
5 A-series SoC's from Allwinner. Currently supports A10, A10s, A13
6 and A20 CPU's. The earlier A1x series of SoCs exports 16 bytes,
7 whereas the newer A20 SoC exposes 512 bytes split into sections.
8 Besides the 16 bytes of SID, there's also an SJTAG area,
9 HDMI-HDCP key and some custom keys. Below a quick overview, for
10 details see the user manual:
11 0x000 128 bit root-key (sun[457]i)
12 0x010 128 bit boot-key (sun7i)
13 0x020 64 bit security-jtag-key (sun7i)
14 0x028 16 bit key configuration (sun7i)
15 0x02b 16 bit custom-vendor-key (sun7i)
16 0x02c 320 bit low general key (sun7i)
17 0x040 32 bit read-control access (sun7i)
18 0x064 224 bit low general key (sun7i)
19 0x080 2304 bit HDCP-key (sun7i)
20 0x1a0 768 bit high general key (sun7i)
21Users: any user space application which wants to read the SID on
22 Allwinner's A-series of CPU's.
diff --git a/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
new file mode 100644
index 000000000000..68ba37295565
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
@@ -0,0 +1,17 @@
1Allwinner sunxi-sid
2
3Required properties:
4- compatible: "allwinner,sun4i-sid" or "allwinner,sun7i-a20-sid".
5- reg: Should contain registers location and length
6
7Example for sun4i:
8 sid@01c23800 {
9 compatible = "allwinner,sun4i-sid";
10 reg = <0x01c23800 0x10>
11 };
12
13Example for sun7i:
14 sid@01c23800 {
15 compatible = "allwinner,sun7i-a20-sid";
16 reg = <0x01c23800 0x200>
17 };
diff --git a/Documentation/devicetree/bindings/misc/ti,dac7512.txt b/Documentation/devicetree/bindings/misc/ti,dac7512.txt
new file mode 100644
index 000000000000..1db45939dac9
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/ti,dac7512.txt
@@ -0,0 +1,20 @@
1TI DAC7512 DEVICETREE BINDINGS
2
3Required properties:
4
5 - "compatible" Must be set to "ti,dac7512"
6
7Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
8apply. In particular, "reg" and "spi-max-frequency" properties must be given.
9
10
11Example:
12
13 spi_master {
14 dac7512: dac7512@0 {
15 compatible = "ti,dac7512";
16 reg = <0>; /* CS0 */
17 spi-max-frequency = <1000000>;
18 };
19 };
20
diff --git a/Documentation/extcon/porting-android-switch-class b/Documentation/extcon/porting-android-switch-class
index eb0fa5f4fe88..5377f6317961 100644
--- a/Documentation/extcon/porting-android-switch-class
+++ b/Documentation/extcon/porting-android-switch-class
@@ -25,8 +25,10 @@ MyungJoo Ham <myungjoo.ham@samsung.com>
25 @print_state: no change but type change (switch_dev->extcon_dev) 25 @print_state: no change but type change (switch_dev->extcon_dev)
26 26
27- switch_dev_register(sdev, dev) 27- switch_dev_register(sdev, dev)
28 => extcon_dev_register(edev, dev) 28 => extcon_dev_register(edev)
29 : no change but type change (sdev->edev) 29 : type change (sdev->edev)
30 : remove second param('dev'). if edev has parent device, should store
31 'dev' to 'edev.dev.parent' before registering extcon device
30- switch_dev_unregister(sdev) 32- switch_dev_unregister(sdev)
31 => extcon_dev_unregister(edev) 33 => extcon_dev_unregister(edev)
32 : no change but type change (sdev->edev) 34 : no change but type change (sdev->edev)
diff --git a/Documentation/mic/mic_overview.txt b/Documentation/mic/mic_overview.txt
new file mode 100644
index 000000000000..b41929224804
--- /dev/null
+++ b/Documentation/mic/mic_overview.txt
@@ -0,0 +1,51 @@
1An Intel MIC X100 device is a PCIe form factor add-in coprocessor
2card based on the Intel Many Integrated Core (MIC) architecture
3that runs a Linux OS. It is a PCIe endpoint in a platform and therefore
4implements the three required standard address spaces i.e. configuration,
5memory and I/O. The host OS loads a device driver as is typical for
6PCIe devices. The card itself runs a bootstrap after reset that
7transfers control to the card OS downloaded from the host driver. The
8host driver supports OSPM suspend and resume operations. It shuts down
9the card during suspend and reboots the card OS during resume.
10The card OS as shipped by Intel is a Linux kernel with modifications
11for the X100 devices.
12
13Since it is a PCIe card, it does not have the ability to host hardware
14devices for networking, storage and console. We provide these devices
15on X100 coprocessors thus enabling a self-bootable equivalent environment
16for applications. A key benefit of our solution is that it leverages
17the standard virtio framework for network, disk and console devices,
18though in our case the virtio framework is used across a PCIe bus.
19
20Here is a block diagram of the various components described above. The
21virtio backends are situated on the host rather than the card given better
22single threaded performance for the host compared to MIC, the ability of
23the host to initiate DMA's to/from the card using the MIC DMA engine and
24the fact that the virtio block storage backend can only be on the host.
25
26 |
27 +----------+ | +----------+
28 | Card OS | | | Host OS |
29 +----------+ | +----------+
30 |
31+-------+ +--------+ +------+ | +---------+ +--------+ +--------+
32| Virtio| |Virtio | |Virtio| | |Virtio | |Virtio | |Virtio |
33| Net | |Console | |Block | | |Net | |Console | |Block |
34| Driver| |Driver | |Driver| | |backend | |backend | |backend |
35+-------+ +--------+ +------+ | +---------+ +--------+ +--------+
36 | | | | | | |
37 | | | |User | | |
38 | | | |------|------------|---------|-------
39 +-------------------+ |Kernel +--------------------------+
40 | | | Virtio over PCIe IOCTLs |
41 | | +--------------------------+
42 +--------------+ | |
43 |Intel MIC | | +---------------+
44 |Card Driver | | |Intel MIC |
45 +--------------+ | |Host Driver |
46 | | +---------------+
47 | | |
48 +-------------------------------------------------------------+
49 | |
50 | PCIe Bus |
51 +-------------------------------------------------------------+
diff --git a/Documentation/mic/mpssd/.gitignore b/Documentation/mic/mpssd/.gitignore
new file mode 100644
index 000000000000..8b7c72f07c92
--- /dev/null
+++ b/Documentation/mic/mpssd/.gitignore
@@ -0,0 +1 @@
mpssd
diff --git a/Documentation/mic/mpssd/Makefile b/Documentation/mic/mpssd/Makefile
new file mode 100644
index 000000000000..eb860a7d152e
--- /dev/null
+++ b/Documentation/mic/mpssd/Makefile
@@ -0,0 +1,19 @@
1#
2# Makefile - Intel MIC User Space Tools.
3# Copyright(c) 2013, Intel Corporation.
4#
5ifdef DEBUG
6CFLAGS += $(USERWARNFLAGS) -I. -g -Wall -DDEBUG=$(DEBUG)
7else
8CFLAGS += $(USERWARNFLAGS) -I. -g -Wall
9endif
10
11mpssd: mpssd.o sysfs.o
12 $(CC) $(CFLAGS) -o $@ $^ -lpthread
13
14install:
15 install mpssd /usr/sbin/mpssd
16 install micctrl /usr/sbin/micctrl
17
18clean:
19 rm -f mpssd *.o
diff --git a/Documentation/mic/mpssd/micctrl b/Documentation/mic/mpssd/micctrl
new file mode 100755
index 000000000000..8f2629b41c5f
--- /dev/null
+++ b/Documentation/mic/mpssd/micctrl
@@ -0,0 +1,173 @@
1#!/bin/bash
2# Intel MIC Platform Software Stack (MPSS)
3#
4# Copyright(c) 2013 Intel Corporation.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License, version 2, as
8# published by the Free Software Foundation.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# The full GNU General Public License is included in this distribution in
16# the file called "COPYING".
17#
18# Intel MIC User Space Tools.
19#
20# micctrl - Controls MIC boot/start/stop.
21#
22# chkconfig: 2345 95 05
23# description: start MPSS stack processing.
24#
25### BEGIN INIT INFO
26# Provides: micctrl
27### END INIT INFO
28
29# Source function library.
30. /etc/init.d/functions
31
32sysfs="/sys/class/mic"
33
34_status()
35{
36 f=$sysfs/$1
37 echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
38}
39
40status()
41{
42 if [ "`echo $1 | head -c3`" == "mic" ]; then
43 _status $1
44 return $?
45 fi
46 for f in $sysfs/*
47 do
48 _status `basename $f`
49 RETVAL=$?
50 [ $RETVAL -ne 0 ] && return $RETVAL
51 done
52 return 0
53}
54
55_reset()
56{
57 f=$sysfs/$1
58 echo reset > $f/state
59}
60
61reset()
62{
63 if [ "`echo $1 | head -c3`" == "mic" ]; then
64 _reset $1
65 return $?
66 fi
67 for f in $sysfs/*
68 do
69 _reset `basename $f`
70 RETVAL=$?
71 [ $RETVAL -ne 0 ] && return $RETVAL
72 done
73 return 0
74}
75
76_boot()
77{
78 f=$sysfs/$1
79 echo "linux" > $f/bootmode
80 echo "mic/uos.img" > $f/firmware
81 echo "mic/$1.image" > $f/ramdisk
82 echo "boot" > $f/state
83}
84
85boot()
86{
87 if [ "`echo $1 | head -c3`" == "mic" ]; then
88 _boot $1
89 return $?
90 fi
91 for f in $sysfs/*
92 do
93 _boot `basename $f`
94 RETVAL=$?
95 [ $RETVAL -ne 0 ] && return $RETVAL
96 done
97 return 0
98}
99
100_shutdown()
101{
102 f=$sysfs/$1
103 echo shutdown > $f/state
104}
105
106shutdown()
107{
108 if [ "`echo $1 | head -c3`" == "mic" ]; then
109 _shutdown $1
110 return $?
111 fi
112 for f in $sysfs/*
113 do
114 _shutdown `basename $f`
115 RETVAL=$?
116 [ $RETVAL -ne 0 ] && return $RETVAL
117 done
118 return 0
119}
120
121_wait()
122{
123 f=$sysfs/$1
124 while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
125 do
126 sleep 1
127 echo -e "Waiting for $1 to go offline"
128 done
129}
130
131wait()
132{
133 if [ "`echo $1 | head -c3`" == "mic" ]; then
134 _wait $1
135 return $?
136 fi
137 # Wait for the cards to go offline
138 for f in $sysfs/*
139 do
140 _wait `basename $f`
141 RETVAL=$?
142 [ $RETVAL -ne 0 ] && return $RETVAL
143 done
144 return 0
145}
146
147if [ ! -d "$sysfs" ]; then
148 echo -e $"Module unloaded "
149 exit 3
150fi
151
152case $1 in
153 -s)
154 status $2
155 ;;
156 -r)
157 reset $2
158 ;;
159 -b)
160 boot $2
161 ;;
162 -S)
163 shutdown $2
164 ;;
165 -w)
166 wait $2
167 ;;
168 *)
169 echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
170 exit 2
171esac
172
173exit $?
diff --git a/Documentation/mic/mpssd/mpss b/Documentation/mic/mpssd/mpss
new file mode 100755
index 000000000000..3136c68dad0b
--- /dev/null
+++ b/Documentation/mic/mpssd/mpss
@@ -0,0 +1,202 @@
1#!/bin/bash
2# Intel MIC Platform Software Stack (MPSS)
3#
4# Copyright(c) 2013 Intel Corporation.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License, version 2, as
8# published by the Free Software Foundation.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# The full GNU General Public License is included in this distribution in
16# the file called "COPYING".
17#
18# Intel MIC User Space Tools.
19#
20# mpss Start mpssd.
21#
22# chkconfig: 2345 95 05
23# description: start MPSS stack processing.
24#
25### BEGIN INIT INFO
26# Provides: mpss
27# Required-Start:
28# Required-Stop:
29# Short-Description: MPSS stack control
30# Description: MPSS stack control
31### END INIT INFO
32
33# Source function library.
34. /etc/init.d/functions
35
36exec=/usr/sbin/mpssd
37sysfs="/sys/class/mic"
38
39start()
40{
41 [ -x $exec ] || exit 5
42
43 if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
44 echo -e $"MPSSD already running! "
45 success
46 echo
47 return 0
48 fi
49
50 echo -e $"Starting MPSS Stack"
51 echo -e $"Loading MIC_HOST Module"
52
53 # Ensure the driver is loaded
54 if [ ! -d "$sysfs" ]; then
55 modprobe mic_host
56 RETVAL=$?
57 if [ $RETVAL -ne 0 ]; then
58 failure
59 echo
60 return $RETVAL
61 fi
62 fi
63
64 # Start the daemon
65 echo -n $"Starting MPSSD "
66 $exec
67 RETVAL=$?
68 if [ $RETVAL -ne 0 ]; then
69 failure
70 echo
71 return $RETVAL
72 fi
73 success
74 echo
75
76 sleep 5
77
78 # Boot the cards
79 micctrl -b
80
81 # Wait till ping works
82 for f in $sysfs/*
83 do
84 count=100
85 ipaddr=`cat $f/cmdline`
86 ipaddr=${ipaddr#*address,}
87 ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
88 while [ $count -ge 0 ]
89 do
90 echo -e "Pinging "`basename $f`" "
91 ping -c 1 $ipaddr &> /dev/null
92 RETVAL=$?
93 if [ $RETVAL -eq 0 ]; then
94 success
95 break
96 fi
97 sleep 1
98 count=`expr $count - 1`
99 done
100 [ $RETVAL -ne 0 ] && failure || success
101 echo
102 done
103 return $RETVAL
104}
105
106stop()
107{
108 echo -e $"Shutting down MPSS Stack: "
109
110 # Bail out if module is unloaded
111 if [ ! -d "$sysfs" ]; then
112 echo -n $"Module unloaded "
113 success
114 echo
115 return 0
116 fi
117
118 # Shut down the cards.
119 micctrl -S
120
121 # Wait for the cards to go offline
122 for f in $sysfs/*
123 do
124 while [ "`cat $f/state`" != "offline" ]
125 do
126 sleep 1
127 echo -e "Waiting for "`basename $f`" to go offline"
128 done
129 done
130
131 # Display the status of the cards
132 micctrl -s
133
134 # Kill MPSSD now
135 echo -n $"Killing MPSSD"
136 killall -9 mpssd 2>/dev/null
137 RETVAL=$?
138 [ $RETVAL -ne 0 ] && failure || success
139 echo
140 return $RETVAL
141}
142
143restart()
144{
145 stop
146 sleep 5
147 start
148}
149
150status()
151{
152 micctrl -s
153 if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
154 echo "mpssd is running"
155 else
156 echo "mpssd is stopped"
157 fi
158 return 0
159}
160
161unload()
162{
163 if [ ! -d "$sysfs" ]; then
164 echo -n $"No MIC_HOST Module: "
165 success
166 echo
167 return
168 fi
169
170 stop
171
172 sleep 5
173 echo -n $"Removing MIC_HOST Module: "
174 modprobe -r mic_host
175 RETVAL=$?
176 [ $RETVAL -ne 0 ] && failure || success
177 echo
178 return $RETVAL
179}
180
181case $1 in
182 start)
183 start
184 ;;
185 stop)
186 stop
187 ;;
188 restart)
189 restart
190 ;;
191 status)
192 status
193 ;;
194 unload)
195 unload
196 ;;
197 *)
198 echo $"Usage: $0 {start|stop|restart|status|unload}"
199 exit 2
200esac
201
202exit $?
diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c
new file mode 100644
index 000000000000..0c980ad40b17
--- /dev/null
+++ b/Documentation/mic/mpssd/mpssd.c
@@ -0,0 +1,1721 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC User Space Tools.
19 */
20
21#define _GNU_SOURCE
22
23#include <stdlib.h>
24#include <fcntl.h>
25#include <getopt.h>
26#include <assert.h>
27#include <unistd.h>
28#include <stdbool.h>
29#include <signal.h>
30#include <poll.h>
31#include <features.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/mman.h>
35#include <sys/socket.h>
36#include <linux/virtio_ring.h>
37#include <linux/virtio_net.h>
38#include <linux/virtio_console.h>
39#include <linux/virtio_blk.h>
40#include <linux/version.h>
41#include "mpssd.h"
42#include <linux/mic_ioctl.h>
43#include <linux/mic_common.h>
44
45static void init_mic(struct mic_info *mic);
46
47static FILE *logfp;
48static struct mic_info mic_list;
49
50#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
51
52#define min_t(type, x, y) ({ \
53 type __min1 = (x); \
54 type __min2 = (y); \
55 __min1 < __min2 ? __min1 : __min2; })
56
57/* align addr on a size boundary - adjust address up/down if needed */
58#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
59#define _ALIGN_UP(addr, size) _ALIGN_DOWN(addr + size - 1, size)
60
61/* align addr on a size boundary - adjust address up if needed */
62#define _ALIGN(addr, size) _ALIGN_UP(addr, size)
63
64/* to align the pointer to the (next) page boundary */
65#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
66
67#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
68
69#define GSO_ENABLED 1
70#define MAX_GSO_SIZE (64 * 1024)
71#define ETH_H_LEN 14
72#define MAX_NET_PKT_SIZE (_ALIGN_UP(MAX_GSO_SIZE + ETH_H_LEN, 64))
73#define MIC_DEVICE_PAGE_END 0x1000
74
75#ifndef VIRTIO_NET_HDR_F_DATA_VALID
76#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */
77#endif
78
79static struct {
80 struct mic_device_desc dd;
81 struct mic_vqconfig vqconfig[2];
82 __u32 host_features, guest_acknowledgements;
83 struct virtio_console_config cons_config;
84} virtcons_dev_page = {
85 .dd = {
86 .type = VIRTIO_ID_CONSOLE,
87 .num_vq = ARRAY_SIZE(virtcons_dev_page.vqconfig),
88 .feature_len = sizeof(virtcons_dev_page.host_features),
89 .config_len = sizeof(virtcons_dev_page.cons_config),
90 },
91 .vqconfig[0] = {
92 .num = htole16(MIC_VRING_ENTRIES),
93 },
94 .vqconfig[1] = {
95 .num = htole16(MIC_VRING_ENTRIES),
96 },
97};
98
99static struct {
100 struct mic_device_desc dd;
101 struct mic_vqconfig vqconfig[2];
102 __u32 host_features, guest_acknowledgements;
103 struct virtio_net_config net_config;
104} virtnet_dev_page = {
105 .dd = {
106 .type = VIRTIO_ID_NET,
107 .num_vq = ARRAY_SIZE(virtnet_dev_page.vqconfig),
108 .feature_len = sizeof(virtnet_dev_page.host_features),
109 .config_len = sizeof(virtnet_dev_page.net_config),
110 },
111 .vqconfig[0] = {
112 .num = htole16(MIC_VRING_ENTRIES),
113 },
114 .vqconfig[1] = {
115 .num = htole16(MIC_VRING_ENTRIES),
116 },
117#if GSO_ENABLED
118 .host_features = htole32(
119 1 << VIRTIO_NET_F_CSUM |
120 1 << VIRTIO_NET_F_GSO |
121 1 << VIRTIO_NET_F_GUEST_TSO4 |
122 1 << VIRTIO_NET_F_GUEST_TSO6 |
123 1 << VIRTIO_NET_F_GUEST_ECN |
124 1 << VIRTIO_NET_F_GUEST_UFO),
125#else
126 .host_features = 0,
127#endif
128};
129
130static const char *mic_config_dir = "/etc/sysconfig/mic";
131static const char *virtblk_backend = "VIRTBLK_BACKEND";
132static struct {
133 struct mic_device_desc dd;
134 struct mic_vqconfig vqconfig[1];
135 __u32 host_features, guest_acknowledgements;
136 struct virtio_blk_config blk_config;
137} virtblk_dev_page = {
138 .dd = {
139 .type = VIRTIO_ID_BLOCK,
140 .num_vq = ARRAY_SIZE(virtblk_dev_page.vqconfig),
141 .feature_len = sizeof(virtblk_dev_page.host_features),
142 .config_len = sizeof(virtblk_dev_page.blk_config),
143 },
144 .vqconfig[0] = {
145 .num = htole16(MIC_VRING_ENTRIES),
146 },
147 .host_features =
148 htole32(1<<VIRTIO_BLK_F_SEG_MAX),
149 .blk_config = {
150 .seg_max = htole32(MIC_VRING_ENTRIES - 2),
151 .capacity = htole64(0),
152 }
153};
154
155static char *myname;
156
157static int
158tap_configure(struct mic_info *mic, char *dev)
159{
160 pid_t pid;
161 char *ifargv[7];
162 char ipaddr[IFNAMSIZ];
163 int ret = 0;
164
165 pid = fork();
166 if (pid == 0) {
167 ifargv[0] = "ip";
168 ifargv[1] = "link";
169 ifargv[2] = "set";
170 ifargv[3] = dev;
171 ifargv[4] = "up";
172 ifargv[5] = NULL;
173 mpsslog("Configuring %s\n", dev);
174 ret = execvp("ip", ifargv);
175 if (ret < 0) {
176 mpsslog("%s execvp failed errno %s\n",
177 mic->name, strerror(errno));
178 return ret;
179 }
180 }
181 if (pid < 0) {
182 mpsslog("%s fork failed errno %s\n",
183 mic->name, strerror(errno));
184 return ret;
185 }
186
187 ret = waitpid(pid, NULL, 0);
188 if (ret < 0) {
189 mpsslog("%s waitpid failed errno %s\n",
190 mic->name, strerror(errno));
191 return ret;
192 }
193
194 snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id);
195
196 pid = fork();
197 if (pid == 0) {
198 ifargv[0] = "ip";
199 ifargv[1] = "addr";
200 ifargv[2] = "add";
201 ifargv[3] = ipaddr;
202 ifargv[4] = "dev";
203 ifargv[5] = dev;
204 ifargv[6] = NULL;
205 mpsslog("Configuring %s ipaddr %s\n", dev, ipaddr);
206 ret = execvp("ip", ifargv);
207 if (ret < 0) {
208 mpsslog("%s execvp failed errno %s\n",
209 mic->name, strerror(errno));
210 return ret;
211 }
212 }
213 if (pid < 0) {
214 mpsslog("%s fork failed errno %s\n",
215 mic->name, strerror(errno));
216 return ret;
217 }
218
219 ret = waitpid(pid, NULL, 0);
220 if (ret < 0) {
221 mpsslog("%s waitpid failed errno %s\n",
222 mic->name, strerror(errno));
223 return ret;
224 }
225 mpsslog("MIC name %s %s %d DONE!\n",
226 mic->name, __func__, __LINE__);
227 return 0;
228}
229
230static int tun_alloc(struct mic_info *mic, char *dev)
231{
232 struct ifreq ifr;
233 int fd, err;
234#if GSO_ENABLED
235 unsigned offload;
236#endif
237 fd = open("/dev/net/tun", O_RDWR);
238 if (fd < 0) {
239 mpsslog("Could not open /dev/net/tun %s\n", strerror(errno));
240 goto done;
241 }
242
243 memset(&ifr, 0, sizeof(ifr));
244
245 ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
246 if (*dev)
247 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
248
249 err = ioctl(fd, TUNSETIFF, (void *)&ifr);
250 if (err < 0) {
251 mpsslog("%s %s %d TUNSETIFF failed %s\n",
252 mic->name, __func__, __LINE__, strerror(errno));
253 close(fd);
254 return err;
255 }
256#if GSO_ENABLED
257 offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
258 TUN_F_TSO_ECN | TUN_F_UFO;
259
260 err = ioctl(fd, TUNSETOFFLOAD, offload);
261 if (err < 0) {
262 mpsslog("%s %s %d TUNSETOFFLOAD failed %s\n",
263 mic->name, __func__, __LINE__, strerror(errno));
264 close(fd);
265 return err;
266 }
267#endif
268 strcpy(dev, ifr.ifr_name);
269 mpsslog("Created TAP %s\n", dev);
270done:
271 return fd;
272}
273
274#define NET_FD_VIRTIO_NET 0
275#define NET_FD_TUN 1
276#define MAX_NET_FD 2
277
278static void set_dp(struct mic_info *mic, int type, void *dp)
279{
280 switch (type) {
281 case VIRTIO_ID_CONSOLE:
282 mic->mic_console.console_dp = dp;
283 return;
284 case VIRTIO_ID_NET:
285 mic->mic_net.net_dp = dp;
286 return;
287 case VIRTIO_ID_BLOCK:
288 mic->mic_virtblk.block_dp = dp;
289 return;
290 }
291 mpsslog("%s %s %d not found\n", mic->name, __func__, type);
292 assert(0);
293}
294
295static void *get_dp(struct mic_info *mic, int type)
296{
297 switch (type) {
298 case VIRTIO_ID_CONSOLE:
299 return mic->mic_console.console_dp;
300 case VIRTIO_ID_NET:
301 return mic->mic_net.net_dp;
302 case VIRTIO_ID_BLOCK:
303 return mic->mic_virtblk.block_dp;
304 }
305 mpsslog("%s %s %d not found\n", mic->name, __func__, type);
306 assert(0);
307 return NULL;
308}
309
310static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
311{
312 struct mic_device_desc *d;
313 int i;
314 void *dp = get_dp(mic, type);
315
316 for (i = mic_aligned_size(struct mic_bootparam); i < PAGE_SIZE;
317 i += mic_total_desc_size(d)) {
318 d = dp + i;
319
320 /* End of list */
321 if (d->type == 0)
322 break;
323
324 if (d->type == -1)
325 continue;
326
327 mpsslog("%s %s d-> type %d d %p\n",
328 mic->name, __func__, d->type, d);
329
330 if (d->type == (__u8)type)
331 return d;
332 }
333 mpsslog("%s %s %d not found\n", mic->name, __func__, type);
334 assert(0);
335 return NULL;
336}
337
338/* See comments in vhost.c for explanation of next_desc() */
339static unsigned next_desc(struct vring_desc *desc)
340{
341 unsigned int next;
342
343 if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT))
344 return -1U;
345 next = le16toh(desc->next);
346 return next;
347}
348
349/* Sum up all the IOVEC length */
350static ssize_t
351sum_iovec_len(struct mic_copy_desc *copy)
352{
353 ssize_t sum = 0;
354 int i;
355
356 for (i = 0; i < copy->iovcnt; i++)
357 sum += copy->iov[i].iov_len;
358 return sum;
359}
360
361static inline void verify_out_len(struct mic_info *mic,
362 struct mic_copy_desc *copy)
363{
364 if (copy->out_len != sum_iovec_len(copy)) {
365 mpsslog("%s %s %d BUG copy->out_len 0x%x len 0x%zx\n",
366 mic->name, __func__, __LINE__,
367 copy->out_len, sum_iovec_len(copy));
368 assert(copy->out_len == sum_iovec_len(copy));
369 }
370}
371
372/* Display an iovec */
373static void
374disp_iovec(struct mic_info *mic, struct mic_copy_desc *copy,
375 const char *s, int line)
376{
377 int i;
378
379 for (i = 0; i < copy->iovcnt; i++)
380 mpsslog("%s %s %d copy->iov[%d] addr %p len 0x%zx\n",
381 mic->name, s, line, i,
382 copy->iov[i].iov_base, copy->iov[i].iov_len);
383}
384
385static inline __u16 read_avail_idx(struct mic_vring *vr)
386{
387 return ACCESS_ONCE(vr->info->avail_idx);
388}
389
390static inline void txrx_prepare(int type, bool tx, struct mic_vring *vr,
391 struct mic_copy_desc *copy, ssize_t len)
392{
393 copy->vr_idx = tx ? 0 : 1;
394 copy->update_used = true;
395 if (type == VIRTIO_ID_NET)
396 copy->iov[1].iov_len = len - sizeof(struct virtio_net_hdr);
397 else
398 copy->iov[0].iov_len = len;
399}
400
401/* Central API which triggers the copies */
402static int
403mic_virtio_copy(struct mic_info *mic, int fd,
404 struct mic_vring *vr, struct mic_copy_desc *copy)
405{
406 int ret;
407
408 ret = ioctl(fd, MIC_VIRTIO_COPY_DESC, copy);
409 if (ret) {
410 mpsslog("%s %s %d errno %s ret %d\n",
411 mic->name, __func__, __LINE__,
412 strerror(errno), ret);
413 }
414 return ret;
415}
416
417/*
418 * This initialization routine requires at least one
419 * vring i.e. vr0. vr1 is optional.
420 */
421static void *
422init_vr(struct mic_info *mic, int fd, int type,
423 struct mic_vring *vr0, struct mic_vring *vr1, int num_vq)
424{
425 int vr_size;
426 char *va;
427
428 vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES,
429 MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info));
430 va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
431 PROT_READ, MAP_SHARED, fd, 0);
432 if (MAP_FAILED == va) {
433 mpsslog("%s %s %d mmap failed errno %s\n",
434 mic->name, __func__, __LINE__,
435 strerror(errno));
436 goto done;
437 }
438 set_dp(mic, type, va);
439 vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
440 vr0->info = vr0->va +
441 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
442 vring_init(&vr0->vr,
443 MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
444 mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
445 __func__, mic->name, vr0->va, vr0->info, vr_size,
446 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
447 mpsslog("magic 0x%x expected 0x%x\n",
448 vr0->info->magic, MIC_MAGIC + type);
449 assert(vr0->info->magic == MIC_MAGIC + type);
450 if (vr1) {
451 vr1->va = (struct mic_vring *)
452 &va[MIC_DEVICE_PAGE_END + vr_size];
453 vr1->info = vr1->va + vring_size(MIC_VRING_ENTRIES,
454 MIC_VIRTIO_RING_ALIGN);
455 vring_init(&vr1->vr,
456 MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
457 mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
458 __func__, mic->name, vr1->va, vr1->info, vr_size,
459 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
460 mpsslog("magic 0x%x expected 0x%x\n",
461 vr1->info->magic, MIC_MAGIC + type + 1);
462 assert(vr1->info->magic == MIC_MAGIC + type + 1);
463 }
464done:
465 return va;
466}
467
468static void
469wait_for_card_driver(struct mic_info *mic, int fd, int type)
470{
471 struct pollfd pollfd;
472 int err;
473 struct mic_device_desc *desc = get_device_desc(mic, type);
474
475 pollfd.fd = fd;
476 mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
477 mic->name, __func__, type, desc->status);
478 while (1) {
479 pollfd.events = POLLIN;
480 pollfd.revents = 0;
481 err = poll(&pollfd, 1, -1);
482 if (err < 0) {
483 mpsslog("%s %s poll failed %s\n",
484 mic->name, __func__, strerror(errno));
485 continue;
486 }
487
488 if (pollfd.revents) {
489 mpsslog("%s %s Waiting... desc-> type %d status 0x%x\n",
490 mic->name, __func__, type, desc->status);
491 if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
492 mpsslog("%s %s poll.revents %d\n",
493 mic->name, __func__, pollfd.revents);
494 mpsslog("%s %s desc-> type %d status 0x%x\n",
495 mic->name, __func__, type,
496 desc->status);
497 break;
498 }
499 }
500 }
501}
502
503/* Spin till we have some descriptors */
504static void
505spin_for_descriptors(struct mic_info *mic, struct mic_vring *vr)
506{
507 __u16 avail_idx = read_avail_idx(vr);
508
509 while (avail_idx == le16toh(ACCESS_ONCE(vr->vr.avail->idx))) {
510#ifdef DEBUG
511 mpsslog("%s %s waiting for desc avail %d info_avail %d\n",
512 mic->name, __func__,
513 le16toh(vr->vr.avail->idx), vr->info->avail_idx);
514#endif
515 sched_yield();
516 }
517}
518
519static void *
520virtio_net(void *arg)
521{
522 static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
523 static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __aligned(64);
524 struct iovec vnet_iov[2][2] = {
525 { { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
526 { .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
527 { { .iov_base = vnet_hdr[1], .iov_len = sizeof(vnet_hdr[1]) },
528 { .iov_base = vnet_buf[1], .iov_len = sizeof(vnet_buf[1]) } },
529 };
530 struct iovec *iov0 = vnet_iov[0], *iov1 = vnet_iov[1];
531 struct mic_info *mic = (struct mic_info *)arg;
532 char if_name[IFNAMSIZ];
533 struct pollfd net_poll[MAX_NET_FD];
534 struct mic_vring tx_vr, rx_vr;
535 struct mic_copy_desc copy;
536 struct mic_device_desc *desc;
537 int err;
538
539 snprintf(if_name, IFNAMSIZ, "mic%d", mic->id);
540 mic->mic_net.tap_fd = tun_alloc(mic, if_name);
541 if (mic->mic_net.tap_fd < 0)
542 goto done;
543
544 if (tap_configure(mic, if_name))
545 goto done;
546 mpsslog("MIC name %s id %d\n", mic->name, mic->id);
547
548 net_poll[NET_FD_VIRTIO_NET].fd = mic->mic_net.virtio_net_fd;
549 net_poll[NET_FD_VIRTIO_NET].events = POLLIN;
550 net_poll[NET_FD_TUN].fd = mic->mic_net.tap_fd;
551 net_poll[NET_FD_TUN].events = POLLIN;
552
553 if (MAP_FAILED == init_vr(mic, mic->mic_net.virtio_net_fd,
554 VIRTIO_ID_NET, &tx_vr, &rx_vr,
555 virtnet_dev_page.dd.num_vq)) {
556 mpsslog("%s init_vr failed %s\n",
557 mic->name, strerror(errno));
558 goto done;
559 }
560
561 copy.iovcnt = 2;
562 desc = get_device_desc(mic, VIRTIO_ID_NET);
563
564 while (1) {
565 ssize_t len;
566
567 net_poll[NET_FD_VIRTIO_NET].revents = 0;
568 net_poll[NET_FD_TUN].revents = 0;
569
570 /* Start polling for data from tap and virtio net */
571 err = poll(net_poll, 2, -1);
572 if (err < 0) {
573 mpsslog("%s poll failed %s\n",
574 __func__, strerror(errno));
575 continue;
576 }
577 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK))
578 wait_for_card_driver(mic, mic->mic_net.virtio_net_fd,
579 VIRTIO_ID_NET);
580 /*
581 * Check if there is data to be read from TUN and write to
582 * virtio net fd if there is.
583 */
584 if (net_poll[NET_FD_TUN].revents & POLLIN) {
585 copy.iov = iov0;
586 len = readv(net_poll[NET_FD_TUN].fd,
587 copy.iov, copy.iovcnt);
588 if (len > 0) {
589 struct virtio_net_hdr *hdr
590 = (struct virtio_net_hdr *)vnet_hdr[0];
591
592 /* Disable checksums on the card since we are on
593 a reliable PCIe link */
594 hdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
595#ifdef DEBUG
596 mpsslog("%s %s %d hdr->flags 0x%x ", mic->name,
597 __func__, __LINE__, hdr->flags);
598 mpsslog("copy.out_len %d hdr->gso_type 0x%x\n",
599 copy.out_len, hdr->gso_type);
600#endif
601#ifdef DEBUG
602 disp_iovec(mic, copy, __func__, __LINE__);
603 mpsslog("%s %s %d read from tap 0x%lx\n",
604 mic->name, __func__, __LINE__,
605 len);
606#endif
607 spin_for_descriptors(mic, &tx_vr);
608 txrx_prepare(VIRTIO_ID_NET, 1, &tx_vr, &copy,
609 len);
610
611 err = mic_virtio_copy(mic,
612 mic->mic_net.virtio_net_fd, &tx_vr,
613 &copy);
614 if (err < 0) {
615 mpsslog("%s %s %d mic_virtio_copy %s\n",
616 mic->name, __func__, __LINE__,
617 strerror(errno));
618 }
619 if (!err)
620 verify_out_len(mic, &copy);
621#ifdef DEBUG
622 disp_iovec(mic, copy, __func__, __LINE__);
623 mpsslog("%s %s %d wrote to net 0x%lx\n",
624 mic->name, __func__, __LINE__,
625 sum_iovec_len(&copy));
626#endif
627 /* Reinitialize IOV for next run */
628 iov0[1].iov_len = MAX_NET_PKT_SIZE;
629 } else if (len < 0) {
630 disp_iovec(mic, &copy, __func__, __LINE__);
631 mpsslog("%s %s %d read failed %s ", mic->name,
632 __func__, __LINE__, strerror(errno));
633 mpsslog("cnt %d sum %zd\n",
634 copy.iovcnt, sum_iovec_len(&copy));
635 }
636 }
637
638 /*
639 * Check if there is data to be read from virtio net and
640 * write to TUN if there is.
641 */
642 if (net_poll[NET_FD_VIRTIO_NET].revents & POLLIN) {
643 while (rx_vr.info->avail_idx !=
644 le16toh(rx_vr.vr.avail->idx)) {
645 copy.iov = iov1;
646 txrx_prepare(VIRTIO_ID_NET, 0, &rx_vr, &copy,
647 MAX_NET_PKT_SIZE
648 + sizeof(struct virtio_net_hdr));
649
650 err = mic_virtio_copy(mic,
651 mic->mic_net.virtio_net_fd, &rx_vr,
652 &copy);
653 if (!err) {
654#ifdef DEBUG
655 struct virtio_net_hdr *hdr
656 = (struct virtio_net_hdr *)
657 vnet_hdr[1];
658
659 mpsslog("%s %s %d hdr->flags 0x%x, ",
660 mic->name, __func__, __LINE__,
661 hdr->flags);
662 mpsslog("out_len %d gso_type 0x%x\n",
663 copy.out_len,
664 hdr->gso_type);
665#endif
666 /* Set the correct output iov_len */
667 iov1[1].iov_len = copy.out_len -
668 sizeof(struct virtio_net_hdr);
669 verify_out_len(mic, &copy);
670#ifdef DEBUG
671 disp_iovec(mic, copy, __func__,
672 __LINE__);
673 mpsslog("%s %s %d ",
674 mic->name, __func__, __LINE__);
675 mpsslog("read from net 0x%lx\n",
676 sum_iovec_len(copy));
677#endif
678 len = writev(net_poll[NET_FD_TUN].fd,
679 copy.iov, copy.iovcnt);
680 if (len != sum_iovec_len(&copy)) {
681 mpsslog("Tun write failed %s ",
682 strerror(errno));
683 mpsslog("len 0x%zx ", len);
684 mpsslog("read_len 0x%zx\n",
685 sum_iovec_len(&copy));
686 } else {
687#ifdef DEBUG
688 disp_iovec(mic, &copy, __func__,
689 __LINE__);
690 mpsslog("%s %s %d ",
691 mic->name, __func__,
692 __LINE__);
693 mpsslog("wrote to tap 0x%lx\n",
694 len);
695#endif
696 }
697 } else {
698 mpsslog("%s %s %d mic_virtio_copy %s\n",
699 mic->name, __func__, __LINE__,
700 strerror(errno));
701 break;
702 }
703 }
704 }
705 if (net_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
706 mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
707 }
708done:
709 pthread_exit(NULL);
710}
711
712/* virtio_console */
713#define VIRTIO_CONSOLE_FD 0
714#define MONITOR_FD (VIRTIO_CONSOLE_FD + 1)
715#define MAX_CONSOLE_FD (MONITOR_FD + 1) /* must be the last one + 1 */
716#define MAX_BUFFER_SIZE PAGE_SIZE
717
718static void *
719virtio_console(void *arg)
720{
721 static __u8 vcons_buf[2][PAGE_SIZE];
722 struct iovec vcons_iov[2] = {
723 { .iov_base = vcons_buf[0], .iov_len = sizeof(vcons_buf[0]) },
724 { .iov_base = vcons_buf[1], .iov_len = sizeof(vcons_buf[1]) },
725 };
726 struct iovec *iov0 = &vcons_iov[0], *iov1 = &vcons_iov[1];
727 struct mic_info *mic = (struct mic_info *)arg;
728 int err;
729 struct pollfd console_poll[MAX_CONSOLE_FD];
730 int pty_fd;
731 char *pts_name;
732 ssize_t len;
733 struct mic_vring tx_vr, rx_vr;
734 struct mic_copy_desc copy;
735 struct mic_device_desc *desc;
736
737 pty_fd = posix_openpt(O_RDWR);
738 if (pty_fd < 0) {
739 mpsslog("can't open a pseudoterminal master device: %s\n",
740 strerror(errno));
741 goto _return;
742 }
743 pts_name = ptsname(pty_fd);
744 if (pts_name == NULL) {
745 mpsslog("can't get pts name\n");
746 goto _close_pty;
747 }
748 printf("%s console message goes to %s\n", mic->name, pts_name);
749 mpsslog("%s console message goes to %s\n", mic->name, pts_name);
750 err = grantpt(pty_fd);
751 if (err < 0) {
752 mpsslog("can't grant access: %s %s\n",
753 pts_name, strerror(errno));
754 goto _close_pty;
755 }
756 err = unlockpt(pty_fd);
757 if (err < 0) {
758 mpsslog("can't unlock a pseudoterminal: %s %s\n",
759 pts_name, strerror(errno));
760 goto _close_pty;
761 }
762 console_poll[MONITOR_FD].fd = pty_fd;
763 console_poll[MONITOR_FD].events = POLLIN;
764
765 console_poll[VIRTIO_CONSOLE_FD].fd = mic->mic_console.virtio_console_fd;
766 console_poll[VIRTIO_CONSOLE_FD].events = POLLIN;
767
768 if (MAP_FAILED == init_vr(mic, mic->mic_console.virtio_console_fd,
769 VIRTIO_ID_CONSOLE, &tx_vr, &rx_vr,
770 virtcons_dev_page.dd.num_vq)) {
771 mpsslog("%s init_vr failed %s\n",
772 mic->name, strerror(errno));
773 goto _close_pty;
774 }
775
776 copy.iovcnt = 1;
777 desc = get_device_desc(mic, VIRTIO_ID_CONSOLE);
778
779 for (;;) {
780 console_poll[MONITOR_FD].revents = 0;
781 console_poll[VIRTIO_CONSOLE_FD].revents = 0;
782 err = poll(console_poll, MAX_CONSOLE_FD, -1);
783 if (err < 0) {
784 mpsslog("%s %d: poll failed: %s\n", __func__, __LINE__,
785 strerror(errno));
786 continue;
787 }
788 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK))
789 wait_for_card_driver(mic,
790 mic->mic_console.virtio_console_fd,
791 VIRTIO_ID_CONSOLE);
792
793 if (console_poll[MONITOR_FD].revents & POLLIN) {
794 copy.iov = iov0;
795 len = readv(pty_fd, copy.iov, copy.iovcnt);
796 if (len > 0) {
797#ifdef DEBUG
798 disp_iovec(mic, copy, __func__, __LINE__);
799 mpsslog("%s %s %d read from tap 0x%lx\n",
800 mic->name, __func__, __LINE__,
801 len);
802#endif
803 spin_for_descriptors(mic, &tx_vr);
804 txrx_prepare(VIRTIO_ID_CONSOLE, 1, &tx_vr,
805 &copy, len);
806
807 err = mic_virtio_copy(mic,
808 mic->mic_console.virtio_console_fd,
809 &tx_vr, &copy);
810 if (err < 0) {
811 mpsslog("%s %s %d mic_virtio_copy %s\n",
812 mic->name, __func__, __LINE__,
813 strerror(errno));
814 }
815 if (!err)
816 verify_out_len(mic, &copy);
817#ifdef DEBUG
818 disp_iovec(mic, copy, __func__, __LINE__);
819 mpsslog("%s %s %d wrote to net 0x%lx\n",
820 mic->name, __func__, __LINE__,
821 sum_iovec_len(copy));
822#endif
823 /* Reinitialize IOV for next run */
824 iov0->iov_len = PAGE_SIZE;
825 } else if (len < 0) {
826 disp_iovec(mic, &copy, __func__, __LINE__);
827 mpsslog("%s %s %d read failed %s ",
828 mic->name, __func__, __LINE__,
829 strerror(errno));
830 mpsslog("cnt %d sum %zd\n",
831 copy.iovcnt, sum_iovec_len(&copy));
832 }
833 }
834
835 if (console_poll[VIRTIO_CONSOLE_FD].revents & POLLIN) {
836 while (rx_vr.info->avail_idx !=
837 le16toh(rx_vr.vr.avail->idx)) {
838 copy.iov = iov1;
839 txrx_prepare(VIRTIO_ID_CONSOLE, 0, &rx_vr,
840 &copy, PAGE_SIZE);
841
842 err = mic_virtio_copy(mic,
843 mic->mic_console.virtio_console_fd,
844 &rx_vr, &copy);
845 if (!err) {
846 /* Set the correct output iov_len */
847 iov1->iov_len = copy.out_len;
848 verify_out_len(mic, &copy);
849#ifdef DEBUG
850 disp_iovec(mic, copy, __func__,
851 __LINE__);
852 mpsslog("%s %s %d ",
853 mic->name, __func__, __LINE__);
854 mpsslog("read from net 0x%lx\n",
855 sum_iovec_len(copy));
856#endif
857 len = writev(pty_fd,
858 copy.iov, copy.iovcnt);
859 if (len != sum_iovec_len(&copy)) {
860 mpsslog("Tun write failed %s ",
861 strerror(errno));
862 mpsslog("len 0x%zx ", len);
863 mpsslog("read_len 0x%zx\n",
864 sum_iovec_len(&copy));
865 } else {
866#ifdef DEBUG
867 disp_iovec(mic, copy, __func__,
868 __LINE__);
869 mpsslog("%s %s %d ",
870 mic->name, __func__,
871 __LINE__);
872 mpsslog("wrote to tap 0x%lx\n",
873 len);
874#endif
875 }
876 } else {
877 mpsslog("%s %s %d mic_virtio_copy %s\n",
878 mic->name, __func__, __LINE__,
879 strerror(errno));
880 break;
881 }
882 }
883 }
884 if (console_poll[NET_FD_VIRTIO_NET].revents & POLLERR)
885 mpsslog("%s: %s: POLLERR\n", __func__, mic->name);
886 }
887_close_pty:
888 close(pty_fd);
889_return:
890 pthread_exit(NULL);
891}
892
893static void
894add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd)
895{
896 char path[PATH_MAX];
897 int fd, err;
898
899 snprintf(path, PATH_MAX, "/dev/mic%d", mic->id);
900 fd = open(path, O_RDWR);
901 if (fd < 0) {
902 mpsslog("Could not open %s %s\n", path, strerror(errno));
903 return;
904 }
905
906 err = ioctl(fd, MIC_VIRTIO_ADD_DEVICE, dd);
907 if (err < 0) {
908 mpsslog("Could not add %d %s\n", dd->type, strerror(errno));
909 close(fd);
910 return;
911 }
912 switch (dd->type) {
913 case VIRTIO_ID_NET:
914 mic->mic_net.virtio_net_fd = fd;
915 mpsslog("Added VIRTIO_ID_NET for %s\n", mic->name);
916 break;
917 case VIRTIO_ID_CONSOLE:
918 mic->mic_console.virtio_console_fd = fd;
919 mpsslog("Added VIRTIO_ID_CONSOLE for %s\n", mic->name);
920 break;
921 case VIRTIO_ID_BLOCK:
922 mic->mic_virtblk.virtio_block_fd = fd;
923 mpsslog("Added VIRTIO_ID_BLOCK for %s\n", mic->name);
924 break;
925 }
926}
927
928static bool
929set_backend_file(struct mic_info *mic)
930{
931 FILE *config;
932 char buff[PATH_MAX], *line, *evv, *p;
933
934 snprintf(buff, PATH_MAX, "%s/mpssd%03d.conf", mic_config_dir, mic->id);
935 config = fopen(buff, "r");
936 if (config == NULL)
937 return false;
938 do { /* look for "virtblk_backend=XXXX" */
939 line = fgets(buff, PATH_MAX, config);
940 if (line == NULL)
941 break;
942 if (*line == '#')
943 continue;
944 p = strchr(line, '\n');
945 if (p)
946 *p = '\0';
947 } while (strncmp(line, virtblk_backend, strlen(virtblk_backend)) != 0);
948 fclose(config);
949 if (line == NULL)
950 return false;
951 evv = strchr(line, '=');
952 if (evv == NULL)
953 return false;
954 mic->mic_virtblk.backend_file = malloc(strlen(evv) + 1);
955 if (mic->mic_virtblk.backend_file == NULL) {
956 mpsslog("%s %d can't allocate memory\n", mic->name, mic->id);
957 return false;
958 }
959 strcpy(mic->mic_virtblk.backend_file, evv + 1);
960 return true;
961}
962
963#define SECTOR_SIZE 512
964static bool
965set_backend_size(struct mic_info *mic)
966{
967 mic->mic_virtblk.backend_size = lseek(mic->mic_virtblk.backend, 0,
968 SEEK_END);
969 if (mic->mic_virtblk.backend_size < 0) {
970 mpsslog("%s: can't seek: %s\n",
971 mic->name, mic->mic_virtblk.backend_file);
972 return false;
973 }
974 virtblk_dev_page.blk_config.capacity =
975 mic->mic_virtblk.backend_size / SECTOR_SIZE;
976 if ((mic->mic_virtblk.backend_size % SECTOR_SIZE) != 0)
977 virtblk_dev_page.blk_config.capacity++;
978
979 virtblk_dev_page.blk_config.capacity =
980 htole64(virtblk_dev_page.blk_config.capacity);
981
982 return true;
983}
984
985static bool
986open_backend(struct mic_info *mic)
987{
988 if (!set_backend_file(mic))
989 goto _error_exit;
990 mic->mic_virtblk.backend = open(mic->mic_virtblk.backend_file, O_RDWR);
991 if (mic->mic_virtblk.backend < 0) {
992 mpsslog("%s: can't open: %s\n", mic->name,
993 mic->mic_virtblk.backend_file);
994 goto _error_free;
995 }
996 if (!set_backend_size(mic))
997 goto _error_close;
998 mic->mic_virtblk.backend_addr = mmap(NULL,
999 mic->mic_virtblk.backend_size,
1000 PROT_READ|PROT_WRITE, MAP_SHARED,
1001 mic->mic_virtblk.backend, 0L);
1002 if (mic->mic_virtblk.backend_addr == MAP_FAILED) {
1003 mpsslog("%s: can't map: %s %s\n",
1004 mic->name, mic->mic_virtblk.backend_file,
1005 strerror(errno));
1006 goto _error_close;
1007 }
1008 return true;
1009
1010 _error_close:
1011 close(mic->mic_virtblk.backend);
1012 _error_free:
1013 free(mic->mic_virtblk.backend_file);
1014 _error_exit:
1015 return false;
1016}
1017
1018static void
1019close_backend(struct mic_info *mic)
1020{
1021 munmap(mic->mic_virtblk.backend_addr, mic->mic_virtblk.backend_size);
1022 close(mic->mic_virtblk.backend);
1023 free(mic->mic_virtblk.backend_file);
1024}
1025
1026static bool
1027start_virtblk(struct mic_info *mic, struct mic_vring *vring)
1028{
1029 if (((unsigned long)&virtblk_dev_page.blk_config % 8) != 0) {
1030 mpsslog("%s: blk_config is not 8 byte aligned.\n",
1031 mic->name);
1032 return false;
1033 }
1034 add_virtio_device(mic, &virtblk_dev_page.dd);
1035 if (MAP_FAILED == init_vr(mic, mic->mic_virtblk.virtio_block_fd,
1036 VIRTIO_ID_BLOCK, vring, NULL,
1037 virtblk_dev_page.dd.num_vq)) {
1038 mpsslog("%s init_vr failed %s\n",
1039 mic->name, strerror(errno));
1040 return false;
1041 }
1042 return true;
1043}
1044
1045static void
1046stop_virtblk(struct mic_info *mic)
1047{
1048 int vr_size, ret;
1049
1050 vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES,
1051 MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info));
1052 ret = munmap(mic->mic_virtblk.block_dp,
1053 MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
1054 if (ret < 0)
1055 mpsslog("%s munmap errno %d\n", mic->name, errno);
1056 close(mic->mic_virtblk.virtio_block_fd);
1057}
1058
1059static __u8
1060header_error_check(struct vring_desc *desc)
1061{
1062 if (le32toh(desc->len) != sizeof(struct virtio_blk_outhdr)) {
1063 mpsslog("%s() %d: length is not sizeof(virtio_blk_outhd)\n",
1064 __func__, __LINE__);
1065 return -EIO;
1066 }
1067 if (!(le16toh(desc->flags) & VRING_DESC_F_NEXT)) {
1068 mpsslog("%s() %d: alone\n",
1069 __func__, __LINE__);
1070 return -EIO;
1071 }
1072 if (le16toh(desc->flags) & VRING_DESC_F_WRITE) {
1073 mpsslog("%s() %d: not read\n",
1074 __func__, __LINE__);
1075 return -EIO;
1076 }
1077 return 0;
1078}
1079
1080static int
1081read_header(int fd, struct virtio_blk_outhdr *hdr, __u32 desc_idx)
1082{
1083 struct iovec iovec;
1084 struct mic_copy_desc copy;
1085
1086 iovec.iov_len = sizeof(*hdr);
1087 iovec.iov_base = hdr;
1088 copy.iov = &iovec;
1089 copy.iovcnt = 1;
1090 copy.vr_idx = 0; /* only one vring on virtio_block */
1091 copy.update_used = false; /* do not update used index */
1092 return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
1093}
1094
1095static int
1096transfer_blocks(int fd, struct iovec *iovec, __u32 iovcnt)
1097{
1098 struct mic_copy_desc copy;
1099
1100 copy.iov = iovec;
1101 copy.iovcnt = iovcnt;
1102 copy.vr_idx = 0; /* only one vring on virtio_block */
1103 copy.update_used = false; /* do not update used index */
1104 return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
1105}
1106
1107static __u8
1108status_error_check(struct vring_desc *desc)
1109{
1110 if (le32toh(desc->len) != sizeof(__u8)) {
1111 mpsslog("%s() %d: length is not sizeof(status)\n",
1112 __func__, __LINE__);
1113 return -EIO;
1114 }
1115 return 0;
1116}
1117
1118static int
1119write_status(int fd, __u8 *status)
1120{
1121 struct iovec iovec;
1122 struct mic_copy_desc copy;
1123
1124 iovec.iov_base = status;
1125 iovec.iov_len = sizeof(*status);
1126 copy.iov = &iovec;
1127 copy.iovcnt = 1;
1128 copy.vr_idx = 0; /* only one vring on virtio_block */
1129 copy.update_used = true; /* Update used index */
1130 return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
1131}
1132
1133static void *
1134virtio_block(void *arg)
1135{
1136 struct mic_info *mic = (struct mic_info *)arg;
1137 int ret;
1138 struct pollfd block_poll;
1139 struct mic_vring vring;
1140 __u16 avail_idx;
1141 __u32 desc_idx;
1142 struct vring_desc *desc;
1143 struct iovec *iovec, *piov;
1144 __u8 status;
1145 __u32 buffer_desc_idx;
1146 struct virtio_blk_outhdr hdr;
1147 void *fos;
1148
1149 for (;;) { /* forever */
1150 if (!open_backend(mic)) { /* No virtblk */
1151 for (mic->mic_virtblk.signaled = 0;
1152 !mic->mic_virtblk.signaled;)
1153 sleep(1);
1154 continue;
1155 }
1156
1157 /* backend file is specified. */
1158 if (!start_virtblk(mic, &vring))
1159 goto _close_backend;
1160 iovec = malloc(sizeof(*iovec) *
1161 le32toh(virtblk_dev_page.blk_config.seg_max));
1162 if (!iovec) {
1163 mpsslog("%s: can't alloc iovec: %s\n",
1164 mic->name, strerror(ENOMEM));
1165 goto _stop_virtblk;
1166 }
1167
1168 block_poll.fd = mic->mic_virtblk.virtio_block_fd;
1169 block_poll.events = POLLIN;
1170 for (mic->mic_virtblk.signaled = 0;
1171 !mic->mic_virtblk.signaled;) {
1172 block_poll.revents = 0;
1173 /* timeout in 1 sec to see signaled */
1174 ret = poll(&block_poll, 1, 1000);
1175 if (ret < 0) {
1176 mpsslog("%s %d: poll failed: %s\n",
1177 __func__, __LINE__,
1178 strerror(errno));
1179 continue;
1180 }
1181
1182 if (!(block_poll.revents & POLLIN)) {
1183#ifdef DEBUG
1184 mpsslog("%s %d: block_poll.revents=0x%x\n",
1185 __func__, __LINE__, block_poll.revents);
1186#endif
1187 continue;
1188 }
1189
1190 /* POLLIN */
1191 while (vring.info->avail_idx !=
1192 le16toh(vring.vr.avail->idx)) {
1193 /* read header element */
1194 avail_idx =
1195 vring.info->avail_idx &
1196 (vring.vr.num - 1);
1197 desc_idx = le16toh(
1198 vring.vr.avail->ring[avail_idx]);
1199 desc = &vring.vr.desc[desc_idx];
1200#ifdef DEBUG
1201 mpsslog("%s() %d: avail_idx=%d ",
1202 __func__, __LINE__,
1203 vring.info->avail_idx);
1204 mpsslog("vring.vr.num=%d desc=%p\n",
1205 vring.vr.num, desc);
1206#endif
1207 status = header_error_check(desc);
1208 ret = read_header(
1209 mic->mic_virtblk.virtio_block_fd,
1210 &hdr, desc_idx);
1211 if (ret < 0) {
1212 mpsslog("%s() %d %s: ret=%d %s\n",
1213 __func__, __LINE__,
1214 mic->name, ret,
1215 strerror(errno));
1216 break;
1217 }
1218 /* buffer element */
1219 piov = iovec;
1220 status = 0;
1221 fos = mic->mic_virtblk.backend_addr +
1222 (hdr.sector * SECTOR_SIZE);
1223 buffer_desc_idx = next_desc(desc);
1224 desc_idx = buffer_desc_idx;
1225 for (desc = &vring.vr.desc[buffer_desc_idx];
1226 desc->flags & VRING_DESC_F_NEXT;
1227 desc_idx = next_desc(desc),
1228 desc = &vring.vr.desc[desc_idx]) {
1229 piov->iov_len = desc->len;
1230 piov->iov_base = fos;
1231 piov++;
1232 fos += desc->len;
1233 }
1234 /* Returning NULLs for VIRTIO_BLK_T_GET_ID. */
1235 if (hdr.type & ~(VIRTIO_BLK_T_OUT |
1236 VIRTIO_BLK_T_GET_ID)) {
1237 /*
1238 VIRTIO_BLK_T_IN - does not do
1239 anything. Probably for documenting.
1240 VIRTIO_BLK_T_SCSI_CMD - for
1241 virtio_scsi.
1242 VIRTIO_BLK_T_FLUSH - turned off in
1243 config space.
1244 VIRTIO_BLK_T_BARRIER - defined but not
1245 used in anywhere.
1246 */
1247 mpsslog("%s() %d: type %x ",
1248 __func__, __LINE__,
1249 hdr.type);
1250 mpsslog("is not supported\n");
1251 status = -ENOTSUP;
1252
1253 } else {
1254 ret = transfer_blocks(
1255 mic->mic_virtblk.virtio_block_fd,
1256 iovec,
1257 piov - iovec);
1258 if (ret < 0 &&
1259 status != 0)
1260 status = ret;
1261 }
1262 /* write status and update used pointer */
1263 if (status != 0)
1264 status = status_error_check(desc);
1265 ret = write_status(
1266 mic->mic_virtblk.virtio_block_fd,
1267 &status);
1268#ifdef DEBUG
1269 mpsslog("%s() %d: write status=%d on desc=%p\n",
1270 __func__, __LINE__,
1271 status, desc);
1272#endif
1273 }
1274 }
1275 free(iovec);
1276_stop_virtblk:
1277 stop_virtblk(mic);
1278_close_backend:
1279 close_backend(mic);
1280 } /* forever */
1281
1282 pthread_exit(NULL);
1283}
1284
1285static void
1286reset(struct mic_info *mic)
1287{
1288#define RESET_TIMEOUT 120
1289 int i = RESET_TIMEOUT;
1290 setsysfs(mic->name, "state", "reset");
1291 while (i) {
1292 char *state;
1293 state = readsysfs(mic->name, "state");
1294 if (!state)
1295 goto retry;
1296 mpsslog("%s: %s %d state %s\n",
1297 mic->name, __func__, __LINE__, state);
1298
1299 /*
1300 * If the shutdown was initiated by OSPM, the state stays
1301 * in "suspended" which is also a valid condition for reset.
1302 */
1303 if ((!strcmp(state, "offline")) ||
1304 (!strcmp(state, "suspended"))) {
1305 free(state);
1306 break;
1307 }
1308 free(state);
1309retry:
1310 sleep(1);
1311 i--;
1312 }
1313}
1314
1315static int
1316get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
1317{
1318 if (!strcmp(shutdown_status, "nop"))
1319 return MIC_NOP;
1320 if (!strcmp(shutdown_status, "crashed"))
1321 return MIC_CRASHED;
1322 if (!strcmp(shutdown_status, "halted"))
1323 return MIC_HALTED;
1324 if (!strcmp(shutdown_status, "poweroff"))
1325 return MIC_POWER_OFF;
1326 if (!strcmp(shutdown_status, "restart"))
1327 return MIC_RESTART;
1328 mpsslog("%s: BUG invalid status %s\n", mic->name, shutdown_status);
1329 /* Invalid state */
1330 assert(0);
1331};
1332
1333static int get_mic_state(struct mic_info *mic, char *state)
1334{
1335 if (!strcmp(state, "offline"))
1336 return MIC_OFFLINE;
1337 if (!strcmp(state, "online"))
1338 return MIC_ONLINE;
1339 if (!strcmp(state, "shutting_down"))
1340 return MIC_SHUTTING_DOWN;
1341 if (!strcmp(state, "reset_failed"))
1342 return MIC_RESET_FAILED;
1343 if (!strcmp(state, "suspending"))
1344 return MIC_SUSPENDING;
1345 if (!strcmp(state, "suspended"))
1346 return MIC_SUSPENDED;
1347 mpsslog("%s: BUG invalid state %s\n", mic->name, state);
1348 /* Invalid state */
1349 assert(0);
1350};
1351
1352static void mic_handle_shutdown(struct mic_info *mic)
1353{
1354#define SHUTDOWN_TIMEOUT 60
1355 int i = SHUTDOWN_TIMEOUT, ret, stat = 0;
1356 char *shutdown_status;
1357 while (i) {
1358 shutdown_status = readsysfs(mic->name, "shutdown_status");
1359 if (!shutdown_status)
1360 continue;
1361 mpsslog("%s: %s %d shutdown_status %s\n",
1362 mic->name, __func__, __LINE__, shutdown_status);
1363 switch (get_mic_shutdown_status(mic, shutdown_status)) {
1364 case MIC_RESTART:
1365 mic->restart = 1;
1366 case MIC_HALTED:
1367 case MIC_POWER_OFF:
1368 case MIC_CRASHED:
1369 free(shutdown_status);
1370 goto reset;
1371 default:
1372 break;
1373 }
1374 free(shutdown_status);
1375 sleep(1);
1376 i--;
1377 }
1378reset:
1379 ret = kill(mic->pid, SIGTERM);
1380 mpsslog("%s: %s %d kill pid %d ret %d\n",
1381 mic->name, __func__, __LINE__,
1382 mic->pid, ret);
1383 if (!ret) {
1384 ret = waitpid(mic->pid, &stat,
1385 WIFSIGNALED(stat));
1386 mpsslog("%s: %s %d waitpid ret %d pid %d\n",
1387 mic->name, __func__, __LINE__,
1388 ret, mic->pid);
1389 }
1390 if (ret == mic->pid)
1391 reset(mic);
1392}
1393
1394static void *
1395mic_config(void *arg)
1396{
1397 struct mic_info *mic = (struct mic_info *)arg;
1398 char *state = NULL;
1399 char pathname[PATH_MAX];
1400 int fd, ret;
1401 struct pollfd ufds[1];
1402 char value[4096];
1403
1404 snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
1405 MICSYSFSDIR, mic->name, "state");
1406
1407 fd = open(pathname, O_RDONLY);
1408 if (fd < 0) {
1409 mpsslog("%s: opening file %s failed %s\n",
1410 mic->name, pathname, strerror(errno));
1411 goto error;
1412 }
1413
1414 do {
1415 ret = read(fd, value, sizeof(value));
1416 if (ret < 0) {
1417 mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
1418 mic->name, pathname, strerror(errno));
1419 goto close_error1;
1420 }
1421retry:
1422 state = readsysfs(mic->name, "state");
1423 if (!state)
1424 goto retry;
1425 mpsslog("%s: %s %d state %s\n",
1426 mic->name, __func__, __LINE__, state);
1427 switch (get_mic_state(mic, state)) {
1428 case MIC_SHUTTING_DOWN:
1429 mic_handle_shutdown(mic);
1430 goto close_error;
1431 case MIC_SUSPENDING:
1432 mic->boot_on_resume = 1;
1433 setsysfs(mic->name, "state", "suspend");
1434 mic_handle_shutdown(mic);
1435 goto close_error;
1436 case MIC_OFFLINE:
1437 if (mic->boot_on_resume) {
1438 setsysfs(mic->name, "state", "boot");
1439 mic->boot_on_resume = 0;
1440 }
1441 break;
1442 default:
1443 break;
1444 }
1445 free(state);
1446
1447 ufds[0].fd = fd;
1448 ufds[0].events = POLLERR | POLLPRI;
1449 ret = poll(ufds, 1, -1);
1450 if (ret < 0) {
1451 mpsslog("%s: poll failed %s\n",
1452 mic->name, strerror(errno));
1453 goto close_error1;
1454 }
1455 } while (1);
1456close_error:
1457 free(state);
1458close_error1:
1459 close(fd);
1460error:
1461 init_mic(mic);
1462 pthread_exit(NULL);
1463}
1464
1465static void
1466set_cmdline(struct mic_info *mic)
1467{
1468 char buffer[PATH_MAX];
1469 int len;
1470
1471 len = snprintf(buffer, PATH_MAX,
1472 "clocksource=tsc highres=off nohz=off ");
1473 len += snprintf(buffer + len, PATH_MAX,
1474 "cpufreq_on;corec6_off;pc3_off;pc6_off ");
1475 len += snprintf(buffer + len, PATH_MAX,
1476 "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
1477 mic->id);
1478
1479 setsysfs(mic->name, "cmdline", buffer);
1480 mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
1481 snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id);
1482 mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
1483}
1484
1485static void
1486set_log_buf_info(struct mic_info *mic)
1487{
1488 int fd;
1489 off_t len;
1490 char system_map[] = "/lib/firmware/mic/System.map";
1491 char *map, *temp, log_buf[17] = {'\0'};
1492
1493 fd = open(system_map, O_RDONLY);
1494 if (fd < 0) {
1495 mpsslog("%s: Opening System.map failed: %d\n",
1496 mic->name, errno);
1497 return;
1498 }
1499 len = lseek(fd, 0, SEEK_END);
1500 if (len < 0) {
1501 mpsslog("%s: Reading System.map size failed: %d\n",
1502 mic->name, errno);
1503 close(fd);
1504 return;
1505 }
1506 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
1507 if (map == MAP_FAILED) {
1508 mpsslog("%s: mmap of System.map failed: %d\n",
1509 mic->name, errno);
1510 close(fd);
1511 return;
1512 }
1513 temp = strstr(map, "__log_buf");
1514 if (!temp) {
1515 mpsslog("%s: __log_buf not found: %d\n", mic->name, errno);
1516 munmap(map, len);
1517 close(fd);
1518 return;
1519 }
1520 strncpy(log_buf, temp - 19, 16);
1521 setsysfs(mic->name, "log_buf_addr", log_buf);
1522 mpsslog("%s: log_buf_addr: %s\n", mic->name, log_buf);
1523 temp = strstr(map, "log_buf_len");
1524 if (!temp) {
1525 mpsslog("%s: log_buf_len not found: %d\n", mic->name, errno);
1526 munmap(map, len);
1527 close(fd);
1528 return;
1529 }
1530 strncpy(log_buf, temp - 19, 16);
1531 setsysfs(mic->name, "log_buf_len", log_buf);
1532 mpsslog("%s: log_buf_len: %s\n", mic->name, log_buf);
1533 munmap(map, len);
1534 close(fd);
1535}
1536
1537static void init_mic(struct mic_info *mic);
1538
1539static void
1540change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
1541{
1542 struct mic_info *mic;
1543
1544 for (mic = mic_list.next; mic != NULL; mic = mic->next)
1545 mic->mic_virtblk.signaled = 1/* true */;
1546}
1547
1548static void
1549init_mic(struct mic_info *mic)
1550{
1551 struct sigaction ignore = {
1552 .sa_flags = 0,
1553 .sa_handler = SIG_IGN
1554 };
1555 struct sigaction act = {
1556 .sa_flags = SA_SIGINFO,
1557 .sa_sigaction = change_virtblk_backend,
1558 };
1559 char buffer[PATH_MAX];
1560 int err;
1561
1562 /*
1563 * Currently, one virtio block device is supported for each MIC card
1564 * at a time. Any user (or test) can send a SIGUSR1 to the MIC daemon.
1565 * The signal informs the virtio block backend about a change in the
1566 * configuration file which specifies the virtio backend file name on
1567 * the host. Virtio block backend then re-reads the configuration file
1568 * and switches to the new block device. This signalling mechanism may
1569 * not be required once multiple virtio block devices are supported by
1570 * the MIC daemon.
1571 */
1572 sigaction(SIGUSR1, &ignore, NULL);
1573
1574 mic->pid = fork();
1575 switch (mic->pid) {
1576 case 0:
1577 set_log_buf_info(mic);
1578 set_cmdline(mic);
1579 add_virtio_device(mic, &virtcons_dev_page.dd);
1580 add_virtio_device(mic, &virtnet_dev_page.dd);
1581 err = pthread_create(&mic->mic_console.console_thread, NULL,
1582 virtio_console, mic);
1583 if (err)
1584 mpsslog("%s virtcons pthread_create failed %s\n",
1585 mic->name, strerror(err));
1586 err = pthread_create(&mic->mic_net.net_thread, NULL,
1587 virtio_net, mic);
1588 if (err)
1589 mpsslog("%s virtnet pthread_create failed %s\n",
1590 mic->name, strerror(err));
1591 err = pthread_create(&mic->mic_virtblk.block_thread, NULL,
1592 virtio_block, mic);
1593 if (err)
1594 mpsslog("%s virtblk pthread_create failed %s\n",
1595 mic->name, strerror(err));
1596 sigemptyset(&act.sa_mask);
1597 err = sigaction(SIGUSR1, &act, NULL);
1598 if (err)
1599 mpsslog("%s sigaction SIGUSR1 failed %s\n",
1600 mic->name, strerror(errno));
1601 while (1)
1602 sleep(60);
1603 case -1:
1604 mpsslog("fork failed MIC name %s id %d errno %d\n",
1605 mic->name, mic->id, errno);
1606 break;
1607 default:
1608 if (mic->restart) {
1609 snprintf(buffer, PATH_MAX, "boot");
1610 setsysfs(mic->name, "state", buffer);
1611 mpsslog("%s restarting mic %d\n",
1612 mic->name, mic->restart);
1613 mic->restart = 0;
1614 }
1615 pthread_create(&mic->config_thread, NULL, mic_config, mic);
1616 }
1617}
1618
1619static void
1620start_daemon(void)
1621{
1622 struct mic_info *mic;
1623
1624 for (mic = mic_list.next; mic != NULL; mic = mic->next)
1625 init_mic(mic);
1626
1627 while (1)
1628 sleep(60);
1629}
1630
1631static int
1632init_mic_list(void)
1633{
1634 struct mic_info *mic = &mic_list;
1635 struct dirent *file;
1636 DIR *dp;
1637 int cnt = 0;
1638
1639 dp = opendir(MICSYSFSDIR);
1640 if (!dp)
1641 return 0;
1642
1643 while ((file = readdir(dp)) != NULL) {
1644 if (!strncmp(file->d_name, "mic", 3)) {
1645 mic->next = calloc(1, sizeof(struct mic_info));
1646 if (mic->next) {
1647 mic = mic->next;
1648 mic->id = atoi(&file->d_name[3]);
1649 mic->name = malloc(strlen(file->d_name) + 16);
1650 if (mic->name)
1651 strcpy(mic->name, file->d_name);
1652 mpsslog("MIC name %s id %d\n", mic->name,
1653 mic->id);
1654 cnt++;
1655 }
1656 }
1657 }
1658
1659 closedir(dp);
1660 return cnt;
1661}
1662
1663void
1664mpsslog(char *format, ...)
1665{
1666 va_list args;
1667 char buffer[4096];
1668 char ts[52], *ts1;
1669 time_t t;
1670
1671 if (logfp == NULL)
1672 return;
1673
1674 va_start(args, format);
1675 vsprintf(buffer, format, args);
1676 va_end(args);
1677
1678 time(&t);
1679 ts1 = ctime_r(&t, ts);
1680 ts1[strlen(ts1) - 1] = '\0';
1681 fprintf(logfp, "%s: %s", ts1, buffer);
1682
1683 fflush(logfp);
1684}
1685
1686int
1687main(int argc, char *argv[])
1688{
1689 int cnt;
1690 pid_t pid;
1691
1692 myname = argv[0];
1693
1694 logfp = fopen(LOGFILE_NAME, "a+");
1695 if (!logfp) {
1696 fprintf(stderr, "cannot open logfile '%s'\n", LOGFILE_NAME);
1697 exit(1);
1698 }
1699 pid = fork();
1700 switch (pid) {
1701 case 0:
1702 break;
1703 case -1:
1704 exit(2);
1705 default:
1706 exit(0);
1707 }
1708
1709 mpsslog("MIC Daemon start\n");
1710
1711 cnt = init_mic_list();
1712 if (cnt == 0) {
1713 mpsslog("MIC module not loaded\n");
1714 exit(3);
1715 }
1716 mpsslog("MIC found %d devices\n", cnt);
1717
1718 start_daemon();
1719
1720 exit(0);
1721}
diff --git a/Documentation/mic/mpssd/mpssd.h b/Documentation/mic/mpssd/mpssd.h
new file mode 100644
index 000000000000..f5f18b15d9a0
--- /dev/null
+++ b/Documentation/mic/mpssd/mpssd.h
@@ -0,0 +1,102 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC User Space Tools.
19 */
20#ifndef _MPSSD_H_
21#define _MPSSD_H_
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <dirent.h>
29#include <libgen.h>
30#include <pthread.h>
31#include <stdarg.h>
32#include <time.h>
33#include <errno.h>
34#include <sys/dir.h>
35#include <sys/ioctl.h>
36#include <sys/poll.h>
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <sys/stat.h>
40#include <sys/types.h>
41#include <sys/mman.h>
42#include <sys/utsname.h>
43#include <sys/wait.h>
44#include <netinet/in.h>
45#include <arpa/inet.h>
46#include <netdb.h>
47#include <pthread.h>
48#include <signal.h>
49#include <limits.h>
50#include <syslog.h>
51#include <getopt.h>
52#include <net/if.h>
53#include <linux/if_tun.h>
54#include <linux/if_tun.h>
55#include <linux/virtio_ids.h>
56
57#define MICSYSFSDIR "/sys/class/mic"
58#define LOGFILE_NAME "/var/log/mpssd"
59#define PAGE_SIZE 4096
60
61struct mic_console_info {
62 pthread_t console_thread;
63 int virtio_console_fd;
64 void *console_dp;
65};
66
67struct mic_net_info {
68 pthread_t net_thread;
69 int virtio_net_fd;
70 int tap_fd;
71 void *net_dp;
72};
73
74struct mic_virtblk_info {
75 pthread_t block_thread;
76 int virtio_block_fd;
77 void *block_dp;
78 volatile sig_atomic_t signaled;
79 char *backend_file;
80 int backend;
81 void *backend_addr;
82 long backend_size;
83};
84
85struct mic_info {
86 int id;
87 char *name;
88 pthread_t config_thread;
89 pid_t pid;
90 struct mic_console_info mic_console;
91 struct mic_net_info mic_net;
92 struct mic_virtblk_info mic_virtblk;
93 int restart;
94 int boot_on_resume;
95 struct mic_info *next;
96};
97
98__attribute__((format(printf, 1, 2)))
99void mpsslog(char *format, ...);
100char *readsysfs(char *dir, char *entry);
101int setsysfs(char *dir, char *entry, char *value);
102#endif
diff --git a/Documentation/mic/mpssd/sysfs.c b/Documentation/mic/mpssd/sysfs.c
new file mode 100644
index 000000000000..8dd326936083
--- /dev/null
+++ b/Documentation/mic/mpssd/sysfs.c
@@ -0,0 +1,102 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC User Space Tools.
19 */
20
21#include "mpssd.h"
22
23#define PAGE_SIZE 4096
24
25char *
26readsysfs(char *dir, char *entry)
27{
28 char filename[PATH_MAX];
29 char value[PAGE_SIZE];
30 char *string = NULL;
31 int fd;
32 int len;
33
34 if (dir == NULL)
35 snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
36 else
37 snprintf(filename, PATH_MAX,
38 "%s/%s/%s", MICSYSFSDIR, dir, entry);
39
40 fd = open(filename, O_RDONLY);
41 if (fd < 0) {
42 mpsslog("Failed to open sysfs entry '%s': %s\n",
43 filename, strerror(errno));
44 return NULL;
45 }
46
47 len = read(fd, value, sizeof(value));
48 if (len < 0) {
49 mpsslog("Failed to read sysfs entry '%s': %s\n",
50 filename, strerror(errno));
51 goto readsys_ret;
52 }
53 if (len == 0)
54 goto readsys_ret;
55
56 value[len - 1] = '\0';
57
58 string = malloc(strlen(value) + 1);
59 if (string)
60 strcpy(string, value);
61
62readsys_ret:
63 close(fd);
64 return string;
65}
66
67int
68setsysfs(char *dir, char *entry, char *value)
69{
70 char filename[PATH_MAX];
71 char *oldvalue;
72 int fd, ret = 0;
73
74 if (dir == NULL)
75 snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
76 else
77 snprintf(filename, PATH_MAX, "%s/%s/%s",
78 MICSYSFSDIR, dir, entry);
79
80 oldvalue = readsysfs(dir, entry);
81
82 fd = open(filename, O_RDWR);
83 if (fd < 0) {
84 ret = errno;
85 mpsslog("Failed to open sysfs entry '%s': %s\n",
86 filename, strerror(errno));
87 goto done;
88 }
89
90 if (!oldvalue || strcmp(value, oldvalue)) {
91 if (write(fd, value, strlen(value)) < 0) {
92 ret = errno;
93 mpsslog("Failed to write new sysfs entry '%s': %s\n",
94 filename, strerror(errno));
95 }
96 }
97 close(fd);
98done:
99 if (oldvalue)
100 free(oldvalue);
101 return ret;
102}
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 448ce5e29c56..dca5834685cf 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -486,8 +486,7 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
486 } 486 }
487 487
488 sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); 488 sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
489 irq_flags = devp->hd_flags & HPET_SHARED_IRQ 489 irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : 0;
490 ? IRQF_SHARED : IRQF_DISABLED;
491 if (request_irq(irq, hpet_interrupt, irq_flags, 490 if (request_irq(irq, hpet_interrupt, irq_flags,
492 devp->hd_name, (void *)devp)) { 491 devp->hd_name, (void *)devp)) {
493 printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); 492 printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
@@ -971,8 +970,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
971 struct acpi_resource_fixed_memory32 *fixmem32; 970 struct acpi_resource_fixed_memory32 *fixmem32;
972 971
973 fixmem32 = &res->data.fixed_memory32; 972 fixmem32 = &res->data.fixed_memory32;
974 if (!fixmem32)
975 return AE_NO_MEMORY;
976 973
977 hdp->hd_phys_address = fixmem32->address; 974 hdp->hd_phys_address = fixmem32->address;
978 hdp->hd_address = ioremap(fixmem32->address, 975 hdp->hd_address = ioremap(fixmem32->address,
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 190d4423653f..2f685f6eda48 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -193,8 +193,8 @@ int misc_register(struct miscdevice * misc)
193 if (misc->minor == MISC_DYNAMIC_MINOR) { 193 if (misc->minor == MISC_DYNAMIC_MINOR) {
194 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); 194 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
195 if (i >= DYNAMIC_MINORS) { 195 if (i >= DYNAMIC_MINORS) {
196 mutex_unlock(&misc_mtx); 196 err = -EBUSY;
197 return -EBUSY; 197 goto out;
198 } 198 }
199 misc->minor = DYNAMIC_MINORS - i - 1; 199 misc->minor = DYNAMIC_MINORS - i - 1;
200 set_bit(i, misc_minors); 200 set_bit(i, misc_minors);
@@ -203,8 +203,8 @@ int misc_register(struct miscdevice * misc)
203 203
204 list_for_each_entry(c, &misc_list, list) { 204 list_for_each_entry(c, &misc_list, list) {
205 if (c->minor == misc->minor) { 205 if (c->minor == misc->minor) {
206 mutex_unlock(&misc_mtx); 206 err = -EBUSY;
207 return -EBUSY; 207 goto out;
208 } 208 }
209 } 209 }
210 } 210 }
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index cfdfe493c6af..1fd00dc06897 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -220,7 +220,7 @@ static int __init nwbutton_init(void)
220 return -EBUSY; 220 return -EBUSY;
221 } 221 }
222 222
223 if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, IRQF_DISABLED, 223 if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, 0,
224 "nwbutton", NULL)) { 224 "nwbutton", NULL)) {
225 printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n", 225 printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n",
226 IRQ_NETWINDER_BUTTON); 226 IRQ_NETWINDER_BUTTON);
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index c0cbbd429bdc..35259961cc38 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -227,7 +227,7 @@ static inline unsigned char rtc_is_updating(void)
227 227
228#ifdef RTC_IRQ 228#ifdef RTC_IRQ
229/* 229/*
230 * A very tiny interrupt handler. It runs with IRQF_DISABLED set, 230 * A very tiny interrupt handler. It runs with interrupts disabled,
231 * but there is possibility of conflicting with the set_rtc_mmss() 231 * but there is possibility of conflicting with the set_rtc_mmss()
232 * call (the rtc irq and the timer irq can easily run at the same 232 * call (the rtc irq and the timer irq can easily run at the same
233 * time in two different CPUs). So we need to serialize 233 * time in two different CPUs). So we need to serialize
@@ -1040,8 +1040,7 @@ no_irq:
1040 rtc_int_handler_ptr = rtc_interrupt; 1040 rtc_int_handler_ptr = rtc_interrupt;
1041 } 1041 }
1042 1042
1043 if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, 1043 if (request_irq(RTC_IRQ, rtc_int_handler_ptr, 0, "rtc", NULL)) {
1044 "rtc", NULL)) {
1045 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */ 1044 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
1046 rtc_has_irq = 0; 1045 rtc_has_irq = 0;
1047 printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ); 1046 printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 5816b39ff5a9..8bab59292a0d 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -108,8 +108,7 @@ scdrv_open(struct inode *inode, struct file *file)
108 /* hook this subchannel up to the system controller interrupt */ 108 /* hook this subchannel up to the system controller interrupt */
109 mutex_lock(&scdrv_mutex); 109 mutex_lock(&scdrv_mutex);
110 rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, 110 rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
111 IRQF_SHARED | IRQF_DISABLED, 111 IRQF_SHARED, SYSCTL_BASENAME, sd);
112 SYSCTL_BASENAME, sd);
113 if (rv) { 112 if (rv) {
114 ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); 113 ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
115 kfree(sd); 114 kfree(sd);
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index ee156948b9f8..59bcefd6ec7c 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -292,8 +292,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
292 292
293 /* hook event subchannel up to the system controller interrupt */ 293 /* hook event subchannel up to the system controller interrupt */
294 rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt, 294 rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt,
295 IRQF_SHARED | IRQF_DISABLED, 295 IRQF_SHARED, "system controller events", event_sd);
296 "system controller events", event_sd);
297 if (rv) { 296 if (rv) {
298 printk(KERN_WARNING "%s: irq request failed (%d)\n", 297 printk(KERN_WARNING "%s: irq request failed (%d)\n",
299 __func__, rv); 298 __func__, rv);
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index e95e0ab0bd87..100cd1de9939 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -222,7 +222,7 @@ static int tlclk_open(struct inode *inode, struct file *filp)
222 /* This device is wired through the FPGA IO space of the ATCA blade 222 /* This device is wired through the FPGA IO space of the ATCA blade
223 * we can't share this IRQ */ 223 * we can't share this IRQ */
224 result = request_irq(telclk_interrupt, &tlclk_interrupt, 224 result = request_irq(telclk_interrupt, &tlclk_interrupt,
225 IRQF_DISABLED, "telco_clock", tlclk_interrupt); 225 0, "telco_clock", tlclk_interrupt);
226 if (result == -EBUSY) 226 if (result == -EBUSY)
227 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); 227 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
228 else 228 else
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 5224da5202d3..f6345f932e46 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -721,7 +721,7 @@ static int hwicap_remove(struct device *dev)
721{ 721{
722 struct hwicap_drvdata *drvdata; 722 struct hwicap_drvdata *drvdata;
723 723
724 drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev); 724 drvdata = dev_get_drvdata(dev);
725 725
726 if (!drvdata) 726 if (!drvdata)
727 return 0; 727 return 0;
@@ -731,7 +731,6 @@ static int hwicap_remove(struct device *dev)
731 iounmap(drvdata->base_address); 731 iounmap(drvdata->base_address);
732 release_mem_region(drvdata->mem_start, drvdata->mem_size); 732 release_mem_region(drvdata->mem_start, drvdata->mem_size);
733 kfree(drvdata); 733 kfree(drvdata);
734 dev_set_drvdata(dev, NULL);
735 734
736 mutex_lock(&icap_sem); 735 mutex_lock(&icap_sem);
737 probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; 736 probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index 5985807e52c9..e23f1c2e5053 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -27,16 +27,16 @@
27 27
28/** 28/**
29 * struct adc_jack_data - internal data for adc_jack device driver 29 * struct adc_jack_data - internal data for adc_jack device driver
30 * @edev - extcon device. 30 * @edev: extcon device.
31 * @cable_names - list of supported cables. 31 * @cable_names: list of supported cables.
32 * @num_cables - size of cable_names. 32 * @num_cables: size of cable_names.
33 * @adc_conditions - list of adc value conditions. 33 * @adc_conditions: list of adc value conditions.
34 * @num_conditions - size of adc_conditions. 34 * @num_conditions: size of adc_conditions.
35 * @irq - irq number of attach/detach event (0 if not exist). 35 * @irq: irq number of attach/detach event (0 if not exist).
36 * @handling_delay - interrupt handler will schedule extcon event 36 * @handling_delay: interrupt handler will schedule extcon event
37 * handling at handling_delay jiffies. 37 * handling at handling_delay jiffies.
38 * @handler - extcon event handler called by interrupt handler. 38 * @handler: extcon event handler called by interrupt handler.
39 * @chan - iio channel being queried. 39 * @chan: iio channel being queried.
40 */ 40 */
41struct adc_jack_data { 41struct adc_jack_data {
42 struct extcon_dev edev; 42 struct extcon_dev edev;
@@ -64,7 +64,7 @@ static void adc_jack_handler(struct work_struct *work)
64 64
65 ret = iio_read_channel_raw(data->chan, &adc_val); 65 ret = iio_read_channel_raw(data->chan, &adc_val);
66 if (ret < 0) { 66 if (ret < 0) {
67 dev_err(data->edev.dev, "read channel() error: %d\n", ret); 67 dev_err(&data->edev.dev, "read channel() error: %d\n", ret);
68 return; 68 return;
69 } 69 }
70 70
@@ -95,7 +95,7 @@ static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
95static int adc_jack_probe(struct platform_device *pdev) 95static int adc_jack_probe(struct platform_device *pdev)
96{ 96{
97 struct adc_jack_data *data; 97 struct adc_jack_data *data;
98 struct adc_jack_pdata *pdata = pdev->dev.platform_data; 98 struct adc_jack_pdata *pdata = dev_get_platdata(&pdev->dev);
99 int i, err = 0; 99 int i, err = 0;
100 100
101 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 101 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
@@ -110,6 +110,7 @@ static int adc_jack_probe(struct platform_device *pdev)
110 goto out; 110 goto out;
111 } 111 }
112 112
113 data->edev.dev.parent = &pdev->dev;
113 data->edev.supported_cable = pdata->cable_names; 114 data->edev.supported_cable = pdata->cable_names;
114 115
115 /* Check the length of array and set num_cables */ 116 /* Check the length of array and set num_cables */
@@ -148,7 +149,7 @@ static int adc_jack_probe(struct platform_device *pdev)
148 149
149 platform_set_drvdata(pdev, data); 150 platform_set_drvdata(pdev, data);
150 151
151 err = extcon_dev_register(&data->edev, &pdev->dev); 152 err = extcon_dev_register(&data->edev);
152 if (err) 153 if (err)
153 goto out; 154 goto out;
154 155
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index e55713083c78..3c55ec856e39 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -86,8 +86,8 @@ struct arizona_extcon_info {
86}; 86};
87 87
88static const struct arizona_micd_config micd_default_modes[] = { 88static const struct arizona_micd_config micd_default_modes[] = {
89 { ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 }, 89 { ARIZONA_ACCDET_SRC, 1, 0 },
90 { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, 90 { 0, 2, 1 },
91}; 91};
92 92
93static const struct arizona_micd_range micd_default_ranges[] = { 93static const struct arizona_micd_range micd_default_ranges[] = {
@@ -182,7 +182,8 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
182 info->micd_modes[mode].gpio); 182 info->micd_modes[mode].gpio);
183 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, 183 regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
184 ARIZONA_MICD_BIAS_SRC_MASK, 184 ARIZONA_MICD_BIAS_SRC_MASK,
185 info->micd_modes[mode].bias); 185 info->micd_modes[mode].bias <<
186 ARIZONA_MICD_BIAS_SRC_SHIFT);
186 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, 187 regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
187 ARIZONA_ACCDET_SRC, info->micd_modes[mode].src); 188 ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
188 189
@@ -193,7 +194,7 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
193 194
194static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info) 195static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
195{ 196{
196 switch (info->micd_modes[0].bias >> ARIZONA_MICD_BIAS_SRC_SHIFT) { 197 switch (info->micd_modes[0].bias) {
197 case 1: 198 case 1:
198 return "MICBIAS1"; 199 return "MICBIAS1";
199 case 2: 200 case 2:
@@ -388,7 +389,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
388 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT; 389 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
389 390
390 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 && 391 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
391 (val < 100 || val > 0x3fb)) { 392 (val < 100 || val >= 0x3fb)) {
392 range++; 393 range++;
393 dev_dbg(arizona->dev, "Moving to HPDET range %d\n", 394 dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
394 range); 395 range);
@@ -401,7 +402,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
401 } 402 }
402 403
403 /* If we go out of range report top of range */ 404 /* If we go out of range report top of range */
404 if (val < 100 || val > 0x3fb) { 405 if (val < 100 || val >= 0x3fb) {
405 dev_dbg(arizona->dev, "Measurement out of range\n"); 406 dev_dbg(arizona->dev, "Measurement out of range\n");
406 return ARIZONA_HPDET_MAX; 407 return ARIZONA_HPDET_MAX;
407 } 408 }
@@ -514,7 +515,7 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
514 } 515 }
515 516
516 /* 517 /*
517 * If we measure the mic as 518 * If we measure the mic as high impedance
518 */ 519 */
519 if (!id_gpio || info->hpdet_res[1] > 50) { 520 if (!id_gpio || info->hpdet_res[1] > 50) {
520 dev_dbg(arizona->dev, "Detected mic\n"); 521 dev_dbg(arizona->dev, "Detected mic\n");
@@ -564,11 +565,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
564 } 565 }
565 566
566 ret = arizona_hpdet_read(info); 567 ret = arizona_hpdet_read(info);
567 if (ret == -EAGAIN) { 568 if (ret == -EAGAIN)
568 goto out; 569 goto out;
569 } else if (ret < 0) { 570 else if (ret < 0)
570 goto done; 571 goto done;
571 }
572 reading = ret; 572 reading = ret;
573 573
574 /* Reset back to starting range */ 574 /* Reset back to starting range */
@@ -578,11 +578,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
578 0); 578 0);
579 579
580 ret = arizona_hpdet_do_id(info, &reading, &mic); 580 ret = arizona_hpdet_do_id(info, &reading, &mic);
581 if (ret == -EAGAIN) { 581 if (ret == -EAGAIN)
582 goto out; 582 goto out;
583 } else if (ret < 0) { 583 else if (ret < 0)
584 goto done; 584 goto done;
585 }
586 585
587 /* Report high impedence cables as line outputs */ 586 /* Report high impedence cables as line outputs */
588 if (reading >= 5000) 587 if (reading >= 5000)
@@ -738,8 +737,8 @@ err:
738static void arizona_micd_timeout_work(struct work_struct *work) 737static void arizona_micd_timeout_work(struct work_struct *work)
739{ 738{
740 struct arizona_extcon_info *info = container_of(work, 739 struct arizona_extcon_info *info = container_of(work,
741 struct arizona_extcon_info, 740 struct arizona_extcon_info,
742 micd_timeout_work.work); 741 micd_timeout_work.work);
743 742
744 mutex_lock(&info->lock); 743 mutex_lock(&info->lock);
745 744
@@ -756,8 +755,8 @@ static void arizona_micd_timeout_work(struct work_struct *work)
756static void arizona_micd_detect(struct work_struct *work) 755static void arizona_micd_detect(struct work_struct *work)
757{ 756{
758 struct arizona_extcon_info *info = container_of(work, 757 struct arizona_extcon_info *info = container_of(work,
759 struct arizona_extcon_info, 758 struct arizona_extcon_info,
760 micd_detect_work.work); 759 micd_detect_work.work);
761 struct arizona *arizona = info->arizona; 760 struct arizona *arizona = info->arizona;
762 unsigned int val = 0, lvl; 761 unsigned int val = 0, lvl;
763 int ret, i, key; 762 int ret, i, key;
@@ -769,7 +768,8 @@ static void arizona_micd_detect(struct work_struct *work)
769 for (i = 0; i < 10 && !(val & 0x7fc); i++) { 768 for (i = 0; i < 10 && !(val & 0x7fc); i++) {
770 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); 769 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
771 if (ret != 0) { 770 if (ret != 0) {
772 dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); 771 dev_err(arizona->dev,
772 "Failed to read MICDET: %d\n", ret);
773 mutex_unlock(&info->lock); 773 mutex_unlock(&info->lock);
774 return; 774 return;
775 } 775 }
@@ -777,7 +777,8 @@ static void arizona_micd_detect(struct work_struct *work)
777 dev_dbg(arizona->dev, "MICDET: %x\n", val); 777 dev_dbg(arizona->dev, "MICDET: %x\n", val);
778 778
779 if (!(val & ARIZONA_MICD_VALID)) { 779 if (!(val & ARIZONA_MICD_VALID)) {
780 dev_warn(arizona->dev, "Microphone detection state invalid\n"); 780 dev_warn(arizona->dev,
781 "Microphone detection state invalid\n");
781 mutex_unlock(&info->lock); 782 mutex_unlock(&info->lock);
782 return; 783 return;
783 } 784 }
@@ -925,8 +926,8 @@ static irqreturn_t arizona_micdet(int irq, void *data)
925static void arizona_hpdet_work(struct work_struct *work) 926static void arizona_hpdet_work(struct work_struct *work)
926{ 927{
927 struct arizona_extcon_info *info = container_of(work, 928 struct arizona_extcon_info *info = container_of(work,
928 struct arizona_extcon_info, 929 struct arizona_extcon_info,
929 hpdet_work.work); 930 hpdet_work.work);
930 931
931 mutex_lock(&info->lock); 932 mutex_lock(&info->lock);
932 arizona_start_hpdet_acc_id(info); 933 arizona_start_hpdet_acc_id(info);
@@ -973,10 +974,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
973 &info->hpdet_work, 974 &info->hpdet_work,
974 msecs_to_jiffies(HPDET_DEBOUNCE)); 975 msecs_to_jiffies(HPDET_DEBOUNCE));
975 976
976 if (cancelled_mic) 977 if (cancelled_mic) {
978 int micd_timeout = info->micd_timeout;
979
977 queue_delayed_work(system_power_efficient_wq, 980 queue_delayed_work(system_power_efficient_wq,
978 &info->micd_timeout_work, 981 &info->micd_timeout_work,
979 msecs_to_jiffies(info->micd_timeout)); 982 msecs_to_jiffies(micd_timeout));
983 }
980 984
981 goto out; 985 goto out;
982 } 986 }
@@ -1039,6 +1043,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
1039 else 1043 else
1040 info->micd_timeout = DEFAULT_MICD_TIMEOUT; 1044 info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1041 1045
1046out:
1042 /* Clear trig_sts to make sure DCVDD is not forced up */ 1047 /* Clear trig_sts to make sure DCVDD is not forced up */
1043 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, 1048 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
1044 ARIZONA_MICD_CLAMP_FALL_TRIG_STS | 1049 ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
@@ -1046,7 +1051,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
1046 ARIZONA_JD1_FALL_TRIG_STS | 1051 ARIZONA_JD1_FALL_TRIG_STS |
1047 ARIZONA_JD1_RISE_TRIG_STS); 1052 ARIZONA_JD1_RISE_TRIG_STS);
1048 1053
1049out:
1050 mutex_unlock(&info->lock); 1054 mutex_unlock(&info->lock);
1051 1055
1052 pm_runtime_mark_last_busy(info->dev); 1056 pm_runtime_mark_last_busy(info->dev);
@@ -1129,9 +1133,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1129 } 1133 }
1130 1134
1131 info->edev.name = "Headset Jack"; 1135 info->edev.name = "Headset Jack";
1136 info->edev.dev.parent = arizona->dev;
1132 info->edev.supported_cable = arizona_cable; 1137 info->edev.supported_cable = arizona_cable;
1133 1138
1134 ret = extcon_dev_register(&info->edev, arizona->dev); 1139 ret = extcon_dev_register(&info->edev);
1135 if (ret < 0) { 1140 if (ret < 0) {
1136 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n", 1141 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1137 ret); 1142 ret);
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 148382faded9..15443d3b6be1 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -74,7 +74,7 @@ static DEFINE_MUTEX(extcon_dev_list_lock);
74 74
75/** 75/**
76 * check_mutually_exclusive - Check if new_state violates mutually_exclusive 76 * check_mutually_exclusive - Check if new_state violates mutually_exclusive
77 * condition. 77 * condition.
78 * @edev: the extcon device 78 * @edev: the extcon device
79 * @new_state: new cable attach status for @edev 79 * @new_state: new cable attach status for @edev
80 * 80 *
@@ -105,7 +105,7 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
105 char *buf) 105 char *buf)
106{ 106{
107 int i, count = 0; 107 int i, count = 0;
108 struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); 108 struct extcon_dev *edev = dev_get_drvdata(dev);
109 109
110 if (edev->print_state) { 110 if (edev->print_state) {
111 int ret = edev->print_state(edev, buf); 111 int ret = edev->print_state(edev, buf);
@@ -129,13 +129,12 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr,
129 return count; 129 return count;
130} 130}
131 131
132int extcon_set_state(struct extcon_dev *edev, u32 state);
133static ssize_t state_store(struct device *dev, struct device_attribute *attr, 132static ssize_t state_store(struct device *dev, struct device_attribute *attr,
134 const char *buf, size_t count) 133 const char *buf, size_t count)
135{ 134{
136 u32 state; 135 u32 state;
137 ssize_t ret = 0; 136 ssize_t ret = 0;
138 struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); 137 struct extcon_dev *edev = dev_get_drvdata(dev);
139 138
140 ret = sscanf(buf, "0x%x", &state); 139 ret = sscanf(buf, "0x%x", &state);
141 if (ret == 0) 140 if (ret == 0)
@@ -153,7 +152,7 @@ static DEVICE_ATTR_RW(state);
153static ssize_t name_show(struct device *dev, struct device_attribute *attr, 152static ssize_t name_show(struct device *dev, struct device_attribute *attr,
154 char *buf) 153 char *buf)
155{ 154{
156 struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); 155 struct extcon_dev *edev = dev_get_drvdata(dev);
157 156
158 /* Optional callback given by the user */ 157 /* Optional callback given by the user */
159 if (edev->print_name) { 158 if (edev->print_name) {
@@ -162,7 +161,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
162 return ret; 161 return ret;
163 } 162 }
164 163
165 return sprintf(buf, "%s\n", dev_name(edev->dev)); 164 return sprintf(buf, "%s\n", dev_name(&edev->dev));
166} 165}
167static DEVICE_ATTR_RO(name); 166static DEVICE_ATTR_RO(name);
168 167
@@ -189,7 +188,7 @@ static ssize_t cable_state_show(struct device *dev,
189 188
190/** 189/**
191 * extcon_update_state() - Update the cable attach states of the extcon device 190 * extcon_update_state() - Update the cable attach states of the extcon device
192 * only for the masked bits. 191 * only for the masked bits.
193 * @edev: the extcon device 192 * @edev: the extcon device
194 * @mask: the bit mask to designate updated bits. 193 * @mask: the bit mask to designate updated bits.
195 * @state: new cable attach status for @edev 194 * @state: new cable attach status for @edev
@@ -227,11 +226,10 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
227 edev->state |= state & mask; 226 edev->state |= state & mask;
228 227
229 raw_notifier_call_chain(&edev->nh, old_state, edev); 228 raw_notifier_call_chain(&edev->nh, old_state, edev);
230
231 /* This could be in interrupt handler */ 229 /* This could be in interrupt handler */
232 prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); 230 prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
233 if (prop_buf) { 231 if (prop_buf) {
234 length = name_show(edev->dev, NULL, prop_buf); 232 length = name_show(&edev->dev, NULL, prop_buf);
235 if (length > 0) { 233 if (length > 0) {
236 if (prop_buf[length - 1] == '\n') 234 if (prop_buf[length - 1] == '\n')
237 prop_buf[length - 1] = 0; 235 prop_buf[length - 1] = 0;
@@ -239,7 +237,7 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
239 "NAME=%s", prop_buf); 237 "NAME=%s", prop_buf);
240 envp[env_offset++] = name_buf; 238 envp[env_offset++] = name_buf;
241 } 239 }
242 length = state_show(edev->dev, NULL, prop_buf); 240 length = state_show(&edev->dev, NULL, prop_buf);
243 if (length > 0) { 241 if (length > 0) {
244 if (prop_buf[length - 1] == '\n') 242 if (prop_buf[length - 1] == '\n')
245 prop_buf[length - 1] = 0; 243 prop_buf[length - 1] = 0;
@@ -251,14 +249,14 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
251 /* Unlock early before uevent */ 249 /* Unlock early before uevent */
252 spin_unlock_irqrestore(&edev->lock, flags); 250 spin_unlock_irqrestore(&edev->lock, flags);
253 251
254 kobject_uevent_env(&edev->dev->kobj, KOBJ_CHANGE, envp); 252 kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);
255 free_page((unsigned long)prop_buf); 253 free_page((unsigned long)prop_buf);
256 } else { 254 } else {
257 /* Unlock early before uevent */ 255 /* Unlock early before uevent */
258 spin_unlock_irqrestore(&edev->lock, flags); 256 spin_unlock_irqrestore(&edev->lock, flags);
259 257
260 dev_err(edev->dev, "out of memory in extcon_set_state\n"); 258 dev_err(&edev->dev, "out of memory in extcon_set_state\n");
261 kobject_uevent(&edev->dev->kobj, KOBJ_CHANGE); 259 kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
262 } 260 }
263 } else { 261 } else {
264 /* No changes */ 262 /* No changes */
@@ -339,8 +337,9 @@ EXPORT_SYMBOL_GPL(extcon_get_cable_state);
339 337
340/** 338/**
341 * extcon_set_cable_state_() - Set the status of a specific cable. 339 * extcon_set_cable_state_() - Set the status of a specific cable.
342 * @edev: the extcon device that has the cable. 340 * @edev: the extcon device that has the cable.
343 * @index: cable index that can be retrieved by extcon_find_cable_index(). 341 * @index: cable index that can be retrieved by
342 * extcon_find_cable_index().
344 * @cable_state: the new cable status. The default semantics is 343 * @cable_state: the new cable status. The default semantics is
345 * true: attached / false: detached. 344 * true: attached / false: detached.
346 */ 345 */
@@ -359,8 +358,8 @@ EXPORT_SYMBOL_GPL(extcon_set_cable_state_);
359 358
360/** 359/**
361 * extcon_set_cable_state() - Set the status of a specific cable. 360 * extcon_set_cable_state() - Set the status of a specific cable.
362 * @edev: the extcon device that has the cable. 361 * @edev: the extcon device that has the cable.
363 * @cable_name: cable name. 362 * @cable_name: cable name.
364 * @cable_state: the new cable status. The default semantics is 363 * @cable_state: the new cable status. The default semantics is
365 * true: attached / false: detached. 364 * true: attached / false: detached.
366 * 365 *
@@ -419,14 +418,14 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val,
419 418
420/** 419/**
421 * extcon_register_interest() - Register a notifier for a state change of a 420 * extcon_register_interest() - Register a notifier for a state change of a
422 * specific cable, not an entier set of cables of a 421 * specific cable, not an entier set of cables of a
423 * extcon device. 422 * extcon device.
424 * @obj: an empty extcon_specific_cable_nb object to be returned. 423 * @obj: an empty extcon_specific_cable_nb object to be returned.
425 * @extcon_name: the name of extcon device. 424 * @extcon_name: the name of extcon device.
426 * if NULL, extcon_register_interest will register 425 * if NULL, extcon_register_interest will register
427 * every cable with the target cable_name given. 426 * every cable with the target cable_name given.
428 * @cable_name: the target cable name. 427 * @cable_name: the target cable name.
429 * @nb: the notifier block to get notified. 428 * @nb: the notifier block to get notified.
430 * 429 *
431 * Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets 430 * Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets
432 * the struct for you. 431 * the struct for you.
@@ -452,7 +451,8 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
452 if (!obj->edev) 451 if (!obj->edev)
453 return -ENODEV; 452 return -ENODEV;
454 453
455 obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); 454 obj->cable_index = extcon_find_cable_index(obj->edev,
455 cable_name);
456 if (obj->cable_index < 0) 456 if (obj->cable_index < 0)
457 return obj->cable_index; 457 return obj->cable_index;
458 458
@@ -460,7 +460,8 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
460 460
461 obj->internal_nb.notifier_call = _call_per_cable; 461 obj->internal_nb.notifier_call = _call_per_cable;
462 462
463 return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); 463 return raw_notifier_chain_register(&obj->edev->nh,
464 &obj->internal_nb);
464 } else { 465 } else {
465 struct class_dev_iter iter; 466 struct class_dev_iter iter;
466 struct extcon_dev *extd; 467 struct extcon_dev *extd;
@@ -470,7 +471,7 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
470 return -ENODEV; 471 return -ENODEV;
471 class_dev_iter_init(&iter, extcon_class, NULL, NULL); 472 class_dev_iter_init(&iter, extcon_class, NULL, NULL);
472 while ((dev = class_dev_iter_next(&iter))) { 473 while ((dev = class_dev_iter_next(&iter))) {
473 extd = (struct extcon_dev *)dev_get_drvdata(dev); 474 extd = dev_get_drvdata(dev);
474 475
475 if (extcon_find_cable_index(extd, cable_name) < 0) 476 if (extcon_find_cable_index(extd, cable_name) < 0)
476 continue; 477 continue;
@@ -487,7 +488,7 @@ EXPORT_SYMBOL_GPL(extcon_register_interest);
487 488
488/** 489/**
489 * extcon_unregister_interest() - Unregister the notifier registered by 490 * extcon_unregister_interest() - Unregister the notifier registered by
490 * extcon_register_interest(). 491 * extcon_register_interest().
491 * @obj: the extcon_specific_cable_nb object returned by 492 * @obj: the extcon_specific_cable_nb object returned by
492 * extcon_register_interest(). 493 * extcon_register_interest().
493 */ 494 */
@@ -502,7 +503,7 @@ EXPORT_SYMBOL_GPL(extcon_unregister_interest);
502 503
503/** 504/**
504 * extcon_register_notifier() - Register a notifiee to get notified by 505 * extcon_register_notifier() - Register a notifiee to get notified by
505 * any attach status changes from the extcon. 506 * any attach status changes from the extcon.
506 * @edev: the extcon device. 507 * @edev: the extcon device.
507 * @nb: a notifier block to be registered. 508 * @nb: a notifier block to be registered.
508 * 509 *
@@ -556,7 +557,6 @@ static int create_extcon_class(void)
556 557
557static void extcon_dev_release(struct device *dev) 558static void extcon_dev_release(struct device *dev)
558{ 559{
559 kfree(dev);
560} 560}
561 561
562static const char *muex_name = "mutually_exclusive"; 562static const char *muex_name = "mutually_exclusive";
@@ -567,14 +567,13 @@ static void dummy_sysfs_dev_release(struct device *dev)
567/** 567/**
568 * extcon_dev_register() - Register a new extcon device 568 * extcon_dev_register() - Register a new extcon device
569 * @edev : the new extcon device (should be allocated before calling) 569 * @edev : the new extcon device (should be allocated before calling)
570 * @dev : the parent device for this extcon device.
571 * 570 *
572 * Among the members of edev struct, please set the "user initializing data" 571 * Among the members of edev struct, please set the "user initializing data"
573 * in any case and set the "optional callbacks" if required. However, please 572 * in any case and set the "optional callbacks" if required. However, please
574 * do not set the values of "internal data", which are initialized by 573 * do not set the values of "internal data", which are initialized by
575 * this function. 574 * this function.
576 */ 575 */
577int extcon_dev_register(struct extcon_dev *edev, struct device *dev) 576int extcon_dev_register(struct extcon_dev *edev)
578{ 577{
579 int ret, index = 0; 578 int ret, index = 0;
580 579
@@ -594,19 +593,20 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
594 } 593 }
595 594
596 if (index > SUPPORTED_CABLE_MAX) { 595 if (index > SUPPORTED_CABLE_MAX) {
597 dev_err(edev->dev, "extcon: maximum number of supported cables exceeded.\n"); 596 dev_err(&edev->dev, "extcon: maximum number of supported cables exceeded.\n");
598 return -EINVAL; 597 return -EINVAL;
599 } 598 }
600 599
601 edev->dev = kzalloc(sizeof(struct device), GFP_KERNEL); 600 edev->dev.class = extcon_class;
602 if (!edev->dev) 601 edev->dev.release = extcon_dev_release;
603 return -ENOMEM;
604 edev->dev->parent = dev;
605 edev->dev->class = extcon_class;
606 edev->dev->release = extcon_dev_release;
607 602
608 edev->name = edev->name ? edev->name : dev_name(dev); 603 edev->name = edev->name ? edev->name : dev_name(edev->dev.parent);
609 dev_set_name(edev->dev, "%s", edev->name); 604 if (IS_ERR_OR_NULL(edev->name)) {
605 dev_err(&edev->dev,
606 "extcon device name is null\n");
607 return -EINVAL;
608 }
609 dev_set_name(&edev->dev, "%s", edev->name);
610 610
611 if (edev->max_supported) { 611 if (edev->max_supported) {
612 char buf[10]; 612 char buf[10];
@@ -714,7 +714,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
714 goto err_alloc_groups; 714 goto err_alloc_groups;
715 } 715 }
716 716
717 edev->extcon_dev_type.name = dev_name(edev->dev); 717 edev->extcon_dev_type.name = dev_name(&edev->dev);
718 edev->extcon_dev_type.release = dummy_sysfs_dev_release; 718 edev->extcon_dev_type.release = dummy_sysfs_dev_release;
719 719
720 for (index = 0; index < edev->max_supported; index++) 720 for (index = 0; index < edev->max_supported; index++)
@@ -724,25 +724,24 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
724 edev->extcon_dev_type.groups[index] = 724 edev->extcon_dev_type.groups[index] =
725 &edev->attr_g_muex; 725 &edev->attr_g_muex;
726 726
727 edev->dev->type = &edev->extcon_dev_type; 727 edev->dev.type = &edev->extcon_dev_type;
728 } 728 }
729 729
730 ret = device_register(edev->dev); 730 ret = device_register(&edev->dev);
731 if (ret) { 731 if (ret) {
732 put_device(edev->dev); 732 put_device(&edev->dev);
733 goto err_dev; 733 goto err_dev;
734 } 734 }
735#if defined(CONFIG_ANDROID) 735#if defined(CONFIG_ANDROID)
736 if (switch_class) 736 if (switch_class)
737 ret = class_compat_create_link(switch_class, edev->dev, 737 ret = class_compat_create_link(switch_class, &edev->dev, NULL);
738 NULL);
739#endif /* CONFIG_ANDROID */ 738#endif /* CONFIG_ANDROID */
740 739
741 spin_lock_init(&edev->lock); 740 spin_lock_init(&edev->lock);
742 741
743 RAW_INIT_NOTIFIER_HEAD(&edev->nh); 742 RAW_INIT_NOTIFIER_HEAD(&edev->nh);
744 743
745 dev_set_drvdata(edev->dev, edev); 744 dev_set_drvdata(&edev->dev, edev);
746 edev->state = 0; 745 edev->state = 0;
747 746
748 mutex_lock(&extcon_dev_list_lock); 747 mutex_lock(&extcon_dev_list_lock);
@@ -768,7 +767,6 @@ err_alloc_cables:
768 if (edev->max_supported) 767 if (edev->max_supported)
769 kfree(edev->cables); 768 kfree(edev->cables);
770err_sysfs_alloc: 769err_sysfs_alloc:
771 kfree(edev->dev);
772 return ret; 770 return ret;
773} 771}
774EXPORT_SYMBOL_GPL(extcon_dev_register); 772EXPORT_SYMBOL_GPL(extcon_dev_register);
@@ -788,9 +786,9 @@ void extcon_dev_unregister(struct extcon_dev *edev)
788 list_del(&edev->entry); 786 list_del(&edev->entry);
789 mutex_unlock(&extcon_dev_list_lock); 787 mutex_unlock(&extcon_dev_list_lock);
790 788
791 if (IS_ERR_OR_NULL(get_device(edev->dev))) { 789 if (IS_ERR_OR_NULL(get_device(&edev->dev))) {
792 dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n", 790 dev_err(&edev->dev, "Failed to unregister extcon_dev (%s)\n",
793 dev_name(edev->dev)); 791 dev_name(&edev->dev));
794 return; 792 return;
795 } 793 }
796 794
@@ -812,10 +810,10 @@ void extcon_dev_unregister(struct extcon_dev *edev)
812 810
813#if defined(CONFIG_ANDROID) 811#if defined(CONFIG_ANDROID)
814 if (switch_class) 812 if (switch_class)
815 class_compat_remove_link(switch_class, edev->dev, NULL); 813 class_compat_remove_link(switch_class, &edev->dev, NULL);
816#endif 814#endif
817 device_unregister(edev->dev); 815 device_unregister(&edev->dev);
818 put_device(edev->dev); 816 put_device(&edev->dev);
819} 817}
820EXPORT_SYMBOL_GPL(extcon_dev_unregister); 818EXPORT_SYMBOL_GPL(extcon_dev_unregister);
821 819
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index f874c30ddbff..7e0dff58e494 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -34,6 +34,7 @@
34struct gpio_extcon_data { 34struct gpio_extcon_data {
35 struct extcon_dev edev; 35 struct extcon_dev edev;
36 unsigned gpio; 36 unsigned gpio;
37 bool gpio_active_low;
37 const char *state_on; 38 const char *state_on;
38 const char *state_off; 39 const char *state_off;
39 int irq; 40 int irq;
@@ -49,6 +50,8 @@ static void gpio_extcon_work(struct work_struct *work)
49 work); 50 work);
50 51
51 state = gpio_get_value(data->gpio); 52 state = gpio_get_value(data->gpio);
53 if (data->gpio_active_low)
54 state = !state;
52 extcon_set_state(&data->edev, state); 55 extcon_set_state(&data->edev, state);
53} 56}
54 57
@@ -78,9 +81,9 @@ static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
78 81
79static int gpio_extcon_probe(struct platform_device *pdev) 82static int gpio_extcon_probe(struct platform_device *pdev)
80{ 83{
81 struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data; 84 struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev);
82 struct gpio_extcon_data *extcon_data; 85 struct gpio_extcon_data *extcon_data;
83 int ret = 0; 86 int ret;
84 87
85 if (!pdata) 88 if (!pdata)
86 return -EBUSY; 89 return -EBUSY;
@@ -95,14 +98,22 @@ static int gpio_extcon_probe(struct platform_device *pdev)
95 return -ENOMEM; 98 return -ENOMEM;
96 99
97 extcon_data->edev.name = pdata->name; 100 extcon_data->edev.name = pdata->name;
101 extcon_data->edev.dev.parent = &pdev->dev;
98 extcon_data->gpio = pdata->gpio; 102 extcon_data->gpio = pdata->gpio;
103 extcon_data->gpio_active_low = pdata->gpio_active_low;
99 extcon_data->state_on = pdata->state_on; 104 extcon_data->state_on = pdata->state_on;
100 extcon_data->state_off = pdata->state_off; 105 extcon_data->state_off = pdata->state_off;
101 if (pdata->state_on && pdata->state_off) 106 if (pdata->state_on && pdata->state_off)
102 extcon_data->edev.print_state = extcon_gpio_print_state; 107 extcon_data->edev.print_state = extcon_gpio_print_state;
103 extcon_data->debounce_jiffies = msecs_to_jiffies(pdata->debounce); 108 if (pdata->debounce) {
109 ret = gpio_set_debounce(extcon_data->gpio,
110 pdata->debounce * 1000);
111 if (ret < 0)
112 extcon_data->debounce_jiffies =
113 msecs_to_jiffies(pdata->debounce);
114 }
104 115
105 ret = extcon_dev_register(&extcon_data->edev, &pdev->dev); 116 ret = extcon_dev_register(&extcon_data->edev);
106 if (ret < 0) 117 if (ret < 0)
107 return ret; 118 return ret;
108 119
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index b56bdaa27d4b..da268fbc901b 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -189,14 +189,17 @@ enum max77693_muic_acc_type {
189 189
190 /* The below accessories have same ADC value so ADCLow and 190 /* The below accessories have same ADC value so ADCLow and
191 ADC1K bit is used to separate specific accessory */ 191 ADC1K bit is used to separate specific accessory */
192 MAX77693_MUIC_GND_USB_OTG = 0x100, /* ADC:0x0, VBVolot:0, ADCLow:0, ADC1K:0 */ 192 /* ADC|VBVolot|ADCLow|ADC1K| */
193 MAX77693_MUIC_GND_USB_OTG_VB = 0x104, /* ADC:0x0, VBVolot:1, ADCLow:0, ADC1K:0 */ 193 MAX77693_MUIC_GND_USB_OTG = 0x100, /* 0x0| 0| 0| 0| */
194 MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:0 */ 194 MAX77693_MUIC_GND_USB_OTG_VB = 0x104, /* 0x0| 1| 0| 0| */
195 MAX77693_MUIC_GND_MHL = 0x103, /* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:1 */ 195 MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* 0x0| 0| 1| 0| */
196 MAX77693_MUIC_GND_MHL_VB = 0x107, /* ADC:0x0, VBVolot:1, ADCLow:1, ADC1K:1 */ 196 MAX77693_MUIC_GND_MHL = 0x103, /* 0x0| 0| 1| 1| */
197 MAX77693_MUIC_GND_MHL_VB = 0x107, /* 0x0| 1| 1| 1| */
197}; 198};
198 199
199/* MAX77693 MUIC device support below list of accessories(external connector) */ 200/*
201 * MAX77693 MUIC device support below list of accessories(external connector)
202 */
200enum { 203enum {
201 EXTCON_CABLE_USB = 0, 204 EXTCON_CABLE_USB = 0,
202 EXTCON_CABLE_USB_HOST, 205 EXTCON_CABLE_USB_HOST,
@@ -395,12 +398,12 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
395 vbvolt >>= STATUS2_VBVOLT_SHIFT; 398 vbvolt >>= STATUS2_VBVOLT_SHIFT;
396 399
397 /** 400 /**
398 * [0x1][VBVolt][ADCLow][ADC1K] 401 * [0x1|VBVolt|ADCLow|ADC1K]
399 * [0x1 0 0 0 ] : USB_OTG 402 * [0x1| 0| 0| 0] USB_OTG
400 * [0x1 1 0 0 ] : USB_OTG_VB 403 * [0x1| 1| 0| 0] USB_OTG_VB
401 * [0x1 0 1 0 ] : Audio Video Cable with load 404 * [0x1| 0| 1| 0] Audio Video cable with load
402 * [0x1 0 1 1 ] : MHL without charging connector 405 * [0x1| 0| 1| 1] MHL without charging cable
403 * [0x1 1 1 1 ] : MHL with charging connector 406 * [0x1| 1| 1| 1] MHL with charging cable
404 */ 407 */
405 cable_type = ((0x1 << 8) 408 cable_type = ((0x1 << 8)
406 | (vbvolt << 2) 409 | (vbvolt << 2)
@@ -723,11 +726,11 @@ static int max77693_muic_adc_handler(struct max77693_muic_info *info)
723 if (ret < 0) 726 if (ret < 0)
724 return ret; 727 return ret;
725 break; 728 break;
726 case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON: /* DOCK_KEY_PREV */ 729 case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON: /* DOCK_KEY_PREV */
727 case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON: /* DOCK_KEY_NEXT */ 730 case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON: /* DOCK_KEY_NEXT */
728 case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON: /* DOCK_VOL_DOWN */ 731 case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON: /* DOCK_VOL_DOWN */
729 case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON: /* DOCK_VOL_UP */ 732 case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON: /* DOCK_VOL_UP */
730 case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON: /* DOCK_KEY_PLAY_PAUSE */ 733 case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON: /* DOCK_KEY_PLAY_PAUSE */
731 /* 734 /*
732 * Button of DOCK device 735 * Button of DOCK device
733 * - the Prev/Next/Volume Up/Volume Down/Play-Pause button 736 * - the Prev/Next/Volume Up/Volume Down/Play-Pause button
@@ -815,19 +818,21 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
815 case MAX77693_MUIC_GND_MHL_VB: 818 case MAX77693_MUIC_GND_MHL_VB:
816 /* 819 /*
817 * MHL cable with MHL_TA(USB/TA) cable 820 * MHL cable with MHL_TA(USB/TA) cable
818 * - MHL cable include two port(HDMI line and separate micro- 821 * - MHL cable include two port(HDMI line and separate
819 * usb port. When the target connect MHL cable, extcon driver 822 * micro-usb port. When the target connect MHL cable,
820 * check whether MHL_TA(USB/TA) cable is connected. If MHL_TA 823 * extcon driver check whether MHL_TA(USB/TA) cable is
821 * cable is connected, extcon driver notify state to notifiee 824 * connected. If MHL_TA cable is connected, extcon
822 * for charging battery. 825 * driver notify state to notifiee for charging battery.
823 * 826 *
824 * Features of 'MHL_TA(USB/TA) with MHL cable' 827 * Features of 'MHL_TA(USB/TA) with MHL cable'
825 * - Support MHL 828 * - Support MHL
826 * - Support charging through micro-usb port without data connection 829 * - Support charging through micro-usb port without
830 * data connection
827 */ 831 */
828 extcon_set_cable_state(info->edev, "MHL_TA", attached); 832 extcon_set_cable_state(info->edev, "MHL_TA", attached);
829 if (!cable_attached) 833 if (!cable_attached)
830 extcon_set_cable_state(info->edev, "MHL", cable_attached); 834 extcon_set_cable_state(info->edev,
835 "MHL", cable_attached);
831 break; 836 break;
832 } 837 }
833 838
@@ -839,47 +844,51 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
839 case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */ 844 case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */
840 /* 845 /*
841 * Dock-Audio device with USB/TA cable 846 * Dock-Audio device with USB/TA cable
842 * - Dock device include two port(Dock-Audio and micro-usb 847 * - Dock device include two port(Dock-Audio and micro-
843 * port). When the target connect Dock-Audio device, extcon 848 * usb port). When the target connect Dock-Audio device,
844 * driver check whether USB/TA cable is connected. If USB/TA 849 * extcon driver check whether USB/TA cable is connected
845 * cable is connected, extcon driver notify state to notifiee 850 * or not. If USB/TA cable is connected, extcon driver
846 * for charging battery. 851 * notify state to notifiee for charging battery.
847 * 852 *
848 * Features of 'USB/TA cable with Dock-Audio device' 853 * Features of 'USB/TA cable with Dock-Audio device'
849 * - Support external output feature of audio. 854 * - Support external output feature of audio.
850 * - Support charging through micro-usb port without data 855 * - Support charging through micro-usb port without
851 * connection. 856 * data connection.
852 */ 857 */
853 extcon_set_cable_state(info->edev, "USB", attached); 858 extcon_set_cable_state(info->edev, "USB", attached);
854 859
855 if (!cable_attached) 860 if (!cable_attached)
856 extcon_set_cable_state(info->edev, "Dock-Audio", cable_attached); 861 extcon_set_cable_state(info->edev, "Dock-Audio",
862 cable_attached);
857 break; 863 break;
858 case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */ 864 case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */
859 /* 865 /*
860 * Dock-Smart device with USB/TA cable 866 * Dock-Smart device with USB/TA cable
861 * - Dock-Desk device include three type of cable which 867 * - Dock-Desk device include three type of cable which
862 * are HDMI, USB for mouse/keyboard and micro-usb port 868 * are HDMI, USB for mouse/keyboard and micro-usb port
863 * for USB/TA cable. Dock-Smart device need always exteranl 869 * for USB/TA cable. Dock-Smart device need always
864 * power supply(USB/TA cable through micro-usb cable). Dock- 870 * exteranl power supply(USB/TA cable through micro-usb
865 * Smart device support screen output of target to separate 871 * cable). Dock-Smart device support screen output of
866 * monitor and mouse/keyboard for desktop mode. 872 * target to separate monitor and mouse/keyboard for
873 * desktop mode.
867 * 874 *
868 * Features of 'USB/TA cable with Dock-Smart device' 875 * Features of 'USB/TA cable with Dock-Smart device'
869 * - Support MHL 876 * - Support MHL
870 * - Support external output feature of audio 877 * - Support external output feature of audio
871 * - Support charging through micro-usb port without data 878 * - Support charging through micro-usb port without
872 * connection if TA cable is connected to target. 879 * data connection if TA cable is connected to target.
873 * - Support charging and data connection through micro-usb port 880 * - Support charging and data connection through micro-
874 * if USB cable is connected between target and host 881 * usb port if USB cable is connected between target
875 * device. 882 * and host device
876 * - Support OTG device (Mouse/Keyboard) 883 * - Support OTG device (Mouse/Keyboard)
877 */ 884 */
878 ret = max77693_muic_set_path(info, info->path_usb, attached); 885 ret = max77693_muic_set_path(info, info->path_usb,
886 attached);
879 if (ret < 0) 887 if (ret < 0)
880 return ret; 888 return ret;
881 889
882 extcon_set_cable_state(info->edev, "Dock-Smart", attached); 890 extcon_set_cable_state(info->edev, "Dock-Smart",
891 attached);
883 extcon_set_cable_state(info->edev, "MHL", attached); 892 extcon_set_cable_state(info->edev, "MHL", attached);
884 893
885 break; 894 break;
@@ -889,25 +898,28 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
889 switch (chg_type) { 898 switch (chg_type) {
890 case MAX77693_CHARGER_TYPE_NONE: 899 case MAX77693_CHARGER_TYPE_NONE:
891 /* 900 /*
892 * When MHL(with USB/TA cable) or Dock-Audio with USB/TA cable 901 * When MHL(with USB/TA cable) or Dock-Audio with USB/TA
893 * is attached, muic device happen below two interrupt. 902 * cable is attached, muic device happen below two irq.
894 * - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting MHL/Dock-Audio. 903 * - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting
895 * - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting USB/TA cable 904 * MHL/Dock-Audio.
896 * connected to MHL or Dock-Audio. 905 * - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting
897 * Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC interrupt 906 * USB/TA cable connected to MHL or Dock-Audio.
898 * than MAX77693_MUIC_IRQ_INT2_CHGTYP interrupt. 907 * Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC
908 * irq than MAX77693_MUIC_IRQ_INT2_CHGTYP irq.
899 * 909 *
900 * If user attach MHL (with USB/TA cable and immediately detach 910 * If user attach MHL (with USB/TA cable and immediately
901 * MHL with USB/TA cable before MAX77693_MUIC_IRQ_INT2_CHGTYP 911 * detach MHL with USB/TA cable before MAX77693_MUIC_IRQ
902 * interrupt is happened, USB/TA cable remain connected state to 912 * _INT2_CHGTYP irq is happened, USB/TA cable remain
903 * target. But USB/TA cable isn't connected to target. The user 913 * connected state to target. But USB/TA cable isn't
904 * be face with unusual action. So, driver should check this 914 * connected to target. The user be face with unusual
905 * situation in spite of, that previous charger type is N/A. 915 * action. So, driver should check this situation in
916 * spite of, that previous charger type is N/A.
906 */ 917 */
907 break; 918 break;
908 case MAX77693_CHARGER_TYPE_USB: 919 case MAX77693_CHARGER_TYPE_USB:
909 /* Only USB cable, PATH:AP_USB */ 920 /* Only USB cable, PATH:AP_USB */
910 ret = max77693_muic_set_path(info, info->path_usb, attached); 921 ret = max77693_muic_set_path(info, info->path_usb,
922 attached);
911 if (ret < 0) 923 if (ret < 0)
912 return ret; 924 return ret;
913 925
@@ -953,7 +965,7 @@ static void max77693_muic_irq_work(struct work_struct *work)
953 965
954 mutex_lock(&info->mutex); 966 mutex_lock(&info->mutex);
955 967
956 for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) 968 for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
957 if (info->irq == muic_irqs[i].virq) 969 if (info->irq == muic_irqs[i].virq)
958 irq_type = muic_irqs[i].irq; 970 irq_type = muic_irqs[i].irq;
959 971
@@ -1171,8 +1183,9 @@ static int max77693_muic_probe(struct platform_device *pdev)
1171 goto err_irq; 1183 goto err_irq;
1172 } 1184 }
1173 info->edev->name = DEV_NAME; 1185 info->edev->name = DEV_NAME;
1186 info->edev->dev.parent = &pdev->dev;
1174 info->edev->supported_cable = max77693_extcon_cable; 1187 info->edev->supported_cable = max77693_extcon_cable;
1175 ret = extcon_dev_register(info->edev, NULL); 1188 ret = extcon_dev_register(info->edev);
1176 if (ret) { 1189 if (ret) {
1177 dev_err(&pdev->dev, "failed to register extcon device\n"); 1190 dev_err(&pdev->dev, "failed to register extcon device\n");
1178 goto err_irq; 1191 goto err_irq;
@@ -1188,7 +1201,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
1188 num_init_data = ARRAY_SIZE(default_init_data); 1201 num_init_data = ARRAY_SIZE(default_init_data);
1189 } 1202 }
1190 1203
1191 for (i = 0 ; i < num_init_data ; i++) { 1204 for (i = 0; i < num_init_data; i++) {
1192 enum max77693_irq_source irq_src 1205 enum max77693_irq_source irq_src
1193 = MAX77693_IRQ_GROUP_NR; 1206 = MAX77693_IRQ_GROUP_NR;
1194 1207
@@ -1214,7 +1227,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
1214 } 1227 }
1215 1228
1216 if (pdata->muic_data) { 1229 if (pdata->muic_data) {
1217 struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; 1230 struct max77693_muic_platform_data *muic_pdata
1231 = pdata->muic_data;
1218 1232
1219 /* 1233 /*
1220 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB 1234 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index 67d6738d85a0..6a00464658c5 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -426,7 +426,8 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info)
426 break; 426 break;
427 case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: 427 case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF:
428 case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: 428 case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON:
429 ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached); 429 ret = max8997_muic_handle_usb(info,
430 MAX8997_USB_DEVICE, attached);
430 if (ret < 0) 431 if (ret < 0)
431 return ret; 432 return ret;
432 break; 433 break;
@@ -504,7 +505,8 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info)
504 } 505 }
505 break; 506 break;
506 case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: 507 case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
507 extcon_set_cable_state(info->edev, "Charge-downstream", attached); 508 extcon_set_cable_state(info->edev,
509 "Charge-downstream", attached);
508 break; 510 break;
509 case MAX8997_CHARGER_TYPE_DEDICATED_CHG: 511 case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
510 extcon_set_cable_state(info->edev, "TA", attached); 512 extcon_set_cable_state(info->edev, "TA", attached);
@@ -537,7 +539,7 @@ static void max8997_muic_irq_work(struct work_struct *work)
537 539
538 mutex_lock(&info->mutex); 540 mutex_lock(&info->mutex);
539 541
540 for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) 542 for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
541 if (info->irq == muic_irqs[i].virq) 543 if (info->irq == muic_irqs[i].virq)
542 irq_type = muic_irqs[i].irq; 544 irq_type = muic_irqs[i].irq;
543 545
@@ -705,8 +707,9 @@ static int max8997_muic_probe(struct platform_device *pdev)
705 goto err_irq; 707 goto err_irq;
706 } 708 }
707 info->edev->name = DEV_NAME; 709 info->edev->name = DEV_NAME;
710 info->edev->dev.parent = &pdev->dev;
708 info->edev->supported_cable = max8997_extcon_cable; 711 info->edev->supported_cable = max8997_extcon_cable;
709 ret = extcon_dev_register(info->edev, NULL); 712 ret = extcon_dev_register(info->edev);
710 if (ret) { 713 if (ret) {
711 dev_err(&pdev->dev, "failed to register extcon device\n"); 714 dev_err(&pdev->dev, "failed to register extcon device\n");
712 goto err_irq; 715 goto err_irq;
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index 89fdd05c5fd6..6c91976dd823 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -135,7 +135,7 @@ static void palmas_enable_irq(struct palmas_usb *palmas_usb)
135static int palmas_usb_probe(struct platform_device *pdev) 135static int palmas_usb_probe(struct platform_device *pdev)
136{ 136{
137 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); 137 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
138 struct palmas_usb_platform_data *pdata = pdev->dev.platform_data; 138 struct palmas_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
139 struct device_node *node = pdev->dev.of_node; 139 struct device_node *node = pdev->dev.of_node;
140 struct palmas_usb *palmas_usb; 140 struct palmas_usb *palmas_usb;
141 int status; 141 int status;
@@ -178,9 +178,10 @@ static int palmas_usb_probe(struct platform_device *pdev)
178 platform_set_drvdata(pdev, palmas_usb); 178 platform_set_drvdata(pdev, palmas_usb);
179 179
180 palmas_usb->edev.supported_cable = palmas_extcon_cable; 180 palmas_usb->edev.supported_cable = palmas_extcon_cable;
181 palmas_usb->edev.dev.parent = palmas_usb->dev;
181 palmas_usb->edev.mutually_exclusive = mutually_exclusive; 182 palmas_usb->edev.mutually_exclusive = mutually_exclusive;
182 183
183 status = extcon_dev_register(&palmas_usb->edev, palmas_usb->dev); 184 status = extcon_dev_register(&palmas_usb->edev);
184 if (status) { 185 if (status) {
185 dev_err(&pdev->dev, "failed to register extcon device\n"); 186 dev_err(&pdev->dev, "failed to register extcon device\n");
186 return status; 187 return status;
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 6de6c98ce6eb..cea623c36ae2 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -47,8 +47,8 @@ static void vmbus_setevent(struct vmbus_channel *channel)
47 (unsigned long *) vmbus_connection.send_int_page + 47 (unsigned long *) vmbus_connection.send_int_page +
48 (channel->offermsg.child_relid >> 5)); 48 (channel->offermsg.child_relid >> 5));
49 49
50 monitorpage = vmbus_connection.monitor_pages; 50 /* Get the child to parent monitor page */
51 monitorpage++; /* Get the child to parent monitor page */ 51 monitorpage = vmbus_connection.monitor_pages[1];
52 52
53 sync_set_bit(channel->monitor_bit, 53 sync_set_bit(channel->monitor_bit,
54 (unsigned long *)&monitorpage->trigger_group 54 (unsigned long *)&monitorpage->trigger_group
@@ -60,50 +60,6 @@ static void vmbus_setevent(struct vmbus_channel *channel)
60} 60}
61 61
62/* 62/*
63 * vmbus_get_debug_info -Retrieve various channel debug info
64 */
65void vmbus_get_debug_info(struct vmbus_channel *channel,
66 struct vmbus_channel_debug_info *debuginfo)
67{
68 struct hv_monitor_page *monitorpage;
69 u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
70 u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
71
72 debuginfo->relid = channel->offermsg.child_relid;
73 debuginfo->state = channel->state;
74 memcpy(&debuginfo->interfacetype,
75 &channel->offermsg.offer.if_type, sizeof(uuid_le));
76 memcpy(&debuginfo->interface_instance,
77 &channel->offermsg.offer.if_instance,
78 sizeof(uuid_le));
79
80 monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
81
82 debuginfo->monitorid = channel->offermsg.monitorid;
83
84 debuginfo->servermonitor_pending =
85 monitorpage->trigger_group[monitor_group].pending;
86 debuginfo->servermonitor_latency =
87 monitorpage->latency[monitor_group][monitor_offset];
88 debuginfo->servermonitor_connectionid =
89 monitorpage->parameter[monitor_group]
90 [monitor_offset].connectionid.u.id;
91
92 monitorpage++;
93
94 debuginfo->clientmonitor_pending =
95 monitorpage->trigger_group[monitor_group].pending;
96 debuginfo->clientmonitor_latency =
97 monitorpage->latency[monitor_group][monitor_offset];
98 debuginfo->clientmonitor_connectionid =
99 monitorpage->parameter[monitor_group]
100 [monitor_offset].connectionid.u.id;
101
102 hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
103 hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
104}
105
106/*
107 * vmbus_open - Open the specified channel. 63 * vmbus_open - Open the specified channel.
108 */ 64 */
109int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, 65int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
@@ -855,6 +811,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
855 if (signal) 811 if (signal)
856 vmbus_setevent(channel); 812 vmbus_setevent(channel);
857 813
858 return 0; 814 return ret;
859} 815}
860EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); 816EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index bbff5f200bef..fa920469bf10 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -203,7 +203,8 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
203 struct vmbus_channel *primary_channel; 203 struct vmbus_channel *primary_channel;
204 struct vmbus_channel_relid_released msg; 204 struct vmbus_channel_relid_released msg;
205 205
206 vmbus_device_unregister(channel->device_obj); 206 if (channel->device_obj)
207 vmbus_device_unregister(channel->device_obj);
207 memset(&msg, 0, sizeof(struct vmbus_channel_relid_released)); 208 memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
208 msg.child_relid = channel->offermsg.child_relid; 209 msg.child_relid = channel->offermsg.child_relid;
209 msg.header.msgtype = CHANNELMSG_RELID_RELEASED; 210 msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
@@ -216,7 +217,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
216 } else { 217 } else {
217 primary_channel = channel->primary_channel; 218 primary_channel = channel->primary_channel;
218 spin_lock_irqsave(&primary_channel->sc_lock, flags); 219 spin_lock_irqsave(&primary_channel->sc_lock, flags);
219 list_del(&channel->listentry); 220 list_del(&channel->sc_list);
220 spin_unlock_irqrestore(&primary_channel->sc_lock, flags); 221 spin_unlock_irqrestore(&primary_channel->sc_lock, flags);
221 } 222 }
222 free_channel(channel); 223 free_channel(channel);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 936093e0271e..af6edf9b1936 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -76,10 +76,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
76 msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT; 76 msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
77 msg->vmbus_version_requested = version; 77 msg->vmbus_version_requested = version;
78 msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); 78 msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
79 msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages); 79 msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
80 msg->monitor_page2 = virt_to_phys( 80 msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
81 (void *)((unsigned long)vmbus_connection.monitor_pages +
82 PAGE_SIZE));
83 81
84 /* 82 /*
85 * Add to list before we send the request since we may 83 * Add to list before we send the request since we may
@@ -169,9 +167,10 @@ int vmbus_connect(void)
169 * Setup the monitor notification facility. The 1st page for 167 * Setup the monitor notification facility. The 1st page for
170 * parent->child and the 2nd page for child->parent 168 * parent->child and the 2nd page for child->parent
171 */ 169 */
172 vmbus_connection.monitor_pages = 170 vmbus_connection.monitor_pages[0] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
173 (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1); 171 vmbus_connection.monitor_pages[1] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
174 if (vmbus_connection.monitor_pages == NULL) { 172 if ((vmbus_connection.monitor_pages[0] == NULL) ||
173 (vmbus_connection.monitor_pages[1] == NULL)) {
175 ret = -ENOMEM; 174 ret = -ENOMEM;
176 goto cleanup; 175 goto cleanup;
177 } 176 }
@@ -229,10 +228,10 @@ cleanup:
229 vmbus_connection.int_page = NULL; 228 vmbus_connection.int_page = NULL;
230 } 229 }
231 230
232 if (vmbus_connection.monitor_pages) { 231 free_pages((unsigned long)vmbus_connection.monitor_pages[0], 1);
233 free_pages((unsigned long)vmbus_connection.monitor_pages, 1); 232 free_pages((unsigned long)vmbus_connection.monitor_pages[1], 1);
234 vmbus_connection.monitor_pages = NULL; 233 vmbus_connection.monitor_pages[0] = NULL;
235 } 234 vmbus_connection.monitor_pages[1] = NULL;
236 235
237 kfree(msginfo); 236 kfree(msginfo);
238 237
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 88f4096fa078..f0c5e07c25ec 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -304,7 +304,7 @@ err:
304void hv_synic_free_cpu(int cpu) 304void hv_synic_free_cpu(int cpu)
305{ 305{
306 kfree(hv_context.event_dpc[cpu]); 306 kfree(hv_context.event_dpc[cpu]);
307 if (hv_context.synic_message_page[cpu]) 307 if (hv_context.synic_event_page[cpu])
308 free_page((unsigned long)hv_context.synic_event_page[cpu]); 308 free_page((unsigned long)hv_context.synic_event_page[cpu]);
309 if (hv_context.synic_message_page[cpu]) 309 if (hv_context.synic_message_page[cpu])
310 free_page((unsigned long)hv_context.synic_message_page[cpu]); 310 free_page((unsigned long)hv_context.synic_message_page[cpu]);
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 273e3ddb3a20..62dfd246b948 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -97,7 +97,7 @@ static void shutdown_onchannelcallback(void *context)
97 struct vmbus_channel *channel = context; 97 struct vmbus_channel *channel = context;
98 u32 recvlen; 98 u32 recvlen;
99 u64 requestid; 99 u64 requestid;
100 u8 execute_shutdown = false; 100 bool execute_shutdown = false;
101 u8 *shut_txf_buf = util_shutdown.recv_buffer; 101 u8 *shut_txf_buf = util_shutdown.recv_buffer;
102 102
103 struct shutdown_msg_data *shutdown_msg; 103 struct shutdown_msg_data *shutdown_msg;
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index d84918fe19ab..e05517616a06 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -514,6 +514,13 @@ struct hv_context {
514 514
515extern struct hv_context hv_context; 515extern struct hv_context hv_context;
516 516
517struct hv_ring_buffer_debug_info {
518 u32 current_interrupt_mask;
519 u32 current_read_index;
520 u32 current_write_index;
521 u32 bytes_avail_toread;
522 u32 bytes_avail_towrite;
523};
517 524
518/* Hv Interface */ 525/* Hv Interface */
519 526
@@ -612,7 +619,7 @@ struct vmbus_connection {
612 * 2 pages - 1st page for parent->child notification and 2nd 619 * 2 pages - 1st page for parent->child notification and 2nd
613 * is child->parent notification 620 * is child->parent notification
614 */ 621 */
615 void *monitor_pages; 622 struct hv_monitor_page *monitor_pages[2];
616 struct list_head chn_msg_list; 623 struct list_head chn_msg_list;
617 spinlock_t channelmsg_lock; 624 spinlock_t channelmsg_lock;
618 625
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f9fe46f52cfa..48aad4faea06 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -46,24 +46,6 @@ static struct tasklet_struct msg_dpc;
46static struct completion probe_event; 46static struct completion probe_event;
47static int irq; 47static int irq;
48 48
49struct hv_device_info {
50 u32 chn_id;
51 u32 chn_state;
52 uuid_le chn_type;
53 uuid_le chn_instance;
54
55 u32 monitor_id;
56 u32 server_monitor_pending;
57 u32 server_monitor_latency;
58 u32 server_monitor_conn_id;
59 u32 client_monitor_pending;
60 u32 client_monitor_latency;
61 u32 client_monitor_conn_id;
62
63 struct hv_dev_port_info inbound;
64 struct hv_dev_port_info outbound;
65};
66
67static int vmbus_exists(void) 49static int vmbus_exists(void)
68{ 50{
69 if (hv_acpi_dev == NULL) 51 if (hv_acpi_dev == NULL)
@@ -72,169 +54,361 @@ static int vmbus_exists(void)
72 return 0; 54 return 0;
73} 55}
74 56
57#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
58static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
59{
60 int i;
61 for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
62 sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
63}
75 64
76static void get_channel_info(struct hv_device *device, 65static u8 channel_monitor_group(struct vmbus_channel *channel)
77 struct hv_device_info *info)
78{ 66{
79 struct vmbus_channel_debug_info debug_info; 67 return (u8)channel->offermsg.monitorid / 32;
68}
80 69
81 if (!device->channel) 70static u8 channel_monitor_offset(struct vmbus_channel *channel)
82 return; 71{
72 return (u8)channel->offermsg.monitorid % 32;
73}
83 74
84 vmbus_get_debug_info(device->channel, &debug_info); 75static u32 channel_pending(struct vmbus_channel *channel,
76 struct hv_monitor_page *monitor_page)
77{
78 u8 monitor_group = channel_monitor_group(channel);
79 return monitor_page->trigger_group[monitor_group].pending;
80}
85 81
86 info->chn_id = debug_info.relid; 82static u32 channel_latency(struct vmbus_channel *channel,
87 info->chn_state = debug_info.state; 83 struct hv_monitor_page *monitor_page)
88 memcpy(&info->chn_type, &debug_info.interfacetype, 84{
89 sizeof(uuid_le)); 85 u8 monitor_group = channel_monitor_group(channel);
90 memcpy(&info->chn_instance, &debug_info.interface_instance, 86 u8 monitor_offset = channel_monitor_offset(channel);
91 sizeof(uuid_le)); 87 return monitor_page->latency[monitor_group][monitor_offset];
88}
92 89
93 info->monitor_id = debug_info.monitorid; 90static u32 channel_conn_id(struct vmbus_channel *channel,
91 struct hv_monitor_page *monitor_page)
92{
93 u8 monitor_group = channel_monitor_group(channel);
94 u8 monitor_offset = channel_monitor_offset(channel);
95 return monitor_page->parameter[monitor_group][monitor_offset].connectionid.u.id;
96}
94 97
95 info->server_monitor_pending = debug_info.servermonitor_pending; 98static ssize_t id_show(struct device *dev, struct device_attribute *dev_attr,
96 info->server_monitor_latency = debug_info.servermonitor_latency; 99 char *buf)
97 info->server_monitor_conn_id = debug_info.servermonitor_connectionid; 100{
101 struct hv_device *hv_dev = device_to_hv_device(dev);
98 102
99 info->client_monitor_pending = debug_info.clientmonitor_pending; 103 if (!hv_dev->channel)
100 info->client_monitor_latency = debug_info.clientmonitor_latency; 104 return -ENODEV;
101 info->client_monitor_conn_id = debug_info.clientmonitor_connectionid; 105 return sprintf(buf, "%d\n", hv_dev->channel->offermsg.child_relid);
106}
107static DEVICE_ATTR_RO(id);
102 108
103 info->inbound.int_mask = debug_info.inbound.current_interrupt_mask; 109static ssize_t state_show(struct device *dev, struct device_attribute *dev_attr,
104 info->inbound.read_idx = debug_info.inbound.current_read_index; 110 char *buf)
105 info->inbound.write_idx = debug_info.inbound.current_write_index; 111{
106 info->inbound.bytes_avail_toread = 112 struct hv_device *hv_dev = device_to_hv_device(dev);
107 debug_info.inbound.bytes_avail_toread;
108 info->inbound.bytes_avail_towrite =
109 debug_info.inbound.bytes_avail_towrite;
110 113
111 info->outbound.int_mask = 114 if (!hv_dev->channel)
112 debug_info.outbound.current_interrupt_mask; 115 return -ENODEV;
113 info->outbound.read_idx = debug_info.outbound.current_read_index; 116 return sprintf(buf, "%d\n", hv_dev->channel->state);
114 info->outbound.write_idx = debug_info.outbound.current_write_index;
115 info->outbound.bytes_avail_toread =
116 debug_info.outbound.bytes_avail_toread;
117 info->outbound.bytes_avail_towrite =
118 debug_info.outbound.bytes_avail_towrite;
119} 117}
118static DEVICE_ATTR_RO(state);
120 119
121#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2) 120static ssize_t monitor_id_show(struct device *dev,
122static void print_alias_name(struct hv_device *hv_dev, char *alias_name) 121 struct device_attribute *dev_attr, char *buf)
123{ 122{
124 int i; 123 struct hv_device *hv_dev = device_to_hv_device(dev);
125 for (i = 0; i < VMBUS_ALIAS_LEN; i += 2) 124
126 sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]); 125 if (!hv_dev->channel)
126 return -ENODEV;
127 return sprintf(buf, "%d\n", hv_dev->channel->offermsg.monitorid);
127} 128}
129static DEVICE_ATTR_RO(monitor_id);
128 130
129/* 131static ssize_t class_id_show(struct device *dev,
130 * vmbus_show_device_attr - Show the device attribute in sysfs. 132 struct device_attribute *dev_attr, char *buf)
131 * 133{
132 * This is invoked when user does a 134 struct hv_device *hv_dev = device_to_hv_device(dev);
133 * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>" 135
134 */ 136 if (!hv_dev->channel)
135static ssize_t vmbus_show_device_attr(struct device *dev, 137 return -ENODEV;
136 struct device_attribute *dev_attr, 138 return sprintf(buf, "{%pUl}\n",
137 char *buf) 139 hv_dev->channel->offermsg.offer.if_type.b);
140}
141static DEVICE_ATTR_RO(class_id);
142
143static ssize_t device_id_show(struct device *dev,
144 struct device_attribute *dev_attr, char *buf)
145{
146 struct hv_device *hv_dev = device_to_hv_device(dev);
147
148 if (!hv_dev->channel)
149 return -ENODEV;
150 return sprintf(buf, "{%pUl}\n",
151 hv_dev->channel->offermsg.offer.if_instance.b);
152}
153static DEVICE_ATTR_RO(device_id);
154
155static ssize_t modalias_show(struct device *dev,
156 struct device_attribute *dev_attr, char *buf)
138{ 157{
139 struct hv_device *hv_dev = device_to_hv_device(dev); 158 struct hv_device *hv_dev = device_to_hv_device(dev);
140 struct hv_device_info *device_info;
141 char alias_name[VMBUS_ALIAS_LEN + 1]; 159 char alias_name[VMBUS_ALIAS_LEN + 1];
142 int ret = 0;
143 160
144 device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL); 161 print_alias_name(hv_dev, alias_name);
145 if (!device_info) 162 return sprintf(buf, "vmbus:%s\n", alias_name);
146 return ret; 163}
164static DEVICE_ATTR_RO(modalias);
147 165
148 get_channel_info(hv_dev, device_info); 166static ssize_t server_monitor_pending_show(struct device *dev,
149 167 struct device_attribute *dev_attr,
150 if (!strcmp(dev_attr->attr.name, "class_id")) { 168 char *buf)
151 ret = sprintf(buf, "{%pUl}\n", device_info->chn_type.b); 169{
152 } else if (!strcmp(dev_attr->attr.name, "device_id")) { 170 struct hv_device *hv_dev = device_to_hv_device(dev);
153 ret = sprintf(buf, "{%pUl}\n", device_info->chn_instance.b);
154 } else if (!strcmp(dev_attr->attr.name, "modalias")) {
155 print_alias_name(hv_dev, alias_name);
156 ret = sprintf(buf, "vmbus:%s\n", alias_name);
157 } else if (!strcmp(dev_attr->attr.name, "state")) {
158 ret = sprintf(buf, "%d\n", device_info->chn_state);
159 } else if (!strcmp(dev_attr->attr.name, "id")) {
160 ret = sprintf(buf, "%d\n", device_info->chn_id);
161 } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
162 ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
163 } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
164 ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
165 } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
166 ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
167 } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
168 ret = sprintf(buf, "%d\n",
169 device_info->outbound.bytes_avail_toread);
170 } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
171 ret = sprintf(buf, "%d\n",
172 device_info->outbound.bytes_avail_towrite);
173 } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
174 ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
175 } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
176 ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
177 } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
178 ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
179 } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
180 ret = sprintf(buf, "%d\n",
181 device_info->inbound.bytes_avail_toread);
182 } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
183 ret = sprintf(buf, "%d\n",
184 device_info->inbound.bytes_avail_towrite);
185 } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
186 ret = sprintf(buf, "%d\n", device_info->monitor_id);
187 } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
188 ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
189 } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
190 ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
191 } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
192 ret = sprintf(buf, "%d\n",
193 device_info->server_monitor_conn_id);
194 } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
195 ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
196 } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
197 ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
198 } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
199 ret = sprintf(buf, "%d\n",
200 device_info->client_monitor_conn_id);
201 }
202 171
203 kfree(device_info); 172 if (!hv_dev->channel)
204 return ret; 173 return -ENODEV;
174 return sprintf(buf, "%d\n",
175 channel_pending(hv_dev->channel,
176 vmbus_connection.monitor_pages[1]));
177}
178static DEVICE_ATTR_RO(server_monitor_pending);
179
180static ssize_t client_monitor_pending_show(struct device *dev,
181 struct device_attribute *dev_attr,
182 char *buf)
183{
184 struct hv_device *hv_dev = device_to_hv_device(dev);
185
186 if (!hv_dev->channel)
187 return -ENODEV;
188 return sprintf(buf, "%d\n",
189 channel_pending(hv_dev->channel,
190 vmbus_connection.monitor_pages[1]));
191}
192static DEVICE_ATTR_RO(client_monitor_pending);
193
194static ssize_t server_monitor_latency_show(struct device *dev,
195 struct device_attribute *dev_attr,
196 char *buf)
197{
198 struct hv_device *hv_dev = device_to_hv_device(dev);
199
200 if (!hv_dev->channel)
201 return -ENODEV;
202 return sprintf(buf, "%d\n",
203 channel_latency(hv_dev->channel,
204 vmbus_connection.monitor_pages[0]));
205}
206static DEVICE_ATTR_RO(server_monitor_latency);
207
208static ssize_t client_monitor_latency_show(struct device *dev,
209 struct device_attribute *dev_attr,
210 char *buf)
211{
212 struct hv_device *hv_dev = device_to_hv_device(dev);
213
214 if (!hv_dev->channel)
215 return -ENODEV;
216 return sprintf(buf, "%d\n",
217 channel_latency(hv_dev->channel,
218 vmbus_connection.monitor_pages[1]));
219}
220static DEVICE_ATTR_RO(client_monitor_latency);
221
222static ssize_t server_monitor_conn_id_show(struct device *dev,
223 struct device_attribute *dev_attr,
224 char *buf)
225{
226 struct hv_device *hv_dev = device_to_hv_device(dev);
227
228 if (!hv_dev->channel)
229 return -ENODEV;
230 return sprintf(buf, "%d\n",
231 channel_conn_id(hv_dev->channel,
232 vmbus_connection.monitor_pages[0]));
233}
234static DEVICE_ATTR_RO(server_monitor_conn_id);
235
236static ssize_t client_monitor_conn_id_show(struct device *dev,
237 struct device_attribute *dev_attr,
238 char *buf)
239{
240 struct hv_device *hv_dev = device_to_hv_device(dev);
241
242 if (!hv_dev->channel)
243 return -ENODEV;
244 return sprintf(buf, "%d\n",
245 channel_conn_id(hv_dev->channel,
246 vmbus_connection.monitor_pages[1]));
247}
248static DEVICE_ATTR_RO(client_monitor_conn_id);
249
250static ssize_t out_intr_mask_show(struct device *dev,
251 struct device_attribute *dev_attr, char *buf)
252{
253 struct hv_device *hv_dev = device_to_hv_device(dev);
254 struct hv_ring_buffer_debug_info outbound;
255
256 if (!hv_dev->channel)
257 return -ENODEV;
258 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
259 return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
260}
261static DEVICE_ATTR_RO(out_intr_mask);
262
263static ssize_t out_read_index_show(struct device *dev,
264 struct device_attribute *dev_attr, char *buf)
265{
266 struct hv_device *hv_dev = device_to_hv_device(dev);
267 struct hv_ring_buffer_debug_info outbound;
268
269 if (!hv_dev->channel)
270 return -ENODEV;
271 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
272 return sprintf(buf, "%d\n", outbound.current_read_index);
273}
274static DEVICE_ATTR_RO(out_read_index);
275
276static ssize_t out_write_index_show(struct device *dev,
277 struct device_attribute *dev_attr,
278 char *buf)
279{
280 struct hv_device *hv_dev = device_to_hv_device(dev);
281 struct hv_ring_buffer_debug_info outbound;
282
283 if (!hv_dev->channel)
284 return -ENODEV;
285 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
286 return sprintf(buf, "%d\n", outbound.current_write_index);
287}
288static DEVICE_ATTR_RO(out_write_index);
289
290static ssize_t out_read_bytes_avail_show(struct device *dev,
291 struct device_attribute *dev_attr,
292 char *buf)
293{
294 struct hv_device *hv_dev = device_to_hv_device(dev);
295 struct hv_ring_buffer_debug_info outbound;
296
297 if (!hv_dev->channel)
298 return -ENODEV;
299 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
300 return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
205} 301}
302static DEVICE_ATTR_RO(out_read_bytes_avail);
303
304static ssize_t out_write_bytes_avail_show(struct device *dev,
305 struct device_attribute *dev_attr,
306 char *buf)
307{
308 struct hv_device *hv_dev = device_to_hv_device(dev);
309 struct hv_ring_buffer_debug_info outbound;
310
311 if (!hv_dev->channel)
312 return -ENODEV;
313 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
314 return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
315}
316static DEVICE_ATTR_RO(out_write_bytes_avail);
317
318static ssize_t in_intr_mask_show(struct device *dev,
319 struct device_attribute *dev_attr, char *buf)
320{
321 struct hv_device *hv_dev = device_to_hv_device(dev);
322 struct hv_ring_buffer_debug_info inbound;
323
324 if (!hv_dev->channel)
325 return -ENODEV;
326 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
327 return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
328}
329static DEVICE_ATTR_RO(in_intr_mask);
330
331static ssize_t in_read_index_show(struct device *dev,
332 struct device_attribute *dev_attr, char *buf)
333{
334 struct hv_device *hv_dev = device_to_hv_device(dev);
335 struct hv_ring_buffer_debug_info inbound;
336
337 if (!hv_dev->channel)
338 return -ENODEV;
339 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
340 return sprintf(buf, "%d\n", inbound.current_read_index);
341}
342static DEVICE_ATTR_RO(in_read_index);
343
344static ssize_t in_write_index_show(struct device *dev,
345 struct device_attribute *dev_attr, char *buf)
346{
347 struct hv_device *hv_dev = device_to_hv_device(dev);
348 struct hv_ring_buffer_debug_info inbound;
349
350 if (!hv_dev->channel)
351 return -ENODEV;
352 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
353 return sprintf(buf, "%d\n", inbound.current_write_index);
354}
355static DEVICE_ATTR_RO(in_write_index);
356
357static ssize_t in_read_bytes_avail_show(struct device *dev,
358 struct device_attribute *dev_attr,
359 char *buf)
360{
361 struct hv_device *hv_dev = device_to_hv_device(dev);
362 struct hv_ring_buffer_debug_info inbound;
363
364 if (!hv_dev->channel)
365 return -ENODEV;
366 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
367 return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
368}
369static DEVICE_ATTR_RO(in_read_bytes_avail);
370
371static ssize_t in_write_bytes_avail_show(struct device *dev,
372 struct device_attribute *dev_attr,
373 char *buf)
374{
375 struct hv_device *hv_dev = device_to_hv_device(dev);
376 struct hv_ring_buffer_debug_info inbound;
377
378 if (!hv_dev->channel)
379 return -ENODEV;
380 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
381 return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
382}
383static DEVICE_ATTR_RO(in_write_bytes_avail);
206 384
207/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */ 385/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
208static struct device_attribute vmbus_device_attrs[] = { 386static struct attribute *vmbus_attrs[] = {
209 __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL), 387 &dev_attr_id.attr,
210 __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL), 388 &dev_attr_state.attr,
211 __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL), 389 &dev_attr_monitor_id.attr,
212 __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL), 390 &dev_attr_class_id.attr,
213 __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL), 391 &dev_attr_device_id.attr,
214 __ATTR(modalias, S_IRUGO, vmbus_show_device_attr, NULL), 392 &dev_attr_modalias.attr,
215 393 &dev_attr_server_monitor_pending.attr,
216 __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL), 394 &dev_attr_client_monitor_pending.attr,
217 __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL), 395 &dev_attr_server_monitor_latency.attr,
218 __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL), 396 &dev_attr_client_monitor_latency.attr,
219 397 &dev_attr_server_monitor_conn_id.attr,
220 __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL), 398 &dev_attr_client_monitor_conn_id.attr,
221 __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL), 399 &dev_attr_out_intr_mask.attr,
222 __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL), 400 &dev_attr_out_read_index.attr,
223 401 &dev_attr_out_write_index.attr,
224 __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL), 402 &dev_attr_out_read_bytes_avail.attr,
225 __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL), 403 &dev_attr_out_write_bytes_avail.attr,
226 __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL), 404 &dev_attr_in_intr_mask.attr,
227 __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL), 405 &dev_attr_in_read_index.attr,
228 __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL), 406 &dev_attr_in_write_index.attr,
229 407 &dev_attr_in_read_bytes_avail.attr,
230 __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL), 408 &dev_attr_in_write_bytes_avail.attr,
231 __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL), 409 NULL,
232 __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
233 __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
234 __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
235 __ATTR_NULL
236}; 410};
237 411ATTRIBUTE_GROUPS(vmbus);
238 412
239/* 413/*
240 * vmbus_uevent - add uevent for our device 414 * vmbus_uevent - add uevent for our device
@@ -383,7 +557,7 @@ static struct bus_type hv_bus = {
383 .remove = vmbus_remove, 557 .remove = vmbus_remove,
384 .probe = vmbus_probe, 558 .probe = vmbus_probe,
385 .uevent = vmbus_uevent, 559 .uevent = vmbus_uevent,
386 .dev_attrs = vmbus_device_attrs, 560 .dev_groups = vmbus_groups,
387}; 561};
388 562
389static const char *driver_name = "hyperv"; 563static const char *driver_name = "hyperv";
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8dacd4c9ee87..e760715bd9cb 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -537,4 +537,5 @@ source "drivers/misc/carma/Kconfig"
537source "drivers/misc/altera-stapl/Kconfig" 537source "drivers/misc/altera-stapl/Kconfig"
538source "drivers/misc/mei/Kconfig" 538source "drivers/misc/mei/Kconfig"
539source "drivers/misc/vmw_vmci/Kconfig" 539source "drivers/misc/vmw_vmci/Kconfig"
540source "drivers/misc/mic/Kconfig"
540endmenu 541endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c235d5b68311..0b7ea3ea8bb8 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/
53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ 53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o 54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
55obj-$(CONFIG_SRAM) += sram.o 55obj-$(CONFIG_SRAM) += sram.o
56obj-y += mic/
diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c
index 1256a4bf1c04..b7ebf8021d99 100644
--- a/drivers/misc/arm-charlcd.c
+++ b/drivers/misc/arm-charlcd.c
@@ -297,7 +297,7 @@ static int __init charlcd_probe(struct platform_device *pdev)
297 lcd->irq = platform_get_irq(pdev, 0); 297 lcd->irq = platform_get_irq(pdev, 0);
298 /* If no IRQ is supplied, we'll survive without it */ 298 /* If no IRQ is supplied, we'll survive without it */
299 if (lcd->irq >= 0) { 299 if (lcd->irq >= 0) {
300 if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED, 300 if (request_irq(lcd->irq, charlcd_interrupt, 0,
301 DRIVERNAME, lcd)) { 301 DRIVERNAME, lcd)) {
302 ret = -EIO; 302 ret = -EIO;
303 goto out_no_irq; 303 goto out_no_irq;
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
index 494d0500bda6..a6dc56e1bc58 100644
--- a/drivers/misc/atmel_pwm.c
+++ b/drivers/misc/atmel_pwm.c
@@ -90,8 +90,10 @@ int pwm_channel_alloc(int index, struct pwm_channel *ch)
90 unsigned long flags; 90 unsigned long flags;
91 int status = 0; 91 int status = 0;
92 92
93 /* insist on PWM init, with this signal pinned out */ 93 if (!pwm)
94 if (!pwm || !(pwm->mask & 1 << index)) 94 return -EPROBE_DEFER;
95
96 if (!(pwm->mask & 1 << index))
95 return -ENODEV; 97 return -ENODEV;
96 98
97 if (index < 0 || index >= PWM_NCHAN || !ch) 99 if (index < 0 || index >= PWM_NCHAN || !ch)
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index 057580e026c0..48ea33d15a79 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/of.h>
26 27
27#define BH1780_REG_CONTROL 0x80 28#define BH1780_REG_CONTROL 0x80
28#define BH1780_REG_PARTID 0x8A 29#define BH1780_REG_PARTID 0x8A
@@ -244,6 +245,15 @@ static const struct i2c_device_id bh1780_id[] = {
244 { }, 245 { },
245}; 246};
246 247
248#ifdef CONFIG_OF
249static const struct of_device_id of_bh1780_match[] = {
250 { .compatible = "rohm,bh1780gli", },
251 {},
252};
253
254MODULE_DEVICE_TABLE(of, of_bh1780_match);
255#endif
256
247static struct i2c_driver bh1780_driver = { 257static struct i2c_driver bh1780_driver = {
248 .probe = bh1780_probe, 258 .probe = bh1780_probe,
249 .remove = bh1780_remove, 259 .remove = bh1780_remove,
@@ -251,6 +261,7 @@ static struct i2c_driver bh1780_driver = {
251 .driver = { 261 .driver = {
252 .name = "bh1780", 262 .name = "bh1780",
253 .pm = &bh1780_pm, 263 .pm = &bh1780_pm,
264 .of_match_table = of_match_ptr(of_bh1780_match),
254 }, 265 },
255}; 266};
256 267
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
index 849e2fed4da2..2704d885a9b3 100644
--- a/drivers/misc/bmp085.c
+++ b/drivers/misc/bmp085.c
@@ -374,7 +374,7 @@ int bmp085_detect(struct device *dev)
374} 374}
375EXPORT_SYMBOL_GPL(bmp085_detect); 375EXPORT_SYMBOL_GPL(bmp085_detect);
376 376
377static void __init bmp085_get_of_properties(struct bmp085_data *data) 377static void bmp085_get_of_properties(struct bmp085_data *data)
378{ 378{
379#ifdef CONFIG_OF 379#ifdef CONFIG_OF
380 struct device_node *np = data->dev->of_node; 380 struct device_node *np = data->dev->of_node;
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 2e50f811ff59..fb397e7d1cce 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -176,7 +176,7 @@ static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
176{ 176{
177 struct cb710_chip *chip = pci_get_drvdata(pdev); 177 struct cb710_chip *chip = pci_get_drvdata(pdev);
178 178
179 free_irq(pdev->irq, chip); 179 devm_free_irq(&pdev->dev, pdev->irq, chip);
180 pci_save_state(pdev); 180 pci_save_state(pdev);
181 pci_disable_device(pdev); 181 pci_disable_device(pdev);
182 if (state.event & PM_EVENT_SLEEP) 182 if (state.event & PM_EVENT_SLEEP)
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index 04f2e1fa9dd1..9536852fd4c6 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -96,4 +96,17 @@ config EEPROM_DIGSY_MTC_CFG
96 96
97 If unsure, say N. 97 If unsure, say N.
98 98
99config EEPROM_SUNXI_SID
100 tristate "Allwinner sunxi security ID support"
101 depends on ARCH_SUNXI && SYSFS
102 help
103 This is a driver for the 'security ID' available on various Allwinner
104 devices.
105
106 Due to the potential risks involved with changing e-fuses,
107 this driver is read-only.
108
109 This driver can also be built as a module. If so, the module
110 will be called sunxi_sid.
111
99endmenu 112endmenu
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
index fc1e81d29267..9507aec95e94 100644
--- a/drivers/misc/eeprom/Makefile
+++ b/drivers/misc/eeprom/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
4obj-$(CONFIG_EEPROM_MAX6875) += max6875.o 4obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
5obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o 5obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
6obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o 6obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o
7obj-$(CONFIG_EEPROM_SUNXI_SID) += sunxi_sid.o
7obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o 8obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 5d4fd69d04ca..94b8a3324319 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -428,6 +428,9 @@ static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
428{ 428{
429 struct at24_data *at24; 429 struct at24_data *at24;
430 430
431 if (unlikely(off >= attr->size))
432 return -EFBIG;
433
431 at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); 434 at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
432 return at24_write(at24, buf, off, count); 435 return at24_write(at24, buf, off, count);
433} 436}
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 840b3594a5ae..4f3bca1003a1 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -462,10 +462,17 @@ static int at25_remove(struct spi_device *spi)
462 462
463/*-------------------------------------------------------------------------*/ 463/*-------------------------------------------------------------------------*/
464 464
465static const struct of_device_id at25_of_match[] = {
466 { .compatible = "atmel,at25", },
467 { }
468};
469MODULE_DEVICE_TABLE(of, at25_of_match);
470
465static struct spi_driver at25_driver = { 471static struct spi_driver at25_driver = {
466 .driver = { 472 .driver = {
467 .name = "at25", 473 .name = "at25",
468 .owner = THIS_MODULE, 474 .owner = THIS_MODULE,
475 .of_match_table = at25_of_match,
469 }, 476 },
470 .probe = at25_probe, 477 .probe = at25_probe,
471 .remove = at25_remove, 478 .remove = at25_remove,
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c
index 94cfc1212577..3a015abb444a 100644
--- a/drivers/misc/eeprom/eeprom_93xx46.c
+++ b/drivers/misc/eeprom/eeprom_93xx46.c
@@ -202,7 +202,7 @@ eeprom_93xx46_bin_write(struct file *filp, struct kobject *kobj,
202 edev = dev_get_drvdata(dev); 202 edev = dev_get_drvdata(dev);
203 203
204 if (unlikely(off >= edev->bin.size)) 204 if (unlikely(off >= edev->bin.size))
205 return 0; 205 return -EFBIG;
206 if ((off + count) > edev->bin.size) 206 if ((off + count) > edev->bin.size)
207 count = edev->bin.size - off; 207 count = edev->bin.size - off;
208 if (unlikely(!count)) 208 if (unlikely(!count))
diff --git a/drivers/misc/eeprom/sunxi_sid.c b/drivers/misc/eeprom/sunxi_sid.c
new file mode 100644
index 000000000000..9c34e5704304
--- /dev/null
+++ b/drivers/misc/eeprom/sunxi_sid.c
@@ -0,0 +1,158 @@
1/*
2 * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl>
3 * http://www.linux-sunxi.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This driver exposes the Allwinner security ID, efuses exported in byte-
16 * sized chunks.
17 */
18
19#include <linux/compiler.h>
20#include <linux/device.h>
21#include <linux/err.h>
22#include <linux/export.h>
23#include <linux/fs.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/kernel.h>
27#include <linux/kobject.h>
28#include <linux/module.h>
29#include <linux/of_device.h>
30#include <linux/platform_device.h>
31#include <linux/random.h>
32#include <linux/slab.h>
33#include <linux/stat.h>
34#include <linux/sysfs.h>
35#include <linux/types.h>
36
37#define DRV_NAME "sunxi-sid"
38
39struct sunxi_sid_data {
40 void __iomem *reg_base;
41 unsigned int keysize;
42};
43
44/* We read the entire key, due to a 32 bit read alignment requirement. Since we
45 * want to return the requested byte, this results in somewhat slower code and
46 * uses 4 times more reads as needed but keeps code simpler. Since the SID is
47 * only very rarely probed, this is not really an issue.
48 */
49static u8 sunxi_sid_read_byte(const struct sunxi_sid_data *sid_data,
50 const unsigned int offset)
51{
52 u32 sid_key;
53
54 if (offset >= sid_data->keysize)
55 return 0;
56
57 sid_key = ioread32be(sid_data->reg_base + round_down(offset, 4));
58 sid_key >>= (offset % 4) * 8;
59
60 return sid_key; /* Only return the last byte */
61}
62
63static ssize_t sid_read(struct file *fd, struct kobject *kobj,
64 struct bin_attribute *attr, char *buf,
65 loff_t pos, size_t size)
66{
67 struct platform_device *pdev;
68 struct sunxi_sid_data *sid_data;
69 int i;
70
71 pdev = to_platform_device(kobj_to_dev(kobj));
72 sid_data = platform_get_drvdata(pdev);
73
74 if (pos < 0 || pos >= sid_data->keysize)
75 return 0;
76 if (size > sid_data->keysize - pos)
77 size = sid_data->keysize - pos;
78
79 for (i = 0; i < size; i++)
80 buf[i] = sunxi_sid_read_byte(sid_data, pos + i);
81
82 return i;
83}
84
85static struct bin_attribute sid_bin_attr = {
86 .attr = { .name = "eeprom", .mode = S_IRUGO, },
87 .read = sid_read,
88};
89
90static int sunxi_sid_remove(struct platform_device *pdev)
91{
92 device_remove_bin_file(&pdev->dev, &sid_bin_attr);
93 dev_dbg(&pdev->dev, "driver unloaded\n");
94
95 return 0;
96}
97
98static const struct of_device_id sunxi_sid_of_match[] = {
99 { .compatible = "allwinner,sun4i-sid", .data = (void *)16},
100 { .compatible = "allwinner,sun7i-a20-sid", .data = (void *)512},
101 {/* sentinel */},
102};
103MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
104
105static int sunxi_sid_probe(struct platform_device *pdev)
106{
107 struct sunxi_sid_data *sid_data;
108 struct resource *res;
109 const struct of_device_id *of_dev_id;
110 u8 *entropy;
111 unsigned int i;
112
113 sid_data = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_sid_data),
114 GFP_KERNEL);
115 if (!sid_data)
116 return -ENOMEM;
117
118 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
119 sid_data->reg_base = devm_ioremap_resource(&pdev->dev, res);
120 if (IS_ERR(sid_data->reg_base))
121 return PTR_ERR(sid_data->reg_base);
122
123 of_dev_id = of_match_device(sunxi_sid_of_match, &pdev->dev);
124 if (!of_dev_id)
125 return -ENODEV;
126 sid_data->keysize = (int)of_dev_id->data;
127
128 platform_set_drvdata(pdev, sid_data);
129
130 sid_bin_attr.size = sid_data->keysize;
131 if (device_create_bin_file(&pdev->dev, &sid_bin_attr))
132 return -ENODEV;
133
134 entropy = kzalloc(sizeof(u8) * sid_data->keysize, GFP_KERNEL);
135 for (i = 0; i < sid_data->keysize; i++)
136 entropy[i] = sunxi_sid_read_byte(sid_data, i);
137 add_device_randomness(entropy, sid_data->keysize);
138 kfree(entropy);
139
140 dev_dbg(&pdev->dev, "loaded\n");
141
142 return 0;
143}
144
145static struct platform_driver sunxi_sid_driver = {
146 .probe = sunxi_sid_probe,
147 .remove = sunxi_sid_remove,
148 .driver = {
149 .name = DRV_NAME,
150 .owner = THIS_MODULE,
151 .of_match_table = sunxi_sid_of_match,
152 },
153};
154module_platform_driver(sunxi_sid_driver);
155
156MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>");
157MODULE_DESCRIPTION("Allwinner sunxi security id driver");
158MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index 0346d87c5fed..6b3bf9ab051d 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -153,7 +153,6 @@ error_ioremap:
153error_heartbeat: 153error_heartbeat:
154 ibmasm_event_buffer_exit(sp); 154 ibmasm_event_buffer_exit(sp);
155error_eventbuffer: 155error_eventbuffer:
156 pci_set_drvdata(pdev, NULL);
157 kfree(sp); 156 kfree(sp);
158error_kmalloc: 157error_kmalloc:
159 pci_release_regions(pdev); 158 pci_release_regions(pdev);
@@ -165,7 +164,7 @@ error_resources:
165 164
166static void ibmasm_remove_one(struct pci_dev *pdev) 165static void ibmasm_remove_one(struct pci_dev *pdev)
167{ 166{
168 struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); 167 struct service_processor *sp = pci_get_drvdata(pdev);
169 168
170 dbg("Unregistering UART\n"); 169 dbg("Unregistering UART\n");
171 ibmasm_unregister_uart(sp); 170 ibmasm_unregister_uart(sp);
@@ -182,7 +181,6 @@ static void ibmasm_remove_one(struct pci_dev *pdev)
182 ibmasm_free_remote_input_dev(sp); 181 ibmasm_free_remote_input_dev(sp);
183 iounmap(sp->base_address); 182 iounmap(sp->base_address);
184 ibmasm_event_buffer_exit(sp); 183 ibmasm_event_buffer_exit(sp);
185 pci_set_drvdata(pdev, NULL);
186 kfree(sp); 184 kfree(sp);
187 pci_release_regions(pdev); 185 pci_release_regions(pdev);
188 pci_disable_device(pdev); 186 pci_disable_device(pdev);
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 2fc0586ce3bb..a2edb2ee0921 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -44,13 +44,25 @@
44#include <scsi/scsi_cmnd.h> 44#include <scsi/scsi_cmnd.h>
45#include <linux/debugfs.h> 45#include <linux/debugfs.h>
46#include <linux/vmalloc.h> 46#include <linux/vmalloc.h>
47#include <linux/mman.h>
47 48
48#ifdef CONFIG_IDE 49#ifdef CONFIG_IDE
49#include <linux/ide.h> 50#include <linux/ide.h>
50#endif 51#endif
51 52
53/*
54 * Make sure our attempts to over run the kernel stack doesn't trigger
55 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
56 * recurse past the end of THREAD_SIZE by default.
57 */
58#if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0)
59#define REC_STACK_SIZE (CONFIG_FRAME_WARN / 2)
60#else
61#define REC_STACK_SIZE (THREAD_SIZE / 8)
62#endif
63#define REC_NUM_DEFAULT ((THREAD_SIZE / REC_STACK_SIZE) * 2)
64
52#define DEFAULT_COUNT 10 65#define DEFAULT_COUNT 10
53#define REC_NUM_DEFAULT 10
54#define EXEC_SIZE 64 66#define EXEC_SIZE 64
55 67
56enum cname { 68enum cname {
@@ -86,6 +98,9 @@ enum ctype {
86 CT_EXEC_STACK, 98 CT_EXEC_STACK,
87 CT_EXEC_KMALLOC, 99 CT_EXEC_KMALLOC,
88 CT_EXEC_VMALLOC, 100 CT_EXEC_VMALLOC,
101 CT_EXEC_USERSPACE,
102 CT_ACCESS_USERSPACE,
103 CT_WRITE_RO,
89}; 104};
90 105
91static char* cp_name[] = { 106static char* cp_name[] = {
@@ -119,6 +134,9 @@ static char* cp_type[] = {
119 "EXEC_STACK", 134 "EXEC_STACK",
120 "EXEC_KMALLOC", 135 "EXEC_KMALLOC",
121 "EXEC_VMALLOC", 136 "EXEC_VMALLOC",
137 "EXEC_USERSPACE",
138 "ACCESS_USERSPACE",
139 "WRITE_RO",
122}; 140};
123 141
124static struct jprobe lkdtm; 142static struct jprobe lkdtm;
@@ -139,9 +157,10 @@ static DEFINE_SPINLOCK(lock_me_up);
139 157
140static u8 data_area[EXEC_SIZE]; 158static u8 data_area[EXEC_SIZE];
141 159
160static const unsigned long rodata = 0xAA55AA55;
161
142module_param(recur_count, int, 0644); 162module_param(recur_count, int, 0644);
143MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ 163MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
144 "default is 10");
145module_param(cpoint_name, charp, 0444); 164module_param(cpoint_name, charp, 0444);
146MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); 165MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
147module_param(cpoint_type, charp, 0444); 166module_param(cpoint_type, charp, 0444);
@@ -280,16 +299,16 @@ static int lkdtm_parse_commandline(void)
280 return -EINVAL; 299 return -EINVAL;
281} 300}
282 301
283static int recursive_loop(int a) 302static int recursive_loop(int remaining)
284{ 303{
285 char buf[1024]; 304 char buf[REC_STACK_SIZE];
286 305
287 memset(buf,0xFF,1024); 306 /* Make sure compiler does not optimize this away. */
288 recur_count--; 307 memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE);
289 if (!recur_count) 308 if (!remaining)
290 return 0; 309 return 0;
291 else 310 else
292 return recursive_loop(a); 311 return recursive_loop(remaining - 1);
293} 312}
294 313
295static void do_nothing(void) 314static void do_nothing(void)
@@ -297,6 +316,14 @@ static void do_nothing(void)
297 return; 316 return;
298} 317}
299 318
319static noinline void corrupt_stack(void)
320{
321 /* Use default char array length that triggers stack protection. */
322 char data[8];
323
324 memset((void *)data, 0, 64);
325}
326
300static void execute_location(void *dst) 327static void execute_location(void *dst)
301{ 328{
302 void (*func)(void) = dst; 329 void (*func)(void) = dst;
@@ -305,6 +332,15 @@ static void execute_location(void *dst)
305 func(); 332 func();
306} 333}
307 334
335static void execute_user_location(void *dst)
336{
337 void (*func)(void) = dst;
338
339 if (copy_to_user(dst, do_nothing, EXEC_SIZE))
340 return;
341 func();
342}
343
308static void lkdtm_do_action(enum ctype which) 344static void lkdtm_do_action(enum ctype which)
309{ 345{
310 switch (which) { 346 switch (which) {
@@ -325,15 +361,11 @@ static void lkdtm_do_action(enum ctype which)
325 ; 361 ;
326 break; 362 break;
327 case CT_OVERFLOW: 363 case CT_OVERFLOW:
328 (void) recursive_loop(0); 364 (void) recursive_loop(recur_count);
329 break; 365 break;
330 case CT_CORRUPT_STACK: { 366 case CT_CORRUPT_STACK:
331 /* Make sure the compiler creates and uses an 8 char array. */ 367 corrupt_stack();
332 volatile char data[8];
333
334 memset((void *)data, 0, 64);
335 break; 368 break;
336 }
337 case CT_UNALIGNED_LOAD_STORE_WRITE: { 369 case CT_UNALIGNED_LOAD_STORE_WRITE: {
338 static u8 data[5] __attribute__((aligned(4))) = {1, 2, 370 static u8 data[5] __attribute__((aligned(4))) = {1, 2,
339 3, 4, 5}; 371 3, 4, 5};
@@ -401,6 +433,49 @@ static void lkdtm_do_action(enum ctype which)
401 vfree(vmalloc_area); 433 vfree(vmalloc_area);
402 break; 434 break;
403 } 435 }
436 case CT_EXEC_USERSPACE: {
437 unsigned long user_addr;
438
439 user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
440 PROT_READ | PROT_WRITE | PROT_EXEC,
441 MAP_ANONYMOUS | MAP_PRIVATE, 0);
442 if (user_addr >= TASK_SIZE) {
443 pr_warn("Failed to allocate user memory\n");
444 return;
445 }
446 execute_user_location((void *)user_addr);
447 vm_munmap(user_addr, PAGE_SIZE);
448 break;
449 }
450 case CT_ACCESS_USERSPACE: {
451 unsigned long user_addr, tmp;
452 unsigned long *ptr;
453
454 user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
455 PROT_READ | PROT_WRITE | PROT_EXEC,
456 MAP_ANONYMOUS | MAP_PRIVATE, 0);
457 if (user_addr >= TASK_SIZE) {
458 pr_warn("Failed to allocate user memory\n");
459 return;
460 }
461
462 ptr = (unsigned long *)user_addr;
463 tmp = *ptr;
464 tmp += 0xc0dec0de;
465 *ptr = tmp;
466
467 vm_munmap(user_addr, PAGE_SIZE);
468
469 break;
470 }
471 case CT_WRITE_RO: {
472 unsigned long *ptr;
473
474 ptr = (unsigned long *)&rodata;
475 *ptr ^= 0xabcd1234;
476
477 break;
478 }
404 case CT_NONE: 479 case CT_NONE:
405 default: 480 default:
406 break; 481 break;
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index f6ff711aa5bb..d22c6864508b 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -58,6 +58,7 @@ void mei_amthif_reset_params(struct mei_device *dev)
58 dev->iamthif_state = MEI_IAMTHIF_IDLE; 58 dev->iamthif_state = MEI_IAMTHIF_IDLE;
59 dev->iamthif_timer = 0; 59 dev->iamthif_timer = 0;
60 dev->iamthif_stall_timer = 0; 60 dev->iamthif_stall_timer = 0;
61 dev->iamthif_open_count = 0;
61} 62}
62 63
63/** 64/**
@@ -78,8 +79,10 @@ int mei_amthif_host_init(struct mei_device *dev)
78 79
79 i = mei_me_cl_by_uuid(dev, &mei_amthif_guid); 80 i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
80 if (i < 0) { 81 if (i < 0) {
81 dev_info(&dev->pdev->dev, "amthif: failed to find the client\n"); 82 ret = i;
82 return -ENOENT; 83 dev_info(&dev->pdev->dev,
84 "amthif: failed to find the client %d\n", ret);
85 return ret;
83 } 86 }
84 87
85 cl->me_client_id = dev->me_clients[i].client_id; 88 cl->me_client_id = dev->me_clients[i].client_id;
@@ -106,8 +109,9 @@ int mei_amthif_host_init(struct mei_device *dev)
106 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); 109 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
107 110
108 if (ret < 0) { 111 if (ret < 0) {
109 dev_err(&dev->pdev->dev, "amthif: failed link client\n"); 112 dev_err(&dev->pdev->dev,
110 return -ENOENT; 113 "amthif: failed link client %d\n", ret);
114 return ret;
111 } 115 }
112 116
113 cl->state = MEI_FILE_CONNECTING; 117 cl->state = MEI_FILE_CONNECTING;
@@ -313,13 +317,13 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
313 mei_hdr.me_addr = dev->iamthif_cl.me_client_id; 317 mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
314 mei_hdr.reserved = 0; 318 mei_hdr.reserved = 0;
315 dev->iamthif_msg_buf_index += mei_hdr.length; 319 dev->iamthif_msg_buf_index += mei_hdr.length;
316 if (mei_write_message(dev, &mei_hdr, 320 ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
317 (unsigned char *)dev->iamthif_msg_buf)) 321 if (ret)
318 return -ENODEV; 322 return ret;
319 323
320 if (mei_hdr.msg_complete) { 324 if (mei_hdr.msg_complete) {
321 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) 325 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
322 return -ENODEV; 326 return -EIO;
323 dev->iamthif_flow_control_pending = true; 327 dev->iamthif_flow_control_pending = true;
324 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 328 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
325 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n"); 329 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
@@ -459,6 +463,16 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
459 struct mei_msg_hdr mei_hdr; 463 struct mei_msg_hdr mei_hdr;
460 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; 464 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
461 u32 msg_slots = mei_data2slots(len); 465 u32 msg_slots = mei_data2slots(len);
466 int rets;
467
468 rets = mei_cl_flow_ctrl_creds(cl);
469 if (rets < 0)
470 return rets;
471
472 if (rets == 0) {
473 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
474 return 0;
475 }
462 476
463 mei_hdr.host_addr = cl->host_client_id; 477 mei_hdr.host_addr = cl->host_client_id;
464 mei_hdr.me_addr = cl->me_client_id; 478 mei_hdr.me_addr = cl->me_client_id;
@@ -481,16 +495,17 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
481 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); 495 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
482 496
483 *slots -= msg_slots; 497 *slots -= msg_slots;
484 if (mei_write_message(dev, &mei_hdr, 498 rets = mei_write_message(dev, &mei_hdr,
485 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) { 499 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
486 dev->iamthif_state = MEI_IAMTHIF_IDLE; 500 if (rets) {
487 cl->status = -ENODEV; 501 dev->iamthif_state = MEI_IAMTHIF_IDLE;
488 list_del(&cb->list); 502 cl->status = rets;
489 return -ENODEV; 503 list_del(&cb->list);
504 return rets;
490 } 505 }
491 506
492 if (mei_cl_flow_ctrl_reduce(cl)) 507 if (mei_cl_flow_ctrl_reduce(cl))
493 return -ENODEV; 508 return -EIO;
494 509
495 dev->iamthif_msg_buf_index += mei_hdr.length; 510 dev->iamthif_msg_buf_index += mei_hdr.length;
496 cl->status = 0; 511 cl->status = 0;
@@ -720,8 +735,8 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file)
720*/ 735*/
721int mei_amthif_release(struct mei_device *dev, struct file *file) 736int mei_amthif_release(struct mei_device *dev, struct file *file)
722{ 737{
723 if (dev->open_handle_count > 0) 738 if (dev->iamthif_open_count > 0)
724 dev->open_handle_count--; 739 dev->iamthif_open_count--;
725 740
726 if (dev->iamthif_file_object == file && 741 if (dev->iamthif_file_object == file &&
727 dev->iamthif_state != MEI_IAMTHIF_IDLE) { 742 dev->iamthif_state != MEI_IAMTHIF_IDLE) {
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index cd2033cd7120..4bc7d620d695 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -245,7 +245,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
245 /* Check if we have an ME client device */ 245 /* Check if we have an ME client device */
246 id = mei_me_cl_by_id(dev, cl->me_client_id); 246 id = mei_me_cl_by_id(dev, cl->me_client_id);
247 if (id < 0) 247 if (id < 0)
248 return -ENODEV; 248 return id;
249 249
250 if (length > dev->me_clients[id].props.max_msg_length) 250 if (length > dev->me_clients[id].props.max_msg_length)
251 return -EINVAL; 251 return -EINVAL;
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e0684b4d9a08..87c96e4669e2 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -187,10 +187,14 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
187 */ 187 */
188int mei_cl_flush_queues(struct mei_cl *cl) 188int mei_cl_flush_queues(struct mei_cl *cl)
189{ 189{
190 struct mei_device *dev;
191
190 if (WARN_ON(!cl || !cl->dev)) 192 if (WARN_ON(!cl || !cl->dev))
191 return -EINVAL; 193 return -EINVAL;
192 194
193 dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); 195 dev = cl->dev;
196
197 cl_dbg(dev, cl, "remove list entry belonging to cl\n");
194 mei_io_list_flush(&cl->dev->read_list, cl); 198 mei_io_list_flush(&cl->dev->read_list, cl);
195 mei_io_list_flush(&cl->dev->write_list, cl); 199 mei_io_list_flush(&cl->dev->write_list, cl);
196 mei_io_list_flush(&cl->dev->write_waiting_list, cl); 200 mei_io_list_flush(&cl->dev->write_waiting_list, cl);
@@ -271,6 +275,7 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
271int mei_cl_link(struct mei_cl *cl, int id) 275int mei_cl_link(struct mei_cl *cl, int id)
272{ 276{
273 struct mei_device *dev; 277 struct mei_device *dev;
278 long open_handle_count;
274 279
275 if (WARN_ON(!cl || !cl->dev)) 280 if (WARN_ON(!cl || !cl->dev))
276 return -EINVAL; 281 return -EINVAL;
@@ -284,7 +289,14 @@ int mei_cl_link(struct mei_cl *cl, int id)
284 289
285 if (id >= MEI_CLIENTS_MAX) { 290 if (id >= MEI_CLIENTS_MAX) {
286 dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ; 291 dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ;
287 return -ENOENT; 292 return -EMFILE;
293 }
294
295 open_handle_count = dev->open_handle_count + dev->iamthif_open_count;
296 if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
297 dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
298 MEI_MAX_OPEN_HANDLE_COUNT);
299 return -EMFILE;
288 } 300 }
289 301
290 dev->open_handle_count++; 302 dev->open_handle_count++;
@@ -296,7 +308,7 @@ int mei_cl_link(struct mei_cl *cl, int id)
296 308
297 cl->state = MEI_FILE_INITIALIZING; 309 cl->state = MEI_FILE_INITIALIZING;
298 310
299 dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id); 311 cl_dbg(dev, cl, "link cl\n");
300 return 0; 312 return 0;
301} 313}
302 314
@@ -308,7 +320,6 @@ int mei_cl_link(struct mei_cl *cl, int id)
308int mei_cl_unlink(struct mei_cl *cl) 320int mei_cl_unlink(struct mei_cl *cl)
309{ 321{
310 struct mei_device *dev; 322 struct mei_device *dev;
311 struct mei_cl *pos, *next;
312 323
313 /* don't shout on error exit path */ 324 /* don't shout on error exit path */
314 if (!cl) 325 if (!cl)
@@ -320,14 +331,21 @@ int mei_cl_unlink(struct mei_cl *cl)
320 331
321 dev = cl->dev; 332 dev = cl->dev;
322 333
323 list_for_each_entry_safe(pos, next, &dev->file_list, link) { 334 cl_dbg(dev, cl, "unlink client");
324 if (cl->host_client_id == pos->host_client_id) { 335
325 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", 336 if (dev->open_handle_count > 0)
326 pos->host_client_id, pos->me_client_id); 337 dev->open_handle_count--;
327 list_del_init(&pos->link); 338
328 break; 339 /* never clear the 0 bit */
329 } 340 if (cl->host_client_id)
330 } 341 clear_bit(cl->host_client_id, dev->host_clients_map);
342
343 list_del_init(&cl->link);
344
345 cl->state = MEI_FILE_INITIALIZING;
346
347 list_del_init(&cl->link);
348
331 return 0; 349 return 0;
332} 350}
333 351
@@ -341,17 +359,6 @@ void mei_host_client_init(struct work_struct *work)
341 359
342 mutex_lock(&dev->device_lock); 360 mutex_lock(&dev->device_lock);
343 361
344 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
345 dev->open_handle_count = 0;
346
347 /*
348 * Reserving the first three client IDs
349 * 0: Reserved for MEI Bus Message communications
350 * 1: Reserved for Watchdog
351 * 2: Reserved for AMTHI
352 */
353 bitmap_set(dev->host_clients_map, 0, 3);
354
355 for (i = 0; i < dev->me_clients_num; i++) { 362 for (i = 0; i < dev->me_clients_num; i++) {
356 client_props = &dev->me_clients[i].props; 363 client_props = &dev->me_clients[i].props;
357 364
@@ -390,6 +397,8 @@ int mei_cl_disconnect(struct mei_cl *cl)
390 397
391 dev = cl->dev; 398 dev = cl->dev;
392 399
400 cl_dbg(dev, cl, "disconnecting");
401
393 if (cl->state != MEI_FILE_DISCONNECTING) 402 if (cl->state != MEI_FILE_DISCONNECTING)
394 return 0; 403 return 0;
395 404
@@ -402,13 +411,13 @@ int mei_cl_disconnect(struct mei_cl *cl)
402 dev->hbuf_is_ready = false; 411 dev->hbuf_is_ready = false;
403 if (mei_hbm_cl_disconnect_req(dev, cl)) { 412 if (mei_hbm_cl_disconnect_req(dev, cl)) {
404 rets = -ENODEV; 413 rets = -ENODEV;
405 dev_err(&dev->pdev->dev, "failed to disconnect.\n"); 414 cl_err(dev, cl, "failed to disconnect.\n");
406 goto free; 415 goto free;
407 } 416 }
408 mdelay(10); /* Wait for hardware disconnection ready */ 417 mdelay(10); /* Wait for hardware disconnection ready */
409 list_add_tail(&cb->list, &dev->ctrl_rd_list.list); 418 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
410 } else { 419 } else {
411 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); 420 cl_dbg(dev, cl, "add disconnect cb to control write list\n");
412 list_add_tail(&cb->list, &dev->ctrl_wr_list.list); 421 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
413 422
414 } 423 }
@@ -421,18 +430,17 @@ int mei_cl_disconnect(struct mei_cl *cl)
421 mutex_lock(&dev->device_lock); 430 mutex_lock(&dev->device_lock);
422 if (MEI_FILE_DISCONNECTED == cl->state) { 431 if (MEI_FILE_DISCONNECTED == cl->state) {
423 rets = 0; 432 rets = 0;
424 dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n"); 433 cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
425 } else { 434 } else {
426 rets = -ENODEV; 435 rets = -ENODEV;
427 if (MEI_FILE_DISCONNECTED != cl->state) 436 if (MEI_FILE_DISCONNECTED != cl->state)
428 dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n"); 437 cl_err(dev, cl, "wrong status client disconnect.\n");
429 438
430 if (err) 439 if (err)
431 dev_dbg(&dev->pdev->dev, 440 cl_dbg(dev, cl, "wait failed disconnect err=%08x\n",
432 "wait failed disconnect err=%08x\n",
433 err); 441 err);
434 442
435 dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); 443 cl_err(dev, cl, "failed to disconnect from FW client.\n");
436 } 444 }
437 445
438 mei_io_list_flush(&dev->ctrl_rd_list, cl); 446 mei_io_list_flush(&dev->ctrl_rd_list, cl);
@@ -639,13 +647,12 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
639 return -ENODEV; 647 return -ENODEV;
640 648
641 if (cl->read_cb) { 649 if (cl->read_cb) {
642 dev_dbg(&dev->pdev->dev, "read is pending.\n"); 650 cl_dbg(dev, cl, "read is pending.\n");
643 return -EBUSY; 651 return -EBUSY;
644 } 652 }
645 i = mei_me_cl_by_id(dev, cl->me_client_id); 653 i = mei_me_cl_by_id(dev, cl->me_client_id);
646 if (i < 0) { 654 if (i < 0) {
647 dev_err(&dev->pdev->dev, "no such me client %d\n", 655 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
648 cl->me_client_id);
649 return -ENODEV; 656 return -ENODEV;
650 } 657 }
651 658
@@ -664,6 +671,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
664 if (dev->hbuf_is_ready) { 671 if (dev->hbuf_is_ready) {
665 dev->hbuf_is_ready = false; 672 dev->hbuf_is_ready = false;
666 if (mei_hbm_cl_flow_control_req(dev, cl)) { 673 if (mei_hbm_cl_flow_control_req(dev, cl)) {
674 cl_err(dev, cl, "flow control send failed\n");
667 rets = -ENODEV; 675 rets = -ENODEV;
668 goto err; 676 goto err;
669 } 677 }
@@ -691,10 +699,32 @@ err:
691int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, 699int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
692 s32 *slots, struct mei_cl_cb *cmpl_list) 700 s32 *slots, struct mei_cl_cb *cmpl_list)
693{ 701{
694 struct mei_device *dev = cl->dev; 702 struct mei_device *dev;
703 struct mei_msg_data *buf;
695 struct mei_msg_hdr mei_hdr; 704 struct mei_msg_hdr mei_hdr;
696 size_t len = cb->request_buffer.size - cb->buf_idx; 705 size_t len;
697 u32 msg_slots = mei_data2slots(len); 706 u32 msg_slots;
707 int rets;
708
709
710 if (WARN_ON(!cl || !cl->dev))
711 return -ENODEV;
712
713 dev = cl->dev;
714
715 buf = &cb->request_buffer;
716
717 rets = mei_cl_flow_ctrl_creds(cl);
718 if (rets < 0)
719 return rets;
720
721 if (rets == 0) {
722 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
723 return 0;
724 }
725
726 len = buf->size - cb->buf_idx;
727 msg_slots = mei_data2slots(len);
698 728
699 mei_hdr.host_addr = cl->host_client_id; 729 mei_hdr.host_addr = cl->host_client_id;
700 mei_hdr.me_addr = cl->me_client_id; 730 mei_hdr.me_addr = cl->me_client_id;
@@ -714,16 +744,15 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
714 return 0; 744 return 0;
715 } 745 }
716 746
717 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", 747 cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
718 cb->request_buffer.size, cb->buf_idx); 748 cb->request_buffer.size, cb->buf_idx);
719 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
720 749
721 *slots -= msg_slots; 750 *slots -= msg_slots;
722 if (mei_write_message(dev, &mei_hdr, 751 rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
723 cb->request_buffer.data + cb->buf_idx)) { 752 if (rets) {
724 cl->status = -ENODEV; 753 cl->status = rets;
725 list_move_tail(&cb->list, &cmpl_list->list); 754 list_move_tail(&cb->list, &cmpl_list->list);
726 return -ENODEV; 755 return rets;
727 } 756 }
728 757
729 cl->status = 0; 758 cl->status = 0;
@@ -732,7 +761,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
732 761
733 if (mei_hdr.msg_complete) { 762 if (mei_hdr.msg_complete) {
734 if (mei_cl_flow_ctrl_reduce(cl)) 763 if (mei_cl_flow_ctrl_reduce(cl))
735 return -ENODEV; 764 return -EIO;
736 list_move_tail(&cb->list, &dev->write_waiting_list.list); 765 list_move_tail(&cb->list, &dev->write_waiting_list.list);
737 } 766 }
738 767
@@ -767,7 +796,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
767 796
768 buf = &cb->request_buffer; 797 buf = &cb->request_buffer;
769 798
770 dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size); 799 cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size);
771 800
772 801
773 cb->fop_type = MEI_FOP_WRITE; 802 cb->fop_type = MEI_FOP_WRITE;
@@ -800,14 +829,10 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
800 mei_hdr.me_addr = cl->me_client_id; 829 mei_hdr.me_addr = cl->me_client_id;
801 mei_hdr.reserved = 0; 830 mei_hdr.reserved = 0;
802 831
803 dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
804 MEI_HDR_PRM(&mei_hdr));
805
806 832
807 if (mei_write_message(dev, &mei_hdr, buf->data)) { 833 rets = mei_write_message(dev, &mei_hdr, buf->data);
808 rets = -EIO; 834 if (rets)
809 goto err; 835 goto err;
810 }
811 836
812 cl->writing_state = MEI_WRITING; 837 cl->writing_state = MEI_WRITING;
813 cb->buf_idx = mei_hdr.length; 838 cb->buf_idx = mei_hdr.length;
@@ -898,11 +923,11 @@ void mei_cl_all_wakeup(struct mei_device *dev)
898 struct mei_cl *cl, *next; 923 struct mei_cl *cl, *next;
899 list_for_each_entry_safe(cl, next, &dev->file_list, link) { 924 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
900 if (waitqueue_active(&cl->rx_wait)) { 925 if (waitqueue_active(&cl->rx_wait)) {
901 dev_dbg(&dev->pdev->dev, "Waking up reading client!\n"); 926 cl_dbg(dev, cl, "Waking up reading client!\n");
902 wake_up_interruptible(&cl->rx_wait); 927 wake_up_interruptible(&cl->rx_wait);
903 } 928 }
904 if (waitqueue_active(&cl->tx_wait)) { 929 if (waitqueue_active(&cl->tx_wait)) {
905 dev_dbg(&dev->pdev->dev, "Waking up writing client!\n"); 930 cl_dbg(dev, cl, "Waking up writing client!\n");
906 wake_up_interruptible(&cl->tx_wait); 931 wake_up_interruptible(&cl->tx_wait);
907 } 932 }
908 } 933 }
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 892cc4207fa2..c8396e582f1c 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -115,4 +115,13 @@ void mei_cl_all_disconnect(struct mei_device *dev);
115void mei_cl_all_wakeup(struct mei_device *dev); 115void mei_cl_all_wakeup(struct mei_device *dev);
116void mei_cl_all_write_clear(struct mei_device *dev); 116void mei_cl_all_write_clear(struct mei_device *dev);
117 117
118#define MEI_CL_FMT "cl:host=%02d me=%02d "
119#define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id
120
121#define cl_dbg(dev, cl, format, arg...) \
122 dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
123
124#define cl_err(dev, cl, format, arg...) \
125 dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
126
118#endif /* _MEI_CLIENT_H_ */ 127#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 0a0448326e9d..9b3a0fb7f265 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -49,7 +49,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
49 kfree(dev->me_clients); 49 kfree(dev->me_clients);
50 dev->me_clients = NULL; 50 dev->me_clients = NULL;
51 51
52 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", 52 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
53 dev->me_clients_num * sizeof(struct mei_me_client)); 53 dev->me_clients_num * sizeof(struct mei_me_client));
54 /* allocate storage for ME clients representation */ 54 /* allocate storage for ME clients representation */
55 clients = kcalloc(dev->me_clients_num, 55 clients = kcalloc(dev->me_clients_num,
@@ -174,7 +174,7 @@ int mei_hbm_start_req(struct mei_device *dev)
174 dev_err(&dev->pdev->dev, "version message write failed\n"); 174 dev_err(&dev->pdev->dev, "version message write failed\n");
175 dev->dev_state = MEI_DEV_RESETTING; 175 dev->dev_state = MEI_DEV_RESETTING;
176 mei_reset(dev, 1); 176 mei_reset(dev, 1);
177 return -ENODEV; 177 return -EIO;
178 } 178 }
179 dev->hbm_state = MEI_HBM_START; 179 dev->hbm_state = MEI_HBM_START;
180 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 180 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
@@ -677,7 +677,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
677 677
678 case HOST_ENUM_RES_CMD: 678 case HOST_ENUM_RES_CMD:
679 enum_res = (struct hbm_host_enum_response *) mei_msg; 679 enum_res = (struct hbm_host_enum_response *) mei_msg;
680 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 680 BUILD_BUG_ON(sizeof(dev->me_clients_map)
681 < sizeof(enum_res->valid_addresses));
682 memcpy(dev->me_clients_map, enum_res->valid_addresses,
683 sizeof(enum_res->valid_addresses));
681 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 684 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
682 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { 685 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
683 dev->init_clients_timer = 0; 686 dev->init_clients_timer = 0;
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index 6a203b6e8346..6c0fde55270d 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -110,6 +110,7 @@
110#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */ 110#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
111 111
112#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */ 112#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
113#define MEI_DEV_ID_LPT_W 0x8D3A /* Lynx Point - Wellsburg */
113#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */ 114#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
114/* 115/*
115 * MEI HW Section 116 * MEI HW Section
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 6197018e2f16..f7f3abbe12b6 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -68,6 +68,14 @@ void mei_device_init(struct mei_device *dev)
68 mei_io_list_init(&dev->amthif_cmd_list); 68 mei_io_list_init(&dev->amthif_cmd_list);
69 mei_io_list_init(&dev->amthif_rd_complete_list); 69 mei_io_list_init(&dev->amthif_rd_complete_list);
70 70
71 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
72 dev->open_handle_count = 0;
73
74 /*
75 * Reserving the first client ID
76 * 0: Reserved for MEI Bus Message communications
77 */
78 bitmap_set(dev->host_clients_map, 0, 1);
71} 79}
72EXPORT_SYMBOL_GPL(mei_device_init); 80EXPORT_SYMBOL_GPL(mei_device_init);
73 81
@@ -139,6 +147,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
139 dev->dev_state != MEI_DEV_POWER_DOWN && 147 dev->dev_state != MEI_DEV_POWER_DOWN &&
140 dev->dev_state != MEI_DEV_POWER_UP); 148 dev->dev_state != MEI_DEV_POWER_UP);
141 149
150 if (unexpected)
151 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
152 mei_dev_state_str(dev->dev_state));
153
142 ret = mei_hw_reset(dev, interrupts_enabled); 154 ret = mei_hw_reset(dev, interrupts_enabled);
143 if (ret) { 155 if (ret) {
144 dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n"); 156 dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
@@ -165,12 +177,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
165 /* remove entry if already in list */ 177 /* remove entry if already in list */
166 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); 178 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
167 mei_cl_unlink(&dev->wd_cl); 179 mei_cl_unlink(&dev->wd_cl);
168 if (dev->open_handle_count > 0)
169 dev->open_handle_count--;
170 mei_cl_unlink(&dev->iamthif_cl); 180 mei_cl_unlink(&dev->iamthif_cl);
171 if (dev->open_handle_count > 0)
172 dev->open_handle_count--;
173
174 mei_amthif_reset_params(dev); 181 mei_amthif_reset_params(dev);
175 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); 182 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
176 } 183 }
@@ -182,10 +189,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
182 dev->rd_msg_hdr = 0; 189 dev->rd_msg_hdr = 0;
183 dev->wd_pending = false; 190 dev->wd_pending = false;
184 191
185 if (unexpected)
186 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
187 mei_dev_state_str(dev->dev_state));
188
189 if (!interrupts_enabled) { 192 if (!interrupts_enabled) {
190 dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n"); 193 dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n");
191 return; 194 return;
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 4b59cb742dee..7a95c07e59a6 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -113,13 +113,13 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
113 113
114 if (cb->response_buffer.size == 0 || 114 if (cb->response_buffer.size == 0 ||
115 cb->response_buffer.data == NULL) { 115 cb->response_buffer.data == NULL) {
116 dev_err(&dev->pdev->dev, "response buffer is not allocated.\n"); 116 cl_err(dev, cl, "response buffer is not allocated.\n");
117 list_del(&cb->list); 117 list_del(&cb->list);
118 return -ENOMEM; 118 return -ENOMEM;
119 } 119 }
120 120
121 if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) { 121 if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) {
122 dev_dbg(&dev->pdev->dev, "message overflow. size %d len %d idx %ld\n", 122 cl_dbg(dev, cl, "message overflow. size %d len %d idx %ld\n",
123 cb->response_buffer.size, 123 cb->response_buffer.size,
124 mei_hdr->length, cb->buf_idx); 124 mei_hdr->length, cb->buf_idx);
125 buffer = krealloc(cb->response_buffer.data, 125 buffer = krealloc(cb->response_buffer.data,
@@ -127,7 +127,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
127 GFP_KERNEL); 127 GFP_KERNEL);
128 128
129 if (!buffer) { 129 if (!buffer) {
130 dev_err(&dev->pdev->dev, "allocation failed.\n"); 130 cl_err(dev, cl, "allocation failed.\n");
131 list_del(&cb->list); 131 list_del(&cb->list);
132 return -ENOMEM; 132 return -ENOMEM;
133 } 133 }
@@ -143,9 +143,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
143 if (mei_hdr->msg_complete) { 143 if (mei_hdr->msg_complete) {
144 cl->status = 0; 144 cl->status = 0;
145 list_del(&cb->list); 145 list_del(&cb->list);
146 dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", 146 cl_dbg(dev, cl, "completed read length = %lu\n",
147 cl->host_client_id,
148 cl->me_client_id,
149 cb->buf_idx); 147 cb->buf_idx);
150 list_add_tail(&cb->list, &complete_list->list); 148 list_add_tail(&cb->list, &complete_list->list);
151 } 149 }
@@ -218,9 +216,11 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
218 s32 *slots, struct mei_cl_cb *cmpl_list) 216 s32 *slots, struct mei_cl_cb *cmpl_list)
219{ 217{
220 struct mei_device *dev = cl->dev; 218 struct mei_device *dev = cl->dev;
221
222 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); 219 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
223 220
221 int ret;
222
223
224 if (*slots < msg_slots) { 224 if (*slots < msg_slots) {
225 /* return the cancel routine */ 225 /* return the cancel routine */
226 list_del(&cb->list); 226 list_del(&cb->list);
@@ -229,12 +229,14 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
229 229
230 *slots -= msg_slots; 230 *slots -= msg_slots;
231 231
232 if (mei_hbm_cl_flow_control_req(dev, cl)) { 232 ret = mei_hbm_cl_flow_control_req(dev, cl);
233 cl->status = -ENODEV; 233 if (ret) {
234 cl->status = ret;
234 cb->buf_idx = 0; 235 cb->buf_idx = 0;
235 list_move_tail(&cb->list, &cmpl_list->list); 236 list_move_tail(&cb->list, &cmpl_list->list);
236 return -ENODEV; 237 return ret;
237 } 238 }
239
238 list_move_tail(&cb->list, &dev->read_list.list); 240 list_move_tail(&cb->list, &dev->read_list.list);
239 241
240 return 0; 242 return 0;
@@ -256,6 +258,7 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
256 s32 *slots, struct mei_cl_cb *cmpl_list) 258 s32 *slots, struct mei_cl_cb *cmpl_list)
257{ 259{
258 struct mei_device *dev = cl->dev; 260 struct mei_device *dev = cl->dev;
261 int ret;
259 262
260 u32 msg_slots = 263 u32 msg_slots =
261 mei_data2slots(sizeof(struct hbm_client_connect_request)); 264 mei_data2slots(sizeof(struct hbm_client_connect_request));
@@ -270,11 +273,12 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
270 273
271 cl->state = MEI_FILE_CONNECTING; 274 cl->state = MEI_FILE_CONNECTING;
272 275
273 if (mei_hbm_cl_connect_req(dev, cl)) { 276 ret = mei_hbm_cl_connect_req(dev, cl);
274 cl->status = -ENODEV; 277 if (ret) {
278 cl->status = ret;
275 cb->buf_idx = 0; 279 cb->buf_idx = 0;
276 list_del(&cb->list); 280 list_del(&cb->list);
277 return -ENODEV; 281 return ret;
278 } 282 }
279 283
280 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 284 list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
@@ -345,14 +349,14 @@ int mei_irq_read_handler(struct mei_device *dev,
345 349
346 /* decide where to read the message too */ 350 /* decide where to read the message too */
347 if (!mei_hdr->host_addr) { 351 if (!mei_hdr->host_addr) {
348 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 352 dev_dbg(&dev->pdev->dev, "call mei_hbm_dispatch.\n");
349 mei_hbm_dispatch(dev, mei_hdr); 353 mei_hbm_dispatch(dev, mei_hdr);
350 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 354 dev_dbg(&dev->pdev->dev, "end mei_hbm_dispatch.\n");
351 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 355 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
352 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 356 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
353 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 357 (dev->iamthif_state == MEI_IAMTHIF_READING)) {
354 358
355 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 359 dev_dbg(&dev->pdev->dev, "call mei_amthif_irq_read_msg.\n");
356 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 360 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
357 361
358 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); 362 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
@@ -423,12 +427,12 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
423 if (MEI_WRITING == cl->writing_state && 427 if (MEI_WRITING == cl->writing_state &&
424 cb->fop_type == MEI_FOP_WRITE && 428 cb->fop_type == MEI_FOP_WRITE &&
425 cl != &dev->iamthif_cl) { 429 cl != &dev->iamthif_cl) {
426 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); 430 cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
427 cl->writing_state = MEI_WRITE_COMPLETE; 431 cl->writing_state = MEI_WRITE_COMPLETE;
428 list_add_tail(&cb->list, &cmpl_list->list); 432 list_add_tail(&cb->list, &cmpl_list->list);
429 } 433 }
430 if (cl == &dev->iamthif_cl) { 434 if (cl == &dev->iamthif_cl) {
431 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); 435 cl_dbg(dev, cl, "check iamthif flow control.\n");
432 if (dev->iamthif_flow_control_pending) { 436 if (dev->iamthif_flow_control_pending) {
433 ret = mei_amthif_irq_read(dev, &slots); 437 ret = mei_amthif_irq_read(dev, &slots);
434 if (ret) 438 if (ret)
@@ -509,13 +513,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
509 cl = cb->cl; 513 cl = cb->cl;
510 if (cl == NULL) 514 if (cl == NULL)
511 continue; 515 continue;
512 if (mei_cl_flow_ctrl_creds(cl) <= 0) {
513 dev_dbg(&dev->pdev->dev,
514 "No flow control credentials for client %d, not sending.\n",
515 cl->host_client_id);
516 continue;
517 }
518
519 if (cl == &dev->iamthif_cl) 516 if (cl == &dev->iamthif_cl)
520 ret = mei_amthif_irq_write_complete(cl, cb, 517 ret = mei_amthif_irq_write_complete(cl, cb,
521 &slots, cmpl_list); 518 &slots, cmpl_list);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index cabeddd66c1f..9661a812f550 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -60,48 +60,45 @@ static int mei_open(struct inode *inode, struct file *file)
60 60
61 int err; 61 int err;
62 62
63 err = -ENODEV;
64 if (!misc->parent) 63 if (!misc->parent)
65 goto out; 64 return -ENODEV;
66 65
67 pdev = container_of(misc->parent, struct pci_dev, dev); 66 pdev = container_of(misc->parent, struct pci_dev, dev);
68 67
69 dev = pci_get_drvdata(pdev); 68 dev = pci_get_drvdata(pdev);
70 if (!dev) 69 if (!dev)
71 goto out; 70 return -ENODEV;
72 71
73 mutex_lock(&dev->device_lock); 72 mutex_lock(&dev->device_lock);
74 err = -ENOMEM; 73
75 cl = mei_cl_allocate(dev); 74 cl = NULL;
76 if (!cl)
77 goto out_unlock;
78 75
79 err = -ENODEV; 76 err = -ENODEV;
80 if (dev->dev_state != MEI_DEV_ENABLED) { 77 if (dev->dev_state != MEI_DEV_ENABLED) {
81 dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", 78 dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n",
82 mei_dev_state_str(dev->dev_state)); 79 mei_dev_state_str(dev->dev_state));
83 goto out_unlock; 80 goto err_unlock;
84 }
85 err = -EMFILE;
86 if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
87 dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
88 MEI_MAX_OPEN_HANDLE_COUNT);
89 goto out_unlock;
90 } 81 }
91 82
83 err = -ENOMEM;
84 cl = mei_cl_allocate(dev);
85 if (!cl)
86 goto err_unlock;
87
88 /* open_handle_count check is handled in the mei_cl_link */
92 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); 89 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
93 if (err) 90 if (err)
94 goto out_unlock; 91 goto err_unlock;
95 92
96 file->private_data = cl; 93 file->private_data = cl;
94
97 mutex_unlock(&dev->device_lock); 95 mutex_unlock(&dev->device_lock);
98 96
99 return nonseekable_open(inode, file); 97 return nonseekable_open(inode, file);
100 98
101out_unlock: 99err_unlock:
102 mutex_unlock(&dev->device_lock); 100 mutex_unlock(&dev->device_lock);
103 kfree(cl); 101 kfree(cl);
104out:
105 return err; 102 return err;
106} 103}
107 104
@@ -144,10 +141,6 @@ static int mei_release(struct inode *inode, struct file *file)
144 cl->host_client_id, 141 cl->host_client_id,
145 cl->me_client_id); 142 cl->me_client_id);
146 143
147 if (dev->open_handle_count > 0) {
148 clear_bit(cl->host_client_id, dev->host_clients_map);
149 dev->open_handle_count--;
150 }
151 mei_cl_unlink(cl); 144 mei_cl_unlink(cl);
152 145
153 146
@@ -165,10 +158,7 @@ static int mei_release(struct inode *inode, struct file *file)
165 158
166 file->private_data = NULL; 159 file->private_data = NULL;
167 160
168 if (cb) { 161 mei_io_cb_free(cb);
169 mei_io_cb_free(cb);
170 cb = NULL;
171 }
172 162
173 kfree(cl); 163 kfree(cl);
174out: 164out:
@@ -203,12 +193,18 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
203 193
204 dev = cl->dev; 194 dev = cl->dev;
205 195
196
206 mutex_lock(&dev->device_lock); 197 mutex_lock(&dev->device_lock);
207 if (dev->dev_state != MEI_DEV_ENABLED) { 198 if (dev->dev_state != MEI_DEV_ENABLED) {
208 rets = -ENODEV; 199 rets = -ENODEV;
209 goto out; 200 goto out;
210 } 201 }
211 202
203 if (length == 0) {
204 rets = 0;
205 goto out;
206 }
207
212 if (cl == &dev->iamthif_cl) { 208 if (cl == &dev->iamthif_cl) {
213 rets = mei_amthif_read(dev, file, ubuf, length, offset); 209 rets = mei_amthif_read(dev, file, ubuf, length, offset);
214 goto out; 210 goto out;
@@ -347,8 +343,14 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
347 rets = -ENODEV; 343 rets = -ENODEV;
348 goto out; 344 goto out;
349 } 345 }
350 if (length > dev->me_clients[id].props.max_msg_length || length <= 0) { 346
351 rets = -EMSGSIZE; 347 if (length == 0) {
348 rets = 0;
349 goto out;
350 }
351
352 if (length > dev->me_clients[id].props.max_msg_length) {
353 rets = -EFBIG;
352 goto out; 354 goto out;
353 } 355 }
354 356
@@ -401,8 +403,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
401 goto out; 403 goto out;
402 404
403 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); 405 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
404 if (rets) 406 if (rets) {
407 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
408 rets = -EFAULT;
405 goto out; 409 goto out;
410 }
406 411
407 if (cl == &dev->iamthif_cl) { 412 if (cl == &dev->iamthif_cl) {
408 rets = mei_amthif_write(dev, write_cb); 413 rets = mei_amthif_write(dev, write_cb);
@@ -489,11 +494,11 @@ static int mei_ioctl_connect_client(struct file *file,
489 rets = -ENODEV; 494 rets = -ENODEV;
490 goto end; 495 goto end;
491 } 496 }
492 clear_bit(cl->host_client_id, dev->host_clients_map);
493 mei_cl_unlink(cl); 497 mei_cl_unlink(cl);
494 498
495 kfree(cl); 499 kfree(cl);
496 cl = NULL; 500 cl = NULL;
501 dev->iamthif_open_count++;
497 file->private_data = &dev->iamthif_cl; 502 file->private_data = &dev->iamthif_cl;
498 503
499 client = &data->out_client_properties; 504 client = &data->out_client_properties;
@@ -564,7 +569,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
564 dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); 569 dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
565 if (copy_from_user(connect_data, (char __user *)data, 570 if (copy_from_user(connect_data, (char __user *)data,
566 sizeof(struct mei_connect_client_data))) { 571 sizeof(struct mei_connect_client_data))) {
567 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); 572 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
568 rets = -EFAULT; 573 rets = -EFAULT;
569 goto out; 574 goto out;
570 } 575 }
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 456b322013e2..406f68e05b4e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -414,6 +414,7 @@ struct mei_device {
414 struct file *iamthif_file_object; 414 struct file *iamthif_file_object;
415 struct mei_cl iamthif_cl; 415 struct mei_cl iamthif_cl;
416 struct mei_cl_cb *iamthif_current_cb; 416 struct mei_cl_cb *iamthif_current_cb;
417 long iamthif_open_count;
417 int iamthif_mtu; 418 int iamthif_mtu;
418 unsigned long iamthif_timer; 419 unsigned long iamthif_timer;
419 u32 iamthif_stall_timer; 420 u32 iamthif_stall_timer;
diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c
index d0c6907dfd92..994ca4aff1a3 100644
--- a/drivers/misc/mei/nfc.c
+++ b/drivers/misc/mei/nfc.c
@@ -485,8 +485,11 @@ int mei_nfc_host_init(struct mei_device *dev)
485 if (ndev->cl_info) 485 if (ndev->cl_info)
486 return 0; 486 return 0;
487 487
488 cl_info = mei_cl_allocate(dev); 488 ndev->cl_info = mei_cl_allocate(dev);
489 cl = mei_cl_allocate(dev); 489 ndev->cl = mei_cl_allocate(dev);
490
491 cl = ndev->cl;
492 cl_info = ndev->cl_info;
490 493
491 if (!cl || !cl_info) { 494 if (!cl || !cl_info) {
492 ret = -ENOMEM; 495 ret = -ENOMEM;
@@ -527,10 +530,9 @@ int mei_nfc_host_init(struct mei_device *dev)
527 530
528 cl->device_uuid = mei_nfc_guid; 531 cl->device_uuid = mei_nfc_guid;
529 532
533
530 list_add_tail(&cl->device_link, &dev->device_list); 534 list_add_tail(&cl->device_link, &dev->device_list);
531 535
532 ndev->cl_info = cl_info;
533 ndev->cl = cl;
534 ndev->req_id = 1; 536 ndev->req_id = 1;
535 537
536 INIT_WORK(&ndev->init_work, mei_nfc_init); 538 INIT_WORK(&ndev->init_work, mei_nfc_init);
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 1b3844e82379..b96205aece0c 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -77,6 +77,7 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = {
77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)}, 77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, 78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)}, 79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)}, 81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
81 82
82 /* required last entry */ 83 /* required last entry */
@@ -189,7 +190,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
189 190
190 schedule_delayed_work(&dev->timer_work, HZ); 191 schedule_delayed_work(&dev->timer_work, HZ);
191 192
192 pr_debug("initialization successful.\n"); 193 dev_dbg(&pdev->dev, "initialization successful.\n");
193 194
194 return 0; 195 return 0;
195 196
@@ -231,7 +232,7 @@ static void mei_me_remove(struct pci_dev *pdev)
231 hw = to_me_hw(dev); 232 hw = to_me_hw(dev);
232 233
233 234
234 dev_err(&pdev->dev, "stop\n"); 235 dev_dbg(&pdev->dev, "stop\n");
235 mei_stop(dev); 236 mei_stop(dev);
236 237
237 /* disable interrupts */ 238 /* disable interrupts */
@@ -239,7 +240,6 @@ static void mei_me_remove(struct pci_dev *pdev)
239 240
240 free_irq(pdev->irq, dev); 241 free_irq(pdev->irq, dev);
241 pci_disable_msi(pdev); 242 pci_disable_msi(pdev);
242 pci_set_drvdata(pdev, NULL);
243 243
244 if (hw->mem_addr) 244 if (hw->mem_addr)
245 pci_iounmap(pdev, hw->mem_addr); 245 pci_iounmap(pdev, hw->mem_addr);
@@ -262,7 +262,7 @@ static int mei_me_pci_suspend(struct device *device)
262 if (!dev) 262 if (!dev)
263 return -ENODEV; 263 return -ENODEV;
264 264
265 dev_err(&pdev->dev, "suspend\n"); 265 dev_dbg(&pdev->dev, "suspend\n");
266 266
267 mei_stop(dev); 267 mei_stop(dev);
268 268
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index b8921432e89d..9e354216c163 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -60,7 +60,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
60int mei_wd_host_init(struct mei_device *dev) 60int mei_wd_host_init(struct mei_device *dev)
61{ 61{
62 struct mei_cl *cl = &dev->wd_cl; 62 struct mei_cl *cl = &dev->wd_cl;
63 int i; 63 int id;
64 int ret; 64 int ret;
65 65
66 mei_cl_init(cl, dev); 66 mei_cl_init(cl, dev);
@@ -70,19 +70,19 @@ int mei_wd_host_init(struct mei_device *dev)
70 70
71 71
72 /* check for valid client id */ 72 /* check for valid client id */
73 i = mei_me_cl_by_uuid(dev, &mei_wd_guid); 73 id = mei_me_cl_by_uuid(dev, &mei_wd_guid);
74 if (i < 0) { 74 if (id < 0) {
75 dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); 75 dev_info(&dev->pdev->dev, "wd: failed to find the client\n");
76 return -ENOENT; 76 return id;
77 } 77 }
78 78
79 cl->me_client_id = dev->me_clients[i].client_id; 79 cl->me_client_id = dev->me_clients[id].client_id;
80 80
81 ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); 81 ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
82 82
83 if (ret < 0) { 83 if (ret < 0) {
84 dev_info(&dev->pdev->dev, "wd: failed link client\n"); 84 dev_info(&dev->pdev->dev, "wd: failed link client\n");
85 return -ENOENT; 85 return ret;
86 } 86 }
87 87
88 cl->state = MEI_FILE_CONNECTING; 88 cl->state = MEI_FILE_CONNECTING;
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
new file mode 100644
index 000000000000..e42b331edbc6
--- /dev/null
+++ b/drivers/misc/mic/Kconfig
@@ -0,0 +1,39 @@
1comment "Intel MIC Host Driver"
2
3config INTEL_MIC_HOST
4 tristate "Intel MIC Host Driver"
5 depends on 64BIT && PCI && X86
6 select VHOST_RING
7 default N
8 help
9 This enables Host Driver support for the Intel Many Integrated
10 Core (MIC) family of PCIe form factor coprocessor devices that
11 run a 64 bit Linux OS. The driver manages card OS state and
12 enables communication between host and card. Intel MIC X100
13 devices are currently supported.
14
15 If you are building a host kernel with an Intel MIC device then
16 say M (recommended) or Y, else say N. If unsure say N.
17
18 More information about the Intel MIC family as well as the Linux
19 OS and tools for MIC to use with this driver are available from
20 <http://software.intel.com/en-us/mic-developer>.
21
22comment "Intel MIC Card Driver"
23
24config INTEL_MIC_CARD
25 tristate "Intel MIC Card Driver"
26 depends on 64BIT && X86
27 select VIRTIO
28 default N
29 help
30 This enables card driver support for the Intel Many Integrated
31 Core (MIC) device family. The card driver communicates shutdown/
32 crash events to the host and allows registration/configuration of
33 virtio devices. Intel MIC X100 devices are currently supported.
34
35 If you are building a card kernel for an Intel MIC device then
36 say M (recommended) or Y, else say N. If unsure say N.
37
38 For more information see
39 <http://software.intel.com/en-us/mic-developer>.
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile
new file mode 100644
index 000000000000..05b34d683a58
--- /dev/null
+++ b/drivers/misc/mic/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5obj-$(CONFIG_INTEL_MIC_HOST) += host/
6obj-$(CONFIG_INTEL_MIC_CARD) += card/
diff --git a/drivers/misc/mic/card/Makefile b/drivers/misc/mic/card/Makefile
new file mode 100644
index 000000000000..69d58bef92ce
--- /dev/null
+++ b/drivers/misc/mic/card/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5ccflags-y += -DINTEL_MIC_CARD
6
7obj-$(CONFIG_INTEL_MIC_CARD) += mic_card.o
8mic_card-y += mic_x100.o
9mic_card-y += mic_device.o
10mic_card-y += mic_debugfs.o
11mic_card-y += mic_virtio.o
diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c
new file mode 100644
index 000000000000..421b3d7911df
--- /dev/null
+++ b/drivers/misc/mic/card/mic_debugfs.c
@@ -0,0 +1,130 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/debugfs.h>
28#include <linux/delay.h>
29#include <linux/seq_file.h>
30#include <linux/interrupt.h>
31#include <linux/device.h>
32
33#include "../common/mic_dev.h"
34#include "mic_device.h"
35
36/* Debugfs parent dir */
37static struct dentry *mic_dbg;
38
39/**
40 * mic_intr_test - Send interrupts to host.
41 */
42static int mic_intr_test(struct seq_file *s, void *unused)
43{
44 struct mic_driver *mdrv = s->private;
45 struct mic_device *mdev = &mdrv->mdev;
46
47 mic_send_intr(mdev, 0);
48 msleep(1000);
49 mic_send_intr(mdev, 1);
50 msleep(1000);
51 mic_send_intr(mdev, 2);
52 msleep(1000);
53 mic_send_intr(mdev, 3);
54 msleep(1000);
55
56 return 0;
57}
58
59static int mic_intr_test_open(struct inode *inode, struct file *file)
60{
61 return single_open(file, mic_intr_test, inode->i_private);
62}
63
64static int mic_intr_test_release(struct inode *inode, struct file *file)
65{
66 return single_release(inode, file);
67}
68
69static const struct file_operations intr_test_ops = {
70 .owner = THIS_MODULE,
71 .open = mic_intr_test_open,
72 .read = seq_read,
73 .llseek = seq_lseek,
74 .release = mic_intr_test_release
75};
76
77/**
78 * mic_create_card_debug_dir - Initialize MIC debugfs entries.
79 */
80void __init mic_create_card_debug_dir(struct mic_driver *mdrv)
81{
82 struct dentry *d;
83
84 if (!mic_dbg)
85 return;
86
87 mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg);
88 if (!mdrv->dbg_dir) {
89 dev_err(mdrv->dev, "Cant create dbg_dir %s\n", mdrv->name);
90 return;
91 }
92
93 d = debugfs_create_file("intr_test", 0444, mdrv->dbg_dir,
94 mdrv, &intr_test_ops);
95
96 if (!d) {
97 dev_err(mdrv->dev,
98 "Cant create dbg intr_test %s\n", mdrv->name);
99 return;
100 }
101}
102
103/**
104 * mic_delete_card_debug_dir - Uninitialize MIC debugfs entries.
105 */
106void mic_delete_card_debug_dir(struct mic_driver *mdrv)
107{
108 if (!mdrv->dbg_dir)
109 return;
110
111 debugfs_remove_recursive(mdrv->dbg_dir);
112}
113
114/**
115 * mic_init_card_debugfs - Initialize global debugfs entry.
116 */
117void __init mic_init_card_debugfs(void)
118{
119 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
120 if (!mic_dbg)
121 pr_err("can't create debugfs dir\n");
122}
123
124/**
125 * mic_exit_card_debugfs - Uninitialize global debugfs entry
126 */
127void mic_exit_card_debugfs(void)
128{
129 debugfs_remove(mic_dbg);
130}
diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c
new file mode 100644
index 000000000000..d0980ff96833
--- /dev/null
+++ b/drivers/misc/mic/card/mic_device.c
@@ -0,0 +1,305 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/interrupt.h>
30#include <linux/reboot.h>
31
32#include <linux/mic_common.h>
33#include "../common/mic_dev.h"
34#include "mic_device.h"
35#include "mic_virtio.h"
36
37static struct mic_driver *g_drv;
38static struct mic_irq *shutdown_cookie;
39
40static void mic_notify_host(u8 state)
41{
42 struct mic_driver *mdrv = g_drv;
43 struct mic_bootparam __iomem *bootparam = mdrv->dp;
44
45 iowrite8(state, &bootparam->shutdown_status);
46 dev_dbg(mdrv->dev, "%s %d system_state %d\n",
47 __func__, __LINE__, state);
48 mic_send_intr(&mdrv->mdev, ioread8(&bootparam->c2h_shutdown_db));
49}
50
51static int mic_panic_event(struct notifier_block *this, unsigned long event,
52 void *ptr)
53{
54 struct mic_driver *mdrv = g_drv;
55 struct mic_bootparam __iomem *bootparam = mdrv->dp;
56
57 iowrite8(-1, &bootparam->h2c_config_db);
58 iowrite8(-1, &bootparam->h2c_shutdown_db);
59 mic_notify_host(MIC_CRASHED);
60 return NOTIFY_DONE;
61}
62
63static struct notifier_block mic_panic = {
64 .notifier_call = mic_panic_event,
65};
66
67static irqreturn_t mic_shutdown_isr(int irq, void *data)
68{
69 struct mic_driver *mdrv = g_drv;
70 struct mic_bootparam __iomem *bootparam = mdrv->dp;
71
72 mic_ack_interrupt(&g_drv->mdev);
73 if (ioread8(&bootparam->shutdown_card))
74 orderly_poweroff(true);
75 return IRQ_HANDLED;
76}
77
78static int mic_shutdown_init(void)
79{
80 int rc = 0;
81 struct mic_driver *mdrv = g_drv;
82 struct mic_bootparam __iomem *bootparam = mdrv->dp;
83 int shutdown_db;
84
85 shutdown_db = mic_next_card_db();
86 shutdown_cookie = mic_request_card_irq(mic_shutdown_isr,
87 "Shutdown", mdrv, shutdown_db);
88 if (IS_ERR(shutdown_cookie))
89 rc = PTR_ERR(shutdown_cookie);
90 else
91 iowrite8(shutdown_db, &bootparam->h2c_shutdown_db);
92 return rc;
93}
94
95static void mic_shutdown_uninit(void)
96{
97 struct mic_driver *mdrv = g_drv;
98 struct mic_bootparam __iomem *bootparam = mdrv->dp;
99
100 iowrite8(-1, &bootparam->h2c_shutdown_db);
101 mic_free_card_irq(shutdown_cookie, mdrv);
102}
103
104static int __init mic_dp_init(void)
105{
106 struct mic_driver *mdrv = g_drv;
107 struct mic_device *mdev = &mdrv->mdev;
108 struct mic_bootparam __iomem *bootparam;
109 u64 lo, hi, dp_dma_addr;
110 u32 magic;
111
112 lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD);
113 hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD);
114
115 dp_dma_addr = lo | (hi << 32);
116 mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE);
117 if (!mdrv->dp) {
118 dev_err(mdrv->dev, "Cannot remap Aperture BAR\n");
119 return -ENOMEM;
120 }
121 bootparam = mdrv->dp;
122 magic = ioread32(&bootparam->magic);
123 if (MIC_MAGIC != magic) {
124 dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic);
125 return -EIO;
126 }
127 return 0;
128}
129
130/* Uninitialize the device page */
131static void mic_dp_uninit(void)
132{
133 mic_card_unmap(&g_drv->mdev, g_drv->dp);
134}
135
136/**
137 * mic_request_card_irq - request an irq.
138 *
139 * @func: The callback function that handles the interrupt.
140 * @name: The ASCII name of the callee requesting the irq.
141 * @data: private data that is returned back when calling the
142 * function handler.
143 * @index: The doorbell index of the requester.
144 *
145 * returns: The cookie that is transparent to the caller. Passed
146 * back when calling mic_free_irq. An appropriate error code
147 * is returned on failure. Caller needs to use IS_ERR(return_val)
148 * to check for failure and PTR_ERR(return_val) to obtained the
149 * error code.
150 *
151 */
152struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
153 const char *name, void *data, int index)
154{
155 int rc = 0;
156 unsigned long cookie;
157 struct mic_driver *mdrv = g_drv;
158
159 rc = request_irq(mic_db_to_irq(mdrv, index), func,
160 0, name, data);
161 if (rc) {
162 dev_err(mdrv->dev, "request_irq failed rc = %d\n", rc);
163 goto err;
164 }
165 mdrv->irq_info.irq_usage_count[index]++;
166 cookie = index;
167 return (struct mic_irq *)cookie;
168err:
169 return ERR_PTR(rc);
170}
171
172/**
173 * mic_free_card_irq - free irq.
174 *
175 * @cookie: cookie obtained during a successful call to mic_request_irq
176 * @data: private data specified by the calling function during the
177 * mic_request_irq
178 *
179 * returns: none.
180 */
181void mic_free_card_irq(struct mic_irq *cookie, void *data)
182{
183 int index;
184 struct mic_driver *mdrv = g_drv;
185
186 index = (unsigned long)cookie & 0xFFFFU;
187 free_irq(mic_db_to_irq(mdrv, index), data);
188 mdrv->irq_info.irq_usage_count[index]--;
189}
190
191/**
192 * mic_next_card_db - Get the doorbell with minimum usage count.
193 *
194 * Returns the irq index.
195 */
196int mic_next_card_db(void)
197{
198 int i;
199 int index = 0;
200 struct mic_driver *mdrv = g_drv;
201
202 for (i = 0; i < mdrv->intr_info.num_intr; i++) {
203 if (mdrv->irq_info.irq_usage_count[i] <
204 mdrv->irq_info.irq_usage_count[index])
205 index = i;
206 }
207
208 return index;
209}
210
211/**
212 * mic_init_irq - Initialize irq information.
213 *
214 * Returns 0 in success. Appropriate error code on failure.
215 */
216static int mic_init_irq(void)
217{
218 struct mic_driver *mdrv = g_drv;
219
220 mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
221 mdrv->intr_info.num_intr),
222 GFP_KERNEL);
223 if (!mdrv->irq_info.irq_usage_count)
224 return -ENOMEM;
225 return 0;
226}
227
228/**
229 * mic_uninit_irq - Uninitialize irq information.
230 *
231 * None.
232 */
233static void mic_uninit_irq(void)
234{
235 struct mic_driver *mdrv = g_drv;
236
237 kfree(mdrv->irq_info.irq_usage_count);
238}
239
240/*
241 * mic_driver_init - MIC driver initialization tasks.
242 *
243 * Returns 0 in success. Appropriate error code on failure.
244 */
245int __init mic_driver_init(struct mic_driver *mdrv)
246{
247 int rc;
248
249 g_drv = mdrv;
250 /*
251 * Unloading the card module is not supported. The MIC card module
252 * handles fundamental operations like host/card initiated shutdowns
253 * and informing the host about card crashes and cannot be unloaded.
254 */
255 if (!try_module_get(mdrv->dev->driver->owner)) {
256 rc = -ENODEV;
257 goto done;
258 }
259 rc = mic_dp_init();
260 if (rc)
261 goto put;
262 rc = mic_init_irq();
263 if (rc)
264 goto dp_uninit;
265 rc = mic_shutdown_init();
266 if (rc)
267 goto irq_uninit;
268 rc = mic_devices_init(mdrv);
269 if (rc)
270 goto shutdown_uninit;
271 mic_create_card_debug_dir(mdrv);
272 atomic_notifier_chain_register(&panic_notifier_list, &mic_panic);
273done:
274 return rc;
275shutdown_uninit:
276 mic_shutdown_uninit();
277irq_uninit:
278 mic_uninit_irq();
279dp_uninit:
280 mic_dp_uninit();
281put:
282 module_put(mdrv->dev->driver->owner);
283 return rc;
284}
285
286/*
287 * mic_driver_uninit - MIC driver uninitialization tasks.
288 *
289 * Returns None
290 */
291void mic_driver_uninit(struct mic_driver *mdrv)
292{
293 mic_delete_card_debug_dir(mdrv);
294 mic_devices_uninit(mdrv);
295 /*
296 * Inform the host about the shutdown status i.e. poweroff/restart etc.
297 * The module cannot be unloaded so the only code path to call
298 * mic_devices_uninit(..) is the shutdown callback.
299 */
300 mic_notify_host(system_state);
301 mic_shutdown_uninit();
302 mic_uninit_irq();
303 mic_dp_uninit();
304 module_put(mdrv->dev->driver->owner);
305}
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h
new file mode 100644
index 000000000000..347b9b3b7916
--- /dev/null
+++ b/drivers/misc/mic/card/mic_device.h
@@ -0,0 +1,133 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef _MIC_CARD_DEVICE_H_
28#define _MIC_CARD_DEVICE_H_
29
30#include <linux/workqueue.h>
31#include <linux/io.h>
32
33/**
34 * struct mic_intr_info - Contains h/w specific interrupt sources info
35 *
36 * @num_intr: The number of irqs available
37 */
38struct mic_intr_info {
39 u32 num_intr;
40};
41
42/**
43 * struct mic_irq_info - OS specific irq information
44 *
45 * @irq_usage_count: usage count array tracking the number of sources
46 * assigned for each irq.
47 */
48struct mic_irq_info {
49 int *irq_usage_count;
50};
51
52/**
53 * struct mic_device - MIC device information.
54 *
55 * @mmio: MMIO bar information.
56 */
57struct mic_device {
58 struct mic_mw mmio;
59};
60
61/**
62 * struct mic_driver - MIC card driver information.
63 *
64 * @name: Name for MIC driver.
65 * @dbg_dir: debugfs directory of this MIC device.
66 * @dev: The device backing this MIC.
67 * @dp: The pointer to the virtio device page.
68 * @mdev: MIC device information for the host.
69 * @hotplug_work: Hot plug work for adding/removing virtio devices.
70 * @irq_info: The OS specific irq information
71 * @intr_info: H/W specific interrupt information.
72 */
73struct mic_driver {
74 char name[20];
75 struct dentry *dbg_dir;
76 struct device *dev;
77 void __iomem *dp;
78 struct mic_device mdev;
79 struct work_struct hotplug_work;
80 struct mic_irq_info irq_info;
81 struct mic_intr_info intr_info;
82};
83
84/**
85 * struct mic_irq - opaque pointer used as cookie
86 */
87struct mic_irq;
88
89/**
90 * mic_mmio_read - read from an MMIO register.
91 * @mw: MMIO register base virtual address.
92 * @offset: register offset.
93 *
94 * RETURNS: register value.
95 */
96static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
97{
98 return ioread32(mw->va + offset);
99}
100
101/**
102 * mic_mmio_write - write to an MMIO register.
103 * @mw: MMIO register base virtual address.
104 * @val: the data value to put into the register
105 * @offset: register offset.
106 *
107 * RETURNS: none.
108 */
109static inline void
110mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
111{
112 iowrite32(val, mw->va + offset);
113}
114
115int mic_driver_init(struct mic_driver *mdrv);
116void mic_driver_uninit(struct mic_driver *mdrv);
117int mic_next_card_db(void);
118struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
119 const char *name, void *data, int intr_src);
120void mic_free_card_irq(struct mic_irq *cookie, void *data);
121u32 mic_read_spad(struct mic_device *mdev, unsigned int idx);
122void mic_send_intr(struct mic_device *mdev, int doorbell);
123int mic_db_to_irq(struct mic_driver *mdrv, int db);
124u32 mic_ack_interrupt(struct mic_device *mdev);
125void mic_hw_intr_init(struct mic_driver *mdrv);
126void __iomem *
127mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size);
128void mic_card_unmap(struct mic_device *mdev, void __iomem *addr);
129void __init mic_create_card_debug_dir(struct mic_driver *mdrv);
130void mic_delete_card_debug_dir(struct mic_driver *mdrv);
131void __init mic_init_card_debugfs(void);
132void mic_exit_card_debugfs(void);
133#endif
diff --git a/drivers/misc/mic/card/mic_virtio.c b/drivers/misc/mic/card/mic_virtio.c
new file mode 100644
index 000000000000..914cc9b2caad
--- /dev/null
+++ b/drivers/misc/mic/card/mic_virtio.c
@@ -0,0 +1,630 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Adapted from:
25 *
26 * virtio for kvm on s390
27 *
28 * Copyright IBM Corp. 2008
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License (version 2 only)
32 * as published by the Free Software Foundation.
33 *
34 * Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
35 *
36 * Intel MIC Card driver.
37 *
38 */
39#include <linux/delay.h>
40#include <linux/slab.h>
41#include <linux/virtio_config.h>
42
43#include "../common/mic_dev.h"
44#include "mic_virtio.h"
45
46#define VIRTIO_SUBCODE_64 0x0D00
47
48#define MIC_MAX_VRINGS 4
49struct mic_vdev {
50 struct virtio_device vdev;
51 struct mic_device_desc __iomem *desc;
52 struct mic_device_ctrl __iomem *dc;
53 struct mic_device *mdev;
54 void __iomem *vr[MIC_MAX_VRINGS];
55 int used_size[MIC_MAX_VRINGS];
56 struct completion reset_done;
57 struct mic_irq *virtio_cookie;
58 int c2h_vdev_db;
59};
60
61static struct mic_irq *virtio_config_cookie;
62#define to_micvdev(vd) container_of(vd, struct mic_vdev, vdev)
63
64/* Helper API to obtain the parent of the virtio device */
65static inline struct device *mic_dev(struct mic_vdev *mvdev)
66{
67 return mvdev->vdev.dev.parent;
68}
69
70/* This gets the device's feature bits. */
71static u32 mic_get_features(struct virtio_device *vdev)
72{
73 unsigned int i, bits;
74 u32 features = 0;
75 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
76 u8 __iomem *in_features = mic_vq_features(desc);
77 int feature_len = ioread8(&desc->feature_len);
78
79 bits = min_t(unsigned, feature_len,
80 sizeof(vdev->features)) * 8;
81 for (i = 0; i < bits; i++)
82 if (ioread8(&in_features[i / 8]) & (BIT(i % 8)))
83 features |= BIT(i);
84
85 return features;
86}
87
88static void mic_finalize_features(struct virtio_device *vdev)
89{
90 unsigned int i, bits;
91 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
92 u8 feature_len = ioread8(&desc->feature_len);
93 /* Second half of bitmap is features we accept. */
94 u8 __iomem *out_features =
95 mic_vq_features(desc) + feature_len;
96
97 /* Give virtio_ring a chance to accept features. */
98 vring_transport_features(vdev);
99
100 memset_io(out_features, 0, feature_len);
101 bits = min_t(unsigned, feature_len,
102 sizeof(vdev->features)) * 8;
103 for (i = 0; i < bits; i++) {
104 if (test_bit(i, vdev->features))
105 iowrite8(ioread8(&out_features[i / 8]) | (1 << (i % 8)),
106 &out_features[i / 8]);
107 }
108}
109
110/*
111 * Reading and writing elements in config space
112 */
113static void mic_get(struct virtio_device *vdev, unsigned int offset,
114 void *buf, unsigned len)
115{
116 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
117
118 if (offset + len > ioread8(&desc->config_len))
119 return;
120 memcpy_fromio(buf, mic_vq_configspace(desc) + offset, len);
121}
122
123static void mic_set(struct virtio_device *vdev, unsigned int offset,
124 const void *buf, unsigned len)
125{
126 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
127
128 if (offset + len > ioread8(&desc->config_len))
129 return;
130 memcpy_toio(mic_vq_configspace(desc) + offset, buf, len);
131}
132
133/*
134 * The operations to get and set the status word just access the status
135 * field of the device descriptor. set_status also interrupts the host
136 * to tell about status changes.
137 */
138static u8 mic_get_status(struct virtio_device *vdev)
139{
140 return ioread8(&to_micvdev(vdev)->desc->status);
141}
142
143static void mic_set_status(struct virtio_device *vdev, u8 status)
144{
145 struct mic_vdev *mvdev = to_micvdev(vdev);
146 if (!status)
147 return;
148 iowrite8(status, &mvdev->desc->status);
149 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
150}
151
152/* Inform host on a virtio device reset and wait for ack from host */
153static void mic_reset_inform_host(struct virtio_device *vdev)
154{
155 struct mic_vdev *mvdev = to_micvdev(vdev);
156 struct mic_device_ctrl __iomem *dc = mvdev->dc;
157 int retry = 100, i;
158
159 iowrite8(0, &dc->host_ack);
160 iowrite8(1, &dc->vdev_reset);
161 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
162
163 /* Wait till host completes all card accesses and acks the reset */
164 for (i = retry; i--;) {
165 if (ioread8(&dc->host_ack))
166 break;
167 msleep(100);
168 };
169
170 dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
171
172 /* Reset status to 0 in case we timed out */
173 iowrite8(0, &mvdev->desc->status);
174}
175
176static void mic_reset(struct virtio_device *vdev)
177{
178 struct mic_vdev *mvdev = to_micvdev(vdev);
179
180 dev_dbg(mic_dev(mvdev), "%s: virtio id %d\n",
181 __func__, vdev->id.device);
182
183 mic_reset_inform_host(vdev);
184 complete_all(&mvdev->reset_done);
185}
186
187/*
188 * The virtio_ring code calls this API when it wants to notify the Host.
189 */
190static void mic_notify(struct virtqueue *vq)
191{
192 struct mic_vdev *mvdev = vq->priv;
193
194 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
195}
196
197static void mic_del_vq(struct virtqueue *vq, int n)
198{
199 struct mic_vdev *mvdev = to_micvdev(vq->vdev);
200 struct vring *vr = (struct vring *)(vq + 1);
201
202 free_pages((unsigned long) vr->used, get_order(mvdev->used_size[n]));
203 vring_del_virtqueue(vq);
204 mic_card_unmap(mvdev->mdev, mvdev->vr[n]);
205 mvdev->vr[n] = NULL;
206}
207
208static void mic_del_vqs(struct virtio_device *vdev)
209{
210 struct mic_vdev *mvdev = to_micvdev(vdev);
211 struct virtqueue *vq, *n;
212 int idx = 0;
213
214 dev_dbg(mic_dev(mvdev), "%s\n", __func__);
215
216 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
217 mic_del_vq(vq, idx++);
218}
219
220/*
221 * This routine will assign vring's allocated in host/io memory. Code in
222 * virtio_ring.c however continues to access this io memory as if it were local
223 * memory without io accessors.
224 */
225static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
226 unsigned index,
227 void (*callback)(struct virtqueue *vq),
228 const char *name)
229{
230 struct mic_vdev *mvdev = to_micvdev(vdev);
231 struct mic_vqconfig __iomem *vqconfig;
232 struct mic_vqconfig config;
233 struct virtqueue *vq;
234 void __iomem *va;
235 struct _mic_vring_info __iomem *info;
236 void *used;
237 int vr_size, _vr_size, err, magic;
238 struct vring *vr;
239 u8 type = ioread8(&mvdev->desc->type);
240
241 if (index >= ioread8(&mvdev->desc->num_vq))
242 return ERR_PTR(-ENOENT);
243
244 if (!name)
245 return ERR_PTR(-ENOENT);
246
247 /* First assign the vring's allocated in host memory */
248 vqconfig = mic_vq_config(mvdev->desc) + index;
249 memcpy_fromio(&config, vqconfig, sizeof(config));
250 _vr_size = vring_size(config.num, MIC_VIRTIO_RING_ALIGN);
251 vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
252 va = mic_card_map(mvdev->mdev, config.address, vr_size);
253 if (!va)
254 return ERR_PTR(-ENOMEM);
255 mvdev->vr[index] = va;
256 memset_io(va, 0x0, _vr_size);
257 vq = vring_new_virtqueue(index,
258 config.num, MIC_VIRTIO_RING_ALIGN, vdev,
259 false,
260 va, mic_notify, callback, name);
261 if (!vq) {
262 err = -ENOMEM;
263 goto unmap;
264 }
265 info = va + _vr_size;
266 magic = ioread32(&info->magic);
267
268 if (WARN(magic != MIC_MAGIC + type + index, "magic mismatch")) {
269 err = -EIO;
270 goto unmap;
271 }
272
273 /* Allocate and reassign used ring now */
274 mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
275 sizeof(struct vring_used_elem) * config.num);
276 used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
277 get_order(mvdev->used_size[index]));
278 if (!used) {
279 err = -ENOMEM;
280 dev_err(mic_dev(mvdev), "%s %d err %d\n",
281 __func__, __LINE__, err);
282 goto del_vq;
283 }
284 iowrite64(virt_to_phys(used), &vqconfig->used_address);
285
286 /*
287 * To reassign the used ring here we are directly accessing
288 * struct vring_virtqueue which is a private data structure
289 * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
290 * vring_new_virtqueue() would ensure that
291 * (&vq->vring == (struct vring *) (&vq->vq + 1));
292 */
293 vr = (struct vring *)(vq + 1);
294 vr->used = used;
295
296 vq->priv = mvdev;
297 return vq;
298del_vq:
299 vring_del_virtqueue(vq);
300unmap:
301 mic_card_unmap(mvdev->mdev, mvdev->vr[index]);
302 return ERR_PTR(err);
303}
304
305static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
306 struct virtqueue *vqs[],
307 vq_callback_t *callbacks[],
308 const char *names[])
309{
310 struct mic_vdev *mvdev = to_micvdev(vdev);
311 struct mic_device_ctrl __iomem *dc = mvdev->dc;
312 int i, err, retry = 100;
313
314 /* We must have this many virtqueues. */
315 if (nvqs > ioread8(&mvdev->desc->num_vq))
316 return -ENOENT;
317
318 for (i = 0; i < nvqs; ++i) {
319 dev_dbg(mic_dev(mvdev), "%s: %d: %s\n",
320 __func__, i, names[i]);
321 vqs[i] = mic_find_vq(vdev, i, callbacks[i], names[i]);
322 if (IS_ERR(vqs[i])) {
323 err = PTR_ERR(vqs[i]);
324 goto error;
325 }
326 }
327
328 iowrite8(1, &dc->used_address_updated);
329 /*
330 * Send an interrupt to the host to inform it that used
331 * rings have been re-assigned.
332 */
333 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
334 for (i = retry; i--;) {
335 if (!ioread8(&dc->used_address_updated))
336 break;
337 msleep(100);
338 };
339
340 dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
341 if (!retry) {
342 err = -ENODEV;
343 goto error;
344 }
345
346 return 0;
347error:
348 mic_del_vqs(vdev);
349 return err;
350}
351
352/*
353 * The config ops structure as defined by virtio config
354 */
355static struct virtio_config_ops mic_vq_config_ops = {
356 .get_features = mic_get_features,
357 .finalize_features = mic_finalize_features,
358 .get = mic_get,
359 .set = mic_set,
360 .get_status = mic_get_status,
361 .set_status = mic_set_status,
362 .reset = mic_reset,
363 .find_vqs = mic_find_vqs,
364 .del_vqs = mic_del_vqs,
365};
366
367static irqreturn_t
368mic_virtio_intr_handler(int irq, void *data)
369{
370 struct mic_vdev *mvdev = data;
371 struct virtqueue *vq;
372
373 mic_ack_interrupt(mvdev->mdev);
374 list_for_each_entry(vq, &mvdev->vdev.vqs, list)
375 vring_interrupt(0, vq);
376
377 return IRQ_HANDLED;
378}
379
380static void mic_virtio_release_dev(struct device *_d)
381{
382 /*
383 * No need for a release method similar to virtio PCI.
384 * Provide an empty one to avoid getting a warning from core.
385 */
386}
387
388/*
389 * adds a new device and register it with virtio
390 * appropriate drivers are loaded by the device model
391 */
392static int mic_add_device(struct mic_device_desc __iomem *d,
393 unsigned int offset, struct mic_driver *mdrv)
394{
395 struct mic_vdev *mvdev;
396 int ret;
397 int virtio_db;
398 u8 type = ioread8(&d->type);
399
400 mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
401 if (!mvdev) {
402 dev_err(mdrv->dev, "Cannot allocate mic dev %u type %u\n",
403 offset, type);
404 return -ENOMEM;
405 }
406
407 mvdev->mdev = &mdrv->mdev;
408 mvdev->vdev.dev.parent = mdrv->dev;
409 mvdev->vdev.dev.release = mic_virtio_release_dev;
410 mvdev->vdev.id.device = type;
411 mvdev->vdev.config = &mic_vq_config_ops;
412 mvdev->desc = d;
413 mvdev->dc = (void __iomem *)d + mic_aligned_desc_size(d);
414 init_completion(&mvdev->reset_done);
415
416 virtio_db = mic_next_card_db();
417 mvdev->virtio_cookie = mic_request_card_irq(mic_virtio_intr_handler,
418 "virtio intr", mvdev, virtio_db);
419 if (IS_ERR(mvdev->virtio_cookie)) {
420 ret = PTR_ERR(mvdev->virtio_cookie);
421 goto kfree;
422 }
423 iowrite8((u8)virtio_db, &mvdev->dc->h2c_vdev_db);
424 mvdev->c2h_vdev_db = ioread8(&mvdev->dc->c2h_vdev_db);
425
426 ret = register_virtio_device(&mvdev->vdev);
427 if (ret) {
428 dev_err(mic_dev(mvdev),
429 "Failed to register mic device %u type %u\n",
430 offset, type);
431 goto free_irq;
432 }
433 iowrite64((u64)mvdev, &mvdev->dc->vdev);
434 dev_dbg(mic_dev(mvdev), "%s: registered mic device %u type %u mvdev %p\n",
435 __func__, offset, type, mvdev);
436
437 return 0;
438
439free_irq:
440 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
441kfree:
442 kfree(mvdev);
443 return ret;
444}
445
446/*
447 * match for a mic device with a specific desc pointer
448 */
449static int mic_match_desc(struct device *dev, void *data)
450{
451 struct virtio_device *vdev = dev_to_virtio(dev);
452 struct mic_vdev *mvdev = to_micvdev(vdev);
453
454 return mvdev->desc == (void __iomem *)data;
455}
456
457static void mic_handle_config_change(struct mic_device_desc __iomem *d,
458 unsigned int offset, struct mic_driver *mdrv)
459{
460 struct mic_device_ctrl __iomem *dc
461 = (void __iomem *)d + mic_aligned_desc_size(d);
462 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
463 struct virtio_driver *drv;
464
465 if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED)
466 return;
467
468 dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__);
469 drv = container_of(mvdev->vdev.dev.driver,
470 struct virtio_driver, driver);
471 if (drv->config_changed)
472 drv->config_changed(&mvdev->vdev);
473 iowrite8(1, &dc->guest_ack);
474}
475
476/*
477 * removes a virtio device if a hot remove event has been
478 * requested by the host.
479 */
480static int mic_remove_device(struct mic_device_desc __iomem *d,
481 unsigned int offset, struct mic_driver *mdrv)
482{
483 struct mic_device_ctrl __iomem *dc
484 = (void __iomem *)d + mic_aligned_desc_size(d);
485 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
486 u8 status;
487 int ret = -1;
488
489 if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) {
490 dev_dbg(mdrv->dev,
491 "%s %d config_change %d type %d mvdev %p\n",
492 __func__, __LINE__,
493 ioread8(&dc->config_change), ioread8(&d->type), mvdev);
494
495 status = ioread8(&d->status);
496 INIT_COMPLETION(mvdev->reset_done);
497 unregister_virtio_device(&mvdev->vdev);
498 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
499 if (status & VIRTIO_CONFIG_S_DRIVER_OK)
500 wait_for_completion(&mvdev->reset_done);
501 kfree(mvdev);
502 iowrite8(1, &dc->guest_ack);
503 dev_dbg(mdrv->dev, "%s %d guest_ack %d\n",
504 __func__, __LINE__, ioread8(&dc->guest_ack));
505 ret = 0;
506 }
507
508 return ret;
509}
510
511#define REMOVE_DEVICES true
512
513static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
514{
515 s8 type;
516 unsigned int i;
517 struct mic_device_desc __iomem *d;
518 struct mic_device_ctrl __iomem *dc;
519 struct device *dev;
520 int ret;
521
522 for (i = mic_aligned_size(struct mic_bootparam);
523 i < MIC_DP_SIZE; i += mic_total_desc_size(d)) {
524 d = mdrv->dp + i;
525 dc = (void __iomem *)d + mic_aligned_desc_size(d);
526 /*
527 * This read barrier is paired with the corresponding write
528 * barrier on the host which is inserted before adding or
529 * removing a virtio device descriptor, by updating the type.
530 */
531 rmb();
532 type = ioread8(&d->type);
533
534 /* end of list */
535 if (type == 0)
536 break;
537
538 if (type == -1)
539 continue;
540
541 /* device already exists */
542 dev = device_find_child(mdrv->dev, d, mic_match_desc);
543 if (dev) {
544 if (remove)
545 iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
546 &dc->config_change);
547 put_device(dev);
548 mic_handle_config_change(d, i, mdrv);
549 ret = mic_remove_device(d, i, mdrv);
550 if (!ret && !remove)
551 iowrite8(-1, &d->type);
552 if (remove) {
553 iowrite8(0, &dc->config_change);
554 iowrite8(0, &dc->guest_ack);
555 }
556 continue;
557 }
558
559 /* new device */
560 dev_dbg(mdrv->dev, "%s %d Adding new virtio device %p\n",
561 __func__, __LINE__, d);
562 if (!remove)
563 mic_add_device(d, i, mdrv);
564 }
565}
566
567/*
568 * mic_hotplug_device tries to find changes in the device page.
569 */
570static void mic_hotplug_devices(struct work_struct *work)
571{
572 struct mic_driver *mdrv = container_of(work,
573 struct mic_driver, hotplug_work);
574
575 mic_scan_devices(mdrv, !REMOVE_DEVICES);
576}
577
578/*
579 * Interrupt handler for hot plug/config changes etc.
580 */
581static irqreturn_t
582mic_extint_handler(int irq, void *data)
583{
584 struct mic_driver *mdrv = (struct mic_driver *)data;
585
586 dev_dbg(mdrv->dev, "%s %d hotplug work\n",
587 __func__, __LINE__);
588 mic_ack_interrupt(&mdrv->mdev);
589 schedule_work(&mdrv->hotplug_work);
590 return IRQ_HANDLED;
591}
592
593/*
594 * Init function for virtio
595 */
596int mic_devices_init(struct mic_driver *mdrv)
597{
598 int rc;
599 struct mic_bootparam __iomem *bootparam;
600 int config_db;
601
602 INIT_WORK(&mdrv->hotplug_work, mic_hotplug_devices);
603 mic_scan_devices(mdrv, !REMOVE_DEVICES);
604
605 config_db = mic_next_card_db();
606 virtio_config_cookie = mic_request_card_irq(mic_extint_handler,
607 "virtio_config_intr", mdrv, config_db);
608 if (IS_ERR(virtio_config_cookie)) {
609 rc = PTR_ERR(virtio_config_cookie);
610 goto exit;
611 }
612
613 bootparam = mdrv->dp;
614 iowrite8(config_db, &bootparam->h2c_config_db);
615 return 0;
616exit:
617 return rc;
618}
619
620/*
621 * Uninit function for virtio
622 */
623void mic_devices_uninit(struct mic_driver *mdrv)
624{
625 struct mic_bootparam __iomem *bootparam = mdrv->dp;
626 iowrite8(-1, &bootparam->h2c_config_db);
627 mic_free_card_irq(virtio_config_cookie, mdrv);
628 flush_work(&mdrv->hotplug_work);
629 mic_scan_devices(mdrv, REMOVE_DEVICES);
630}
diff --git a/drivers/misc/mic/card/mic_virtio.h b/drivers/misc/mic/card/mic_virtio.h
new file mode 100644
index 000000000000..2c5c22c93ba8
--- /dev/null
+++ b/drivers/misc/mic/card/mic_virtio.h
@@ -0,0 +1,77 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef __MIC_CARD_VIRTIO_H
28#define __MIC_CARD_VIRTIO_H
29
30#include <linux/mic_common.h>
31#include "mic_device.h"
32
33/*
34 * 64 bit I/O access
35 */
36#ifndef ioread64
37#define ioread64 readq
38#endif
39#ifndef iowrite64
40#define iowrite64 writeq
41#endif
42
43static inline unsigned mic_desc_size(struct mic_device_desc __iomem *desc)
44{
45 return mic_aligned_size(*desc)
46 + ioread8(&desc->num_vq) * mic_aligned_size(struct mic_vqconfig)
47 + ioread8(&desc->feature_len) * 2
48 + ioread8(&desc->config_len);
49}
50
51static inline struct mic_vqconfig __iomem *
52mic_vq_config(struct mic_device_desc __iomem *desc)
53{
54 return (struct mic_vqconfig __iomem *)(desc + 1);
55}
56
57static inline __u8 __iomem *
58mic_vq_features(struct mic_device_desc __iomem *desc)
59{
60 return (__u8 __iomem *)(mic_vq_config(desc) + ioread8(&desc->num_vq));
61}
62
63static inline __u8 __iomem *
64mic_vq_configspace(struct mic_device_desc __iomem *desc)
65{
66 return mic_vq_features(desc) + ioread8(&desc->feature_len) * 2;
67}
68static inline unsigned mic_total_desc_size(struct mic_device_desc __iomem *desc)
69{
70 return mic_aligned_desc_size(desc) +
71 mic_aligned_size(struct mic_device_ctrl);
72}
73
74int mic_devices_init(struct mic_driver *mdrv);
75void mic_devices_uninit(struct mic_driver *mdrv);
76
77#endif
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c
new file mode 100644
index 000000000000..2868945c9a4d
--- /dev/null
+++ b/drivers/misc/mic/card/mic_x100.c
@@ -0,0 +1,256 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/platform_device.h>
30
31#include "../common/mic_dev.h"
32#include "mic_device.h"
33#include "mic_x100.h"
34
35static const char mic_driver_name[] = "mic";
36
37static struct mic_driver g_drv;
38
39/**
40 * mic_read_spad - read from the scratchpad register
41 * @mdev: pointer to mic_device instance
42 * @idx: index to scratchpad register, 0 based
43 *
44 * This function allows reading of the 32bit scratchpad register.
45 *
46 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
47 */
48u32 mic_read_spad(struct mic_device *mdev, unsigned int idx)
49{
50 return mic_mmio_read(&mdev->mmio,
51 MIC_X100_SBOX_BASE_ADDRESS +
52 MIC_X100_SBOX_SPAD0 + idx * 4);
53}
54
55/**
56 * __mic_send_intr - Send interrupt to Host.
57 * @mdev: pointer to mic_device instance
58 * @doorbell: Doorbell number.
59 */
60void mic_send_intr(struct mic_device *mdev, int doorbell)
61{
62 struct mic_mw *mw = &mdev->mmio;
63
64 if (doorbell > MIC_X100_MAX_DOORBELL_IDX)
65 return;
66 /* Ensure that the interrupt is ordered w.r.t previous stores. */
67 wmb();
68 mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT,
69 MIC_X100_SBOX_BASE_ADDRESS +
70 (MIC_X100_SBOX_SDBIC0 + (4 * doorbell)));
71}
72
73/**
74 * mic_ack_interrupt - Device specific interrupt handling.
75 * @mdev: pointer to mic_device instance
76 *
77 * Returns: bitmask of doorbell events triggered.
78 */
79u32 mic_ack_interrupt(struct mic_device *mdev)
80{
81 return 0;
82}
83
84static inline int mic_get_sbox_irq(int db)
85{
86 return MIC_X100_IRQ_BASE + db;
87}
88
89static inline int mic_get_rdmasr_irq(int index)
90{
91 return MIC_X100_RDMASR_IRQ_BASE + index;
92}
93
94/**
95 * mic_hw_intr_init - Initialize h/w specific interrupt
96 * information.
97 * @mdrv: pointer to mic_driver
98 */
99void mic_hw_intr_init(struct mic_driver *mdrv)
100{
101 mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ +
102 MIC_X100_NUM_RDMASR_IRQ;
103}
104
105/**
106 * mic_db_to_irq - Retrieve irq number corresponding to a doorbell.
107 * @mdrv: pointer to mic_driver
108 * @db: The doorbell obtained for which the irq is needed. Doorbell
109 * may correspond to an sbox doorbell or an rdmasr index.
110 *
111 * Returns the irq corresponding to the doorbell.
112 */
113int mic_db_to_irq(struct mic_driver *mdrv, int db)
114{
115 int rdmasr_index;
116 if (db < MIC_X100_NUM_SBOX_IRQ) {
117 return mic_get_sbox_irq(db);
118 } else {
119 rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ +
120 MIC_X100_RDMASR_IRQ_BASE;
121 return mic_get_rdmasr_irq(rdmasr_index);
122 }
123}
124
125/*
126 * mic_card_map - Allocate virtual address for a remote memory region.
127 * @mdev: pointer to mic_device instance.
128 * @addr: Remote DMA address.
129 * @size: Size of the region.
130 *
131 * Returns: Virtual address backing the remote memory region.
132 */
133void __iomem *
134mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size)
135{
136 return ioremap(addr, size);
137}
138
139/*
140 * mic_card_unmap - Unmap the virtual address for a remote memory region.
141 * @mdev: pointer to mic_device instance.
142 * @addr: Virtual address for remote memory region.
143 *
144 * Returns: None.
145 */
146void mic_card_unmap(struct mic_device *mdev, void __iomem *addr)
147{
148 iounmap(addr);
149}
150
151static int __init mic_probe(struct platform_device *pdev)
152{
153 struct mic_driver *mdrv = &g_drv;
154 struct mic_device *mdev = &mdrv->mdev;
155 int rc = 0;
156
157 mdrv->dev = &pdev->dev;
158 snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name);
159
160 mdev->mmio.pa = MIC_X100_MMIO_BASE;
161 mdev->mmio.len = MIC_X100_MMIO_LEN;
162 mdev->mmio.va = ioremap(MIC_X100_MMIO_BASE, MIC_X100_MMIO_LEN);
163 if (!mdev->mmio.va) {
164 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
165 rc = -EIO;
166 goto done;
167 }
168 mic_hw_intr_init(mdrv);
169 rc = mic_driver_init(mdrv);
170 if (rc) {
171 dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc);
172 goto iounmap;
173 }
174done:
175 return rc;
176iounmap:
177 iounmap(mdev->mmio.va);
178 return rc;
179}
180
181static int mic_remove(struct platform_device *pdev)
182{
183 struct mic_driver *mdrv = &g_drv;
184 struct mic_device *mdev = &mdrv->mdev;
185
186 mic_driver_uninit(mdrv);
187 iounmap(mdev->mmio.va);
188 return 0;
189}
190
191static void mic_platform_shutdown(struct platform_device *pdev)
192{
193 mic_remove(pdev);
194}
195
196static struct platform_device mic_platform_dev = {
197 .name = mic_driver_name,
198 .id = 0,
199 .num_resources = 0,
200};
201
202static struct platform_driver __refdata mic_platform_driver = {
203 .probe = mic_probe,
204 .remove = mic_remove,
205 .shutdown = mic_platform_shutdown,
206 .driver = {
207 .name = mic_driver_name,
208 .owner = THIS_MODULE,
209 },
210};
211
212static int __init mic_init(void)
213{
214 int ret;
215 struct cpuinfo_x86 *c = &cpu_data(0);
216
217 if (!(c->x86 == 11 && c->x86_model == 1)) {
218 ret = -ENODEV;
219 pr_err("%s not running on X100 ret %d\n", __func__, ret);
220 goto done;
221 }
222
223 mic_init_card_debugfs();
224 ret = platform_device_register(&mic_platform_dev);
225 if (ret) {
226 pr_err("platform_device_register ret %d\n", ret);
227 goto cleanup_debugfs;
228 }
229 ret = platform_driver_register(&mic_platform_driver);
230 if (ret) {
231 pr_err("platform_driver_register ret %d\n", ret);
232 goto device_unregister;
233 }
234 return ret;
235
236device_unregister:
237 platform_device_unregister(&mic_platform_dev);
238cleanup_debugfs:
239 mic_exit_card_debugfs();
240done:
241 return ret;
242}
243
244static void __exit mic_exit(void)
245{
246 platform_driver_unregister(&mic_platform_driver);
247 platform_device_unregister(&mic_platform_dev);
248 mic_exit_card_debugfs();
249}
250
251module_init(mic_init);
252module_exit(mic_exit);
253
254MODULE_AUTHOR("Intel Corporation");
255MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver");
256MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/card/mic_x100.h b/drivers/misc/mic/card/mic_x100.h
new file mode 100644
index 000000000000..d66ea55639c3
--- /dev/null
+++ b/drivers/misc/mic/card/mic_x100.h
@@ -0,0 +1,48 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef _MIC_X100_CARD_H_
28#define _MIC_X100_CARD_H_
29
30#define MIC_X100_MMIO_BASE 0x08007C0000ULL
31#define MIC_X100_MMIO_LEN 0x00020000ULL
32#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000ULL
33
34#define MIC_X100_SBOX_SPAD0 0x0000AB20
35#define MIC_X100_SBOX_SDBIC0 0x0000CC90
36#define MIC_X100_SBOX_SDBIC0_DBREQ_BIT 0x80000000
37#define MIC_X100_SBOX_RDMASR0 0x0000B180
38
39#define MIC_X100_MAX_DOORBELL_IDX 8
40
41#define MIC_X100_NUM_SBOX_IRQ 8
42#define MIC_X100_NUM_RDMASR_IRQ 8
43#define MIC_X100_SBOX_IRQ_BASE 0
44#define MIC_X100_RDMASR_IRQ_BASE 17
45
46#define MIC_X100_IRQ_BASE 26
47
48#endif
diff --git a/drivers/misc/mic/common/mic_dev.h b/drivers/misc/mic/common/mic_dev.h
new file mode 100644
index 000000000000..92999c2bbf82
--- /dev/null
+++ b/drivers/misc/mic/common/mic_dev.h
@@ -0,0 +1,51 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC driver.
19 *
20 */
21#ifndef __MIC_DEV_H__
22#define __MIC_DEV_H__
23
24/**
25 * struct mic_mw - MIC memory window
26 *
27 * @pa: Base physical address.
28 * @va: Base ioremap'd virtual address.
29 * @len: Size of the memory window.
30 */
31struct mic_mw {
32 phys_addr_t pa;
33 void __iomem *va;
34 resource_size_t len;
35};
36
37/*
38 * Scratch pad register offsets used by the host to communicate
39 * device page DMA address to the card.
40 */
41#define MIC_DPLO_SPAD 14
42#define MIC_DPHI_SPAD 15
43
44/*
45 * These values are supposed to be in the config_change field of the
46 * device page when the host sends a config change interrupt to the card.
47 */
48#define MIC_VIRTIO_PARAM_DEV_REMOVE 0x1
49#define MIC_VIRTIO_PARAM_CONFIG_CHANGED 0x2
50
51#endif
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile
new file mode 100644
index 000000000000..c2197f999394
--- /dev/null
+++ b/drivers/misc/mic/host/Makefile
@@ -0,0 +1,14 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o
6mic_host-objs := mic_main.o
7mic_host-objs += mic_x100.o
8mic_host-objs += mic_sysfs.o
9mic_host-objs += mic_smpt.o
10mic_host-objs += mic_intr.o
11mic_host-objs += mic_boot.o
12mic_host-objs += mic_debugfs.o
13mic_host-objs += mic_fops.o
14mic_host-objs += mic_virtio.o
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c
new file mode 100644
index 000000000000..b079c65eed6d
--- /dev/null
+++ b/drivers/misc/mic/host/mic_boot.c
@@ -0,0 +1,300 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/delay.h>
22#include <linux/firmware.h>
23#include <linux/pci.h>
24
25#include <linux/mic_common.h>
26#include "../common/mic_dev.h"
27#include "mic_device.h"
28#include "mic_smpt.h"
29#include "mic_virtio.h"
30
31/**
32 * mic_reset - Reset the MIC device.
33 * @mdev: pointer to mic_device instance
34 */
35static void mic_reset(struct mic_device *mdev)
36{
37 int i;
38
39#define MIC_RESET_TO (45)
40
41 INIT_COMPLETION(mdev->reset_wait);
42 mdev->ops->reset_fw_ready(mdev);
43 mdev->ops->reset(mdev);
44
45 for (i = 0; i < MIC_RESET_TO; i++) {
46 if (mdev->ops->is_fw_ready(mdev))
47 goto done;
48 /*
49 * Resets typically take 10s of seconds to complete.
50 * Since an MMIO read is required to check if the
51 * firmware is ready or not, a 1 second delay works nicely.
52 */
53 msleep(1000);
54 }
55 mic_set_state(mdev, MIC_RESET_FAILED);
56done:
57 complete_all(&mdev->reset_wait);
58}
59
60/* Initialize the MIC bootparams */
61void mic_bootparam_init(struct mic_device *mdev)
62{
63 struct mic_bootparam *bootparam = mdev->dp;
64
65 bootparam->magic = MIC_MAGIC;
66 bootparam->c2h_shutdown_db = mdev->shutdown_db;
67 bootparam->h2c_shutdown_db = -1;
68 bootparam->h2c_config_db = -1;
69 bootparam->shutdown_status = 0;
70 bootparam->shutdown_card = 0;
71}
72
73/**
74 * mic_start - Start the MIC.
75 * @mdev: pointer to mic_device instance
76 * @buf: buffer containing boot string including firmware/ramdisk path.
77 *
78 * This function prepares an MIC for boot and initiates boot.
79 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
80 */
81int mic_start(struct mic_device *mdev, const char *buf)
82{
83 int rc;
84 mutex_lock(&mdev->mic_mutex);
85retry:
86 if (MIC_OFFLINE != mdev->state) {
87 rc = -EINVAL;
88 goto unlock_ret;
89 }
90 if (!mdev->ops->is_fw_ready(mdev)) {
91 mic_reset(mdev);
92 /*
93 * The state will either be MIC_OFFLINE if the reset succeeded
94 * or MIC_RESET_FAILED if the firmware reset failed.
95 */
96 goto retry;
97 }
98 rc = mdev->ops->load_mic_fw(mdev, buf);
99 if (rc)
100 goto unlock_ret;
101 mic_smpt_restore(mdev);
102 mic_intr_restore(mdev);
103 mdev->intr_ops->enable_interrupts(mdev);
104 mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
105 mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
106 mdev->ops->send_firmware_intr(mdev);
107 mic_set_state(mdev, MIC_ONLINE);
108unlock_ret:
109 mutex_unlock(&mdev->mic_mutex);
110 return rc;
111}
112
113/**
114 * mic_stop - Prepare the MIC for reset and trigger reset.
115 * @mdev: pointer to mic_device instance
116 * @force: force a MIC to reset even if it is already offline.
117 *
118 * RETURNS: None.
119 */
120void mic_stop(struct mic_device *mdev, bool force)
121{
122 mutex_lock(&mdev->mic_mutex);
123 if (MIC_OFFLINE != mdev->state || force) {
124 mic_virtio_reset_devices(mdev);
125 mic_bootparam_init(mdev);
126 mic_reset(mdev);
127 if (MIC_RESET_FAILED == mdev->state)
128 goto unlock;
129 mic_set_shutdown_status(mdev, MIC_NOP);
130 if (MIC_SUSPENDED != mdev->state)
131 mic_set_state(mdev, MIC_OFFLINE);
132 }
133unlock:
134 mutex_unlock(&mdev->mic_mutex);
135}
136
137/**
138 * mic_shutdown - Initiate MIC shutdown.
139 * @mdev: pointer to mic_device instance
140 *
141 * RETURNS: None.
142 */
143void mic_shutdown(struct mic_device *mdev)
144{
145 struct mic_bootparam *bootparam = mdev->dp;
146 s8 db = bootparam->h2c_shutdown_db;
147
148 mutex_lock(&mdev->mic_mutex);
149 if (MIC_ONLINE == mdev->state && db != -1) {
150 bootparam->shutdown_card = 1;
151 mdev->ops->send_intr(mdev, db);
152 mic_set_state(mdev, MIC_SHUTTING_DOWN);
153 }
154 mutex_unlock(&mdev->mic_mutex);
155}
156
157/**
158 * mic_shutdown_work - Handle shutdown interrupt from MIC.
159 * @work: The work structure.
160 *
161 * This work is scheduled whenever the host has received a shutdown
162 * interrupt from the MIC.
163 */
164void mic_shutdown_work(struct work_struct *work)
165{
166 struct mic_device *mdev = container_of(work, struct mic_device,
167 shutdown_work);
168 struct mic_bootparam *bootparam = mdev->dp;
169
170 mutex_lock(&mdev->mic_mutex);
171 mic_set_shutdown_status(mdev, bootparam->shutdown_status);
172 bootparam->shutdown_status = 0;
173
174 /*
175 * if state is MIC_SUSPENDED, OSPM suspend is in progress. We do not
176 * change the state here so as to prevent users from booting the card
177 * during and after the suspend operation.
178 */
179 if (MIC_SHUTTING_DOWN != mdev->state &&
180 MIC_SUSPENDED != mdev->state)
181 mic_set_state(mdev, MIC_SHUTTING_DOWN);
182 mutex_unlock(&mdev->mic_mutex);
183}
184
185/**
186 * mic_reset_trigger_work - Trigger MIC reset.
187 * @work: The work structure.
188 *
189 * This work is scheduled whenever the host wants to reset the MIC.
190 */
191void mic_reset_trigger_work(struct work_struct *work)
192{
193 struct mic_device *mdev = container_of(work, struct mic_device,
194 reset_trigger_work);
195
196 mic_stop(mdev, false);
197}
198
199/**
200 * mic_complete_resume - Complete MIC Resume after an OSPM suspend/hibernate
201 * event.
202 * @mdev: pointer to mic_device instance
203 *
204 * RETURNS: None.
205 */
206void mic_complete_resume(struct mic_device *mdev)
207{
208 if (mdev->state != MIC_SUSPENDED) {
209 dev_warn(mdev->sdev->parent, "state %d should be %d\n",
210 mdev->state, MIC_SUSPENDED);
211 return;
212 }
213
214 /* Make sure firmware is ready */
215 if (!mdev->ops->is_fw_ready(mdev))
216 mic_stop(mdev, true);
217
218 mutex_lock(&mdev->mic_mutex);
219 mic_set_state(mdev, MIC_OFFLINE);
220 mutex_unlock(&mdev->mic_mutex);
221}
222
223/**
224 * mic_prepare_suspend - Handle suspend notification for the MIC device.
225 * @mdev: pointer to mic_device instance
226 *
227 * RETURNS: None.
228 */
229void mic_prepare_suspend(struct mic_device *mdev)
230{
231 int rc;
232
233#define MIC_SUSPEND_TIMEOUT (60 * HZ)
234
235 mutex_lock(&mdev->mic_mutex);
236 switch (mdev->state) {
237 case MIC_OFFLINE:
238 /*
239 * Card is already offline. Set state to MIC_SUSPENDED
240 * to prevent users from booting the card.
241 */
242 mic_set_state(mdev, MIC_SUSPENDED);
243 mutex_unlock(&mdev->mic_mutex);
244 break;
245 case MIC_ONLINE:
246 /*
247 * Card is online. Set state to MIC_SUSPENDING and notify
248 * MIC user space daemon which will issue card
249 * shutdown and reset.
250 */
251 mic_set_state(mdev, MIC_SUSPENDING);
252 mutex_unlock(&mdev->mic_mutex);
253 rc = wait_for_completion_timeout(&mdev->reset_wait,
254 MIC_SUSPEND_TIMEOUT);
255 /* Force reset the card if the shutdown completion timed out */
256 if (!rc) {
257 mutex_lock(&mdev->mic_mutex);
258 mic_set_state(mdev, MIC_SUSPENDED);
259 mutex_unlock(&mdev->mic_mutex);
260 mic_stop(mdev, true);
261 }
262 break;
263 case MIC_SHUTTING_DOWN:
264 /*
265 * Card is shutting down. Set state to MIC_SUSPENDED
266 * to prevent further boot of the card.
267 */
268 mic_set_state(mdev, MIC_SUSPENDED);
269 mutex_unlock(&mdev->mic_mutex);
270 rc = wait_for_completion_timeout(&mdev->reset_wait,
271 MIC_SUSPEND_TIMEOUT);
272 /* Force reset the card if the shutdown completion timed out */
273 if (!rc)
274 mic_stop(mdev, true);
275 break;
276 default:
277 mutex_unlock(&mdev->mic_mutex);
278 break;
279 }
280}
281
282/**
283 * mic_suspend - Initiate MIC suspend. Suspend merely issues card shutdown.
284 * @mdev: pointer to mic_device instance
285 *
286 * RETURNS: None.
287 */
288void mic_suspend(struct mic_device *mdev)
289{
290 struct mic_bootparam *bootparam = mdev->dp;
291 s8 db = bootparam->h2c_shutdown_db;
292
293 mutex_lock(&mdev->mic_mutex);
294 if (MIC_SUSPENDING == mdev->state && db != -1) {
295 bootparam->shutdown_card = 1;
296 mdev->ops->send_intr(mdev, db);
297 mic_set_state(mdev, MIC_SUSPENDED);
298 }
299 mutex_unlock(&mdev->mic_mutex);
300}
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
new file mode 100644
index 000000000000..028ba5d6fd1c
--- /dev/null
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -0,0 +1,491 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/debugfs.h>
22#include <linux/pci.h>
23#include <linux/seq_file.h>
24
25#include <linux/mic_common.h>
26#include "../common/mic_dev.h"
27#include "mic_device.h"
28#include "mic_smpt.h"
29#include "mic_virtio.h"
30
31/* Debugfs parent dir */
32static struct dentry *mic_dbg;
33
34/**
35 * mic_log_buf_show - Display MIC kernel log buffer.
36 *
37 * log_buf addr/len is read from System.map by user space
38 * and populated in sysfs entries.
39 */
40static int mic_log_buf_show(struct seq_file *s, void *unused)
41{
42 void __iomem *log_buf_va;
43 int __iomem *log_buf_len_va;
44 struct mic_device *mdev = s->private;
45 void *kva;
46 int size;
47 unsigned long aper_offset;
48
49 if (!mdev || !mdev->log_buf_addr || !mdev->log_buf_len)
50 goto done;
51 /*
52 * Card kernel will never be relocated and any kernel text/data mapping
53 * can be translated to phys address by subtracting __START_KERNEL_map.
54 */
55 aper_offset = (unsigned long)mdev->log_buf_len - __START_KERNEL_map;
56 log_buf_len_va = mdev->aper.va + aper_offset;
57 aper_offset = (unsigned long)mdev->log_buf_addr - __START_KERNEL_map;
58 log_buf_va = mdev->aper.va + aper_offset;
59 size = ioread32(log_buf_len_va);
60
61 kva = kmalloc(size, GFP_KERNEL);
62 if (!kva)
63 goto done;
64 mutex_lock(&mdev->mic_mutex);
65 memcpy_fromio(kva, log_buf_va, size);
66 switch (mdev->state) {
67 case MIC_ONLINE:
68 /* Fall through */
69 case MIC_SHUTTING_DOWN:
70 seq_write(s, kva, size);
71 break;
72 default:
73 break;
74 }
75 mutex_unlock(&mdev->mic_mutex);
76 kfree(kva);
77done:
78 return 0;
79}
80
81static int mic_log_buf_open(struct inode *inode, struct file *file)
82{
83 return single_open(file, mic_log_buf_show, inode->i_private);
84}
85
86static int mic_log_buf_release(struct inode *inode, struct file *file)
87{
88 return single_release(inode, file);
89}
90
91static const struct file_operations log_buf_ops = {
92 .owner = THIS_MODULE,
93 .open = mic_log_buf_open,
94 .read = seq_read,
95 .llseek = seq_lseek,
96 .release = mic_log_buf_release
97};
98
99static int mic_smpt_show(struct seq_file *s, void *pos)
100{
101 int i;
102 struct mic_device *mdev = s->private;
103 unsigned long flags;
104
105 seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n",
106 mdev->id, "SMPT entry", "SW DMA addr", "RefCount");
107 seq_puts(s, "====================================================\n");
108
109 if (mdev->smpt) {
110 struct mic_smpt_info *smpt_info = mdev->smpt;
111 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
112 for (i = 0; i < smpt_info->info.num_reg; i++) {
113 seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n",
114 " ", i, smpt_info->entry[i].dma_addr,
115 smpt_info->entry[i].ref_count);
116 }
117 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
118 }
119 seq_puts(s, "====================================================\n");
120 return 0;
121}
122
123static int mic_smpt_debug_open(struct inode *inode, struct file *file)
124{
125 return single_open(file, mic_smpt_show, inode->i_private);
126}
127
128static int mic_smpt_debug_release(struct inode *inode, struct file *file)
129{
130 return single_release(inode, file);
131}
132
133static const struct file_operations smpt_file_ops = {
134 .owner = THIS_MODULE,
135 .open = mic_smpt_debug_open,
136 .read = seq_read,
137 .llseek = seq_lseek,
138 .release = mic_smpt_debug_release
139};
140
141static int mic_soft_reset_show(struct seq_file *s, void *pos)
142{
143 struct mic_device *mdev = s->private;
144
145 mic_stop(mdev, true);
146 return 0;
147}
148
149static int mic_soft_reset_debug_open(struct inode *inode, struct file *file)
150{
151 return single_open(file, mic_soft_reset_show, inode->i_private);
152}
153
154static int mic_soft_reset_debug_release(struct inode *inode, struct file *file)
155{
156 return single_release(inode, file);
157}
158
159static const struct file_operations soft_reset_ops = {
160 .owner = THIS_MODULE,
161 .open = mic_soft_reset_debug_open,
162 .read = seq_read,
163 .llseek = seq_lseek,
164 .release = mic_soft_reset_debug_release
165};
166
167static int mic_post_code_show(struct seq_file *s, void *pos)
168{
169 struct mic_device *mdev = s->private;
170 u32 reg = mdev->ops->get_postcode(mdev);
171
172 seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff);
173 return 0;
174}
175
176static int mic_post_code_debug_open(struct inode *inode, struct file *file)
177{
178 return single_open(file, mic_post_code_show, inode->i_private);
179}
180
181static int mic_post_code_debug_release(struct inode *inode, struct file *file)
182{
183 return single_release(inode, file);
184}
185
186static const struct file_operations post_code_ops = {
187 .owner = THIS_MODULE,
188 .open = mic_post_code_debug_open,
189 .read = seq_read,
190 .llseek = seq_lseek,
191 .release = mic_post_code_debug_release
192};
193
194static int mic_dp_show(struct seq_file *s, void *pos)
195{
196 struct mic_device *mdev = s->private;
197 struct mic_device_desc *d;
198 struct mic_device_ctrl *dc;
199 struct mic_vqconfig *vqconfig;
200 __u32 *features;
201 __u8 *config;
202 struct mic_bootparam *bootparam = mdev->dp;
203 int i, j;
204
205 seq_printf(s, "Bootparam: magic 0x%x\n",
206 bootparam->magic);
207 seq_printf(s, "Bootparam: h2c_shutdown_db %d\n",
208 bootparam->h2c_shutdown_db);
209 seq_printf(s, "Bootparam: h2c_config_db %d\n",
210 bootparam->h2c_config_db);
211 seq_printf(s, "Bootparam: c2h_shutdown_db %d\n",
212 bootparam->c2h_shutdown_db);
213 seq_printf(s, "Bootparam: shutdown_status %d\n",
214 bootparam->shutdown_status);
215 seq_printf(s, "Bootparam: shutdown_card %d\n",
216 bootparam->shutdown_card);
217
218 for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
219 i += mic_total_desc_size(d)) {
220 d = mdev->dp + i;
221 dc = (void *)d + mic_aligned_desc_size(d);
222
223 /* end of list */
224 if (d->type == 0)
225 break;
226
227 if (d->type == -1)
228 continue;
229
230 seq_printf(s, "Type %d ", d->type);
231 seq_printf(s, "Num VQ %d ", d->num_vq);
232 seq_printf(s, "Feature Len %d\n", d->feature_len);
233 seq_printf(s, "Config Len %d ", d->config_len);
234 seq_printf(s, "Shutdown Status %d\n", d->status);
235
236 for (j = 0; j < d->num_vq; j++) {
237 vqconfig = mic_vq_config(d) + j;
238 seq_printf(s, "vqconfig[%d]: ", j);
239 seq_printf(s, "address 0x%llx ", vqconfig->address);
240 seq_printf(s, "num %d ", vqconfig->num);
241 seq_printf(s, "used address 0x%llx\n",
242 vqconfig->used_address);
243 }
244
245 features = (__u32 *)mic_vq_features(d);
246 seq_printf(s, "Features: Host 0x%x ", features[0]);
247 seq_printf(s, "Guest 0x%x\n", features[1]);
248
249 config = mic_vq_configspace(d);
250 for (j = 0; j < d->config_len; j++)
251 seq_printf(s, "config[%d]=%d\n", j, config[j]);
252
253 seq_puts(s, "Device control:\n");
254 seq_printf(s, "Config Change %d ", dc->config_change);
255 seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
256 seq_printf(s, "Guest Ack %d ", dc->guest_ack);
257 seq_printf(s, "Host ack %d\n", dc->host_ack);
258 seq_printf(s, "Used address updated %d ",
259 dc->used_address_updated);
260 seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
261 seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
262 seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
263 }
264
265 return 0;
266}
267
268static int mic_dp_debug_open(struct inode *inode, struct file *file)
269{
270 return single_open(file, mic_dp_show, inode->i_private);
271}
272
273static int mic_dp_debug_release(struct inode *inode, struct file *file)
274{
275 return single_release(inode, file);
276}
277
278static const struct file_operations dp_ops = {
279 .owner = THIS_MODULE,
280 .open = mic_dp_debug_open,
281 .read = seq_read,
282 .llseek = seq_lseek,
283 .release = mic_dp_debug_release
284};
285
286static int mic_vdev_info_show(struct seq_file *s, void *unused)
287{
288 struct mic_device *mdev = s->private;
289 struct list_head *pos, *tmp;
290 struct mic_vdev *mvdev;
291 int i, j;
292
293 mutex_lock(&mdev->mic_mutex);
294 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
295 mvdev = list_entry(pos, struct mic_vdev, list);
296 seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
297 mvdev->virtio_id,
298 mic_vdevup(mvdev) ? "UP" : "DOWN",
299 mvdev->in_bytes,
300 mvdev->out_bytes);
301 for (i = 0; i < MIC_MAX_VRINGS; i++) {
302 struct vring_desc *desc;
303 struct vring_avail *avail;
304 struct vring_used *used;
305 struct mic_vringh *mvr = &mvdev->mvr[i];
306 struct vringh *vrh = &mvr->vrh;
307 int num = vrh->vring.num;
308 if (!num)
309 continue;
310 desc = vrh->vring.desc;
311 seq_printf(s, "vring i %d avail_idx %d",
312 i, mvr->vring.info->avail_idx & (num - 1));
313 seq_printf(s, " vring i %d avail_idx %d\n",
314 i, mvr->vring.info->avail_idx);
315 seq_printf(s, "vrh i %d weak_barriers %d",
316 i, vrh->weak_barriers);
317 seq_printf(s, " last_avail_idx %d last_used_idx %d",
318 vrh->last_avail_idx, vrh->last_used_idx);
319 seq_printf(s, " completed %d\n", vrh->completed);
320 for (j = 0; j < num; j++) {
321 seq_printf(s, "desc[%d] addr 0x%llx len %d",
322 j, desc->addr, desc->len);
323 seq_printf(s, " flags 0x%x next %d\n",
324 desc->flags, desc->next);
325 desc++;
326 }
327 avail = vrh->vring.avail;
328 seq_printf(s, "avail flags 0x%x idx %d\n",
329 avail->flags, avail->idx & (num - 1));
330 seq_printf(s, "avail flags 0x%x idx %d\n",
331 avail->flags, avail->idx);
332 for (j = 0; j < num; j++)
333 seq_printf(s, "avail ring[%d] %d\n",
334 j, avail->ring[j]);
335 used = vrh->vring.used;
336 seq_printf(s, "used flags 0x%x idx %d\n",
337 used->flags, used->idx & (num - 1));
338 seq_printf(s, "used flags 0x%x idx %d\n",
339 used->flags, used->idx);
340 for (j = 0; j < num; j++)
341 seq_printf(s, "used ring[%d] id %d len %d\n",
342 j, used->ring[j].id,
343 used->ring[j].len);
344 }
345 }
346 mutex_unlock(&mdev->mic_mutex);
347
348 return 0;
349}
350
351static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
352{
353 return single_open(file, mic_vdev_info_show, inode->i_private);
354}
355
356static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
357{
358 return single_release(inode, file);
359}
360
361static const struct file_operations vdev_info_ops = {
362 .owner = THIS_MODULE,
363 .open = mic_vdev_info_debug_open,
364 .read = seq_read,
365 .llseek = seq_lseek,
366 .release = mic_vdev_info_debug_release
367};
368
369static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
370{
371 struct mic_device *mdev = s->private;
372 int reg;
373 int i, j;
374 u16 entry;
375 u16 vector;
376 struct pci_dev *pdev = container_of(mdev->sdev->parent,
377 struct pci_dev, dev);
378
379 if (pci_dev_msi_enabled(pdev)) {
380 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
381 if (pdev->msix_enabled) {
382 entry = mdev->irq_info.msix_entries[i].entry;
383 vector = mdev->irq_info.msix_entries[i].vector;
384 } else {
385 entry = 0;
386 vector = pdev->irq;
387 }
388
389 reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry);
390
391 seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n",
392 "IRQ:", vector, "Entry:", entry, i, reg);
393
394 seq_printf(s, "%-10s", "offset:");
395 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
396 seq_printf(s, "%4d ", j);
397 seq_puts(s, "\n");
398
399
400 seq_printf(s, "%-10s", "count:");
401 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
402 seq_printf(s, "%4d ",
403 (mdev->irq_info.mic_msi_map[i] &
404 BIT(j)) ? 1 : 0);
405 seq_puts(s, "\n\n");
406 }
407 } else {
408 seq_puts(s, "MSI/MSIx interrupts not enabled\n");
409 }
410
411 return 0;
412}
413
414static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
415{
416 return single_open(file, mic_msi_irq_info_show, inode->i_private);
417}
418
419static int
420mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
421{
422 return single_release(inode, file);
423}
424
425static const struct file_operations msi_irq_info_ops = {
426 .owner = THIS_MODULE,
427 .open = mic_msi_irq_info_debug_open,
428 .read = seq_read,
429 .llseek = seq_lseek,
430 .release = mic_msi_irq_info_debug_release
431};
432
433/**
434 * mic_create_debug_dir - Initialize MIC debugfs entries.
435 */
436void mic_create_debug_dir(struct mic_device *mdev)
437{
438 if (!mic_dbg)
439 return;
440
441 mdev->dbg_dir = debugfs_create_dir(dev_name(mdev->sdev), mic_dbg);
442 if (!mdev->dbg_dir)
443 return;
444
445 debugfs_create_file("log_buf", 0444, mdev->dbg_dir, mdev, &log_buf_ops);
446
447 debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &smpt_file_ops);
448
449 debugfs_create_file("soft_reset", 0444, mdev->dbg_dir, mdev,
450 &soft_reset_ops);
451
452 debugfs_create_file("post_code", 0444, mdev->dbg_dir, mdev,
453 &post_code_ops);
454
455 debugfs_create_file("dp", 0444, mdev->dbg_dir, mdev, &dp_ops);
456
457 debugfs_create_file("vdev_info", 0444, mdev->dbg_dir, mdev,
458 &vdev_info_ops);
459
460 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, mdev,
461 &msi_irq_info_ops);
462}
463
464/**
465 * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
466 */
467void mic_delete_debug_dir(struct mic_device *mdev)
468{
469 if (!mdev->dbg_dir)
470 return;
471
472 debugfs_remove_recursive(mdev->dbg_dir);
473}
474
475/**
476 * mic_init_debugfs - Initialize global debugfs entry.
477 */
478void __init mic_init_debugfs(void)
479{
480 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
481 if (!mic_dbg)
482 pr_err("can't create debugfs dir\n");
483}
484
485/**
486 * mic_exit_debugfs - Uninitialize global debugfs entry
487 */
488void mic_exit_debugfs(void)
489{
490 debugfs_remove(mic_dbg);
491}
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h
new file mode 100644
index 000000000000..3574cc375bb9
--- /dev/null
+++ b/drivers/misc/mic/host/mic_device.h
@@ -0,0 +1,203 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef _MIC_DEVICE_H_
22#define _MIC_DEVICE_H_
23
24#include <linux/cdev.h>
25#include <linux/idr.h>
26#include <linux/notifier.h>
27
28#include "mic_intr.h"
29
30/* The maximum number of MIC devices supported in a single host system. */
31#define MIC_MAX_NUM_DEVS 256
32
33/**
34 * enum mic_hw_family - The hardware family to which a device belongs.
35 */
36enum mic_hw_family {
37 MIC_FAMILY_X100 = 0,
38 MIC_FAMILY_UNKNOWN
39};
40
41/**
42 * enum mic_stepping - MIC stepping ids.
43 */
44enum mic_stepping {
45 MIC_A0_STEP = 0x0,
46 MIC_B0_STEP = 0x10,
47 MIC_B1_STEP = 0x11,
48 MIC_C0_STEP = 0x20,
49};
50
51/**
52 * struct mic_device - MIC device information for each card.
53 *
54 * @mmio: MMIO bar information.
55 * @aper: Aperture bar information.
56 * @family: The MIC family to which this device belongs.
57 * @ops: MIC HW specific operations.
58 * @id: The unique device id for this MIC device.
59 * @stepping: Stepping ID.
60 * @attr_group: Pointer to list of sysfs attribute groups.
61 * @sdev: Device for sysfs entries.
62 * @mic_mutex: Mutex for synchronizing access to mic_device.
63 * @intr_ops: HW specific interrupt operations.
64 * @smpt_ops: Hardware specific SMPT operations.
65 * @smpt: MIC SMPT information.
66 * @intr_info: H/W specific interrupt information.
67 * @irq_info: The OS specific irq information
68 * @dbg_dir: debugfs directory of this MIC device.
69 * @cmdline: Kernel command line.
70 * @firmware: Firmware file name.
71 * @ramdisk: Ramdisk file name.
72 * @bootmode: Boot mode i.e. "linux" or "elf" for flash updates.
73 * @bootaddr: MIC boot address.
74 * @reset_trigger_work: Work for triggering reset requests.
75 * @shutdown_work: Work for handling shutdown interrupts.
76 * @state: MIC state.
77 * @shutdown_status: MIC status reported by card for shutdown/crashes.
78 * @state_sysfs: Sysfs dirent for notifying ring 3 about MIC state changes.
79 * @reset_wait: Waitqueue for sleeping while reset completes.
80 * @log_buf_addr: Log buffer address for MIC.
81 * @log_buf_len: Log buffer length address for MIC.
82 * @dp: virtio device page
83 * @dp_dma_addr: virtio device page DMA address.
84 * @shutdown_db: shutdown doorbell.
85 * @shutdown_cookie: shutdown cookie.
86 * @cdev: Character device for MIC.
87 * @vdev_list: list of virtio devices.
88 * @pm_notifier: Handles PM notifications from the OS.
89 */
90struct mic_device {
91 struct mic_mw mmio;
92 struct mic_mw aper;
93 enum mic_hw_family family;
94 struct mic_hw_ops *ops;
95 int id;
96 enum mic_stepping stepping;
97 const struct attribute_group **attr_group;
98 struct device *sdev;
99 struct mutex mic_mutex;
100 struct mic_hw_intr_ops *intr_ops;
101 struct mic_smpt_ops *smpt_ops;
102 struct mic_smpt_info *smpt;
103 struct mic_intr_info *intr_info;
104 struct mic_irq_info irq_info;
105 struct dentry *dbg_dir;
106 char *cmdline;
107 char *firmware;
108 char *ramdisk;
109 char *bootmode;
110 u32 bootaddr;
111 struct work_struct reset_trigger_work;
112 struct work_struct shutdown_work;
113 u8 state;
114 u8 shutdown_status;
115 struct sysfs_dirent *state_sysfs;
116 struct completion reset_wait;
117 void *log_buf_addr;
118 int *log_buf_len;
119 void *dp;
120 dma_addr_t dp_dma_addr;
121 int shutdown_db;
122 struct mic_irq *shutdown_cookie;
123 struct cdev cdev;
124 struct list_head vdev_list;
125 struct notifier_block pm_notifier;
126};
127
128/**
129 * struct mic_hw_ops - MIC HW specific operations.
130 * @aper_bar: Aperture bar resource number.
131 * @mmio_bar: MMIO bar resource number.
132 * @read_spad: Read from scratch pad register.
133 * @write_spad: Write to scratch pad register.
134 * @send_intr: Send an interrupt for a particular doorbell on the card.
135 * @ack_interrupt: Hardware specific operations to ack the h/w on
136 * receipt of an interrupt.
137 * @reset: Reset the remote processor.
138 * @reset_fw_ready: Reset firmware ready field.
139 * @is_fw_ready: Check if firmware is ready for OS download.
140 * @send_firmware_intr: Send an interrupt to the card firmware.
141 * @load_mic_fw: Load firmware segments required to boot the card
142 * into card memory. This includes the kernel, command line, ramdisk etc.
143 * @get_postcode: Get post code status from firmware.
144 */
145struct mic_hw_ops {
146 u8 aper_bar;
147 u8 mmio_bar;
148 u32 (*read_spad)(struct mic_device *mdev, unsigned int idx);
149 void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val);
150 void (*send_intr)(struct mic_device *mdev, int doorbell);
151 u32 (*ack_interrupt)(struct mic_device *mdev);
152 void (*reset)(struct mic_device *mdev);
153 void (*reset_fw_ready)(struct mic_device *mdev);
154 bool (*is_fw_ready)(struct mic_device *mdev);
155 void (*send_firmware_intr)(struct mic_device *mdev);
156 int (*load_mic_fw)(struct mic_device *mdev, const char *buf);
157 u32 (*get_postcode)(struct mic_device *mdev);
158};
159
160/**
161 * mic_mmio_read - read from an MMIO register.
162 * @mw: MMIO register base virtual address.
163 * @offset: register offset.
164 *
165 * RETURNS: register value.
166 */
167static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
168{
169 return ioread32(mw->va + offset);
170}
171
172/**
173 * mic_mmio_write - write to an MMIO register.
174 * @mw: MMIO register base virtual address.
175 * @val: the data value to put into the register
176 * @offset: register offset.
177 *
178 * RETURNS: none.
179 */
180static inline void
181mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
182{
183 iowrite32(val, mw->va + offset);
184}
185
186void mic_sysfs_init(struct mic_device *mdev);
187int mic_start(struct mic_device *mdev, const char *buf);
188void mic_stop(struct mic_device *mdev, bool force);
189void mic_shutdown(struct mic_device *mdev);
190void mic_reset_delayed_work(struct work_struct *work);
191void mic_reset_trigger_work(struct work_struct *work);
192void mic_shutdown_work(struct work_struct *work);
193void mic_bootparam_init(struct mic_device *mdev);
194void mic_set_state(struct mic_device *mdev, u8 state);
195void mic_set_shutdown_status(struct mic_device *mdev, u8 status);
196void mic_create_debug_dir(struct mic_device *dev);
197void mic_delete_debug_dir(struct mic_device *dev);
198void __init mic_init_debugfs(void);
199void mic_exit_debugfs(void);
200void mic_prepare_suspend(struct mic_device *mdev);
201void mic_complete_resume(struct mic_device *mdev);
202void mic_suspend(struct mic_device *mdev);
203#endif
diff --git a/drivers/misc/mic/host/mic_fops.c b/drivers/misc/mic/host/mic_fops.c
new file mode 100644
index 000000000000..85776d7327f3
--- /dev/null
+++ b/drivers/misc/mic/host/mic_fops.c
@@ -0,0 +1,222 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/poll.h>
22#include <linux/pci.h>
23
24#include <linux/mic_common.h>
25#include "../common/mic_dev.h"
26#include "mic_device.h"
27#include "mic_fops.h"
28#include "mic_virtio.h"
29
30int mic_open(struct inode *inode, struct file *f)
31{
32 struct mic_vdev *mvdev;
33 struct mic_device *mdev = container_of(inode->i_cdev,
34 struct mic_device, cdev);
35
36 mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
37 if (!mvdev)
38 return -ENOMEM;
39
40 init_waitqueue_head(&mvdev->waitq);
41 INIT_LIST_HEAD(&mvdev->list);
42 mvdev->mdev = mdev;
43 mvdev->virtio_id = -1;
44
45 f->private_data = mvdev;
46 return 0;
47}
48
49int mic_release(struct inode *inode, struct file *f)
50{
51 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
52
53 if (-1 != mvdev->virtio_id)
54 mic_virtio_del_device(mvdev);
55 f->private_data = NULL;
56 kfree(mvdev);
57 return 0;
58}
59
60long mic_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
61{
62 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
63 void __user *argp = (void __user *)arg;
64 int ret;
65
66 switch (cmd) {
67 case MIC_VIRTIO_ADD_DEVICE:
68 {
69 ret = mic_virtio_add_device(mvdev, argp);
70 if (ret < 0) {
71 dev_err(mic_dev(mvdev),
72 "%s %d errno ret %d\n",
73 __func__, __LINE__, ret);
74 return ret;
75 }
76 break;
77 }
78 case MIC_VIRTIO_COPY_DESC:
79 {
80 struct mic_copy_desc copy;
81
82 ret = mic_vdev_inited(mvdev);
83 if (ret)
84 return ret;
85
86 if (copy_from_user(&copy, argp, sizeof(copy)))
87 return -EFAULT;
88
89 dev_dbg(mic_dev(mvdev),
90 "%s %d === iovcnt 0x%x vr_idx 0x%x update_used %d\n",
91 __func__, __LINE__, copy.iovcnt, copy.vr_idx,
92 copy.update_used);
93
94 ret = mic_virtio_copy_desc(mvdev, &copy);
95 if (ret < 0) {
96 dev_err(mic_dev(mvdev),
97 "%s %d errno ret %d\n",
98 __func__, __LINE__, ret);
99 return ret;
100 }
101 if (copy_to_user(
102 &((struct mic_copy_desc __user *)argp)->out_len,
103 &copy.out_len, sizeof(copy.out_len))) {
104 dev_err(mic_dev(mvdev), "%s %d errno ret %d\n",
105 __func__, __LINE__, -EFAULT);
106 return -EFAULT;
107 }
108 break;
109 }
110 case MIC_VIRTIO_CONFIG_CHANGE:
111 {
112 ret = mic_vdev_inited(mvdev);
113 if (ret)
114 return ret;
115
116 ret = mic_virtio_config_change(mvdev, argp);
117 if (ret < 0) {
118 dev_err(mic_dev(mvdev),
119 "%s %d errno ret %d\n",
120 __func__, __LINE__, ret);
121 return ret;
122 }
123 break;
124 }
125 default:
126 return -ENOIOCTLCMD;
127 };
128 return 0;
129}
130
131/*
132 * We return POLLIN | POLLOUT from poll when new buffers are enqueued, and
133 * not when previously enqueued buffers may be available. This means that
134 * in the card->host (TX) path, when userspace is unblocked by poll it
135 * must drain all available descriptors or it can stall.
136 */
137unsigned int mic_poll(struct file *f, poll_table *wait)
138{
139 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
140 int mask = 0;
141
142 poll_wait(f, &mvdev->waitq, wait);
143
144 if (mic_vdev_inited(mvdev)) {
145 mask = POLLERR;
146 } else if (mvdev->poll_wake) {
147 mvdev->poll_wake = 0;
148 mask = POLLIN | POLLOUT;
149 }
150
151 return mask;
152}
153
154static inline int
155mic_query_offset(struct mic_vdev *mvdev, unsigned long offset,
156 unsigned long *size, unsigned long *pa)
157{
158 struct mic_device *mdev = mvdev->mdev;
159 unsigned long start = MIC_DP_SIZE;
160 int i;
161
162 /*
163 * MMAP interface is as follows:
164 * offset region
165 * 0x0 virtio device_page
166 * 0x1000 first vring
167 * 0x1000 + size of 1st vring second vring
168 * ....
169 */
170 if (!offset) {
171 *pa = virt_to_phys(mdev->dp);
172 *size = MIC_DP_SIZE;
173 return 0;
174 }
175
176 for (i = 0; i < mvdev->dd->num_vq; i++) {
177 struct mic_vringh *mvr = &mvdev->mvr[i];
178 if (offset == start) {
179 *pa = virt_to_phys(mvr->vring.va);
180 *size = mvr->vring.len;
181 return 0;
182 }
183 start += mvr->vring.len;
184 }
185 return -1;
186}
187
188/*
189 * Maps the device page and virtio rings to user space for readonly access.
190 */
191int
192mic_mmap(struct file *f, struct vm_area_struct *vma)
193{
194 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
195 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
196 unsigned long pa, size = vma->vm_end - vma->vm_start, size_rem = size;
197 int i, err;
198
199 err = mic_vdev_inited(mvdev);
200 if (err)
201 return err;
202
203 if (vma->vm_flags & VM_WRITE)
204 return -EACCES;
205
206 while (size_rem) {
207 i = mic_query_offset(mvdev, offset, &size, &pa);
208 if (i < 0)
209 return -EINVAL;
210 err = remap_pfn_range(vma, vma->vm_start + offset,
211 pa >> PAGE_SHIFT, size, vma->vm_page_prot);
212 if (err)
213 return err;
214 dev_dbg(mic_dev(mvdev),
215 "%s %d type %d size 0x%lx off 0x%lx pa 0x%lx vma 0x%lx\n",
216 __func__, __LINE__, mvdev->virtio_id, size, offset,
217 pa, vma->vm_start + offset);
218 size_rem -= size;
219 offset += size;
220 }
221 return 0;
222}
diff --git a/drivers/misc/mic/host/mic_fops.h b/drivers/misc/mic/host/mic_fops.h
new file mode 100644
index 000000000000..dc3893dff667
--- /dev/null
+++ b/drivers/misc/mic/host/mic_fops.h
@@ -0,0 +1,32 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef _MIC_FOPS_H_
22#define _MIC_FOPS_H_
23
24int mic_open(struct inode *inode, struct file *filp);
25int mic_release(struct inode *inode, struct file *filp);
26ssize_t mic_read(struct file *filp, char __user *buf,
27 size_t count, loff_t *pos);
28long mic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
29int mic_mmap(struct file *f, struct vm_area_struct *vma);
30unsigned int mic_poll(struct file *f, poll_table *wait);
31
32#endif
diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c
new file mode 100644
index 000000000000..f9c29bc918bc
--- /dev/null
+++ b/drivers/misc/mic/host/mic_intr.c
@@ -0,0 +1,630 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/pci.h>
22#include <linux/interrupt.h>
23
24#include "../common/mic_dev.h"
25#include "mic_device.h"
26
27/*
28 * mic_invoke_callback - Invoke callback functions registered for
29 * the corresponding source id.
30 *
31 * @mdev: pointer to the mic_device instance
32 * @idx: The interrupt source id.
33 *
34 * Returns none.
35 */
36static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
37{
38 struct mic_intr_cb *intr_cb;
39 struct pci_dev *pdev = container_of(mdev->sdev->parent,
40 struct pci_dev, dev);
41
42 spin_lock(&mdev->irq_info.mic_intr_lock);
43 list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
44 if (intr_cb->func)
45 intr_cb->func(pdev->irq, intr_cb->data);
46 spin_unlock(&mdev->irq_info.mic_intr_lock);
47}
48
49/**
50 * mic_interrupt - Generic interrupt handler for
51 * MSI and INTx based interrupts.
52 */
53static irqreturn_t mic_interrupt(int irq, void *dev)
54{
55 struct mic_device *mdev = dev;
56 struct mic_intr_info *info = mdev->intr_info;
57 u32 mask;
58 int i;
59
60 mask = mdev->ops->ack_interrupt(mdev);
61 if (!mask)
62 return IRQ_NONE;
63
64 for (i = info->intr_start_idx[MIC_INTR_DB];
65 i < info->intr_len[MIC_INTR_DB]; i++)
66 if (mask & BIT(i))
67 mic_invoke_callback(mdev, i);
68
69 return IRQ_HANDLED;
70}
71
72/* Return the interrupt offset from the index. Index is 0 based. */
73static u16 mic_map_src_to_offset(struct mic_device *mdev,
74 int intr_src, enum mic_intr_type type)
75{
76 if (type >= MIC_NUM_INTR_TYPES)
77 return MIC_NUM_OFFSETS;
78 if (intr_src >= mdev->intr_info->intr_len[type])
79 return MIC_NUM_OFFSETS;
80
81 return mdev->intr_info->intr_start_idx[type] + intr_src;
82}
83
84/* Return next available msix_entry. */
85static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
86{
87 int i;
88 struct mic_irq_info *info = &mdev->irq_info;
89
90 for (i = 0; i < info->num_vectors; i++)
91 if (!info->mic_msi_map[i])
92 return &info->msix_entries[i];
93 return NULL;
94}
95
96/**
97 * mic_register_intr_callback - Register a callback handler for the
98 * given source id.
99 *
100 * @mdev: pointer to the mic_device instance
101 * @idx: The source id to be registered.
102 * @func: The function to be called when the source id receives
103 * the interrupt.
104 * @data: Private data of the requester.
105 * Return the callback structure that was registered or an
106 * appropriate error on failure.
107 */
108static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
109 u8 idx, irqreturn_t (*func) (int irq, void *dev),
110 void *data)
111{
112 struct mic_intr_cb *intr_cb;
113 unsigned long flags;
114 int rc;
115 intr_cb = kmalloc(sizeof(*intr_cb), GFP_KERNEL);
116
117 if (!intr_cb)
118 return ERR_PTR(-ENOMEM);
119
120 intr_cb->func = func;
121 intr_cb->data = data;
122 intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
123 0, 0, GFP_KERNEL);
124 if (intr_cb->cb_id < 0) {
125 rc = intr_cb->cb_id;
126 goto ida_fail;
127 }
128
129 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
130 list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
131 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
132
133 return intr_cb;
134ida_fail:
135 kfree(intr_cb);
136 return ERR_PTR(rc);
137}
138
139/**
140 * mic_unregister_intr_callback - Unregister the callback handler
141 * identified by its callback id.
142 *
143 * @mdev: pointer to the mic_device instance
144 * @idx: The callback structure id to be unregistered.
145 * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
146 * such callback handler was found.
147 */
148static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
149{
150 struct list_head *pos, *tmp;
151 struct mic_intr_cb *intr_cb;
152 unsigned long flags;
153 int i;
154
155 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
156 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
157 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
158 intr_cb = list_entry(pos, struct mic_intr_cb, list);
159 if (intr_cb->cb_id == idx) {
160 list_del(pos);
161 ida_simple_remove(&mdev->irq_info.cb_ida,
162 intr_cb->cb_id);
163 kfree(intr_cb);
164 spin_unlock_irqrestore(
165 &mdev->irq_info.mic_intr_lock, flags);
166 return i;
167 }
168 }
169 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
170 }
171 return MIC_NUM_OFFSETS;
172}
173
174/**
175 * mic_setup_msix - Initializes MSIx interrupts.
176 *
177 * @mdev: pointer to mic_device instance
178 *
179 *
180 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
181 */
182static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
183{
184 int rc, i;
185 int entry_size = sizeof(*mdev->irq_info.msix_entries);
186
187 mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX,
188 entry_size, GFP_KERNEL);
189 if (!mdev->irq_info.msix_entries) {
190 rc = -ENOMEM;
191 goto err_nomem1;
192 }
193
194 for (i = 0; i < MIC_MIN_MSIX; i++)
195 mdev->irq_info.msix_entries[i].entry = i;
196
197 rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
198 MIC_MIN_MSIX);
199 if (rc) {
200 dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
201 goto err_enable_msix;
202 }
203
204 mdev->irq_info.num_vectors = MIC_MIN_MSIX;
205 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
206 mdev->irq_info.num_vectors), GFP_KERNEL);
207
208 if (!mdev->irq_info.mic_msi_map) {
209 rc = -ENOMEM;
210 goto err_nomem2;
211 }
212
213 dev_dbg(mdev->sdev->parent,
214 "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
215 return 0;
216err_nomem2:
217 pci_disable_msix(pdev);
218err_enable_msix:
219 kfree(mdev->irq_info.msix_entries);
220err_nomem1:
221 mdev->irq_info.num_vectors = 0;
222 return rc;
223}
224
225/**
226 * mic_setup_callbacks - Initialize data structures needed
227 * to handle callbacks.
228 *
229 * @mdev: pointer to mic_device instance
230 */
231static int mic_setup_callbacks(struct mic_device *mdev)
232{
233 int i;
234
235 mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS,
236 sizeof(*mdev->irq_info.cb_list),
237 GFP_KERNEL);
238 if (!mdev->irq_info.cb_list)
239 return -ENOMEM;
240
241 for (i = 0; i < MIC_NUM_OFFSETS; i++)
242 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
243 ida_init(&mdev->irq_info.cb_ida);
244 spin_lock_init(&mdev->irq_info.mic_intr_lock);
245 return 0;
246}
247
248/**
249 * mic_release_callbacks - Uninitialize data structures needed
250 * to handle callbacks.
251 *
252 * @mdev: pointer to mic_device instance
253 */
254static void mic_release_callbacks(struct mic_device *mdev)
255{
256 unsigned long flags;
257 struct list_head *pos, *tmp;
258 struct mic_intr_cb *intr_cb;
259 int i;
260
261 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
262 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
263
264 if (list_empty(&mdev->irq_info.cb_list[i])) {
265 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
266 flags);
267 break;
268 }
269
270 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
271 intr_cb = list_entry(pos, struct mic_intr_cb, list);
272 list_del(pos);
273 ida_simple_remove(&mdev->irq_info.cb_ida,
274 intr_cb->cb_id);
275 kfree(intr_cb);
276 }
277 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
278 }
279 ida_destroy(&mdev->irq_info.cb_ida);
280 kfree(mdev->irq_info.cb_list);
281}
282
283/**
284 * mic_setup_msi - Initializes MSI interrupts.
285 *
286 * @mdev: pointer to mic_device instance
287 * @pdev: PCI device structure
288 *
289 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
290 */
291static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
292{
293 int rc;
294
295 rc = pci_enable_msi(pdev);
296 if (rc) {
297 dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
298 return rc;
299 }
300
301 mdev->irq_info.num_vectors = 1;
302 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
303 mdev->irq_info.num_vectors), GFP_KERNEL);
304
305 if (!mdev->irq_info.mic_msi_map) {
306 rc = -ENOMEM;
307 goto err_nomem1;
308 }
309
310 rc = mic_setup_callbacks(mdev);
311 if (rc) {
312 dev_err(&pdev->dev, "Error setting up callbacks\n");
313 goto err_nomem2;
314 }
315
316 rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
317 if (rc) {
318 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
319 goto err_irq_req_fail;
320 }
321
322 dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
323 return 0;
324err_irq_req_fail:
325 mic_release_callbacks(mdev);
326err_nomem2:
327 kfree(mdev->irq_info.mic_msi_map);
328err_nomem1:
329 pci_disable_msi(pdev);
330 mdev->irq_info.num_vectors = 0;
331 return rc;
332}
333
334/**
335 * mic_setup_intx - Initializes legacy interrupts.
336 *
337 * @mdev: pointer to mic_device instance
338 * @pdev: PCI device structure
339 *
340 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
341 */
342static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
343{
344 int rc;
345
346 pci_msi_off(pdev);
347
348 /* Enable intx */
349 pci_intx(pdev, 1);
350 rc = mic_setup_callbacks(mdev);
351 if (rc) {
352 dev_err(&pdev->dev, "Error setting up callbacks\n");
353 goto err_nomem;
354 }
355
356 rc = request_irq(pdev->irq, mic_interrupt,
357 IRQF_SHARED, "mic-intx", mdev);
358 if (rc)
359 goto err;
360
361 dev_dbg(&pdev->dev, "intx irq setup\n");
362 return 0;
363err:
364 mic_release_callbacks(mdev);
365err_nomem:
366 return rc;
367}
368
369/**
370 * mic_next_db - Retrieve the next doorbell interrupt source id.
371 * The id is picked sequentially from the available pool of
372 * doorlbell ids.
373 *
374 * @mdev: pointer to the mic_device instance.
375 *
376 * Returns the next doorbell interrupt source.
377 */
378int mic_next_db(struct mic_device *mdev)
379{
380 int next_db;
381
382 next_db = mdev->irq_info.next_avail_src %
383 mdev->intr_info->intr_len[MIC_INTR_DB];
384 mdev->irq_info.next_avail_src++;
385 return next_db;
386}
387
388#define COOKIE_ID_SHIFT 16
389#define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
390#define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
391#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
392
393/**
394 * mic_request_irq - request an irq. mic_mutex needs
395 * to be held before calling this function.
396 *
397 * @mdev: pointer to mic_device instance
398 * @func: The callback function that handles the interrupt.
399 * The function needs to call ack_interrupts
400 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
401 * @name: The ASCII name of the callee requesting the irq.
402 * @data: private data that is returned back when calling the
403 * function handler.
404 * @intr_src: The source id of the requester. Its the doorbell id
405 * for Doorbell interrupts and DMA channel id for DMA interrupts.
406 * @type: The type of interrupt. Values defined in mic_intr_type
407 *
408 * returns: The cookie that is transparent to the caller. Passed
409 * back when calling mic_free_irq. An appropriate error code
410 * is returned on failure. Caller needs to use IS_ERR(return_val)
411 * to check for failure and PTR_ERR(return_val) to obtained the
412 * error code.
413 *
414 */
415struct mic_irq *mic_request_irq(struct mic_device *mdev,
416 irqreturn_t (*func)(int irq, void *dev),
417 const char *name, void *data, int intr_src,
418 enum mic_intr_type type)
419{
420 u16 offset;
421 int rc = 0;
422 struct msix_entry *msix = NULL;
423 unsigned long cookie = 0;
424 u16 entry;
425 struct mic_intr_cb *intr_cb;
426 struct pci_dev *pdev = container_of(mdev->sdev->parent,
427 struct pci_dev, dev);
428
429 offset = mic_map_src_to_offset(mdev, intr_src, type);
430 if (offset >= MIC_NUM_OFFSETS) {
431 dev_err(mdev->sdev->parent,
432 "Error mapping index %d to a valid source id.\n",
433 intr_src);
434 rc = -EINVAL;
435 goto err;
436 }
437
438 if (mdev->irq_info.num_vectors > 1) {
439 msix = mic_get_available_vector(mdev);
440 if (!msix) {
441 dev_err(mdev->sdev->parent,
442 "No MSIx vectors available for use.\n");
443 rc = -ENOSPC;
444 goto err;
445 }
446
447 rc = request_irq(msix->vector, func, 0, name, data);
448 if (rc) {
449 dev_dbg(mdev->sdev->parent,
450 "request irq failed rc = %d\n", rc);
451 goto err;
452 }
453 entry = msix->entry;
454 mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
455 mdev->intr_ops->program_msi_to_src_map(mdev,
456 entry, offset, true);
457 cookie = MK_COOKIE(entry, offset);
458 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
459 msix->vector, intr_src);
460 } else {
461 intr_cb = mic_register_intr_callback(mdev,
462 offset, func, data);
463 if (IS_ERR(intr_cb)) {
464 dev_err(mdev->sdev->parent,
465 "No available callback entries for use\n");
466 rc = PTR_ERR(intr_cb);
467 goto err;
468 }
469
470 entry = 0;
471 if (pci_dev_msi_enabled(pdev)) {
472 mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
473 mdev->intr_ops->program_msi_to_src_map(mdev,
474 entry, offset, true);
475 }
476 cookie = MK_COOKIE(entry, intr_cb->cb_id);
477 dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
478 intr_cb->cb_id, intr_src);
479 }
480 return (struct mic_irq *)cookie;
481err:
482 return ERR_PTR(rc);
483}
484
485/**
486 * mic_free_irq - free irq. mic_mutex
487 * needs to be held before calling this function.
488 *
489 * @mdev: pointer to mic_device instance
490 * @cookie: cookie obtained during a successful call to mic_request_irq
491 * @data: private data specified by the calling function during the
492 * mic_request_irq
493 *
494 * returns: none.
495 */
496void mic_free_irq(struct mic_device *mdev,
497 struct mic_irq *cookie, void *data)
498{
499 u32 offset;
500 u32 entry;
501 u8 src_id;
502 unsigned int irq;
503 struct pci_dev *pdev = container_of(mdev->sdev->parent,
504 struct pci_dev, dev);
505
506 entry = GET_ENTRY((unsigned long)cookie);
507 offset = GET_OFFSET((unsigned long)cookie);
508 if (mdev->irq_info.num_vectors > 1) {
509 if (entry >= mdev->irq_info.num_vectors) {
510 dev_warn(mdev->sdev->parent,
511 "entry %d should be < num_irq %d\n",
512 entry, mdev->irq_info.num_vectors);
513 return;
514 }
515 irq = mdev->irq_info.msix_entries[entry].vector;
516 free_irq(irq, data);
517 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
518 mdev->intr_ops->program_msi_to_src_map(mdev,
519 entry, offset, false);
520
521 dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
522 } else {
523 irq = pdev->irq;
524 src_id = mic_unregister_intr_callback(mdev, offset);
525 if (src_id >= MIC_NUM_OFFSETS) {
526 dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
527 return;
528 }
529 if (pci_dev_msi_enabled(pdev)) {
530 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
531 mdev->intr_ops->program_msi_to_src_map(mdev,
532 entry, src_id, false);
533 }
534 dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
535 offset, src_id);
536 }
537}
538
539/**
540 * mic_setup_interrupts - Initializes interrupts.
541 *
542 * @mdev: pointer to mic_device instance
543 * @pdev: PCI device structure
544 *
545 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
546 */
547int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
548{
549 int rc;
550
551 rc = mic_setup_msix(mdev, pdev);
552 if (!rc)
553 goto done;
554
555 rc = mic_setup_msi(mdev, pdev);
556 if (!rc)
557 goto done;
558
559 rc = mic_setup_intx(mdev, pdev);
560 if (rc) {
561 dev_err(mdev->sdev->parent, "no usable interrupts\n");
562 return rc;
563 }
564done:
565 mdev->intr_ops->enable_interrupts(mdev);
566 return 0;
567}
568
569/**
570 * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
571 *
572 * @mdev: pointer to mic_device instance
573 * @pdev: PCI device structure
574 *
575 * returns none.
576 */
577void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
578{
579 int i;
580
581 mdev->intr_ops->disable_interrupts(mdev);
582 if (mdev->irq_info.num_vectors > 1) {
583 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
584 if (mdev->irq_info.mic_msi_map[i])
585 dev_warn(&pdev->dev, "irq %d may still be in use.\n",
586 mdev->irq_info.msix_entries[i].vector);
587 }
588 kfree(mdev->irq_info.mic_msi_map);
589 kfree(mdev->irq_info.msix_entries);
590 pci_disable_msix(pdev);
591 } else {
592 if (pci_dev_msi_enabled(pdev)) {
593 free_irq(pdev->irq, mdev);
594 kfree(mdev->irq_info.mic_msi_map);
595 pci_disable_msi(pdev);
596 } else {
597 free_irq(pdev->irq, mdev);
598 }
599 mic_release_callbacks(mdev);
600 }
601}
602
603/**
604 * mic_intr_restore - Restore MIC interrupt registers.
605 *
606 * @mdev: pointer to mic_device instance.
607 *
608 * Restore the interrupt registers to values previously
609 * stored in the SW data structures. mic_mutex needs to
610 * be held before calling this function.
611 *
612 * returns None.
613 */
614void mic_intr_restore(struct mic_device *mdev)
615{
616 int entry, offset;
617 struct pci_dev *pdev = container_of(mdev->sdev->parent,
618 struct pci_dev, dev);
619
620 if (!pci_dev_msi_enabled(pdev))
621 return;
622
623 for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
624 for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
625 if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
626 mdev->intr_ops->program_msi_to_src_map(mdev,
627 entry, offset, true);
628 }
629 }
630}
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h
new file mode 100644
index 000000000000..6091aa97e116
--- /dev/null
+++ b/drivers/misc/mic/host/mic_intr.h
@@ -0,0 +1,137 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef _MIC_INTR_H_
22#define _MIC_INTR_H_
23
24/*
25 * The minimum number of msix vectors required for normal operation.
26 * 3 for virtio network, console and block devices.
27 * 1 for card shutdown notifications.
28 */
29#define MIC_MIN_MSIX 4
30#define MIC_NUM_OFFSETS 32
31
32/**
33 * mic_intr_source - The type of source that will generate
34 * the interrupt.The number of types needs to be in sync with
35 * MIC_NUM_INTR_TYPES
36 *
37 * MIC_INTR_DB: The source is a doorbell
38 * MIC_INTR_DMA: The source is a DMA channel
39 * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR
40 * MIC_NUM_INTR_TYPES: Total number of interrupt sources.
41 */
42enum mic_intr_type {
43 MIC_INTR_DB = 0,
44 MIC_INTR_DMA,
45 MIC_INTR_ERR,
46 MIC_NUM_INTR_TYPES
47};
48
49/**
50 * struct mic_intr_info - Contains h/w specific interrupt sources
51 * information.
52 *
53 * @intr_start_idx: Contains the starting indexes of the
54 * interrupt types.
55 * @intr_len: Contains the length of the interrupt types.
56 */
57struct mic_intr_info {
58 u16 intr_start_idx[MIC_NUM_INTR_TYPES];
59 u16 intr_len[MIC_NUM_INTR_TYPES];
60};
61
62/**
63 * struct mic_irq_info - OS specific irq information
64 *
65 * @next_avail_src: next available doorbell that can be assigned.
66 * @msix_entries: msix entries allocated while setting up MSI-x
67 * @mic_msi_map: The MSI/MSI-x mapping information.
68 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
69 * @cb_ida: callback ID allocator to track the callbacks registered.
70 * @mic_intr_lock: spinlock to protect the interrupt callback list.
71 * @cb_list: Array of callback lists one for each source.
72 */
73struct mic_irq_info {
74 int next_avail_src;
75 struct msix_entry *msix_entries;
76 u32 *mic_msi_map;
77 u16 num_vectors;
78 struct ida cb_ida;
79 spinlock_t mic_intr_lock;
80 struct list_head *cb_list;
81};
82
83/**
84 * struct mic_intr_cb - Interrupt callback structure.
85 *
86 * @func: The callback function
87 * @data: Private data of the requester.
88 * @cb_id: The callback id. Identifies this callback.
89 * @list: list head pointing to the next callback structure.
90 */
91struct mic_intr_cb {
92 irqreturn_t (*func) (int irq, void *data);
93 void *data;
94 int cb_id;
95 struct list_head list;
96};
97
98/**
99 * struct mic_irq - opaque pointer used as cookie
100 */
101struct mic_irq;
102
103/* Forward declaration */
104struct mic_device;
105
106/**
107 * struct mic_hw_intr_ops: MIC HW specific interrupt operations
108 * @intr_init: Initialize H/W specific interrupt information.
109 * @enable_interrupts: Enable interrupts from the hardware.
110 * @disable_interrupts: Disable interrupts from the hardware.
111 * @program_msi_to_src_map: Update MSI mapping registers with
112 * irq information.
113 * @read_msi_to_src_map: Read MSI mapping registers containing
114 * irq information.
115 */
116struct mic_hw_intr_ops {
117 void (*intr_init)(struct mic_device *mdev);
118 void (*enable_interrupts)(struct mic_device *mdev);
119 void (*disable_interrupts)(struct mic_device *mdev);
120 void (*program_msi_to_src_map) (struct mic_device *mdev,
121 int idx, int intr_src, bool set);
122 u32 (*read_msi_to_src_map) (struct mic_device *mdev,
123 int idx);
124};
125
126int mic_next_db(struct mic_device *mdev);
127struct mic_irq *mic_request_irq(struct mic_device *mdev,
128 irqreturn_t (*func)(int irq, void *data),
129 const char *name, void *data, int intr_src,
130 enum mic_intr_type type);
131
132void mic_free_irq(struct mic_device *mdev,
133 struct mic_irq *cookie, void *data);
134int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
135void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
136void mic_intr_restore(struct mic_device *mdev);
137#endif
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c
new file mode 100644
index 000000000000..b3520859abd3
--- /dev/null
+++ b/drivers/misc/mic/host/mic_main.c
@@ -0,0 +1,537 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 * Global TODO's across the driver to be added after initial base
21 * patches are accepted upstream:
22 * 1) Enable DMA support.
23 * 2) Enable per vring interrupt support.
24 */
25#include <linux/fs.h>
26#include <linux/module.h>
27#include <linux/pci.h>
28#include <linux/poll.h>
29#include <linux/suspend.h>
30
31#include <linux/mic_common.h>
32#include "../common/mic_dev.h"
33#include "mic_device.h"
34#include "mic_x100.h"
35#include "mic_smpt.h"
36#include "mic_fops.h"
37#include "mic_virtio.h"
38
39static const char mic_driver_name[] = "mic";
40
41static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = {
42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
44 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)},
46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)},
47 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)},
48 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)},
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)},
56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)},
57
58 /* required last entry */
59 { 0, }
60};
61
62MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
63
64/* ID allocator for MIC devices */
65static struct ida g_mic_ida;
66/* Class of MIC devices for sysfs accessibility. */
67static struct class *g_mic_class;
68/* Base device node number for MIC devices */
69static dev_t g_mic_devno;
70
71static const struct file_operations mic_fops = {
72 .open = mic_open,
73 .release = mic_release,
74 .unlocked_ioctl = mic_ioctl,
75 .poll = mic_poll,
76 .mmap = mic_mmap,
77 .owner = THIS_MODULE,
78};
79
80/* Initialize the device page */
81static int mic_dp_init(struct mic_device *mdev)
82{
83 mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL);
84 if (!mdev->dp) {
85 dev_err(mdev->sdev->parent, "%s %d err %d\n",
86 __func__, __LINE__, -ENOMEM);
87 return -ENOMEM;
88 }
89
90 mdev->dp_dma_addr = mic_map_single(mdev,
91 mdev->dp, MIC_DP_SIZE);
92 if (mic_map_error(mdev->dp_dma_addr)) {
93 kfree(mdev->dp);
94 dev_err(mdev->sdev->parent, "%s %d err %d\n",
95 __func__, __LINE__, -ENOMEM);
96 return -ENOMEM;
97 }
98 mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
99 mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
100 return 0;
101}
102
103/* Uninitialize the device page */
104static void mic_dp_uninit(struct mic_device *mdev)
105{
106 mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE);
107 kfree(mdev->dp);
108}
109
110/**
111 * mic_shutdown_db - Shutdown doorbell interrupt handler.
112 */
113static irqreturn_t mic_shutdown_db(int irq, void *data)
114{
115 struct mic_device *mdev = data;
116 struct mic_bootparam *bootparam = mdev->dp;
117
118 mdev->ops->ack_interrupt(mdev);
119
120 switch (bootparam->shutdown_status) {
121 case MIC_HALTED:
122 case MIC_POWER_OFF:
123 case MIC_RESTART:
124 /* Fall through */
125 case MIC_CRASHED:
126 schedule_work(&mdev->shutdown_work);
127 break;
128 default:
129 break;
130 };
131 return IRQ_HANDLED;
132}
133
134/**
135 * mic_ops_init: Initialize HW specific operation tables.
136 *
137 * @mdev: pointer to mic_device instance
138 *
139 * returns none.
140 */
141static void mic_ops_init(struct mic_device *mdev)
142{
143 switch (mdev->family) {
144 case MIC_FAMILY_X100:
145 mdev->ops = &mic_x100_ops;
146 mdev->intr_ops = &mic_x100_intr_ops;
147 mdev->smpt_ops = &mic_x100_smpt_ops;
148 break;
149 default:
150 break;
151 }
152}
153
154/**
155 * mic_get_family - Determine hardware family to which this MIC belongs.
156 *
157 * @pdev: The pci device structure
158 *
159 * returns family.
160 */
161static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
162{
163 enum mic_hw_family family;
164
165 switch (pdev->device) {
166 case MIC_X100_PCI_DEVICE_2250:
167 case MIC_X100_PCI_DEVICE_2251:
168 case MIC_X100_PCI_DEVICE_2252:
169 case MIC_X100_PCI_DEVICE_2253:
170 case MIC_X100_PCI_DEVICE_2254:
171 case MIC_X100_PCI_DEVICE_2255:
172 case MIC_X100_PCI_DEVICE_2256:
173 case MIC_X100_PCI_DEVICE_2257:
174 case MIC_X100_PCI_DEVICE_2258:
175 case MIC_X100_PCI_DEVICE_2259:
176 case MIC_X100_PCI_DEVICE_225a:
177 case MIC_X100_PCI_DEVICE_225b:
178 case MIC_X100_PCI_DEVICE_225c:
179 case MIC_X100_PCI_DEVICE_225d:
180 case MIC_X100_PCI_DEVICE_225e:
181 family = MIC_FAMILY_X100;
182 break;
183 default:
184 family = MIC_FAMILY_UNKNOWN;
185 break;
186 }
187 return family;
188}
189
190/**
191* mic_pm_notifier: Notifier callback function that handles
192* PM notifications.
193*
194* @notifier_block: The notifier structure.
195* @pm_event: The event for which the driver was notified.
196* @unused: Meaningless. Always NULL.
197*
198* returns NOTIFY_DONE
199*/
200static int mic_pm_notifier(struct notifier_block *notifier,
201 unsigned long pm_event, void *unused)
202{
203 struct mic_device *mdev = container_of(notifier,
204 struct mic_device, pm_notifier);
205
206 switch (pm_event) {
207 case PM_HIBERNATION_PREPARE:
208 /* Fall through */
209 case PM_SUSPEND_PREPARE:
210 mic_prepare_suspend(mdev);
211 break;
212 case PM_POST_HIBERNATION:
213 /* Fall through */
214 case PM_POST_SUSPEND:
215 /* Fall through */
216 case PM_POST_RESTORE:
217 mic_complete_resume(mdev);
218 break;
219 case PM_RESTORE_PREPARE:
220 break;
221 default:
222 break;
223 }
224 return NOTIFY_DONE;
225}
226
227/**
228 * mic_device_init - Allocates and initializes the MIC device structure
229 *
230 * @mdev: pointer to mic_device instance
231 * @pdev: The pci device structure
232 *
233 * returns none.
234 */
235static int
236mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
237{
238 int rc;
239
240 mdev->family = mic_get_family(pdev);
241 mdev->stepping = pdev->revision;
242 mic_ops_init(mdev);
243 mic_sysfs_init(mdev);
244 mutex_init(&mdev->mic_mutex);
245 mdev->irq_info.next_avail_src = 0;
246 INIT_WORK(&mdev->reset_trigger_work, mic_reset_trigger_work);
247 INIT_WORK(&mdev->shutdown_work, mic_shutdown_work);
248 init_completion(&mdev->reset_wait);
249 INIT_LIST_HEAD(&mdev->vdev_list);
250 mdev->pm_notifier.notifier_call = mic_pm_notifier;
251 rc = register_pm_notifier(&mdev->pm_notifier);
252 if (rc) {
253 dev_err(&pdev->dev, "register_pm_notifier failed rc %d\n",
254 rc);
255 goto register_pm_notifier_fail;
256 }
257 return 0;
258register_pm_notifier_fail:
259 flush_work(&mdev->shutdown_work);
260 flush_work(&mdev->reset_trigger_work);
261 return rc;
262}
263
264/**
265 * mic_device_uninit - Frees resources allocated during mic_device_init(..)
266 *
267 * @mdev: pointer to mic_device instance
268 *
269 * returns none
270 */
271static void mic_device_uninit(struct mic_device *mdev)
272{
273 /* The cmdline sysfs entry might have allocated cmdline */
274 kfree(mdev->cmdline);
275 kfree(mdev->firmware);
276 kfree(mdev->ramdisk);
277 kfree(mdev->bootmode);
278 flush_work(&mdev->reset_trigger_work);
279 flush_work(&mdev->shutdown_work);
280 unregister_pm_notifier(&mdev->pm_notifier);
281}
282
283/**
284 * mic_probe - Device Initialization Routine
285 *
286 * @pdev: PCI device structure
287 * @ent: entry in mic_pci_tbl
288 *
289 * returns 0 on success, < 0 on failure.
290 */
291static int mic_probe(struct pci_dev *pdev,
292 const struct pci_device_id *ent)
293{
294 int rc;
295 struct mic_device *mdev;
296
297 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
298 if (!mdev) {
299 rc = -ENOMEM;
300 dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc);
301 goto mdev_alloc_fail;
302 }
303 mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL);
304 if (mdev->id < 0) {
305 rc = mdev->id;
306 dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc);
307 goto ida_fail;
308 }
309
310 rc = mic_device_init(mdev, pdev);
311 if (rc) {
312 dev_err(&pdev->dev, "mic_device_init failed rc %d\n", rc);
313 goto device_init_fail;
314 }
315
316 rc = pci_enable_device(pdev);
317 if (rc) {
318 dev_err(&pdev->dev, "failed to enable pci device.\n");
319 goto uninit_device;
320 }
321
322 pci_set_master(pdev);
323
324 rc = pci_request_regions(pdev, mic_driver_name);
325 if (rc) {
326 dev_err(&pdev->dev, "failed to get pci regions.\n");
327 goto disable_device;
328 }
329
330 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
331 if (rc) {
332 dev_err(&pdev->dev, "Cannot set DMA mask\n");
333 goto release_regions;
334 }
335
336 mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar);
337 mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar);
338 mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar);
339 if (!mdev->mmio.va) {
340 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
341 rc = -EIO;
342 goto release_regions;
343 }
344
345 mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar);
346 mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar);
347 mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len);
348 if (!mdev->aper.va) {
349 dev_err(&pdev->dev, "Cannot remap Aperture BAR\n");
350 rc = -EIO;
351 goto unmap_mmio;
352 }
353
354 mdev->intr_ops->intr_init(mdev);
355 rc = mic_setup_interrupts(mdev, pdev);
356 if (rc) {
357 dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc);
358 goto unmap_aper;
359 }
360 rc = mic_smpt_init(mdev);
361 if (rc) {
362 dev_err(&pdev->dev, "smpt_init failed %d\n", rc);
363 goto free_interrupts;
364 }
365
366 pci_set_drvdata(pdev, mdev);
367
368 mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev,
369 MKDEV(MAJOR(g_mic_devno), mdev->id), NULL,
370 mdev->attr_group, "mic%d", mdev->id);
371 if (IS_ERR(mdev->sdev)) {
372 rc = PTR_ERR(mdev->sdev);
373 dev_err(&pdev->dev,
374 "device_create_with_groups failed rc %d\n", rc);
375 goto smpt_uninit;
376 }
377 mdev->state_sysfs = sysfs_get_dirent(mdev->sdev->kobj.sd,
378 NULL, "state");
379 if (!mdev->state_sysfs) {
380 rc = -ENODEV;
381 dev_err(&pdev->dev, "sysfs_get_dirent failed rc %d\n", rc);
382 goto destroy_device;
383 }
384
385 rc = mic_dp_init(mdev);
386 if (rc) {
387 dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc);
388 goto sysfs_put;
389 }
390 mutex_lock(&mdev->mic_mutex);
391
392 mdev->shutdown_db = mic_next_db(mdev);
393 mdev->shutdown_cookie = mic_request_irq(mdev, mic_shutdown_db,
394 "shutdown-interrupt", mdev, mdev->shutdown_db, MIC_INTR_DB);
395 if (IS_ERR(mdev->shutdown_cookie)) {
396 rc = PTR_ERR(mdev->shutdown_cookie);
397 mutex_unlock(&mdev->mic_mutex);
398 goto dp_uninit;
399 }
400 mutex_unlock(&mdev->mic_mutex);
401 mic_bootparam_init(mdev);
402
403 mic_create_debug_dir(mdev);
404 cdev_init(&mdev->cdev, &mic_fops);
405 mdev->cdev.owner = THIS_MODULE;
406 rc = cdev_add(&mdev->cdev, MKDEV(MAJOR(g_mic_devno), mdev->id), 1);
407 if (rc) {
408 dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc);
409 goto cleanup_debug_dir;
410 }
411 return 0;
412cleanup_debug_dir:
413 mic_delete_debug_dir(mdev);
414 mutex_lock(&mdev->mic_mutex);
415 mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
416 mutex_unlock(&mdev->mic_mutex);
417dp_uninit:
418 mic_dp_uninit(mdev);
419sysfs_put:
420 sysfs_put(mdev->state_sysfs);
421destroy_device:
422 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
423smpt_uninit:
424 mic_smpt_uninit(mdev);
425free_interrupts:
426 mic_free_interrupts(mdev, pdev);
427unmap_aper:
428 iounmap(mdev->aper.va);
429unmap_mmio:
430 iounmap(mdev->mmio.va);
431release_regions:
432 pci_release_regions(pdev);
433disable_device:
434 pci_disable_device(pdev);
435uninit_device:
436 mic_device_uninit(mdev);
437device_init_fail:
438 ida_simple_remove(&g_mic_ida, mdev->id);
439ida_fail:
440 kfree(mdev);
441mdev_alloc_fail:
442 dev_err(&pdev->dev, "Probe failed rc %d\n", rc);
443 return rc;
444}
445
446/**
447 * mic_remove - Device Removal Routine
448 * mic_remove is called by the PCI subsystem to alert the driver
449 * that it should release a PCI device.
450 *
451 * @pdev: PCI device structure
452 */
453static void mic_remove(struct pci_dev *pdev)
454{
455 struct mic_device *mdev;
456
457 mdev = pci_get_drvdata(pdev);
458 if (!mdev)
459 return;
460
461 mic_stop(mdev, false);
462 cdev_del(&mdev->cdev);
463 mic_delete_debug_dir(mdev);
464 mutex_lock(&mdev->mic_mutex);
465 mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
466 mutex_unlock(&mdev->mic_mutex);
467 flush_work(&mdev->shutdown_work);
468 mic_dp_uninit(mdev);
469 sysfs_put(mdev->state_sysfs);
470 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
471 mic_smpt_uninit(mdev);
472 mic_free_interrupts(mdev, pdev);
473 iounmap(mdev->mmio.va);
474 iounmap(mdev->aper.va);
475 mic_device_uninit(mdev);
476 pci_release_regions(pdev);
477 pci_disable_device(pdev);
478 ida_simple_remove(&g_mic_ida, mdev->id);
479 kfree(mdev);
480}
481static struct pci_driver mic_driver = {
482 .name = mic_driver_name,
483 .id_table = mic_pci_tbl,
484 .probe = mic_probe,
485 .remove = mic_remove
486};
487
488static int __init mic_init(void)
489{
490 int ret;
491
492 ret = alloc_chrdev_region(&g_mic_devno, 0,
493 MIC_MAX_NUM_DEVS, mic_driver_name);
494 if (ret) {
495 pr_err("alloc_chrdev_region failed ret %d\n", ret);
496 goto error;
497 }
498
499 g_mic_class = class_create(THIS_MODULE, mic_driver_name);
500 if (IS_ERR(g_mic_class)) {
501 ret = PTR_ERR(g_mic_class);
502 pr_err("class_create failed ret %d\n", ret);
503 goto cleanup_chrdev;
504 }
505
506 mic_init_debugfs();
507 ida_init(&g_mic_ida);
508 ret = pci_register_driver(&mic_driver);
509 if (ret) {
510 pr_err("pci_register_driver failed ret %d\n", ret);
511 goto cleanup_debugfs;
512 }
513 return ret;
514cleanup_debugfs:
515 mic_exit_debugfs();
516 class_destroy(g_mic_class);
517cleanup_chrdev:
518 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
519error:
520 return ret;
521}
522
523static void __exit mic_exit(void)
524{
525 pci_unregister_driver(&mic_driver);
526 ida_destroy(&g_mic_ida);
527 mic_exit_debugfs();
528 class_destroy(g_mic_class);
529 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
530}
531
532module_init(mic_init);
533module_exit(mic_exit);
534
535MODULE_AUTHOR("Intel Corporation");
536MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver");
537MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/host/mic_smpt.c b/drivers/misc/mic/host/mic_smpt.c
new file mode 100644
index 000000000000..fae474c4899e
--- /dev/null
+++ b/drivers/misc/mic/host/mic_smpt.c
@@ -0,0 +1,442 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/pci.h>
22
23#include "../common/mic_dev.h"
24#include "mic_device.h"
25#include "mic_smpt.h"
26
27static inline u64 mic_system_page_mask(struct mic_device *mdev)
28{
29 return (1ULL << mdev->smpt->info.page_shift) - 1ULL;
30}
31
32static inline u8 mic_sys_addr_to_smpt(struct mic_device *mdev, dma_addr_t pa)
33{
34 return (pa - mdev->smpt->info.base) >> mdev->smpt->info.page_shift;
35}
36
37static inline u64 mic_smpt_to_pa(struct mic_device *mdev, u8 index)
38{
39 return mdev->smpt->info.base + (index * mdev->smpt->info.page_size);
40}
41
42static inline u64 mic_smpt_offset(struct mic_device *mdev, dma_addr_t pa)
43{
44 return pa & mic_system_page_mask(mdev);
45}
46
47static inline u64 mic_smpt_align_low(struct mic_device *mdev, dma_addr_t pa)
48{
49 return ALIGN(pa - mic_system_page_mask(mdev),
50 mdev->smpt->info.page_size);
51}
52
53static inline u64 mic_smpt_align_high(struct mic_device *mdev, dma_addr_t pa)
54{
55 return ALIGN(pa, mdev->smpt->info.page_size);
56}
57
58/* Total Cumulative system memory accessible by MIC across all SMPT entries */
59static inline u64 mic_max_system_memory(struct mic_device *mdev)
60{
61 return mdev->smpt->info.num_reg * mdev->smpt->info.page_size;
62}
63
64/* Maximum system memory address accessible by MIC */
65static inline u64 mic_max_system_addr(struct mic_device *mdev)
66{
67 return mdev->smpt->info.base + mic_max_system_memory(mdev) - 1ULL;
68}
69
70/* Check if the DMA address is a MIC system memory address */
71static inline bool
72mic_is_system_addr(struct mic_device *mdev, dma_addr_t pa)
73{
74 return pa >= mdev->smpt->info.base && pa <= mic_max_system_addr(mdev);
75}
76
77/* Populate an SMPT entry and update the reference counts. */
78static void mic_add_smpt_entry(int spt, s64 *ref, u64 addr,
79 int entries, struct mic_device *mdev)
80{
81 struct mic_smpt_info *smpt_info = mdev->smpt;
82 int i;
83
84 for (i = spt; i < spt + entries; i++,
85 addr += smpt_info->info.page_size) {
86 if (!smpt_info->entry[i].ref_count &&
87 (smpt_info->entry[i].dma_addr != addr)) {
88 mdev->smpt_ops->set(mdev, addr, i);
89 smpt_info->entry[i].dma_addr = addr;
90 }
91 smpt_info->entry[i].ref_count += ref[i - spt];
92 }
93}
94
95/*
96 * Find an available MIC address in MIC SMPT address space
97 * for a given DMA address and size.
98 */
99static dma_addr_t mic_smpt_op(struct mic_device *mdev, u64 dma_addr,
100 int entries, s64 *ref, size_t size)
101{
102 int spt;
103 int ae = 0;
104 int i;
105 unsigned long flags;
106 dma_addr_t mic_addr = 0;
107 dma_addr_t addr = dma_addr;
108 struct mic_smpt_info *smpt_info = mdev->smpt;
109
110 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
111
112 /* find existing entries */
113 for (i = 0; i < smpt_info->info.num_reg; i++) {
114 if (smpt_info->entry[i].dma_addr == addr) {
115 ae++;
116 addr += smpt_info->info.page_size;
117 } else if (ae) /* cannot find contiguous entries */
118 goto not_found;
119
120 if (ae == entries)
121 goto found;
122 }
123
124 /* find free entry */
125 for (ae = 0, i = 0; i < smpt_info->info.num_reg; i++) {
126 ae = (smpt_info->entry[i].ref_count == 0) ? ae + 1 : 0;
127 if (ae == entries)
128 goto found;
129 }
130
131not_found:
132 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
133 return mic_addr;
134
135found:
136 spt = i - entries + 1;
137 mic_addr = mic_smpt_to_pa(mdev, spt);
138 mic_add_smpt_entry(spt, ref, dma_addr, entries, mdev);
139 smpt_info->map_count++;
140 smpt_info->ref_count += (s64)size;
141 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
142 return mic_addr;
143}
144
145/*
146 * Returns number of smpt entries needed for dma_addr to dma_addr + size
147 * also returns the reference count array for each of those entries
148 * and the starting smpt address
149 */
150static int mic_get_smpt_ref_count(struct mic_device *mdev, dma_addr_t dma_addr,
151 size_t size, s64 *ref, u64 *smpt_start)
152{
153 u64 start = dma_addr;
154 u64 end = dma_addr + size;
155 int i = 0;
156
157 while (start < end) {
158 ref[i++] = min(mic_smpt_align_high(mdev, start + 1),
159 end) - start;
160 start = mic_smpt_align_high(mdev, start + 1);
161 }
162
163 if (smpt_start)
164 *smpt_start = mic_smpt_align_low(mdev, dma_addr);
165
166 return i;
167}
168
169/*
170 * mic_to_dma_addr - Converts a MIC address to a DMA address.
171 *
172 * @mdev: pointer to mic_device instance.
173 * @mic_addr: MIC address.
174 *
175 * returns a DMA address.
176 */
177static dma_addr_t
178mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr)
179{
180 struct mic_smpt_info *smpt_info = mdev->smpt;
181 int spt;
182 dma_addr_t dma_addr;
183
184 if (!mic_is_system_addr(mdev, mic_addr)) {
185 dev_err(mdev->sdev->parent,
186 "mic_addr is invalid. mic_addr = 0x%llx\n", mic_addr);
187 return -EINVAL;
188 }
189 spt = mic_sys_addr_to_smpt(mdev, mic_addr);
190 dma_addr = smpt_info->entry[spt].dma_addr +
191 mic_smpt_offset(mdev, mic_addr);
192 return dma_addr;
193}
194
195/**
196 * mic_map - Maps a DMA address to a MIC physical address.
197 *
198 * @mdev: pointer to mic_device instance.
199 * @dma_addr: DMA address.
200 * @size: Size of the region to be mapped.
201 *
202 * This API converts the DMA address provided to a DMA address understood
203 * by MIC. Caller should check for errors by calling mic_map_error(..).
204 *
205 * returns DMA address as required by MIC.
206 */
207dma_addr_t mic_map(struct mic_device *mdev, dma_addr_t dma_addr, size_t size)
208{
209 dma_addr_t mic_addr = 0;
210 int num_entries;
211 s64 *ref;
212 u64 smpt_start;
213
214 if (!size || size > mic_max_system_memory(mdev))
215 return mic_addr;
216
217 ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
218 if (!ref)
219 return mic_addr;
220
221 num_entries = mic_get_smpt_ref_count(mdev, dma_addr, size,
222 ref, &smpt_start);
223
224 /* Set the smpt table appropriately and get 16G aligned mic address */
225 mic_addr = mic_smpt_op(mdev, smpt_start, num_entries, ref, size);
226
227 kfree(ref);
228
229 /*
230 * If mic_addr is zero then its an error case
231 * since mic_addr can never be zero.
232 * else generate mic_addr by adding the 16G offset in dma_addr
233 */
234 if (!mic_addr && MIC_FAMILY_X100 == mdev->family) {
235 dev_err(mdev->sdev->parent,
236 "mic_map failed dma_addr 0x%llx size 0x%lx\n",
237 dma_addr, size);
238 return mic_addr;
239 } else {
240 return mic_addr + mic_smpt_offset(mdev, dma_addr);
241 }
242}
243
244/**
245 * mic_unmap - Unmaps a MIC physical address.
246 *
247 * @mdev: pointer to mic_device instance.
248 * @mic_addr: MIC physical address.
249 * @size: Size of the region to be unmapped.
250 *
251 * This API unmaps the mappings created by mic_map(..).
252 *
253 * returns None.
254 */
255void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
256{
257 struct mic_smpt_info *smpt_info = mdev->smpt;
258 s64 *ref;
259 int num_smpt;
260 int spt;
261 int i;
262 unsigned long flags;
263
264 if (!size)
265 return;
266
267 if (!mic_is_system_addr(mdev, mic_addr)) {
268 dev_err(mdev->sdev->parent,
269 "invalid address: 0x%llx\n", mic_addr);
270 return;
271 }
272
273 spt = mic_sys_addr_to_smpt(mdev, mic_addr);
274 ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
275 if (!ref)
276 return;
277
278 /* Get number of smpt entries to be mapped, ref count array */
279 num_smpt = mic_get_smpt_ref_count(mdev, mic_addr, size, ref, NULL);
280
281 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
282 smpt_info->unmap_count++;
283 smpt_info->ref_count -= (s64)size;
284
285 for (i = spt; i < spt + num_smpt; i++) {
286 smpt_info->entry[i].ref_count -= ref[i - spt];
287 if (smpt_info->entry[i].ref_count < 0)
288 dev_warn(mdev->sdev->parent,
289 "ref count for entry %d is negative\n", i);
290 }
291 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
292 kfree(ref);
293}
294
295/**
296 * mic_map_single - Maps a virtual address to a MIC physical address.
297 *
298 * @mdev: pointer to mic_device instance.
299 * @va: Kernel direct mapped virtual address.
300 * @size: Size of the region to be mapped.
301 *
302 * This API calls pci_map_single(..) for the direct mapped virtual address
303 * and then converts the DMA address provided to a DMA address understood
304 * by MIC. Caller should check for errors by calling mic_map_error(..).
305 *
306 * returns DMA address as required by MIC.
307 */
308dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size)
309{
310 dma_addr_t mic_addr = 0;
311 struct pci_dev *pdev = container_of(mdev->sdev->parent,
312 struct pci_dev, dev);
313 dma_addr_t dma_addr =
314 pci_map_single(pdev, va, size, PCI_DMA_BIDIRECTIONAL);
315
316 if (!pci_dma_mapping_error(pdev, dma_addr)) {
317 mic_addr = mic_map(mdev, dma_addr, size);
318 if (!mic_addr) {
319 dev_err(mdev->sdev->parent,
320 "mic_map failed dma_addr 0x%llx size 0x%lx\n",
321 dma_addr, size);
322 pci_unmap_single(pdev, dma_addr,
323 size, PCI_DMA_BIDIRECTIONAL);
324 }
325 }
326 return mic_addr;
327}
328
329/**
330 * mic_unmap_single - Unmaps a MIC physical address.
331 *
332 * @mdev: pointer to mic_device instance.
333 * @mic_addr: MIC physical address.
334 * @size: Size of the region to be unmapped.
335 *
336 * This API unmaps the mappings created by mic_map_single(..).
337 *
338 * returns None.
339 */
340void
341mic_unmap_single(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
342{
343 struct pci_dev *pdev = container_of(mdev->sdev->parent,
344 struct pci_dev, dev);
345 dma_addr_t dma_addr = mic_to_dma_addr(mdev, mic_addr);
346 mic_unmap(mdev, mic_addr, size);
347 pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
348}
349
350/**
351 * mic_smpt_init - Initialize MIC System Memory Page Tables.
352 *
353 * @mdev: pointer to mic_device instance.
354 *
355 * returns 0 for success and -errno for error.
356 */
357int mic_smpt_init(struct mic_device *mdev)
358{
359 int i, err = 0;
360 dma_addr_t dma_addr;
361 struct mic_smpt_info *smpt_info;
362
363 mdev->smpt = kmalloc(sizeof(*mdev->smpt), GFP_KERNEL);
364 if (!mdev->smpt)
365 return -ENOMEM;
366
367 smpt_info = mdev->smpt;
368 mdev->smpt_ops->init(mdev);
369 smpt_info->entry = kmalloc_array(smpt_info->info.num_reg,
370 sizeof(*smpt_info->entry), GFP_KERNEL);
371 if (!smpt_info->entry) {
372 err = -ENOMEM;
373 goto free_smpt;
374 }
375 spin_lock_init(&smpt_info->smpt_lock);
376 for (i = 0; i < smpt_info->info.num_reg; i++) {
377 dma_addr = i * smpt_info->info.page_size;
378 smpt_info->entry[i].dma_addr = dma_addr;
379 smpt_info->entry[i].ref_count = 0;
380 mdev->smpt_ops->set(mdev, dma_addr, i);
381 }
382 smpt_info->ref_count = 0;
383 smpt_info->map_count = 0;
384 smpt_info->unmap_count = 0;
385 return 0;
386free_smpt:
387 kfree(smpt_info);
388 return err;
389}
390
391/**
392 * mic_smpt_uninit - UnInitialize MIC System Memory Page Tables.
393 *
394 * @mdev: pointer to mic_device instance.
395 *
396 * returns None.
397 */
398void mic_smpt_uninit(struct mic_device *mdev)
399{
400 struct mic_smpt_info *smpt_info = mdev->smpt;
401 int i;
402
403 dev_dbg(mdev->sdev->parent,
404 "nodeid %d SMPT ref count %lld map %lld unmap %lld\n",
405 mdev->id, smpt_info->ref_count,
406 smpt_info->map_count, smpt_info->unmap_count);
407
408 for (i = 0; i < smpt_info->info.num_reg; i++) {
409 dev_dbg(mdev->sdev->parent,
410 "SMPT entry[%d] dma_addr = 0x%llx ref_count = %lld\n",
411 i, smpt_info->entry[i].dma_addr,
412 smpt_info->entry[i].ref_count);
413 if (smpt_info->entry[i].ref_count)
414 dev_warn(mdev->sdev->parent,
415 "ref count for entry %d is not zero\n", i);
416 }
417 kfree(smpt_info->entry);
418 kfree(smpt_info);
419}
420
421/**
422 * mic_smpt_restore - Restore MIC System Memory Page Tables.
423 *
424 * @mdev: pointer to mic_device instance.
425 *
426 * Restore the SMPT registers to values previously stored in the
427 * SW data structures. Some MIC steppings lose register state
428 * across resets and this API should be called for performing
429 * a restore operation if required.
430 *
431 * returns None.
432 */
433void mic_smpt_restore(struct mic_device *mdev)
434{
435 int i;
436 dma_addr_t dma_addr;
437
438 for (i = 0; i < mdev->smpt->info.num_reg; i++) {
439 dma_addr = mdev->smpt->entry[i].dma_addr;
440 mdev->smpt_ops->set(mdev, dma_addr, i);
441 }
442}
diff --git a/drivers/misc/mic/host/mic_smpt.h b/drivers/misc/mic/host/mic_smpt.h
new file mode 100644
index 000000000000..51970abfe7df
--- /dev/null
+++ b/drivers/misc/mic/host/mic_smpt.h
@@ -0,0 +1,98 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef MIC_SMPT_H
22#define MIC_SMPT_H
23/**
24 * struct mic_smpt_ops - MIC HW specific SMPT operations.
25 * @init: Initialize hardware specific SMPT information in mic_smpt_hw_info.
26 * @set: Set the value for a particular SMPT entry.
27 */
28struct mic_smpt_ops {
29 void (*init)(struct mic_device *mdev);
30 void (*set)(struct mic_device *mdev, dma_addr_t dma_addr, u8 index);
31};
32
33/**
34 * struct mic_smpt - MIC SMPT entry information.
35 * @dma_addr: Base DMA address for this SMPT entry.
36 * @ref_count: Number of active mappings for this SMPT entry in bytes.
37 */
38struct mic_smpt {
39 dma_addr_t dma_addr;
40 s64 ref_count;
41};
42
43/**
44 * struct mic_smpt_hw_info - MIC SMPT hardware specific information.
45 * @num_reg: Number of SMPT registers.
46 * @page_shift: System memory page shift.
47 * @page_size: System memory page size.
48 * @base: System address base.
49 */
50struct mic_smpt_hw_info {
51 u8 num_reg;
52 u8 page_shift;
53 u64 page_size;
54 u64 base;
55};
56
57/**
58 * struct mic_smpt_info - MIC SMPT information.
59 * @entry: Array of SMPT entries.
60 * @smpt_lock: Spin lock protecting access to SMPT data structures.
61 * @info: Hardware specific SMPT information.
62 * @ref_count: Number of active SMPT mappings (for debug).
63 * @map_count: Number of SMPT mappings created (for debug).
64 * @unmap_count: Number of SMPT mappings destroyed (for debug).
65 */
66struct mic_smpt_info {
67 struct mic_smpt *entry;
68 spinlock_t smpt_lock;
69 struct mic_smpt_hw_info info;
70 s64 ref_count;
71 s64 map_count;
72 s64 unmap_count;
73};
74
75dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size);
76void mic_unmap_single(struct mic_device *mdev,
77 dma_addr_t mic_addr, size_t size);
78dma_addr_t mic_map(struct mic_device *mdev,
79 dma_addr_t dma_addr, size_t size);
80void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size);
81
82/**
83 * mic_map_error - Check a MIC address for errors.
84 *
85 * @mdev: pointer to mic_device instance.
86 *
87 * returns Whether there was an error during mic_map..(..) APIs.
88 */
89static inline bool mic_map_error(dma_addr_t mic_addr)
90{
91 return !mic_addr;
92}
93
94int mic_smpt_init(struct mic_device *mdev);
95void mic_smpt_uninit(struct mic_device *mdev);
96void mic_smpt_restore(struct mic_device *mdev);
97
98#endif
diff --git a/drivers/misc/mic/host/mic_sysfs.c b/drivers/misc/mic/host/mic_sysfs.c
new file mode 100644
index 000000000000..6dd864e4a617
--- /dev/null
+++ b/drivers/misc/mic/host/mic_sysfs.c
@@ -0,0 +1,459 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/pci.h>
22
23#include <linux/mic_common.h>
24#include "../common/mic_dev.h"
25#include "mic_device.h"
26
27/*
28 * A state-to-string lookup table, for exposing a human readable state
29 * via sysfs. Always keep in sync with enum mic_states
30 */
31static const char * const mic_state_string[] = {
32 [MIC_OFFLINE] = "offline",
33 [MIC_ONLINE] = "online",
34 [MIC_SHUTTING_DOWN] = "shutting_down",
35 [MIC_RESET_FAILED] = "reset_failed",
36 [MIC_SUSPENDING] = "suspending",
37 [MIC_SUSPENDED] = "suspended",
38};
39
40/*
41 * A shutdown-status-to-string lookup table, for exposing a human
42 * readable state via sysfs. Always keep in sync with enum mic_shutdown_status
43 */
44static const char * const mic_shutdown_status_string[] = {
45 [MIC_NOP] = "nop",
46 [MIC_CRASHED] = "crashed",
47 [MIC_HALTED] = "halted",
48 [MIC_POWER_OFF] = "poweroff",
49 [MIC_RESTART] = "restart",
50};
51
52void mic_set_shutdown_status(struct mic_device *mdev, u8 shutdown_status)
53{
54 dev_dbg(mdev->sdev->parent, "Shutdown Status %s -> %s\n",
55 mic_shutdown_status_string[mdev->shutdown_status],
56 mic_shutdown_status_string[shutdown_status]);
57 mdev->shutdown_status = shutdown_status;
58}
59
60void mic_set_state(struct mic_device *mdev, u8 state)
61{
62 dev_dbg(mdev->sdev->parent, "State %s -> %s\n",
63 mic_state_string[mdev->state],
64 mic_state_string[state]);
65 mdev->state = state;
66 sysfs_notify_dirent(mdev->state_sysfs);
67}
68
69static ssize_t
70family_show(struct device *dev, struct device_attribute *attr, char *buf)
71{
72 static const char x100[] = "x100";
73 static const char unknown[] = "Unknown";
74 const char *card = NULL;
75 struct mic_device *mdev = dev_get_drvdata(dev->parent);
76
77 if (!mdev)
78 return -EINVAL;
79
80 switch (mdev->family) {
81 case MIC_FAMILY_X100:
82 card = x100;
83 break;
84 default:
85 card = unknown;
86 break;
87 }
88 return scnprintf(buf, PAGE_SIZE, "%s\n", card);
89}
90static DEVICE_ATTR_RO(family);
91
92static ssize_t
93stepping_show(struct device *dev, struct device_attribute *attr, char *buf)
94{
95 struct mic_device *mdev = dev_get_drvdata(dev->parent);
96 char *string = "??";
97
98 if (!mdev)
99 return -EINVAL;
100
101 switch (mdev->stepping) {
102 case MIC_A0_STEP:
103 string = "A0";
104 break;
105 case MIC_B0_STEP:
106 string = "B0";
107 break;
108 case MIC_B1_STEP:
109 string = "B1";
110 break;
111 case MIC_C0_STEP:
112 string = "C0";
113 break;
114 default:
115 break;
116 }
117 return scnprintf(buf, PAGE_SIZE, "%s\n", string);
118}
119static DEVICE_ATTR_RO(stepping);
120
121static ssize_t
122state_show(struct device *dev, struct device_attribute *attr, char *buf)
123{
124 struct mic_device *mdev = dev_get_drvdata(dev->parent);
125
126 if (!mdev || mdev->state >= MIC_LAST)
127 return -EINVAL;
128
129 return scnprintf(buf, PAGE_SIZE, "%s\n",
130 mic_state_string[mdev->state]);
131}
132
133static ssize_t
134state_store(struct device *dev, struct device_attribute *attr,
135 const char *buf, size_t count)
136{
137 int rc = 0;
138 struct mic_device *mdev = dev_get_drvdata(dev->parent);
139 if (!mdev)
140 return -EINVAL;
141 if (sysfs_streq(buf, "boot")) {
142 rc = mic_start(mdev, buf);
143 if (rc) {
144 dev_err(mdev->sdev->parent,
145 "mic_boot failed rc %d\n", rc);
146 count = rc;
147 }
148 goto done;
149 }
150
151 if (sysfs_streq(buf, "reset")) {
152 schedule_work(&mdev->reset_trigger_work);
153 goto done;
154 }
155
156 if (sysfs_streq(buf, "shutdown")) {
157 mic_shutdown(mdev);
158 goto done;
159 }
160
161 if (sysfs_streq(buf, "suspend")) {
162 mic_suspend(mdev);
163 goto done;
164 }
165
166 count = -EINVAL;
167done:
168 return count;
169}
170static DEVICE_ATTR_RW(state);
171
172static ssize_t shutdown_status_show(struct device *dev,
173 struct device_attribute *attr, char *buf)
174{
175 struct mic_device *mdev = dev_get_drvdata(dev->parent);
176
177 if (!mdev || mdev->shutdown_status >= MIC_STATUS_LAST)
178 return -EINVAL;
179
180 return scnprintf(buf, PAGE_SIZE, "%s\n",
181 mic_shutdown_status_string[mdev->shutdown_status]);
182}
183static DEVICE_ATTR_RO(shutdown_status);
184
185static ssize_t
186cmdline_show(struct device *dev, struct device_attribute *attr, char *buf)
187{
188 struct mic_device *mdev = dev_get_drvdata(dev->parent);
189 char *cmdline;
190
191 if (!mdev)
192 return -EINVAL;
193
194 cmdline = mdev->cmdline;
195
196 if (cmdline)
197 return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
198 return 0;
199}
200
201static ssize_t
202cmdline_store(struct device *dev, struct device_attribute *attr,
203 const char *buf, size_t count)
204{
205 struct mic_device *mdev = dev_get_drvdata(dev->parent);
206
207 if (!mdev)
208 return -EINVAL;
209
210 mutex_lock(&mdev->mic_mutex);
211 kfree(mdev->cmdline);
212
213 mdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
214 if (!mdev->cmdline) {
215 count = -ENOMEM;
216 goto unlock;
217 }
218
219 strncpy(mdev->cmdline, buf, count);
220
221 if (mdev->cmdline[count - 1] == '\n')
222 mdev->cmdline[count - 1] = '\0';
223 else
224 mdev->cmdline[count] = '\0';
225unlock:
226 mutex_unlock(&mdev->mic_mutex);
227 return count;
228}
229static DEVICE_ATTR_RW(cmdline);
230
231static ssize_t
232firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
233{
234 struct mic_device *mdev = dev_get_drvdata(dev->parent);
235 char *firmware;
236
237 if (!mdev)
238 return -EINVAL;
239
240 firmware = mdev->firmware;
241
242 if (firmware)
243 return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
244 return 0;
245}
246
247static ssize_t
248firmware_store(struct device *dev, struct device_attribute *attr,
249 const char *buf, size_t count)
250{
251 struct mic_device *mdev = dev_get_drvdata(dev->parent);
252
253 if (!mdev)
254 return -EINVAL;
255
256 mutex_lock(&mdev->mic_mutex);
257 kfree(mdev->firmware);
258
259 mdev->firmware = kmalloc(count + 1, GFP_KERNEL);
260 if (!mdev->firmware) {
261 count = -ENOMEM;
262 goto unlock;
263 }
264 strncpy(mdev->firmware, buf, count);
265
266 if (mdev->firmware[count - 1] == '\n')
267 mdev->firmware[count - 1] = '\0';
268 else
269 mdev->firmware[count] = '\0';
270unlock:
271 mutex_unlock(&mdev->mic_mutex);
272 return count;
273}
274static DEVICE_ATTR_RW(firmware);
275
276static ssize_t
277ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf)
278{
279 struct mic_device *mdev = dev_get_drvdata(dev->parent);
280 char *ramdisk;
281
282 if (!mdev)
283 return -EINVAL;
284
285 ramdisk = mdev->ramdisk;
286
287 if (ramdisk)
288 return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
289 return 0;
290}
291
292static ssize_t
293ramdisk_store(struct device *dev, struct device_attribute *attr,
294 const char *buf, size_t count)
295{
296 struct mic_device *mdev = dev_get_drvdata(dev->parent);
297
298 if (!mdev)
299 return -EINVAL;
300
301 mutex_lock(&mdev->mic_mutex);
302 kfree(mdev->ramdisk);
303
304 mdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
305 if (!mdev->ramdisk) {
306 count = -ENOMEM;
307 goto unlock;
308 }
309
310 strncpy(mdev->ramdisk, buf, count);
311
312 if (mdev->ramdisk[count - 1] == '\n')
313 mdev->ramdisk[count - 1] = '\0';
314 else
315 mdev->ramdisk[count] = '\0';
316unlock:
317 mutex_unlock(&mdev->mic_mutex);
318 return count;
319}
320static DEVICE_ATTR_RW(ramdisk);
321
322static ssize_t
323bootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
324{
325 struct mic_device *mdev = dev_get_drvdata(dev->parent);
326 char *bootmode;
327
328 if (!mdev)
329 return -EINVAL;
330
331 bootmode = mdev->bootmode;
332
333 if (bootmode)
334 return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
335 return 0;
336}
337
338static ssize_t
339bootmode_store(struct device *dev, struct device_attribute *attr,
340 const char *buf, size_t count)
341{
342 struct mic_device *mdev = dev_get_drvdata(dev->parent);
343
344 if (!mdev)
345 return -EINVAL;
346
347 if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "elf"))
348 return -EINVAL;
349
350 mutex_lock(&mdev->mic_mutex);
351 kfree(mdev->bootmode);
352
353 mdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
354 if (!mdev->bootmode) {
355 count = -ENOMEM;
356 goto unlock;
357 }
358
359 strncpy(mdev->bootmode, buf, count);
360
361 if (mdev->bootmode[count - 1] == '\n')
362 mdev->bootmode[count - 1] = '\0';
363 else
364 mdev->bootmode[count] = '\0';
365unlock:
366 mutex_unlock(&mdev->mic_mutex);
367 return count;
368}
369static DEVICE_ATTR_RW(bootmode);
370
371static ssize_t
372log_buf_addr_show(struct device *dev, struct device_attribute *attr,
373 char *buf)
374{
375 struct mic_device *mdev = dev_get_drvdata(dev->parent);
376
377 if (!mdev)
378 return -EINVAL;
379
380 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_addr);
381}
382
383static ssize_t
384log_buf_addr_store(struct device *dev, struct device_attribute *attr,
385 const char *buf, size_t count)
386{
387 struct mic_device *mdev = dev_get_drvdata(dev->parent);
388 int ret;
389 unsigned long addr;
390
391 if (!mdev)
392 return -EINVAL;
393
394 ret = kstrtoul(buf, 16, &addr);
395 if (ret)
396 goto exit;
397
398 mdev->log_buf_addr = (void *)addr;
399 ret = count;
400exit:
401 return ret;
402}
403static DEVICE_ATTR_RW(log_buf_addr);
404
405static ssize_t
406log_buf_len_show(struct device *dev, struct device_attribute *attr,
407 char *buf)
408{
409 struct mic_device *mdev = dev_get_drvdata(dev->parent);
410
411 if (!mdev)
412 return -EINVAL;
413
414 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_len);
415}
416
417static ssize_t
418log_buf_len_store(struct device *dev, struct device_attribute *attr,
419 const char *buf, size_t count)
420{
421 struct mic_device *mdev = dev_get_drvdata(dev->parent);
422 int ret;
423 unsigned long addr;
424
425 if (!mdev)
426 return -EINVAL;
427
428 ret = kstrtoul(buf, 16, &addr);
429 if (ret)
430 goto exit;
431
432 mdev->log_buf_len = (int *)addr;
433 ret = count;
434exit:
435 return ret;
436}
437static DEVICE_ATTR_RW(log_buf_len);
438
439static struct attribute *mic_default_attrs[] = {
440 &dev_attr_family.attr,
441 &dev_attr_stepping.attr,
442 &dev_attr_state.attr,
443 &dev_attr_shutdown_status.attr,
444 &dev_attr_cmdline.attr,
445 &dev_attr_firmware.attr,
446 &dev_attr_ramdisk.attr,
447 &dev_attr_bootmode.attr,
448 &dev_attr_log_buf_addr.attr,
449 &dev_attr_log_buf_len.attr,
450
451 NULL
452};
453
454ATTRIBUTE_GROUPS(mic_default);
455
456void mic_sysfs_init(struct mic_device *mdev)
457{
458 mdev->attr_group = mic_default_groups;
459}
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
new file mode 100644
index 000000000000..5b8494bd1e00
--- /dev/null
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -0,0 +1,700 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/pci.h>
22#include <linux/sched.h>
23#include <linux/uaccess.h>
24
25#include <linux/mic_common.h>
26#include "../common/mic_dev.h"
27#include "mic_device.h"
28#include "mic_smpt.h"
29#include "mic_virtio.h"
30
31/*
32 * Initiates the copies across the PCIe bus from card memory to
33 * a user space buffer.
34 */
35static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
36 void __user *ubuf, size_t len, u64 addr)
37{
38 int err;
39 void __iomem *dbuf = mvdev->mdev->aper.va + addr;
40 /*
41 * We are copying from IO below an should ideally use something
42 * like copy_to_user_fromio(..) if it existed.
43 */
44 if (copy_to_user(ubuf, dbuf, len)) {
45 err = -EFAULT;
46 dev_err(mic_dev(mvdev), "%s %d err %d\n",
47 __func__, __LINE__, err);
48 goto err;
49 }
50 mvdev->in_bytes += len;
51 err = 0;
52err:
53 return err;
54}
55
56/*
57 * Initiates copies across the PCIe bus from a user space
58 * buffer to card memory.
59 */
60static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
61 void __user *ubuf, size_t len, u64 addr)
62{
63 int err;
64 void __iomem *dbuf = mvdev->mdev->aper.va + addr;
65 /*
66 * We are copying to IO below and should ideally use something
67 * like copy_from_user_toio(..) if it existed.
68 */
69 if (copy_from_user(dbuf, ubuf, len)) {
70 err = -EFAULT;
71 dev_err(mic_dev(mvdev), "%s %d err %d\n",
72 __func__, __LINE__, err);
73 goto err;
74 }
75 mvdev->out_bytes += len;
76 err = 0;
77err:
78 return err;
79}
80
81#define MIC_VRINGH_READ true
82
83/* The function to call to notify the card about added buffers */
84static void mic_notify(struct vringh *vrh)
85{
86 struct mic_vringh *mvrh = container_of(vrh, struct mic_vringh, vrh);
87 struct mic_vdev *mvdev = mvrh->mvdev;
88 s8 db = mvdev->dc->h2c_vdev_db;
89
90 if (db != -1)
91 mvdev->mdev->ops->send_intr(mvdev->mdev, db);
92}
93
94/* Determine the total number of bytes consumed in a VRINGH KIOV */
95static inline u32 mic_vringh_iov_consumed(struct vringh_kiov *iov)
96{
97 int i;
98 u32 total = iov->consumed;
99
100 for (i = 0; i < iov->i; i++)
101 total += iov->iov[i].iov_len;
102 return total;
103}
104
105/*
106 * Traverse the VRINGH KIOV and issue the APIs to trigger the copies.
107 * This API is heavily based on the vringh_iov_xfer(..) implementation
108 * in vringh.c. The reason we cannot reuse vringh_iov_pull_kern(..)
109 * and vringh_iov_push_kern(..) directly is because there is no
110 * way to override the VRINGH xfer(..) routines as of v3.10.
111 */
112static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
113 void __user *ubuf, size_t len, bool read, size_t *out_len)
114{
115 int ret = 0;
116 size_t partlen, tot_len = 0;
117
118 while (len && iov->i < iov->used) {
119 partlen = min(iov->iov[iov->i].iov_len, len);
120 if (read)
121 ret = mic_virtio_copy_to_user(mvdev,
122 ubuf, partlen,
123 (u64)iov->iov[iov->i].iov_base);
124 else
125 ret = mic_virtio_copy_from_user(mvdev,
126 ubuf, partlen,
127 (u64)iov->iov[iov->i].iov_base);
128 if (ret) {
129 dev_err(mic_dev(mvdev), "%s %d err %d\n",
130 __func__, __LINE__, ret);
131 break;
132 }
133 len -= partlen;
134 ubuf += partlen;
135 tot_len += partlen;
136 iov->consumed += partlen;
137 iov->iov[iov->i].iov_len -= partlen;
138 iov->iov[iov->i].iov_base += partlen;
139 if (!iov->iov[iov->i].iov_len) {
140 /* Fix up old iov element then increment. */
141 iov->iov[iov->i].iov_len = iov->consumed;
142 iov->iov[iov->i].iov_base -= iov->consumed;
143
144 iov->consumed = 0;
145 iov->i++;
146 }
147 }
148 *out_len = tot_len;
149 return ret;
150}
151
152/*
153 * Use the standard VRINGH infrastructure in the kernel to fetch new
154 * descriptors, initiate the copies and update the used ring.
155 */
156static int _mic_virtio_copy(struct mic_vdev *mvdev,
157 struct mic_copy_desc *copy)
158{
159 int ret = 0, iovcnt = copy->iovcnt;
160 struct iovec iov;
161 struct iovec __user *u_iov = copy->iov;
162 void __user *ubuf = NULL;
163 struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
164 struct vringh_kiov *riov = &mvr->riov;
165 struct vringh_kiov *wiov = &mvr->wiov;
166 struct vringh *vrh = &mvr->vrh;
167 u16 *head = &mvr->head;
168 struct mic_vring *vr = &mvr->vring;
169 size_t len = 0, out_len;
170
171 copy->out_len = 0;
172 /* Fetch a new IOVEC if all previous elements have been processed */
173 if (riov->i == riov->used && wiov->i == wiov->used) {
174 ret = vringh_getdesc_kern(vrh, riov, wiov,
175 head, GFP_KERNEL);
176 /* Check if there are available descriptors */
177 if (ret <= 0)
178 return ret;
179 }
180 while (iovcnt) {
181 if (!len) {
182 /* Copy over a new iovec from user space. */
183 ret = copy_from_user(&iov, u_iov, sizeof(*u_iov));
184 if (ret) {
185 ret = -EINVAL;
186 dev_err(mic_dev(mvdev), "%s %d err %d\n",
187 __func__, __LINE__, ret);
188 break;
189 }
190 len = iov.iov_len;
191 ubuf = iov.iov_base;
192 }
193 /* Issue all the read descriptors first */
194 ret = mic_vringh_copy(mvdev, riov, ubuf, len,
195 MIC_VRINGH_READ, &out_len);
196 if (ret) {
197 dev_err(mic_dev(mvdev), "%s %d err %d\n",
198 __func__, __LINE__, ret);
199 break;
200 }
201 len -= out_len;
202 ubuf += out_len;
203 copy->out_len += out_len;
204 /* Issue the write descriptors next */
205 ret = mic_vringh_copy(mvdev, wiov, ubuf, len,
206 !MIC_VRINGH_READ, &out_len);
207 if (ret) {
208 dev_err(mic_dev(mvdev), "%s %d err %d\n",
209 __func__, __LINE__, ret);
210 break;
211 }
212 len -= out_len;
213 ubuf += out_len;
214 copy->out_len += out_len;
215 if (!len) {
216 /* One user space iovec is now completed */
217 iovcnt--;
218 u_iov++;
219 }
220 /* Exit loop if all elements in KIOVs have been processed. */
221 if (riov->i == riov->used && wiov->i == wiov->used)
222 break;
223 }
224 /*
225 * Update the used ring if a descriptor was available and some data was
226 * copied in/out and the user asked for a used ring update.
227 */
228 if (*head != USHRT_MAX && copy->out_len && copy->update_used) {
229 u32 total = 0;
230
231 /* Determine the total data consumed */
232 total += mic_vringh_iov_consumed(riov);
233 total += mic_vringh_iov_consumed(wiov);
234 vringh_complete_kern(vrh, *head, total);
235 *head = USHRT_MAX;
236 if (vringh_need_notify_kern(vrh) > 0)
237 vringh_notify(vrh);
238 vringh_kiov_cleanup(riov);
239 vringh_kiov_cleanup(wiov);
240 /* Update avail idx for user space */
241 vr->info->avail_idx = vrh->last_avail_idx;
242 }
243 return ret;
244}
245
246static inline int mic_verify_copy_args(struct mic_vdev *mvdev,
247 struct mic_copy_desc *copy)
248{
249 if (copy->vr_idx >= mvdev->dd->num_vq) {
250 dev_err(mic_dev(mvdev), "%s %d err %d\n",
251 __func__, __LINE__, -EINVAL);
252 return -EINVAL;
253 }
254 return 0;
255}
256
257/* Copy a specified number of virtio descriptors in a chain */
258int mic_virtio_copy_desc(struct mic_vdev *mvdev,
259 struct mic_copy_desc *copy)
260{
261 int err;
262 struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
263
264 err = mic_verify_copy_args(mvdev, copy);
265 if (err)
266 return err;
267
268 mutex_lock(&mvr->vr_mutex);
269 if (!mic_vdevup(mvdev)) {
270 err = -ENODEV;
271 dev_err(mic_dev(mvdev), "%s %d err %d\n",
272 __func__, __LINE__, err);
273 goto err;
274 }
275 err = _mic_virtio_copy(mvdev, copy);
276 if (err) {
277 dev_err(mic_dev(mvdev), "%s %d err %d\n",
278 __func__, __LINE__, err);
279 }
280err:
281 mutex_unlock(&mvr->vr_mutex);
282 return err;
283}
284
285static void mic_virtio_init_post(struct mic_vdev *mvdev)
286{
287 struct mic_vqconfig *vqconfig = mic_vq_config(mvdev->dd);
288 int i;
289
290 for (i = 0; i < mvdev->dd->num_vq; i++) {
291 if (!le64_to_cpu(vqconfig[i].used_address)) {
292 dev_warn(mic_dev(mvdev), "used_address zero??\n");
293 continue;
294 }
295 mvdev->mvr[i].vrh.vring.used =
296 mvdev->mdev->aper.va +
297 le64_to_cpu(vqconfig[i].used_address);
298 }
299
300 mvdev->dc->used_address_updated = 0;
301
302 dev_dbg(mic_dev(mvdev), "%s: device type %d LINKUP\n",
303 __func__, mvdev->virtio_id);
304}
305
306static inline void mic_virtio_device_reset(struct mic_vdev *mvdev)
307{
308 int i;
309
310 dev_dbg(mic_dev(mvdev), "%s: status %d device type %d RESET\n",
311 __func__, mvdev->dd->status, mvdev->virtio_id);
312
313 for (i = 0; i < mvdev->dd->num_vq; i++)
314 /*
315 * Avoid lockdep false positive. The + 1 is for the mic
316 * mutex which is held in the reset devices code path.
317 */
318 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
319
320 /* 0 status means "reset" */
321 mvdev->dd->status = 0;
322 mvdev->dc->vdev_reset = 0;
323 mvdev->dc->host_ack = 1;
324
325 for (i = 0; i < mvdev->dd->num_vq; i++) {
326 struct vringh *vrh = &mvdev->mvr[i].vrh;
327 mvdev->mvr[i].vring.info->avail_idx = 0;
328 vrh->completed = 0;
329 vrh->last_avail_idx = 0;
330 vrh->last_used_idx = 0;
331 }
332
333 for (i = 0; i < mvdev->dd->num_vq; i++)
334 mutex_unlock(&mvdev->mvr[i].vr_mutex);
335}
336
337void mic_virtio_reset_devices(struct mic_device *mdev)
338{
339 struct list_head *pos, *tmp;
340 struct mic_vdev *mvdev;
341
342 dev_dbg(mdev->sdev->parent, "%s\n", __func__);
343
344 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
345 mvdev = list_entry(pos, struct mic_vdev, list);
346 mic_virtio_device_reset(mvdev);
347 mvdev->poll_wake = 1;
348 wake_up(&mvdev->waitq);
349 }
350}
351
352void mic_bh_handler(struct work_struct *work)
353{
354 struct mic_vdev *mvdev = container_of(work, struct mic_vdev,
355 virtio_bh_work);
356
357 if (mvdev->dc->used_address_updated)
358 mic_virtio_init_post(mvdev);
359
360 if (mvdev->dc->vdev_reset)
361 mic_virtio_device_reset(mvdev);
362
363 mvdev->poll_wake = 1;
364 wake_up(&mvdev->waitq);
365}
366
367static irqreturn_t mic_virtio_intr_handler(int irq, void *data)
368{
369 struct mic_vdev *mvdev = data;
370 struct mic_device *mdev = mvdev->mdev;
371
372 mdev->ops->ack_interrupt(mdev);
373 schedule_work(&mvdev->virtio_bh_work);
374 return IRQ_HANDLED;
375}
376
377int mic_virtio_config_change(struct mic_vdev *mvdev,
378 void __user *argp)
379{
380 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
381 int ret = 0, retry = 100, i;
382 struct mic_bootparam *bootparam = mvdev->mdev->dp;
383 s8 db = bootparam->h2c_config_db;
384
385 mutex_lock(&mvdev->mdev->mic_mutex);
386 for (i = 0; i < mvdev->dd->num_vq; i++)
387 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
388
389 if (db == -1 || mvdev->dd->type == -1) {
390 ret = -EIO;
391 goto exit;
392 }
393
394 if (copy_from_user(mic_vq_configspace(mvdev->dd),
395 argp, mvdev->dd->config_len)) {
396 dev_err(mic_dev(mvdev), "%s %d err %d\n",
397 __func__, __LINE__, -EFAULT);
398 ret = -EFAULT;
399 goto exit;
400 }
401 mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
402 mvdev->mdev->ops->send_intr(mvdev->mdev, db);
403
404 for (i = retry; i--;) {
405 ret = wait_event_timeout(wake,
406 mvdev->dc->guest_ack, msecs_to_jiffies(100));
407 if (ret)
408 break;
409 }
410
411 dev_dbg(mic_dev(mvdev),
412 "%s %d retry: %d\n", __func__, __LINE__, retry);
413 mvdev->dc->config_change = 0;
414 mvdev->dc->guest_ack = 0;
415exit:
416 for (i = 0; i < mvdev->dd->num_vq; i++)
417 mutex_unlock(&mvdev->mvr[i].vr_mutex);
418 mutex_unlock(&mvdev->mdev->mic_mutex);
419 return ret;
420}
421
422static int mic_copy_dp_entry(struct mic_vdev *mvdev,
423 void __user *argp,
424 __u8 *type,
425 struct mic_device_desc **devpage)
426{
427 struct mic_device *mdev = mvdev->mdev;
428 struct mic_device_desc dd, *dd_config, *devp;
429 struct mic_vqconfig *vqconfig;
430 int ret = 0, i;
431 bool slot_found = false;
432
433 if (copy_from_user(&dd, argp, sizeof(dd))) {
434 dev_err(mic_dev(mvdev), "%s %d err %d\n",
435 __func__, __LINE__, -EFAULT);
436 return -EFAULT;
437 }
438
439 if (mic_aligned_desc_size(&dd) > MIC_MAX_DESC_BLK_SIZE ||
440 dd.num_vq > MIC_MAX_VRINGS) {
441 dev_err(mic_dev(mvdev), "%s %d err %d\n",
442 __func__, __LINE__, -EINVAL);
443 return -EINVAL;
444 }
445
446 dd_config = kmalloc(mic_desc_size(&dd), GFP_KERNEL);
447 if (dd_config == NULL) {
448 dev_err(mic_dev(mvdev), "%s %d err %d\n",
449 __func__, __LINE__, -ENOMEM);
450 return -ENOMEM;
451 }
452 if (copy_from_user(dd_config, argp, mic_desc_size(&dd))) {
453 ret = -EFAULT;
454 dev_err(mic_dev(mvdev), "%s %d err %d\n",
455 __func__, __LINE__, ret);
456 goto exit;
457 }
458
459 vqconfig = mic_vq_config(dd_config);
460 for (i = 0; i < dd.num_vq; i++) {
461 if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) {
462 ret = -EINVAL;
463 dev_err(mic_dev(mvdev), "%s %d err %d\n",
464 __func__, __LINE__, ret);
465 goto exit;
466 }
467 }
468
469 /* Find the first free device page entry */
470 for (i = mic_aligned_size(struct mic_bootparam);
471 i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
472 i += mic_total_desc_size(devp)) {
473 devp = mdev->dp + i;
474 if (devp->type == 0 || devp->type == -1) {
475 slot_found = true;
476 break;
477 }
478 }
479 if (!slot_found) {
480 ret = -EINVAL;
481 dev_err(mic_dev(mvdev), "%s %d err %d\n",
482 __func__, __LINE__, ret);
483 goto exit;
484 }
485 /*
486 * Save off the type before doing the memcpy. Type will be set in the
487 * end after completing all initialization for the new device.
488 */
489 *type = dd_config->type;
490 dd_config->type = 0;
491 memcpy(devp, dd_config, mic_desc_size(dd_config));
492
493 *devpage = devp;
494exit:
495 kfree(dd_config);
496 return ret;
497}
498
499static void mic_init_device_ctrl(struct mic_vdev *mvdev,
500 struct mic_device_desc *devpage)
501{
502 struct mic_device_ctrl *dc;
503
504 dc = (void *)devpage + mic_aligned_desc_size(devpage);
505
506 dc->config_change = 0;
507 dc->guest_ack = 0;
508 dc->vdev_reset = 0;
509 dc->host_ack = 0;
510 dc->used_address_updated = 0;
511 dc->c2h_vdev_db = -1;
512 dc->h2c_vdev_db = -1;
513 mvdev->dc = dc;
514}
515
516int mic_virtio_add_device(struct mic_vdev *mvdev,
517 void __user *argp)
518{
519 struct mic_device *mdev = mvdev->mdev;
520 struct mic_device_desc *dd = NULL;
521 struct mic_vqconfig *vqconfig;
522 int vr_size, i, j, ret;
523 u8 type = 0;
524 s8 db;
525 char irqname[10];
526 struct mic_bootparam *bootparam = mdev->dp;
527 u16 num;
528
529 mutex_lock(&mdev->mic_mutex);
530
531 ret = mic_copy_dp_entry(mvdev, argp, &type, &dd);
532 if (ret) {
533 mutex_unlock(&mdev->mic_mutex);
534 return ret;
535 }
536
537 mic_init_device_ctrl(mvdev, dd);
538
539 mvdev->dd = dd;
540 mvdev->virtio_id = type;
541 vqconfig = mic_vq_config(dd);
542 INIT_WORK(&mvdev->virtio_bh_work, mic_bh_handler);
543
544 for (i = 0; i < dd->num_vq; i++) {
545 struct mic_vringh *mvr = &mvdev->mvr[i];
546 struct mic_vring *vr = &mvdev->mvr[i].vring;
547 num = le16_to_cpu(vqconfig[i].num);
548 mutex_init(&mvr->vr_mutex);
549 vr_size = PAGE_ALIGN(vring_size(num, MIC_VIRTIO_RING_ALIGN) +
550 sizeof(struct _mic_vring_info));
551 vr->va = (void *)
552 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
553 get_order(vr_size));
554 if (!vr->va) {
555 ret = -ENOMEM;
556 dev_err(mic_dev(mvdev), "%s %d err %d\n",
557 __func__, __LINE__, ret);
558 goto err;
559 }
560 vr->len = vr_size;
561 vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
562 vr->info->magic = MIC_MAGIC + mvdev->virtio_id + i;
563 vqconfig[i].address = mic_map_single(mdev,
564 vr->va, vr_size);
565 if (mic_map_error(vqconfig[i].address)) {
566 free_pages((unsigned long)vr->va, get_order(vr_size));
567 ret = -ENOMEM;
568 dev_err(mic_dev(mvdev), "%s %d err %d\n",
569 __func__, __LINE__, ret);
570 goto err;
571 }
572 vqconfig[i].address = cpu_to_le64(vqconfig[i].address);
573
574 vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
575 ret = vringh_init_kern(&mvr->vrh,
576 *(u32 *)mic_vq_features(mvdev->dd), num, false,
577 vr->vr.desc, vr->vr.avail, vr->vr.used);
578 if (ret) {
579 dev_err(mic_dev(mvdev), "%s %d err %d\n",
580 __func__, __LINE__, ret);
581 goto err;
582 }
583 vringh_kiov_init(&mvr->riov, NULL, 0);
584 vringh_kiov_init(&mvr->wiov, NULL, 0);
585 mvr->head = USHRT_MAX;
586 mvr->mvdev = mvdev;
587 mvr->vrh.notify = mic_notify;
588 dev_dbg(mdev->sdev->parent,
589 "%s %d index %d va %p info %p vr_size 0x%x\n",
590 __func__, __LINE__, i, vr->va, vr->info, vr_size);
591 }
592
593 snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id,
594 mvdev->virtio_id);
595 mvdev->virtio_db = mic_next_db(mdev);
596 mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler,
597 irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB);
598 if (IS_ERR(mvdev->virtio_cookie)) {
599 ret = PTR_ERR(mvdev->virtio_cookie);
600 dev_dbg(mdev->sdev->parent, "request irq failed\n");
601 goto err;
602 }
603
604 mvdev->dc->c2h_vdev_db = mvdev->virtio_db;
605
606 list_add_tail(&mvdev->list, &mdev->vdev_list);
607 /*
608 * Order the type update with previous stores. This write barrier
609 * is paired with the corresponding read barrier before the uncached
610 * system memory read of the type, on the card while scanning the
611 * device page.
612 */
613 smp_wmb();
614 dd->type = type;
615
616 dev_dbg(mdev->sdev->parent, "Added virtio device id %d\n", dd->type);
617
618 db = bootparam->h2c_config_db;
619 if (db != -1)
620 mdev->ops->send_intr(mdev, db);
621 mutex_unlock(&mdev->mic_mutex);
622 return 0;
623err:
624 vqconfig = mic_vq_config(dd);
625 for (j = 0; j < i; j++) {
626 struct mic_vringh *mvr = &mvdev->mvr[j];
627 mic_unmap_single(mdev, le64_to_cpu(vqconfig[j].address),
628 mvr->vring.len);
629 free_pages((unsigned long)mvr->vring.va,
630 get_order(mvr->vring.len));
631 }
632 mutex_unlock(&mdev->mic_mutex);
633 return ret;
634}
635
636void mic_virtio_del_device(struct mic_vdev *mvdev)
637{
638 struct list_head *pos, *tmp;
639 struct mic_vdev *tmp_mvdev;
640 struct mic_device *mdev = mvdev->mdev;
641 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
642 int i, ret, retry = 100;
643 struct mic_vqconfig *vqconfig;
644 struct mic_bootparam *bootparam = mdev->dp;
645 s8 db;
646
647 mutex_lock(&mdev->mic_mutex);
648 db = bootparam->h2c_config_db;
649 if (db == -1)
650 goto skip_hot_remove;
651 dev_dbg(mdev->sdev->parent,
652 "Requesting hot remove id %d\n", mvdev->virtio_id);
653 mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
654 mdev->ops->send_intr(mdev, db);
655 for (i = retry; i--;) {
656 ret = wait_event_timeout(wake,
657 mvdev->dc->guest_ack, msecs_to_jiffies(100));
658 if (ret)
659 break;
660 }
661 dev_dbg(mdev->sdev->parent,
662 "Device id %d config_change %d guest_ack %d\n",
663 mvdev->virtio_id, mvdev->dc->config_change,
664 mvdev->dc->guest_ack);
665 mvdev->dc->config_change = 0;
666 mvdev->dc->guest_ack = 0;
667skip_hot_remove:
668 mic_free_irq(mdev, mvdev->virtio_cookie, mvdev);
669 flush_work(&mvdev->virtio_bh_work);
670 vqconfig = mic_vq_config(mvdev->dd);
671 for (i = 0; i < mvdev->dd->num_vq; i++) {
672 struct mic_vringh *mvr = &mvdev->mvr[i];
673 vringh_kiov_cleanup(&mvr->riov);
674 vringh_kiov_cleanup(&mvr->wiov);
675 mic_unmap_single(mdev, le64_to_cpu(vqconfig[i].address),
676 mvr->vring.len);
677 free_pages((unsigned long)mvr->vring.va,
678 get_order(mvr->vring.len));
679 }
680
681 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
682 tmp_mvdev = list_entry(pos, struct mic_vdev, list);
683 if (tmp_mvdev == mvdev) {
684 list_del(pos);
685 dev_dbg(mdev->sdev->parent,
686 "Removing virtio device id %d\n",
687 mvdev->virtio_id);
688 break;
689 }
690 }
691 /*
692 * Order the type update with previous stores. This write barrier
693 * is paired with the corresponding read barrier before the uncached
694 * system memory read of the type, on the card while scanning the
695 * device page.
696 */
697 smp_wmb();
698 mvdev->dd->type = -1;
699 mutex_unlock(&mdev->mic_mutex);
700}
diff --git a/drivers/misc/mic/host/mic_virtio.h b/drivers/misc/mic/host/mic_virtio.h
new file mode 100644
index 000000000000..184f3c84805b
--- /dev/null
+++ b/drivers/misc/mic/host/mic_virtio.h
@@ -0,0 +1,138 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef MIC_VIRTIO_H
22#define MIC_VIRTIO_H
23
24#include <linux/virtio_config.h>
25#include <linux/mic_ioctl.h>
26
27/*
28 * Note on endianness.
29 * 1. Host can be both BE or LE
30 * 2. Guest/card is LE. Host uses le_to_cpu to access desc/avail
31 * rings and ioreadXX/iowriteXX to access used ring.
32 * 3. Device page exposed by host to guest contains LE values. Guest
33 * accesses these using ioreadXX/iowriteXX etc. This way in general we
34 * obey the virtio spec according to which guest works with native
35 * endianness and host is aware of guest endianness and does all
36 * required endianness conversion.
37 * 4. Data provided from user space to guest (in ADD_DEVICE and
38 * CONFIG_CHANGE ioctl's) is not interpreted by the driver and should be
39 * in guest endianness.
40 */
41
42/**
43 * struct mic_vringh - Virtio ring host information.
44 *
45 * @vring: The MIC vring used for setting up user space mappings.
46 * @vrh: The host VRINGH used for accessing the card vrings.
47 * @riov: The VRINGH read kernel IOV.
48 * @wiov: The VRINGH write kernel IOV.
49 * @head: The VRINGH head index address passed to vringh_getdesc_kern(..).
50 * @vr_mutex: Mutex for synchronizing access to the VRING.
51 * @mvdev: Back pointer to MIC virtio device for vringh_notify(..).
52 */
53struct mic_vringh {
54 struct mic_vring vring;
55 struct vringh vrh;
56 struct vringh_kiov riov;
57 struct vringh_kiov wiov;
58 u16 head;
59 struct mutex vr_mutex;
60 struct mic_vdev *mvdev;
61};
62
63/**
64 * struct mic_vdev - Host information for a card Virtio device.
65 *
66 * @virtio_id - Virtio device id.
67 * @waitq - Waitqueue to allow ring3 apps to poll.
68 * @mdev - Back pointer to host MIC device.
69 * @poll_wake - Used for waking up threads blocked in poll.
70 * @out_bytes - Debug stats for number of bytes copied from host to card.
71 * @in_bytes - Debug stats for number of bytes copied from card to host.
72 * @mvr - Store per VRING data structures.
73 * @virtio_bh_work - Work struct used to schedule virtio bottom half handling.
74 * @dd - Virtio device descriptor.
75 * @dc - Virtio device control fields.
76 * @list - List of Virtio devices.
77 * @virtio_db - The doorbell used by the card to interrupt the host.
78 * @virtio_cookie - The cookie returned while requesting interrupts.
79 */
80struct mic_vdev {
81 int virtio_id;
82 wait_queue_head_t waitq;
83 struct mic_device *mdev;
84 int poll_wake;
85 unsigned long out_bytes;
86 unsigned long in_bytes;
87 struct mic_vringh mvr[MIC_MAX_VRINGS];
88 struct work_struct virtio_bh_work;
89 struct mic_device_desc *dd;
90 struct mic_device_ctrl *dc;
91 struct list_head list;
92 int virtio_db;
93 struct mic_irq *virtio_cookie;
94};
95
96void mic_virtio_uninit(struct mic_device *mdev);
97int mic_virtio_add_device(struct mic_vdev *mvdev,
98 void __user *argp);
99void mic_virtio_del_device(struct mic_vdev *mvdev);
100int mic_virtio_config_change(struct mic_vdev *mvdev,
101 void __user *argp);
102int mic_virtio_copy_desc(struct mic_vdev *mvdev,
103 struct mic_copy_desc *request);
104void mic_virtio_reset_devices(struct mic_device *mdev);
105void mic_bh_handler(struct work_struct *work);
106
107/* Helper API to obtain the MIC PCIe device */
108static inline struct device *mic_dev(struct mic_vdev *mvdev)
109{
110 return mvdev->mdev->sdev->parent;
111}
112
113/* Helper API to check if a virtio device is initialized */
114static inline int mic_vdev_inited(struct mic_vdev *mvdev)
115{
116 /* Device has not been created yet */
117 if (!mvdev->dd || !mvdev->dd->type) {
118 dev_err(mic_dev(mvdev), "%s %d err %d\n",
119 __func__, __LINE__, -EINVAL);
120 return -EINVAL;
121 }
122
123 /* Device has been removed/deleted */
124 if (mvdev->dd->type == -1) {
125 dev_err(mic_dev(mvdev), "%s %d err %d\n",
126 __func__, __LINE__, -ENODEV);
127 return -ENODEV;
128 }
129
130 return 0;
131}
132
133/* Helper API to check if a virtio device is running */
134static inline bool mic_vdevup(struct mic_vdev *mvdev)
135{
136 return !!mvdev->dd->status;
137}
138#endif
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c
new file mode 100644
index 000000000000..81e9541b784c
--- /dev/null
+++ b/drivers/misc/mic/host/mic_x100.c
@@ -0,0 +1,570 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#include <linux/fs.h>
22#include <linux/pci.h>
23#include <linux/sched.h>
24#include <linux/firmware.h>
25#include <linux/delay.h>
26
27#include "../common/mic_dev.h"
28#include "mic_device.h"
29#include "mic_x100.h"
30#include "mic_smpt.h"
31
32/**
33 * mic_x100_write_spad - write to the scratchpad register
34 * @mdev: pointer to mic_device instance
35 * @idx: index to the scratchpad register, 0 based
36 * @val: the data value to put into the register
37 *
38 * This function allows writing of a 32bit value to the indexed scratchpad
39 * register.
40 *
41 * RETURNS: none.
42 */
43static void
44mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val)
45{
46 dev_dbg(mdev->sdev->parent, "Writing 0x%x to scratch pad index %d\n",
47 val, idx);
48 mic_mmio_write(&mdev->mmio, val,
49 MIC_X100_SBOX_BASE_ADDRESS +
50 MIC_X100_SBOX_SPAD0 + idx * 4);
51}
52
53/**
54 * mic_x100_read_spad - read from the scratchpad register
55 * @mdev: pointer to mic_device instance
56 * @idx: index to scratchpad register, 0 based
57 *
58 * This function allows reading of the 32bit scratchpad register.
59 *
60 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
61 */
62static u32
63mic_x100_read_spad(struct mic_device *mdev, unsigned int idx)
64{
65 u32 val = mic_mmio_read(&mdev->mmio,
66 MIC_X100_SBOX_BASE_ADDRESS +
67 MIC_X100_SBOX_SPAD0 + idx * 4);
68
69 dev_dbg(mdev->sdev->parent,
70 "Reading 0x%x from scratch pad index %d\n", val, idx);
71 return val;
72}
73
74/**
75 * mic_x100_enable_interrupts - Enable interrupts.
76 * @mdev: pointer to mic_device instance
77 */
78static void mic_x100_enable_interrupts(struct mic_device *mdev)
79{
80 u32 reg;
81 struct mic_mw *mw = &mdev->mmio;
82 u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
83 u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
84
85 reg = mic_mmio_read(mw, sice0);
86 reg |= MIC_X100_SBOX_DBR_BITS(0xf) | MIC_X100_SBOX_DMA_BITS(0xff);
87 mic_mmio_write(mw, reg, sice0);
88
89 /*
90 * Enable auto-clear when enabling interrupts. Applicable only for
91 * MSI-x. Legacy and MSI mode cannot have auto-clear enabled.
92 */
93 if (mdev->irq_info.num_vectors > 1) {
94 reg = mic_mmio_read(mw, siac0);
95 reg |= MIC_X100_SBOX_DBR_BITS(0xf) |
96 MIC_X100_SBOX_DMA_BITS(0xff);
97 mic_mmio_write(mw, reg, siac0);
98 }
99}
100
101/**
102 * mic_x100_disable_interrupts - Disable interrupts.
103 * @mdev: pointer to mic_device instance
104 */
105static void mic_x100_disable_interrupts(struct mic_device *mdev)
106{
107 u32 reg;
108 struct mic_mw *mw = &mdev->mmio;
109 u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
110 u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
111 u32 sicc0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICC0;
112
113 reg = mic_mmio_read(mw, sice0);
114 mic_mmio_write(mw, reg, sicc0);
115
116 if (mdev->irq_info.num_vectors > 1) {
117 reg = mic_mmio_read(mw, siac0);
118 reg &= ~(MIC_X100_SBOX_DBR_BITS(0xf) |
119 MIC_X100_SBOX_DMA_BITS(0xff));
120 mic_mmio_write(mw, reg, siac0);
121 }
122}
123
124/**
125 * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC.
126 * @mdev: pointer to mic_device instance
127 */
128static void mic_x100_send_sbox_intr(struct mic_device *mdev,
129 int doorbell)
130{
131 struct mic_mw *mw = &mdev->mmio;
132 u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8;
133 u32 apicicr_low = mic_mmio_read(mw, MIC_X100_SBOX_BASE_ADDRESS +
134 apic_icr_offset);
135
136 /* for MIC we need to make sure we "hit" the send_icr bit (13) */
137 apicicr_low = (apicicr_low | (1 << 13));
138
139 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
140 wmb();
141 mic_mmio_write(mw, apicicr_low,
142 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
143}
144
145/**
146 * mic_x100_send_rdmasr_intr - Send an RDMASR interrupt to MIC.
147 * @mdev: pointer to mic_device instance
148 */
149static void mic_x100_send_rdmasr_intr(struct mic_device *mdev,
150 int doorbell)
151{
152 int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2);
153 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
154 wmb();
155 mic_mmio_write(&mdev->mmio, 0,
156 MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset);
157}
158
159/**
160 * __mic_x100_send_intr - Send interrupt to MIC.
161 * @mdev: pointer to mic_device instance
162 * @doorbell: doorbell number.
163 */
164static void mic_x100_send_intr(struct mic_device *mdev, int doorbell)
165{
166 int rdmasr_db;
167 if (doorbell < MIC_X100_NUM_SBOX_IRQ) {
168 mic_x100_send_sbox_intr(mdev, doorbell);
169 } else {
170 rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ +
171 MIC_X100_RDMASR_IRQ_BASE;
172 mic_x100_send_rdmasr_intr(mdev, rdmasr_db);
173 }
174}
175
176/**
177 * mic_ack_interrupt - Device specific interrupt handling.
178 * @mdev: pointer to mic_device instance
179 *
180 * Returns: bitmask of doorbell events triggered.
181 */
182static u32 mic_x100_ack_interrupt(struct mic_device *mdev)
183{
184 u32 reg = 0;
185 struct mic_mw *mw = &mdev->mmio;
186 u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0;
187
188 /* Clear pending bit array. */
189 if (MIC_A0_STEP == mdev->stepping)
190 mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS +
191 MIC_X100_SBOX_MSIXPBACR);
192
193 if (mdev->irq_info.num_vectors <= 1) {
194 reg = mic_mmio_read(mw, sicr0);
195
196 if (unlikely(!reg))
197 goto done;
198
199 mic_mmio_write(mw, reg, sicr0);
200 }
201
202 if (mdev->stepping >= MIC_B0_STEP)
203 mdev->intr_ops->enable_interrupts(mdev);
204done:
205 return reg;
206}
207
208/**
209 * mic_x100_hw_intr_init - Initialize h/w specific interrupt
210 * information.
211 * @mdev: pointer to mic_device instance
212 */
213static void mic_x100_hw_intr_init(struct mic_device *mdev)
214{
215 mdev->intr_info = (struct mic_intr_info *)mic_x100_intr_init;
216}
217
218/**
219 * mic_x100_read_msi_to_src_map - read from the MSI mapping registers
220 * @mdev: pointer to mic_device instance
221 * @idx: index to the mapping register, 0 based
222 *
223 * This function allows reading of the 32bit MSI mapping register.
224 *
225 * RETURNS: The value in the register.
226 */
227static u32
228mic_x100_read_msi_to_src_map(struct mic_device *mdev, int idx)
229{
230 return mic_mmio_read(&mdev->mmio,
231 MIC_X100_SBOX_BASE_ADDRESS +
232 MIC_X100_SBOX_MXAR0 + idx * 4);
233}
234
235/**
236 * mic_x100_program_msi_to_src_map - program the MSI mapping registers
237 * @mdev: pointer to mic_device instance
238 * @idx: index to the mapping register, 0 based
239 * @offset: The bit offset in the register that needs to be updated.
240 * @set: boolean specifying if the bit in the specified offset needs
241 * to be set or cleared.
242 *
243 * RETURNS: None.
244 */
245static void
246mic_x100_program_msi_to_src_map(struct mic_device *mdev,
247 int idx, int offset, bool set)
248{
249 unsigned long reg;
250 struct mic_mw *mw = &mdev->mmio;
251 u32 mxar = MIC_X100_SBOX_BASE_ADDRESS +
252 MIC_X100_SBOX_MXAR0 + idx * 4;
253
254 reg = mic_mmio_read(mw, mxar);
255 if (set)
256 __set_bit(offset, &reg);
257 else
258 __clear_bit(offset, &reg);
259 mic_mmio_write(mw, reg, mxar);
260}
261
262/*
263 * mic_x100_reset_fw_ready - Reset Firmware ready status field.
264 * @mdev: pointer to mic_device instance
265 */
266static void mic_x100_reset_fw_ready(struct mic_device *mdev)
267{
268 mdev->ops->write_spad(mdev, MIC_X100_DOWNLOAD_INFO, 0);
269}
270
271/*
272 * mic_x100_is_fw_ready - Check if firmware is ready.
273 * @mdev: pointer to mic_device instance
274 */
275static bool mic_x100_is_fw_ready(struct mic_device *mdev)
276{
277 u32 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
278 return MIC_X100_SPAD2_DOWNLOAD_STATUS(scratch2) ? true : false;
279}
280
281/**
282 * mic_x100_get_apic_id - Get bootstrap APIC ID.
283 * @mdev: pointer to mic_device instance
284 */
285static u32 mic_x100_get_apic_id(struct mic_device *mdev)
286{
287 u32 scratch2 = 0;
288
289 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
290 return MIC_X100_SPAD2_APIC_ID(scratch2);
291}
292
293/**
294 * mic_x100_send_firmware_intr - Send an interrupt to the firmware on MIC.
295 * @mdev: pointer to mic_device instance
296 */
297static void mic_x100_send_firmware_intr(struct mic_device *mdev)
298{
299 u32 apicicr_low;
300 u64 apic_icr_offset = MIC_X100_SBOX_APICICR7;
301 int vector = MIC_X100_BSP_INTERRUPT_VECTOR;
302 struct mic_mw *mw = &mdev->mmio;
303
304 /*
305 * For MIC we need to make sure we "hit"
306 * the send_icr bit (13).
307 */
308 apicicr_low = (vector | (1 << 13));
309
310 mic_mmio_write(mw, mic_x100_get_apic_id(mdev),
311 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset + 4);
312
313 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
314 wmb();
315 mic_mmio_write(mw, apicicr_low,
316 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
317}
318
319/**
320 * mic_x100_hw_reset - Reset the MIC device.
321 * @mdev: pointer to mic_device instance
322 */
323static void mic_x100_hw_reset(struct mic_device *mdev)
324{
325 u32 reset_reg;
326 u32 rgcr = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_RGCR;
327 struct mic_mw *mw = &mdev->mmio;
328
329 /* Ensure that the reset is ordered w.r.t. previous loads and stores */
330 mb();
331 /* Trigger reset */
332 reset_reg = mic_mmio_read(mw, rgcr);
333 reset_reg |= 0x1;
334 mic_mmio_write(mw, reset_reg, rgcr);
335 /*
336 * It seems we really want to delay at least 1 second
337 * after touching reset to prevent a lot of problems.
338 */
339 msleep(1000);
340}
341
342/**
343 * mic_x100_load_command_line - Load command line to MIC.
344 * @mdev: pointer to mic_device instance
345 * @fw: the firmware image
346 *
347 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
348 */
349static int
350mic_x100_load_command_line(struct mic_device *mdev, const struct firmware *fw)
351{
352 u32 len = 0;
353 u32 boot_mem;
354 char *buf;
355 void __iomem *cmd_line_va = mdev->aper.va + mdev->bootaddr + fw->size;
356#define CMDLINE_SIZE 2048
357
358 boot_mem = mdev->aper.len >> 20;
359 buf = kzalloc(CMDLINE_SIZE, GFP_KERNEL);
360 if (!buf) {
361 dev_err(mdev->sdev->parent,
362 "%s %d allocation failed\n", __func__, __LINE__);
363 return -ENOMEM;
364 }
365 len += snprintf(buf, CMDLINE_SIZE - len,
366 " mem=%dM", boot_mem);
367 if (mdev->cmdline)
368 snprintf(buf + len, CMDLINE_SIZE - len, " %s", mdev->cmdline);
369 memcpy_toio(cmd_line_va, buf, strlen(buf) + 1);
370 kfree(buf);
371 return 0;
372}
373
374/**
375 * mic_x100_load_ramdisk - Load ramdisk to MIC.
376 * @mdev: pointer to mic_device instance
377 *
378 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
379 */
380static int
381mic_x100_load_ramdisk(struct mic_device *mdev)
382{
383 const struct firmware *fw;
384 int rc;
385 struct boot_params __iomem *bp = mdev->aper.va + mdev->bootaddr;
386
387 rc = request_firmware(&fw,
388 mdev->ramdisk, mdev->sdev->parent);
389 if (rc < 0) {
390 dev_err(mdev->sdev->parent,
391 "ramdisk request_firmware failed: %d %s\n",
392 rc, mdev->ramdisk);
393 goto error;
394 }
395 /*
396 * Typically the bootaddr for card OS is 64M
397 * so copy over the ramdisk @ 128M.
398 */
399 memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size);
400 iowrite32(cpu_to_le32(mdev->bootaddr << 1), &bp->hdr.ramdisk_image);
401 iowrite32(cpu_to_le32(fw->size), &bp->hdr.ramdisk_size);
402 release_firmware(fw);
403error:
404 return rc;
405}
406
407/**
408 * mic_x100_get_boot_addr - Get MIC boot address.
409 * @mdev: pointer to mic_device instance
410 *
411 * This function is called during firmware load to determine
412 * the address at which the OS should be downloaded in card
413 * memory i.e. GDDR.
414 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
415 */
416static int
417mic_x100_get_boot_addr(struct mic_device *mdev)
418{
419 u32 scratch2, boot_addr;
420 int rc = 0;
421
422 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
423 boot_addr = MIC_X100_SPAD2_DOWNLOAD_ADDR(scratch2);
424 dev_dbg(mdev->sdev->parent, "%s %d boot_addr 0x%x\n",
425 __func__, __LINE__, boot_addr);
426 if (boot_addr > (1 << 31)) {
427 dev_err(mdev->sdev->parent,
428 "incorrect bootaddr 0x%x\n",
429 boot_addr);
430 rc = -EINVAL;
431 goto error;
432 }
433 mdev->bootaddr = boot_addr;
434error:
435 return rc;
436}
437
438/**
439 * mic_x100_load_firmware - Load firmware to MIC.
440 * @mdev: pointer to mic_device instance
441 * @buf: buffer containing boot string including firmware/ramdisk path.
442 *
443 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
444 */
445static int
446mic_x100_load_firmware(struct mic_device *mdev, const char *buf)
447{
448 int rc;
449 const struct firmware *fw;
450
451 rc = mic_x100_get_boot_addr(mdev);
452 if (rc)
453 goto error;
454 /* load OS */
455 rc = request_firmware(&fw, mdev->firmware, mdev->sdev->parent);
456 if (rc < 0) {
457 dev_err(mdev->sdev->parent,
458 "ramdisk request_firmware failed: %d %s\n",
459 rc, mdev->firmware);
460 goto error;
461 }
462 if (mdev->bootaddr > mdev->aper.len - fw->size) {
463 rc = -EINVAL;
464 dev_err(mdev->sdev->parent, "%s %d rc %d bootaddr 0x%x\n",
465 __func__, __LINE__, rc, mdev->bootaddr);
466 release_firmware(fw);
467 goto error;
468 }
469 memcpy_toio(mdev->aper.va + mdev->bootaddr, fw->data, fw->size);
470 mdev->ops->write_spad(mdev, MIC_X100_FW_SIZE, fw->size);
471 if (!strcmp(mdev->bootmode, "elf"))
472 goto done;
473 /* load command line */
474 rc = mic_x100_load_command_line(mdev, fw);
475 if (rc) {
476 dev_err(mdev->sdev->parent, "%s %d rc %d\n",
477 __func__, __LINE__, rc);
478 goto error;
479 }
480 release_firmware(fw);
481 /* load ramdisk */
482 if (mdev->ramdisk)
483 rc = mic_x100_load_ramdisk(mdev);
484error:
485 dev_dbg(mdev->sdev->parent, "%s %d rc %d\n", __func__, __LINE__, rc);
486done:
487 return rc;
488}
489
490/**
491 * mic_x100_get_postcode - Get postcode status from firmware.
492 * @mdev: pointer to mic_device instance
493 *
494 * RETURNS: postcode.
495 */
496static u32 mic_x100_get_postcode(struct mic_device *mdev)
497{
498 return mic_mmio_read(&mdev->mmio, MIC_X100_POSTCODE);
499}
500
501/**
502 * mic_x100_smpt_set - Update an SMPT entry with a DMA address.
503 * @mdev: pointer to mic_device instance
504 *
505 * RETURNS: none.
506 */
507static void
508mic_x100_smpt_set(struct mic_device *mdev, dma_addr_t dma_addr, u8 index)
509{
510#define SNOOP_ON (0 << 0)
511#define SNOOP_OFF (1 << 0)
512/*
513 * Sbox Smpt Reg Bits:
514 * Bits 31:2 Host address
515 * Bits 1 RSVD
516 * Bits 0 No snoop
517 */
518#define BUILD_SMPT(NO_SNOOP, HOST_ADDR) \
519 (u32)(((HOST_ADDR) << 2) | ((NO_SNOOP) & 0x01))
520
521 uint32_t smpt_reg_val = BUILD_SMPT(SNOOP_ON,
522 dma_addr >> mdev->smpt->info.page_shift);
523 mic_mmio_write(&mdev->mmio, smpt_reg_val,
524 MIC_X100_SBOX_BASE_ADDRESS +
525 MIC_X100_SBOX_SMPT00 + (4 * index));
526}
527
528/**
529 * mic_x100_smpt_hw_init - Initialize SMPT X100 specific fields.
530 * @mdev: pointer to mic_device instance
531 *
532 * RETURNS: none.
533 */
534static void mic_x100_smpt_hw_init(struct mic_device *mdev)
535{
536 struct mic_smpt_hw_info *info = &mdev->smpt->info;
537
538 info->num_reg = 32;
539 info->page_shift = 34;
540 info->page_size = (1ULL << info->page_shift);
541 info->base = 0x8000000000ULL;
542}
543
544struct mic_smpt_ops mic_x100_smpt_ops = {
545 .init = mic_x100_smpt_hw_init,
546 .set = mic_x100_smpt_set,
547};
548
549struct mic_hw_ops mic_x100_ops = {
550 .aper_bar = MIC_X100_APER_BAR,
551 .mmio_bar = MIC_X100_MMIO_BAR,
552 .read_spad = mic_x100_read_spad,
553 .write_spad = mic_x100_write_spad,
554 .send_intr = mic_x100_send_intr,
555 .ack_interrupt = mic_x100_ack_interrupt,
556 .reset = mic_x100_hw_reset,
557 .reset_fw_ready = mic_x100_reset_fw_ready,
558 .is_fw_ready = mic_x100_is_fw_ready,
559 .send_firmware_intr = mic_x100_send_firmware_intr,
560 .load_mic_fw = mic_x100_load_firmware,
561 .get_postcode = mic_x100_get_postcode,
562};
563
564struct mic_hw_intr_ops mic_x100_intr_ops = {
565 .intr_init = mic_x100_hw_intr_init,
566 .enable_interrupts = mic_x100_enable_interrupts,
567 .disable_interrupts = mic_x100_disable_interrupts,
568 .program_msi_to_src_map = mic_x100_program_msi_to_src_map,
569 .read_msi_to_src_map = mic_x100_read_msi_to_src_map,
570};
diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h
new file mode 100644
index 000000000000..8b7daa182e54
--- /dev/null
+++ b/drivers/misc/mic/host/mic_x100.h
@@ -0,0 +1,98 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef _MIC_X100_HW_H_
22#define _MIC_X100_HW_H_
23
24#define MIC_X100_PCI_DEVICE_2250 0x2250
25#define MIC_X100_PCI_DEVICE_2251 0x2251
26#define MIC_X100_PCI_DEVICE_2252 0x2252
27#define MIC_X100_PCI_DEVICE_2253 0x2253
28#define MIC_X100_PCI_DEVICE_2254 0x2254
29#define MIC_X100_PCI_DEVICE_2255 0x2255
30#define MIC_X100_PCI_DEVICE_2256 0x2256
31#define MIC_X100_PCI_DEVICE_2257 0x2257
32#define MIC_X100_PCI_DEVICE_2258 0x2258
33#define MIC_X100_PCI_DEVICE_2259 0x2259
34#define MIC_X100_PCI_DEVICE_225a 0x225a
35#define MIC_X100_PCI_DEVICE_225b 0x225b
36#define MIC_X100_PCI_DEVICE_225c 0x225c
37#define MIC_X100_PCI_DEVICE_225d 0x225d
38#define MIC_X100_PCI_DEVICE_225e 0x225e
39
40#define MIC_X100_APER_BAR 0
41#define MIC_X100_MMIO_BAR 4
42
43#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000
44#define MIC_X100_SBOX_SPAD0 0x0000AB20
45#define MIC_X100_SBOX_SICR0_DBR(x) ((x) & 0xf)
46#define MIC_X100_SBOX_SICR0_DMA(x) (((x) >> 8) & 0xff)
47#define MIC_X100_SBOX_SICE0_DBR(x) ((x) & 0xf)
48#define MIC_X100_SBOX_DBR_BITS(x) ((x) & 0xf)
49#define MIC_X100_SBOX_SICE0_DMA(x) (((x) >> 8) & 0xff)
50#define MIC_X100_SBOX_DMA_BITS(x) (((x) & 0xff) << 8)
51
52#define MIC_X100_SBOX_APICICR0 0x0000A9D0
53#define MIC_X100_SBOX_SICR0 0x00009004
54#define MIC_X100_SBOX_SICE0 0x0000900C
55#define MIC_X100_SBOX_SICC0 0x00009010
56#define MIC_X100_SBOX_SIAC0 0x00009014
57#define MIC_X100_SBOX_MSIXPBACR 0x00009084
58#define MIC_X100_SBOX_MXAR0 0x00009044
59#define MIC_X100_SBOX_SMPT00 0x00003100
60#define MIC_X100_SBOX_RDMASR0 0x0000B180
61
62#define MIC_X100_DOORBELL_IDX_START 0
63#define MIC_X100_NUM_DOORBELL 4
64#define MIC_X100_DMA_IDX_START 8
65#define MIC_X100_NUM_DMA 8
66#define MIC_X100_ERR_IDX_START 30
67#define MIC_X100_NUM_ERR 1
68
69#define MIC_X100_NUM_SBOX_IRQ 8
70#define MIC_X100_NUM_RDMASR_IRQ 8
71#define MIC_X100_RDMASR_IRQ_BASE 17
72#define MIC_X100_SPAD2_DOWNLOAD_STATUS(x) ((x) & 0x1)
73#define MIC_X100_SPAD2_APIC_ID(x) (((x) >> 1) & 0x1ff)
74#define MIC_X100_SPAD2_DOWNLOAD_ADDR(x) ((x) & 0xfffff000)
75#define MIC_X100_SBOX_APICICR7 0x0000AA08
76#define MIC_X100_SBOX_RGCR 0x00004010
77#define MIC_X100_SBOX_SDBIC0 0x0000CC90
78#define MIC_X100_DOWNLOAD_INFO 2
79#define MIC_X100_FW_SIZE 5
80#define MIC_X100_POSTCODE 0x242c
81
82static const u16 mic_x100_intr_init[] = {
83 MIC_X100_DOORBELL_IDX_START,
84 MIC_X100_DMA_IDX_START,
85 MIC_X100_ERR_IDX_START,
86 MIC_X100_NUM_DOORBELL,
87 MIC_X100_NUM_DMA,
88 MIC_X100_NUM_ERR,
89};
90
91/* Host->Card(bootstrap) Interrupt Vector */
92#define MIC_X100_BSP_INTERRUPT_VECTOR 229
93
94extern struct mic_hw_ops mic_x100_ops;
95extern struct mic_smpt_ops mic_x100_smpt_ops;
96extern struct mic_hw_intr_ops mic_x100_intr_ops;
97
98#endif
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 68b7c773d2cf..30754927fd80 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -395,7 +395,7 @@ static int phantom_probe(struct pci_dev *pdev,
395 iowrite32(0, pht->caddr + PHN_IRQCTL); 395 iowrite32(0, pht->caddr + PHN_IRQCTL);
396 ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */ 396 ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
397 retval = request_irq(pdev->irq, phantom_isr, 397 retval = request_irq(pdev->irq, phantom_isr,
398 IRQF_SHARED | IRQF_DISABLED, "phantom", pht); 398 IRQF_SHARED, "phantom", pht);
399 if (retval) { 399 if (retval) {
400 dev_err(&pdev->dev, "can't establish ISR\n"); 400 dev_err(&pdev->dev, "can't establish ISR\n");
401 goto err_unmo; 401 goto err_unmo;
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index f84ff0c06035..eda38cbe8530 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -892,7 +892,6 @@ static void pti_pci_remove(struct pci_dev *pdev)
892 } 892 }
893 893
894 iounmap(drv_data->pti_ioaddr); 894 iounmap(drv_data->pti_ioaddr);
895 pci_set_drvdata(pdev, NULL);
896 kfree(drv_data); 895 kfree(drv_data);
897 pci_release_region(pdev, 1); 896 pci_release_region(pdev, 1);
898 pci_disable_device(pdev); 897 pci_disable_device(pdev);
diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c
index 9b237221bc4e..83da711ce9f1 100644
--- a/drivers/misc/ti_dac7512.c
+++ b/drivers/misc/ti_dac7512.c
@@ -22,9 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25 25#include <linux/of.h>
26#define DAC7512_DRV_NAME "dac7512"
27#define DRIVER_VERSION "1.0"
28 26
29static ssize_t dac7512_store_val(struct device *dev, 27static ssize_t dac7512_store_val(struct device *dev,
30 struct device_attribute *attr, 28 struct device_attribute *attr,
@@ -75,13 +73,29 @@ static int dac7512_remove(struct spi_device *spi)
75 return 0; 73 return 0;
76} 74}
77 75
76static const struct spi_device_id dac7512_id_table[] = {
77 { "dac7512", 0 },
78 { }
79};
80MODULE_DEVICE_TABLE(spi, dac7512_id_table);
81
82#ifdef CONFIG_OF
83static const struct of_device_id dac7512_of_match[] = {
84 { .compatible = "ti,dac7512", },
85 { }
86};
87MODULE_DEVICE_TABLE(of, dac7512_of_match);
88#endif
89
78static struct spi_driver dac7512_driver = { 90static struct spi_driver dac7512_driver = {
79 .driver = { 91 .driver = {
80 .name = DAC7512_DRV_NAME, 92 .name = "dac7512",
81 .owner = THIS_MODULE, 93 .owner = THIS_MODULE,
94 .of_match_table = of_match_ptr(dac7512_of_match),
82 }, 95 },
83 .probe = dac7512_probe, 96 .probe = dac7512_probe,
84 .remove = dac7512_remove, 97 .remove = dac7512_remove,
98 .id_table = dac7512_id_table,
85}; 99};
86 100
87module_spi_driver(dac7512_driver); 101module_spi_driver(dac7512_driver);
@@ -89,4 +103,3 @@ module_spi_driver(dac7512_driver);
89MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 103MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
90MODULE_DESCRIPTION("DAC7512 16-bit DAC"); 104MODULE_DESCRIPTION("DAC7512 16-bit DAC");
91MODULE_LICENSE("GPL v2"); 105MODULE_LICENSE("GPL v2");
92MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index f8d6654391e5..a606c8901e18 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -356,8 +356,10 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
356 pci_set_drvdata(dev, fm); 356 pci_set_drvdata(dev, fm);
357 357
358 fm->addr = pci_ioremap_bar(dev, 0); 358 fm->addr = pci_ioremap_bar(dev, 0);
359 if (!fm->addr) 359 if (!fm->addr) {
360 rc = -ENODEV;
360 goto err_out_free; 361 goto err_out_free;
362 }
361 363
362 rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm); 364 rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
363 if (rc) 365 if (rc)
@@ -378,7 +380,6 @@ err_out_irq:
378err_out_unmap: 380err_out_unmap:
379 iounmap(fm->addr); 381 iounmap(fm->addr);
380err_out_free: 382err_out_free:
381 pci_set_drvdata(dev, NULL);
382 tifm_free_adapter(fm); 383 tifm_free_adapter(fm);
383err_out_int: 384err_out_int:
384 pci_intx(dev, 0); 385 pci_intx(dev, 0);
@@ -405,8 +406,6 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
405 for (cnt = 0; cnt < fm->num_sockets; cnt++) 406 for (cnt = 0; cnt < fm->num_sockets; cnt++)
406 tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt)); 407 tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
407 408
408 pci_set_drvdata(dev, NULL);
409
410 iounmap(fm->addr); 409 iounmap(fm->addr);
411 pci_intx(dev, 0); 410 pci_intx(dev, 0);
412 pci_release_regions(dev); 411 pci_release_regions(dev);
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index b3a2b763ecf2..c98b03b99353 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -649,7 +649,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
649 return 0; 649 return 0;
650 650
651err_free_irq: 651err_free_irq:
652 free_irq(vmci_dev->irq, &vmci_dev); 652 free_irq(vmci_dev->irq, vmci_dev);
653 tasklet_kill(&vmci_dev->datagram_tasklet); 653 tasklet_kill(&vmci_dev->datagram_tasklet);
654 tasklet_kill(&vmci_dev->bm_tasklet); 654 tasklet_kill(&vmci_dev->bm_tasklet);
655 655
diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
index d4722b3dc8ec..1723a6e4f2e8 100644
--- a/drivers/misc/vmw_vmci/vmci_host.c
+++ b/drivers/misc/vmw_vmci/vmci_host.c
@@ -243,11 +243,7 @@ static int vmci_host_setup_notify(struct vmci_ctx *context,
243 /* 243 /*
244 * Lock physical page backing a given user VA. 244 * Lock physical page backing a given user VA.
245 */ 245 */
246 down_read(&current->mm->mmap_sem); 246 retval = get_user_pages_fast(PAGE_ALIGN(uva), 1, 1, &page);
247 retval = get_user_pages(current, current->mm,
248 PAGE_ALIGN(uva),
249 1, 1, 0, &page, NULL);
250 up_read(&current->mm->mmap_sem);
251 if (retval != 1) 247 if (retval != 1)
252 return VMCI_ERROR_GENERIC; 248 return VMCI_ERROR_GENERIC;
253 249
diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
index a0515a6d6ebd..1b7b303085d2 100644
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
+++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
@@ -732,13 +732,9 @@ static int qp_host_get_user_memory(u64 produce_uva,
732 int retval; 732 int retval;
733 int err = VMCI_SUCCESS; 733 int err = VMCI_SUCCESS;
734 734
735 down_write(&current->mm->mmap_sem); 735 retval = get_user_pages_fast((uintptr_t) produce_uva,
736 retval = get_user_pages(current, 736 produce_q->kernel_if->num_pages, 1,
737 current->mm, 737 produce_q->kernel_if->u.h.header_page);
738 (uintptr_t) produce_uva,
739 produce_q->kernel_if->num_pages,
740 1, 0,
741 produce_q->kernel_if->u.h.header_page, NULL);
742 if (retval < produce_q->kernel_if->num_pages) { 738 if (retval < produce_q->kernel_if->num_pages) {
743 pr_warn("get_user_pages(produce) failed (retval=%d)", retval); 739 pr_warn("get_user_pages(produce) failed (retval=%d)", retval);
744 qp_release_pages(produce_q->kernel_if->u.h.header_page, 740 qp_release_pages(produce_q->kernel_if->u.h.header_page,
@@ -747,12 +743,9 @@ static int qp_host_get_user_memory(u64 produce_uva,
747 goto out; 743 goto out;
748 } 744 }
749 745
750 retval = get_user_pages(current, 746 retval = get_user_pages_fast((uintptr_t) consume_uva,
751 current->mm, 747 consume_q->kernel_if->num_pages, 1,
752 (uintptr_t) consume_uva, 748 consume_q->kernel_if->u.h.header_page);
753 consume_q->kernel_if->num_pages,
754 1, 0,
755 consume_q->kernel_if->u.h.header_page, NULL);
756 if (retval < consume_q->kernel_if->num_pages) { 749 if (retval < consume_q->kernel_if->num_pages) {
757 pr_warn("get_user_pages(consume) failed (retval=%d)", retval); 750 pr_warn("get_user_pages(consume) failed (retval=%d)", retval);
758 qp_release_pages(consume_q->kernel_if->u.h.header_page, 751 qp_release_pages(consume_q->kernel_if->u.h.header_page,
@@ -763,8 +756,6 @@ static int qp_host_get_user_memory(u64 produce_uva,
763 } 756 }
764 757
765 out: 758 out:
766 up_write(&current->mm->mmap_sem);
767
768 return err; 759 return err;
769} 760}
770 761
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index a4c16ee5c718..622dd6fe7347 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -777,15 +777,4 @@ static struct pci_driver pd6729_pci_driver = {
777 .remove = pd6729_pci_remove, 777 .remove = pd6729_pci_remove,
778}; 778};
779 779
780static int pd6729_module_init(void) 780module_pci_driver(pd6729_pci_driver);
781{
782 return pci_register_driver(&pd6729_pci_driver);
783}
784
785static void pd6729_module_exit(void)
786{
787 pci_unregister_driver(&pd6729_pci_driver);
788}
789
790module_init(pd6729_module_init);
791module_exit(pd6729_module_exit);
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 6b4ff099fb13..dc18a3a5e010 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1439,20 +1439,6 @@ static struct pci_driver yenta_cardbus_driver = {
1439 .driver.pm = YENTA_PM_OPS, 1439 .driver.pm = YENTA_PM_OPS,
1440}; 1440};
1441 1441
1442 1442module_pci_driver(yenta_cardbus_driver);
1443static int __init yenta_socket_init(void)
1444{
1445 return pci_register_driver(&yenta_cardbus_driver);
1446}
1447
1448
1449static void __exit yenta_socket_exit(void)
1450{
1451 pci_unregister_driver(&yenta_cardbus_driver);
1452}
1453
1454
1455module_init(yenta_socket_init);
1456module_exit(yenta_socket_exit);
1457 1443
1458MODULE_LICENSE("GPL"); 1444MODULE_LICENSE("GPL");
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 0e808cf91d97..67beb8444930 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -288,13 +288,13 @@ static int uio_dev_add_attributes(struct uio_device *idev)
288 } 288 }
289 map = kzalloc(sizeof(*map), GFP_KERNEL); 289 map = kzalloc(sizeof(*map), GFP_KERNEL);
290 if (!map) 290 if (!map)
291 goto err_map; 291 goto err_map_kobj;
292 kobject_init(&map->kobj, &map_attr_type); 292 kobject_init(&map->kobj, &map_attr_type);
293 map->mem = mem; 293 map->mem = mem;
294 mem->map = map; 294 mem->map = map;
295 ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi); 295 ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi);
296 if (ret) 296 if (ret)
297 goto err_map; 297 goto err_map_kobj;
298 ret = kobject_uevent(&map->kobj, KOBJ_ADD); 298 ret = kobject_uevent(&map->kobj, KOBJ_ADD);
299 if (ret) 299 if (ret)
300 goto err_map; 300 goto err_map;
@@ -313,14 +313,14 @@ static int uio_dev_add_attributes(struct uio_device *idev)
313 } 313 }
314 portio = kzalloc(sizeof(*portio), GFP_KERNEL); 314 portio = kzalloc(sizeof(*portio), GFP_KERNEL);
315 if (!portio) 315 if (!portio)
316 goto err_portio; 316 goto err_portio_kobj;
317 kobject_init(&portio->kobj, &portio_attr_type); 317 kobject_init(&portio->kobj, &portio_attr_type);
318 portio->port = port; 318 portio->port = port;
319 port->portio = portio; 319 port->portio = portio;
320 ret = kobject_add(&portio->kobj, idev->portio_dir, 320 ret = kobject_add(&portio->kobj, idev->portio_dir,
321 "port%d", pi); 321 "port%d", pi);
322 if (ret) 322 if (ret)
323 goto err_portio; 323 goto err_portio_kobj;
324 ret = kobject_uevent(&portio->kobj, KOBJ_ADD); 324 ret = kobject_uevent(&portio->kobj, KOBJ_ADD);
325 if (ret) 325 if (ret)
326 goto err_portio; 326 goto err_portio;
@@ -329,14 +329,18 @@ static int uio_dev_add_attributes(struct uio_device *idev)
329 return 0; 329 return 0;
330 330
331err_portio: 331err_portio:
332 for (pi--; pi >= 0; pi--) { 332 pi--;
333err_portio_kobj:
334 for (; pi >= 0; pi--) {
333 port = &idev->info->port[pi]; 335 port = &idev->info->port[pi];
334 portio = port->portio; 336 portio = port->portio;
335 kobject_put(&portio->kobj); 337 kobject_put(&portio->kobj);
336 } 338 }
337 kobject_put(idev->portio_dir); 339 kobject_put(idev->portio_dir);
338err_map: 340err_map:
339 for (mi--; mi>=0; mi--) { 341 mi--;
342err_map_kobj:
343 for (; mi >= 0; mi--) {
340 mem = &idev->info->mem[mi]; 344 mem = &idev->info->mem[mi];
341 map = mem->map; 345 map = mem->map;
342 kobject_put(&map->kobj); 346 kobject_put(&map->kobj);
@@ -601,6 +605,7 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
601 struct uio_device *idev = vma->vm_private_data; 605 struct uio_device *idev = vma->vm_private_data;
602 struct page *page; 606 struct page *page;
603 unsigned long offset; 607 unsigned long offset;
608 void *addr;
604 609
605 int mi = uio_find_mem_index(vma); 610 int mi = uio_find_mem_index(vma);
606 if (mi < 0) 611 if (mi < 0)
@@ -612,10 +617,11 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
612 */ 617 */
613 offset = (vmf->pgoff - mi) << PAGE_SHIFT; 618 offset = (vmf->pgoff - mi) << PAGE_SHIFT;
614 619
620 addr = (void *)(unsigned long)idev->info->mem[mi].addr + offset;
615 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) 621 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
616 page = virt_to_page(idev->info->mem[mi].addr + offset); 622 page = virt_to_page(addr);
617 else 623 else
618 page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset); 624 page = vmalloc_to_page(addr);
619 get_page(page); 625 get_page(page);
620 vmf->page = page; 626 vmf->page = page;
621 return 0; 627 return 0;
@@ -809,10 +815,9 @@ int __uio_register_device(struct module *owner,
809 815
810 info->uio_dev = NULL; 816 info->uio_dev = NULL;
811 817
812 idev = kzalloc(sizeof(*idev), GFP_KERNEL); 818 idev = devm_kzalloc(parent, sizeof(*idev), GFP_KERNEL);
813 if (!idev) { 819 if (!idev) {
814 ret = -ENOMEM; 820 return -ENOMEM;
815 goto err_kzalloc;
816 } 821 }
817 822
818 idev->owner = owner; 823 idev->owner = owner;
@@ -822,7 +827,7 @@ int __uio_register_device(struct module *owner,
822 827
823 ret = uio_get_minor(idev); 828 ret = uio_get_minor(idev);
824 if (ret) 829 if (ret)
825 goto err_get_minor; 830 return ret;
826 831
827 idev->dev = device_create(&uio_class, parent, 832 idev->dev = device_create(&uio_class, parent,
828 MKDEV(uio_major, idev->minor), idev, 833 MKDEV(uio_major, idev->minor), idev,
@@ -840,7 +845,7 @@ int __uio_register_device(struct module *owner,
840 info->uio_dev = idev; 845 info->uio_dev = idev;
841 846
842 if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { 847 if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
843 ret = request_irq(info->irq, uio_interrupt, 848 ret = devm_request_irq(parent, info->irq, uio_interrupt,
844 info->irq_flags, info->name, idev); 849 info->irq_flags, info->name, idev);
845 if (ret) 850 if (ret)
846 goto err_request_irq; 851 goto err_request_irq;
@@ -854,9 +859,6 @@ err_uio_dev_add_attributes:
854 device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); 859 device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
855err_device_create: 860err_device_create:
856 uio_free_minor(idev); 861 uio_free_minor(idev);
857err_get_minor:
858 kfree(idev);
859err_kzalloc:
860 return ret; 862 return ret;
861} 863}
862EXPORT_SYMBOL_GPL(__uio_register_device); 864EXPORT_SYMBOL_GPL(__uio_register_device);
@@ -877,13 +879,9 @@ void uio_unregister_device(struct uio_info *info)
877 879
878 uio_free_minor(idev); 880 uio_free_minor(idev);
879 881
880 if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
881 free_irq(info->irq, idev);
882
883 uio_dev_del_attributes(idev); 882 uio_dev_del_attributes(idev);
884 883
885 device_destroy(&uio_class, MKDEV(uio_major, idev->minor)); 884 device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
886 kfree(idev);
887 885
888 return; 886 return;
889} 887}
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
index f3611c2d83b6..1549fab633c6 100644
--- a/drivers/uio/uio_aec.c
+++ b/drivers/uio/uio_aec.c
@@ -147,7 +147,6 @@ static void remove(struct pci_dev *pdev)
147 uio_unregister_device(info); 147 uio_unregister_device(info);
148 pci_release_regions(pdev); 148 pci_release_regions(pdev);
149 pci_disable_device(pdev); 149 pci_disable_device(pdev);
150 pci_set_drvdata(pdev, NULL);
151 iounmap(info->priv); 150 iounmap(info->priv);
152 151
153 kfree(info); 152 kfree(info);
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index 22cdf385ab33..30f533ce3758 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -106,7 +106,6 @@ static void hilscher_pci_remove(struct pci_dev *dev)
106 uio_unregister_device(info); 106 uio_unregister_device(info);
107 pci_release_regions(dev); 107 pci_release_regions(dev);
108 pci_disable_device(dev); 108 pci_disable_device(dev);
109 pci_set_drvdata(dev, NULL);
110 iounmap(info->mem[0].internal_addr); 109 iounmap(info->mem[0].internal_addr);
111 110
112 kfree (info); 111 kfree (info);
diff --git a/drivers/uio/uio_mf624.c b/drivers/uio/uio_mf624.c
index a1768b2f4493..f764adbfe036 100644
--- a/drivers/uio/uio_mf624.c
+++ b/drivers/uio/uio_mf624.c
@@ -42,7 +42,7 @@
42 42
43enum mf624_interrupt_source {ADC, CTR4, ALL}; 43enum mf624_interrupt_source {ADC, CTR4, ALL};
44 44
45void mf624_disable_interrupt(enum mf624_interrupt_source source, 45static void mf624_disable_interrupt(enum mf624_interrupt_source source,
46 struct uio_info *info) 46 struct uio_info *info)
47{ 47{
48 void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR; 48 void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
@@ -70,7 +70,7 @@ void mf624_disable_interrupt(enum mf624_interrupt_source source,
70 } 70 }
71} 71}
72 72
73void mf624_enable_interrupt(enum mf624_interrupt_source source, 73static void mf624_enable_interrupt(enum mf624_interrupt_source source,
74 struct uio_info *info) 74 struct uio_info *info)
75{ 75{
76 void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR; 76 void __iomem *INTCSR_reg = info->mem[0].internal_addr + INTCSR;
@@ -220,7 +220,6 @@ static void mf624_pci_remove(struct pci_dev *dev)
220 uio_unregister_device(info); 220 uio_unregister_device(info);
221 pci_release_regions(dev); 221 pci_release_regions(dev);
222 pci_disable_device(dev); 222 pci_disable_device(dev);
223 pci_set_drvdata(dev, NULL);
224 223
225 iounmap(info->mem[0].internal_addr); 224 iounmap(info->mem[0].internal_addr);
226 iounmap(info->mem[1].internal_addr); 225 iounmap(info->mem[1].internal_addr);
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
index 28a766b9e198..4c345db8b016 100644
--- a/drivers/uio/uio_netx.c
+++ b/drivers/uio/uio_netx.c
@@ -127,7 +127,6 @@ static void netx_pci_remove(struct pci_dev *dev)
127 uio_unregister_device(info); 127 uio_unregister_device(info);
128 pci_release_regions(dev); 128 pci_release_regions(dev);
129 pci_disable_device(dev); 129 pci_disable_device(dev);
130 pci_set_drvdata(dev, NULL);
131 iounmap(info->mem[0].internal_addr); 130 iounmap(info->mem[0].internal_addr);
132 131
133 kfree(info); 132 kfree(info);
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 90ff17a0202f..76669313e9a7 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -112,11 +112,11 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
112 112
113 if (pdev->dev.of_node) { 113 if (pdev->dev.of_node) {
114 /* alloc uioinfo for one device */ 114 /* alloc uioinfo for one device */
115 uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL); 115 uioinfo = devm_kzalloc(&pdev->dev, sizeof(*uioinfo),
116 GFP_KERNEL);
116 if (!uioinfo) { 117 if (!uioinfo) {
117 ret = -ENOMEM;
118 dev_err(&pdev->dev, "unable to kmalloc\n"); 118 dev_err(&pdev->dev, "unable to kmalloc\n");
119 return ret; 119 return -ENOMEM;
120 } 120 }
121 uioinfo->name = pdev->dev.of_node->name; 121 uioinfo->name = pdev->dev.of_node->name;
122 uioinfo->version = "devicetree"; 122 uioinfo->version = "devicetree";
@@ -125,20 +125,19 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
125 125
126 if (!uioinfo || !uioinfo->name || !uioinfo->version) { 126 if (!uioinfo || !uioinfo->name || !uioinfo->version) {
127 dev_err(&pdev->dev, "missing platform_data\n"); 127 dev_err(&pdev->dev, "missing platform_data\n");
128 goto bad0; 128 return ret;
129 } 129 }
130 130
131 if (uioinfo->handler || uioinfo->irqcontrol || 131 if (uioinfo->handler || uioinfo->irqcontrol ||
132 uioinfo->irq_flags & IRQF_SHARED) { 132 uioinfo->irq_flags & IRQF_SHARED) {
133 dev_err(&pdev->dev, "interrupt configuration error\n"); 133 dev_err(&pdev->dev, "interrupt configuration error\n");
134 goto bad0; 134 return ret;
135 } 135 }
136 136
137 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 137 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
138 if (!priv) { 138 if (!priv) {
139 ret = -ENOMEM;
140 dev_err(&pdev->dev, "unable to kmalloc\n"); 139 dev_err(&pdev->dev, "unable to kmalloc\n");
141 goto bad0; 140 return -ENOMEM;
142 } 141 }
143 142
144 priv->uioinfo = uioinfo; 143 priv->uioinfo = uioinfo;
@@ -153,7 +152,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
153 uioinfo->irq = UIO_IRQ_NONE; 152 uioinfo->irq = UIO_IRQ_NONE;
154 else if (ret < 0) { 153 else if (ret < 0) {
155 dev_err(&pdev->dev, "failed to get IRQ\n"); 154 dev_err(&pdev->dev, "failed to get IRQ\n");
156 goto bad1; 155 return ret;
157 } 156 }
158 } 157 }
159 158
@@ -209,20 +208,12 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
209 ret = uio_register_device(&pdev->dev, priv->uioinfo); 208 ret = uio_register_device(&pdev->dev, priv->uioinfo);
210 if (ret) { 209 if (ret) {
211 dev_err(&pdev->dev, "unable to register uio device\n"); 210 dev_err(&pdev->dev, "unable to register uio device\n");
212 goto bad2; 211 pm_runtime_disable(&pdev->dev);
212 return ret;
213 } 213 }
214 214
215 platform_set_drvdata(pdev, priv); 215 platform_set_drvdata(pdev, priv);
216 return 0; 216 return 0;
217 bad2:
218 pm_runtime_disable(&pdev->dev);
219 bad1:
220 kfree(priv);
221 bad0:
222 /* kfree uioinfo for OF */
223 if (pdev->dev.of_node)
224 kfree(uioinfo);
225 return ret;
226} 217}
227 218
228static int uio_pdrv_genirq_remove(struct platform_device *pdev) 219static int uio_pdrv_genirq_remove(struct platform_device *pdev)
@@ -235,11 +226,6 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev)
235 priv->uioinfo->handler = NULL; 226 priv->uioinfo->handler = NULL;
236 priv->uioinfo->irqcontrol = NULL; 227 priv->uioinfo->irqcontrol = NULL;
237 228
238 /* kfree uioinfo for OF */
239 if (pdev->dev.of_node)
240 kfree(priv->uioinfo);
241
242 kfree(priv);
243 return 0; 229 return 0;
244} 230}
245 231
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
index 541983217085..9cfdfcafa262 100644
--- a/drivers/uio/uio_sercos3.c
+++ b/drivers/uio/uio_sercos3.c
@@ -188,7 +188,6 @@ static void sercos3_pci_remove(struct pci_dev *dev)
188 uio_unregister_device(info); 188 uio_unregister_device(info);
189 pci_release_regions(dev); 189 pci_release_regions(dev);
190 pci_disable_device(dev); 190 pci_disable_device(dev);
191 pci_set_drvdata(dev, NULL);
192 for (i = 0; i < 5; i++) { 191 for (i = 0; i < 5; i++) {
193 if (info->mem[i].internal_addr) 192 if (info->mem[i].internal_addr)
194 iounmap(info->mem[i].internal_addr); 193 iounmap(info->mem[i].internal_addr);
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 96cab6ac2b4e..41613f92a723 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -498,7 +498,7 @@ static int ds1wm_probe(struct platform_device *pdev)
498 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING); 498 irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
499 499
500 ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr, 500 ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
501 IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data); 501 IRQF_SHARED, "ds1wm", ds1wm_data);
502 if (ret) 502 if (ret)
503 return ret; 503 return ret;
504 504
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 6e94d8dd3d00..9900e8ec7393 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -577,8 +577,7 @@ static int omap_hdq_probe(struct platform_device *pdev)
577 goto err_irq; 577 goto err_irq;
578 } 578 }
579 579
580 ret = devm_request_irq(dev, irq, hdq_isr, IRQF_DISABLED, 580 ret = devm_request_irq(dev, irq, hdq_isr, 0, "omap_hdq", hdq_data);
581 "omap_hdq", hdq_data);
582 if (ret < 0) { 581 if (ret < 0) {
583 dev_dbg(&pdev->dev, "could not request irq\n"); 582 dev_dbg(&pdev->dev, "could not request irq\n");
584 goto err_irq; 583 goto err_irq;
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index f54ece268c98..264ad1c583ab 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -58,6 +58,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
58{ 58{
59 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; 59 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
60 struct device_node *np = pdev->dev.of_node; 60 struct device_node *np = pdev->dev.of_node;
61 int gpio;
61 62
62 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 63 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
63 if (!pdata) 64 if (!pdata)
@@ -66,7 +67,11 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
66 if (of_get_property(np, "linux,open-drain", NULL)) 67 if (of_get_property(np, "linux,open-drain", NULL))
67 pdata->is_open_drain = 1; 68 pdata->is_open_drain = 1;
68 69
69 pdata->pin = of_get_gpio(np, 0); 70 gpio = of_get_gpio(np, 0);
71 if (gpio < 0)
72 return gpio;
73 pdata->pin = gpio;
74
70 pdata->ext_pullup_enable_pin = of_get_gpio(np, 1); 75 pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
71 pdev->dev.platform_data = pdata; 76 pdev->dev.platform_data = pdata;
72 77
@@ -94,25 +99,27 @@ static int w1_gpio_probe(struct platform_device *pdev)
94 return -ENXIO; 99 return -ENXIO;
95 } 100 }
96 101
97 master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); 102 master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master),
103 GFP_KERNEL);
98 if (!master) { 104 if (!master) {
99 dev_err(&pdev->dev, "Out of memory\n"); 105 dev_err(&pdev->dev, "Out of memory\n");
100 return -ENOMEM; 106 return -ENOMEM;
101 } 107 }
102 108
103 err = gpio_request(pdata->pin, "w1"); 109 err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");
104 if (err) { 110 if (err) {
105 dev_err(&pdev->dev, "gpio_request (pin) failed\n"); 111 dev_err(&pdev->dev, "gpio_request (pin) failed\n");
106 goto free_master; 112 return err;
107 } 113 }
108 114
109 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { 115 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
110 err = gpio_request_one(pdata->ext_pullup_enable_pin, 116 err = devm_gpio_request_one(&pdev->dev,
111 GPIOF_INIT_LOW, "w1 pullup"); 117 pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW,
118 "w1 pullup");
112 if (err < 0) { 119 if (err < 0) {
113 dev_err(&pdev->dev, "gpio_request_one " 120 dev_err(&pdev->dev, "gpio_request_one "
114 "(ext_pullup_enable_pin) failed\n"); 121 "(ext_pullup_enable_pin) failed\n");
115 goto free_gpio; 122 return err;
116 } 123 }
117 } 124 }
118 125
@@ -130,7 +137,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
130 err = w1_add_master_device(master); 137 err = w1_add_master_device(master);
131 if (err) { 138 if (err) {
132 dev_err(&pdev->dev, "w1_add_master device failed\n"); 139 dev_err(&pdev->dev, "w1_add_master device failed\n");
133 goto free_gpio_ext_pu; 140 return err;
134 } 141 }
135 142
136 if (pdata->enable_external_pullup) 143 if (pdata->enable_external_pullup)
@@ -142,16 +149,6 @@ static int w1_gpio_probe(struct platform_device *pdev)
142 platform_set_drvdata(pdev, master); 149 platform_set_drvdata(pdev, master);
143 150
144 return 0; 151 return 0;
145
146 free_gpio_ext_pu:
147 if (gpio_is_valid(pdata->ext_pullup_enable_pin))
148 gpio_free(pdata->ext_pullup_enable_pin);
149 free_gpio:
150 gpio_free(pdata->pin);
151 free_master:
152 kfree(master);
153
154 return err;
155} 152}
156 153
157static int w1_gpio_remove(struct platform_device *pdev) 154static int w1_gpio_remove(struct platform_device *pdev)
@@ -166,8 +163,6 @@ static int w1_gpio_remove(struct platform_device *pdev)
166 gpio_set_value(pdata->ext_pullup_enable_pin, 0); 163 gpio_set_value(pdata->ext_pullup_enable_pin, 0);
167 164
168 w1_remove_master_device(master); 165 w1_remove_master_device(master);
169 gpio_free(pdata->pin);
170 kfree(master);
171 166
172 return 0; 167 return 0;
173} 168}
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index fcb51c88319f..21c59af1150b 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -51,10 +51,10 @@
51enum extcon_cable_name { 51enum extcon_cable_name {
52 EXTCON_USB = 0, 52 EXTCON_USB = 0,
53 EXTCON_USB_HOST, 53 EXTCON_USB_HOST,
54 EXTCON_TA, /* Travel Adaptor */ 54 EXTCON_TA, /* Travel Adaptor */
55 EXTCON_FAST_CHARGER, 55 EXTCON_FAST_CHARGER,
56 EXTCON_SLOW_CHARGER, 56 EXTCON_SLOW_CHARGER,
57 EXTCON_CHARGE_DOWNSTREAM, /* Charging an external device */ 57 EXTCON_CHARGE_DOWNSTREAM, /* Charging an external device */
58 EXTCON_HDMI, 58 EXTCON_HDMI,
59 EXTCON_MHL, 59 EXTCON_MHL,
60 EXTCON_DVI, 60 EXTCON_DVI,
@@ -76,8 +76,8 @@ struct extcon_cable;
76 76
77/** 77/**
78 * struct extcon_dev - An extcon device represents one external connector. 78 * struct extcon_dev - An extcon device represents one external connector.
79 * @name: The name of this extcon device. Parent device name is used 79 * @name: The name of this extcon device. Parent device name is
80 * if NULL. 80 * used if NULL.
81 * @supported_cable: Array of supported cable names ending with NULL. 81 * @supported_cable: Array of supported cable names ending with NULL.
82 * If supported_cable is NULL, cable name related APIs 82 * If supported_cable is NULL, cable name related APIs
83 * are disabled. 83 * are disabled.
@@ -89,21 +89,21 @@ struct extcon_cable;
89 * be attached simulataneously. {0x7, 0} is equivalent to 89 * be attached simulataneously. {0x7, 0} is equivalent to
90 * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there 90 * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there
91 * can be no simultaneous connections. 91 * can be no simultaneous connections.
92 * @print_name: An optional callback to override the method to print the 92 * @print_name: An optional callback to override the method to print the
93 * name of the extcon device. 93 * name of the extcon device.
94 * @print_state: An optional callback to override the method to print the 94 * @print_state: An optional callback to override the method to print the
95 * status of the extcon device. 95 * status of the extcon device.
96 * @dev: Device of this extcon. Do not provide at register-time. 96 * @dev: Device of this extcon.
97 * @state: Attach/detach state of this extcon. Do not provide at 97 * @state: Attach/detach state of this extcon. Do not provide at
98 * register-time 98 * register-time.
99 * @nh: Notifier for the state change events from this extcon 99 * @nh: Notifier for the state change events from this extcon
100 * @entry: To support list of extcon devices so that users can search 100 * @entry: To support list of extcon devices so that users can search
101 * for extcon devices based on the extcon name. 101 * for extcon devices based on the extcon name.
102 * @lock: 102 * @lock:
103 * @max_supported: Internal value to store the number of cables. 103 * @max_supported: Internal value to store the number of cables.
104 * @extcon_dev_type: Device_type struct to provide attribute_groups 104 * @extcon_dev_type: Device_type struct to provide attribute_groups
105 * customized for each extcon device. 105 * customized for each extcon device.
106 * @cables: Sysfs subdirectories. Each represents one cable. 106 * @cables: Sysfs subdirectories. Each represents one cable.
107 * 107 *
108 * In most cases, users only need to provide "User initializing data" of 108 * In most cases, users only need to provide "User initializing data" of
109 * this struct when registering an extcon. In some exceptional cases, 109 * this struct when registering an extcon. In some exceptional cases,
@@ -111,26 +111,27 @@ struct extcon_cable;
111 * are overwritten by register function. 111 * are overwritten by register function.
112 */ 112 */
113struct extcon_dev { 113struct extcon_dev {
114 /* --- Optional user initializing data --- */ 114 /* Optional user initializing data */
115 const char *name; 115 const char *name;
116 const char **supported_cable; 116 const char **supported_cable;
117 const u32 *mutually_exclusive; 117 const u32 *mutually_exclusive;
118 118
119 /* --- Optional callbacks to override class functions --- */ 119 /* Optional callbacks to override class functions */
120 ssize_t (*print_name)(struct extcon_dev *edev, char *buf); 120 ssize_t (*print_name)(struct extcon_dev *edev, char *buf);
121 ssize_t (*print_state)(struct extcon_dev *edev, char *buf); 121 ssize_t (*print_state)(struct extcon_dev *edev, char *buf);
122 122
123 /* --- Internal data. Please do not set. --- */ 123 /* Internal data. Please do not set. */
124 struct device *dev; 124 struct device dev;
125 u32 state;
126 struct raw_notifier_head nh; 125 struct raw_notifier_head nh;
127 struct list_head entry; 126 struct list_head entry;
128 spinlock_t lock; /* could be called by irq handler */
129 int max_supported; 127 int max_supported;
128 spinlock_t lock; /* could be called by irq handler */
129 u32 state;
130 130
131 /* /sys/class/extcon/.../cable.n/... */ 131 /* /sys/class/extcon/.../cable.n/... */
132 struct device_type extcon_dev_type; 132 struct device_type extcon_dev_type;
133 struct extcon_cable *cables; 133 struct extcon_cable *cables;
134
134 /* /sys/class/extcon/.../mutually_exclusive/... */ 135 /* /sys/class/extcon/.../mutually_exclusive/... */
135 struct attribute_group attr_g_muex; 136 struct attribute_group attr_g_muex;
136 struct attribute **attrs_muex; 137 struct attribute **attrs_muex;
@@ -138,13 +139,13 @@ struct extcon_dev {
138}; 139};
139 140
140/** 141/**
141 * struct extcon_cable - An internal data for each cable of extcon device. 142 * struct extcon_cable - An internal data for each cable of extcon device.
142 * @edev: The extcon device 143 * @edev: The extcon device
143 * @cable_index: Index of this cable in the edev 144 * @cable_index: Index of this cable in the edev
144 * @attr_g: Attribute group for the cable 145 * @attr_g: Attribute group for the cable
145 * @attr_name: "name" sysfs entry 146 * @attr_name: "name" sysfs entry
146 * @attr_state: "state" sysfs entry 147 * @attr_state: "state" sysfs entry
147 * @attrs: Array pointing to attr_name and attr_state for attr_g 148 * @attrs: Array pointing to attr_name and attr_state for attr_g
148 */ 149 */
149struct extcon_cable { 150struct extcon_cable {
150 struct extcon_dev *edev; 151 struct extcon_dev *edev;
@@ -159,11 +160,13 @@ struct extcon_cable {
159 160
160/** 161/**
161 * struct extcon_specific_cable_nb - An internal data for 162 * struct extcon_specific_cable_nb - An internal data for
162 * extcon_register_interest(). 163 * extcon_register_interest().
163 * @internal_nb: a notifier block bridging extcon notifier and cable notifier. 164 * @internal_nb: A notifier block bridging extcon notifier
164 * @user_nb: user provided notifier block for events from a specific cable. 165 * and cable notifier.
166 * @user_nb: user provided notifier block for events from
167 * a specific cable.
165 * @cable_index: the target cable. 168 * @cable_index: the target cable.
166 * @edev: the target extcon device. 169 * @edev: the target extcon device.
167 * @previous_value: the saved previous event value. 170 * @previous_value: the saved previous event value.
168 */ 171 */
169struct extcon_specific_cable_nb { 172struct extcon_specific_cable_nb {
@@ -180,7 +183,7 @@ struct extcon_specific_cable_nb {
180 * Following APIs are for notifiers or configurations. 183 * Following APIs are for notifiers or configurations.
181 * Notifiers are the external port and connection devices. 184 * Notifiers are the external port and connection devices.
182 */ 185 */
183extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev); 186extern int extcon_dev_register(struct extcon_dev *edev);
184extern void extcon_dev_unregister(struct extcon_dev *edev); 187extern void extcon_dev_unregister(struct extcon_dev *edev);
185extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); 188extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
186 189
@@ -238,8 +241,7 @@ extern int extcon_register_notifier(struct extcon_dev *edev,
238extern int extcon_unregister_notifier(struct extcon_dev *edev, 241extern int extcon_unregister_notifier(struct extcon_dev *edev,
239 struct notifier_block *nb); 242 struct notifier_block *nb);
240#else /* CONFIG_EXTCON */ 243#else /* CONFIG_EXTCON */
241static inline int extcon_dev_register(struct extcon_dev *edev, 244static inline int extcon_dev_register(struct extcon_dev *edev)
242 struct device *dev)
243{ 245{
244 return 0; 246 return 0;
245} 247}
diff --git a/include/linux/extcon/extcon-adc-jack.h b/include/linux/extcon/extcon-adc-jack.h
index 20e9eef25d4c..9ca958c4e94c 100644
--- a/include/linux/extcon/extcon-adc-jack.h
+++ b/include/linux/extcon/extcon-adc-jack.h
@@ -20,10 +20,10 @@
20 20
21/** 21/**
22 * struct adc_jack_cond - condition to use an extcon state 22 * struct adc_jack_cond - condition to use an extcon state
23 * @state - the corresponding extcon state (if 0, this struct denotes 23 * @state: the corresponding extcon state (if 0, this struct
24 * the last adc_jack_cond element among the array) 24 * denotes the last adc_jack_cond element among the array)
25 * @min_adc - min adc value for this condition 25 * @min_adc: min adc value for this condition
26 * @max_adc - max adc value for this condition 26 * @max_adc: max adc value for this condition
27 * 27 *
28 * For example, if { .state = 0x3, .min_adc = 100, .max_adc = 200}, it means 28 * For example, if { .state = 0x3, .min_adc = 100, .max_adc = 200}, it means
29 * that if ADC value is between (inclusive) 100 and 200, than the cable 0 and 29 * that if ADC value is between (inclusive) 100 and 200, than the cable 0 and
@@ -33,34 +33,34 @@
33 * because when no adc_jack_cond is met, state = 0 is automatically chosen. 33 * because when no adc_jack_cond is met, state = 0 is automatically chosen.
34 */ 34 */
35struct adc_jack_cond { 35struct adc_jack_cond {
36 u32 state; /* extcon state value. 0 if invalid */ 36 u32 state; /* extcon state value. 0 if invalid */
37 u32 min_adc; 37 u32 min_adc;
38 u32 max_adc; 38 u32 max_adc;
39}; 39};
40 40
41/** 41/**
42 * struct adc_jack_pdata - platform data for adc jack device. 42 * struct adc_jack_pdata - platform data for adc jack device.
43 * @name - name of the extcon device. If null, "adc-jack" is used. 43 * @name: name of the extcon device. If null, "adc-jack" is used.
44 * @consumer_channel - Unique name to identify the channel on the consumer 44 * @consumer_channel: Unique name to identify the channel on the consumer
45 * side. This typically describes the channels used within 45 * side. This typically describes the channels used within
46 * the consumer. E.g. 'battery_voltage' 46 * the consumer. E.g. 'battery_voltage'
47 * @cable_names - array of cable names ending with null. 47 * @cable_names: array of cable names ending with null.
48 * @adc_contitions - array of struct adc_jack_cond conditions ending 48 * @adc_contitions: array of struct adc_jack_cond conditions ending
49 * with .state = 0 entry. This describes how to decode 49 * with .state = 0 entry. This describes how to decode
50 * adc values into extcon state. 50 * adc values into extcon state.
51 * @irq_flags - irq flags used for the @irq 51 * @irq_flags: irq flags used for the @irq
52 * @handling_delay_ms - in some devices, we need to read ADC value some 52 * @handling_delay_ms: in some devices, we need to read ADC value some
53 * milli-seconds after the interrupt occurs. You may 53 * milli-seconds after the interrupt occurs. You may
54 * describe such delays with @handling_delay_ms, which 54 * describe such delays with @handling_delay_ms, which
55 * is rounded-off by jiffies. 55 * is rounded-off by jiffies.
56 */ 56 */
57struct adc_jack_pdata { 57struct adc_jack_pdata {
58 const char *name; 58 const char *name;
59 const char *consumer_channel; 59 const char *consumer_channel;
60 /* 60
61 * The last entry should be NULL 61 /* The last entry should be NULL */
62 */
63 const char **cable_names; 62 const char **cable_names;
63
64 /* The last entry's state should be 0 */ 64 /* The last entry's state should be 0 */
65 struct adc_jack_cond *adc_conditions; 65 struct adc_jack_cond *adc_conditions;
66 66
diff --git a/include/linux/extcon/extcon-gpio.h b/include/linux/extcon/extcon-gpio.h
index 2d8307f7d67d..4195810f87fe 100644
--- a/include/linux/extcon/extcon-gpio.h
+++ b/include/linux/extcon/extcon-gpio.h
@@ -25,14 +25,17 @@
25 25
26/** 26/**
27 * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device. 27 * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device.
28 * @name The name of this GPIO extcon device. 28 * @name: The name of this GPIO extcon device.
29 * @gpio Corresponding GPIO. 29 * @gpio: Corresponding GPIO.
30 * @debounce Debounce time for GPIO IRQ in ms. 30 * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0
31 * @irq_flags IRQ Flags (e.g., IRQF_TRIGGER_LOW). 31 * If true, low state of gpio means active.
32 * @state_on print_state is overriden with state_on if attached. If Null, 32 * If false, high state of gpio means active.
33 * default method of extcon class is used. 33 * @debounce: Debounce time for GPIO IRQ in ms.
34 * @state_off print_state is overriden with state_on if detached. If Null, 34 * @irq_flags: IRQ Flags (e.g., IRQF_TRIGGER_LOW).
35 * default method of extcon class is used. 35 * @state_on: print_state is overriden with state_on if attached.
36 * If NULL, default method of extcon class is used.
37 * @state_off: print_state is overriden with state_on if detached.
38 * If NUll, default method of extcon class is used.
36 * 39 *
37 * Note that in order for state_on or state_off to be valid, both state_on 40 * Note that in order for state_on or state_off to be valid, both state_on
38 * and state_off should be not NULL. If at least one of them is NULL, 41 * and state_off should be not NULL. If at least one of them is NULL,
@@ -41,6 +44,7 @@
41struct gpio_extcon_platform_data { 44struct gpio_extcon_platform_data {
42 const char *name; 45 const char *name;
43 unsigned gpio; 46 unsigned gpio;
47 bool gpio_active_low;
44 unsigned long debounce; 48 unsigned long debounce;
45 unsigned long irq_flags; 49 unsigned long irq_flags;
46 50
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index d98503bde7e9..15da677478dd 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -432,15 +432,6 @@ struct hv_ring_buffer_info {
432 u32 ring_data_startoffset; 432 u32 ring_data_startoffset;
433}; 433};
434 434
435struct hv_ring_buffer_debug_info {
436 u32 current_interrupt_mask;
437 u32 current_read_index;
438 u32 current_write_index;
439 u32 bytes_avail_toread;
440 u32 bytes_avail_towrite;
441};
442
443
444/* 435/*
445 * 436 *
446 * hv_get_ringbuffer_availbytes() 437 * hv_get_ringbuffer_availbytes()
@@ -902,23 +893,6 @@ enum vmbus_channel_state {
902 CHANNEL_OPENED_STATE, 893 CHANNEL_OPENED_STATE,
903}; 894};
904 895
905struct vmbus_channel_debug_info {
906 u32 relid;
907 enum vmbus_channel_state state;
908 uuid_le interfacetype;
909 uuid_le interface_instance;
910 u32 monitorid;
911 u32 servermonitor_pending;
912 u32 servermonitor_latency;
913 u32 servermonitor_connectionid;
914 u32 clientmonitor_pending;
915 u32 clientmonitor_latency;
916 u32 clientmonitor_connectionid;
917
918 struct hv_ring_buffer_debug_info inbound;
919 struct hv_ring_buffer_debug_info outbound;
920};
921
922/* 896/*
923 * Represents each channel msg on the vmbus connection This is a 897 * Represents each channel msg on the vmbus connection This is a
924 * variable-size data structure depending on the msg type itself 898 * variable-size data structure depending on the msg type itself
@@ -1184,19 +1158,8 @@ extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
1184 u64 *requestid); 1158 u64 *requestid);
1185 1159
1186 1160
1187extern void vmbus_get_debug_info(struct vmbus_channel *channel,
1188 struct vmbus_channel_debug_info *debug);
1189
1190extern void vmbus_ontimer(unsigned long data); 1161extern void vmbus_ontimer(unsigned long data);
1191 1162
1192struct hv_dev_port_info {
1193 u32 int_mask;
1194 u32 read_idx;
1195 u32 write_idx;
1196 u32 bytes_avail_toread;
1197 u32 bytes_avail_towrite;
1198};
1199
1200/* Base driver object */ 1163/* Base driver object */
1201struct hv_driver { 1164struct hv_driver {
1202 const char *name; 1165 const char *name;
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 115add2515aa..33d2b8fe166d 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -241,6 +241,8 @@ header-y += media.h
241header-y += mei.h 241header-y += mei.h
242header-y += mempolicy.h 242header-y += mempolicy.h
243header-y += meye.h 243header-y += meye.h
244header-y += mic_common.h
245header-y += mic_ioctl.h
244header-y += mii.h 246header-y += mii.h
245header-y += minix_fs.h 247header-y += minix_fs.h
246header-y += mman.h 248header-y += mman.h
diff --git a/include/uapi/linux/mic_common.h b/include/uapi/linux/mic_common.h
new file mode 100644
index 000000000000..17e7d95e4f53
--- /dev/null
+++ b/include/uapi/linux/mic_common.h
@@ -0,0 +1,240 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC driver.
19 *
20 */
21#ifndef __MIC_COMMON_H_
22#define __MIC_COMMON_H_
23
24#include <linux/virtio_ring.h>
25
26#ifndef __KERNEL__
27#define ALIGN(a, x) (((a) + (x) - 1) & ~((x) - 1))
28#define __aligned(x) __attribute__ ((aligned(x)))
29#endif
30
31#define mic_aligned_size(x) ALIGN(sizeof(x), 8)
32
33/**
34 * struct mic_device_desc: Virtio device information shared between the
35 * virtio driver and userspace backend
36 *
37 * @type: Device type: console/network/disk etc. Type 0/-1 terminates.
38 * @num_vq: Number of virtqueues.
39 * @feature_len: Number of bytes of feature bits. Multiply by 2: one for
40 host features and one for guest acknowledgements.
41 * @config_len: Number of bytes of the config array after virtqueues.
42 * @status: A status byte, written by the Guest.
43 * @config: Start of the following variable length config.
44 */
45struct mic_device_desc {
46 __s8 type;
47 __u8 num_vq;
48 __u8 feature_len;
49 __u8 config_len;
50 __u8 status;
51 __u64 config[0];
52} __aligned(8);
53
54/**
55 * struct mic_device_ctrl: Per virtio device information in the device page
56 * used internally by the host and card side drivers.
57 *
58 * @vdev: Used for storing MIC vdev information by the guest.
59 * @config_change: Set to 1 by host when a config change is requested.
60 * @vdev_reset: Set to 1 by guest to indicate virtio device has been reset.
61 * @guest_ack: Set to 1 by guest to ack a command.
62 * @host_ack: Set to 1 by host to ack a command.
63 * @used_address_updated: Set to 1 by guest when the used address should be
64 * updated.
65 * @c2h_vdev_db: The doorbell number to be used by guest. Set by host.
66 * @h2c_vdev_db: The doorbell number to be used by host. Set by guest.
67 */
68struct mic_device_ctrl {
69 __u64 vdev;
70 __u8 config_change;
71 __u8 vdev_reset;
72 __u8 guest_ack;
73 __u8 host_ack;
74 __u8 used_address_updated;
75 __s8 c2h_vdev_db;
76 __s8 h2c_vdev_db;
77} __aligned(8);
78
79/**
80 * struct mic_bootparam: Virtio device independent information in device page
81 *
82 * @magic: A magic value used by the card to ensure it can see the host
83 * @c2h_shutdown_db: Card to Host shutdown doorbell set by host
84 * @h2c_shutdown_db: Host to Card shutdown doorbell set by card
85 * @h2c_config_db: Host to Card Virtio config doorbell set by card
86 * @shutdown_status: Card shutdown status set by card
87 * @shutdown_card: Set to 1 by the host when a card shutdown is initiated
88 */
89struct mic_bootparam {
90 __u32 magic;
91 __s8 c2h_shutdown_db;
92 __s8 h2c_shutdown_db;
93 __s8 h2c_config_db;
94 __u8 shutdown_status;
95 __u8 shutdown_card;
96} __aligned(8);
97
98/**
99 * struct mic_device_page: High level representation of the device page
100 *
101 * @bootparam: The bootparam structure is used for sharing information and
102 * status updates between MIC host and card drivers.
103 * @desc: Array of MIC virtio device descriptors.
104 */
105struct mic_device_page {
106 struct mic_bootparam bootparam;
107 struct mic_device_desc desc[0];
108};
109/**
110 * struct mic_vqconfig: This is how we expect the device configuration field
111 * for a virtqueue to be laid out in config space.
112 *
113 * @address: Guest/MIC physical address of the virtio ring
114 * (avail and desc rings)
115 * @used_address: Guest/MIC physical address of the used ring
116 * @num: The number of entries in the virtio_ring
117 */
118struct mic_vqconfig {
119 __u64 address;
120 __u64 used_address;
121 __u16 num;
122} __aligned(8);
123
124/*
125 * The alignment to use between consumer and producer parts of vring.
126 * This is pagesize for historical reasons.
127 */
128#define MIC_VIRTIO_RING_ALIGN 4096
129
130#define MIC_MAX_VRINGS 4
131#define MIC_VRING_ENTRIES 128
132
133/*
134 * Max vring entries (power of 2) to ensure desc and avail rings
135 * fit in a single page
136 */
137#define MIC_MAX_VRING_ENTRIES 128
138
139/**
140 * Max size of the desc block in bytes: includes:
141 * - struct mic_device_desc
142 * - struct mic_vqconfig (num_vq of these)
143 * - host and guest features
144 * - virtio device config space
145 */
146#define MIC_MAX_DESC_BLK_SIZE 256
147
148/**
149 * struct _mic_vring_info - Host vring info exposed to userspace backend
150 * for the avail index and magic for the card.
151 *
152 * @avail_idx: host avail idx
153 * @magic: A magic debug cookie.
154 */
155struct _mic_vring_info {
156 __u16 avail_idx;
157 int magic;
158};
159
160/**
161 * struct mic_vring - Vring information.
162 *
163 * @vr: The virtio ring.
164 * @info: Host vring information exposed to the userspace backend for the
165 * avail index and magic for the card.
166 * @va: The va for the buffer allocated for vr and info.
167 * @len: The length of the buffer required for allocating vr and info.
168 */
169struct mic_vring {
170 struct vring vr;
171 struct _mic_vring_info *info;
172 void *va;
173 int len;
174};
175
176#define mic_aligned_desc_size(d) ALIGN(mic_desc_size(d), 8)
177
178#ifndef INTEL_MIC_CARD
179static inline unsigned mic_desc_size(const struct mic_device_desc *desc)
180{
181 return mic_aligned_size(*desc)
182 + desc->num_vq * mic_aligned_size(struct mic_vqconfig)
183 + desc->feature_len * 2
184 + desc->config_len;
185}
186
187static inline struct mic_vqconfig *
188mic_vq_config(const struct mic_device_desc *desc)
189{
190 return (struct mic_vqconfig *)(desc + 1);
191}
192
193static inline __u8 *mic_vq_features(const struct mic_device_desc *desc)
194{
195 return (__u8 *)(mic_vq_config(desc) + desc->num_vq);
196}
197
198static inline __u8 *mic_vq_configspace(const struct mic_device_desc *desc)
199{
200 return mic_vq_features(desc) + desc->feature_len * 2;
201}
202static inline unsigned mic_total_desc_size(struct mic_device_desc *desc)
203{
204 return mic_aligned_desc_size(desc) +
205 mic_aligned_size(struct mic_device_ctrl);
206}
207#endif
208
209/* Device page size */
210#define MIC_DP_SIZE 4096
211
212#define MIC_MAGIC 0xc0ffee00
213
214/**
215 * enum mic_states - MIC states.
216 */
217enum mic_states {
218 MIC_OFFLINE = 0,
219 MIC_ONLINE,
220 MIC_SHUTTING_DOWN,
221 MIC_RESET_FAILED,
222 MIC_SUSPENDING,
223 MIC_SUSPENDED,
224 MIC_LAST
225};
226
227/**
228 * enum mic_status - MIC status reported by card after
229 * a host or card initiated shutdown or a card crash.
230 */
231enum mic_status {
232 MIC_NOP = 0,
233 MIC_CRASHED,
234 MIC_HALTED,
235 MIC_POWER_OFF,
236 MIC_RESTART,
237 MIC_STATUS_LAST
238};
239
240#endif
diff --git a/include/uapi/linux/mic_ioctl.h b/include/uapi/linux/mic_ioctl.h
new file mode 100644
index 000000000000..7fabba5059cf
--- /dev/null
+++ b/include/uapi/linux/mic_ioctl.h
@@ -0,0 +1,76 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 */
21#ifndef _MIC_IOCTL_H_
22#define _MIC_IOCTL_H_
23
24#include <linux/types.h>
25
26/*
27 * mic_copy - MIC virtio descriptor copy.
28 *
29 * @iov: An array of IOVEC structures containing user space buffers.
30 * @iovcnt: Number of IOVEC structures in iov.
31 * @vr_idx: The vring index.
32 * @update_used: A non zero value results in used index being updated.
33 * @out_len: The aggregate of the total length written to or read from
34 * the virtio device.
35 */
36struct mic_copy_desc {
37#ifdef __KERNEL__
38 struct iovec __user *iov;
39#else
40 struct iovec *iov;
41#endif
42 int iovcnt;
43 __u8 vr_idx;
44 __u8 update_used;
45 __u32 out_len;
46};
47
48/*
49 * Add a new virtio device
50 * The (struct mic_device_desc *) pointer points to a device page entry
51 * for the virtio device consisting of:
52 * - struct mic_device_desc
53 * - struct mic_vqconfig (num_vq of these)
54 * - host and guest features
55 * - virtio device config space
56 * The total size referenced by the pointer should equal the size returned
57 * by desc_size() in mic_common.h
58 */
59#define MIC_VIRTIO_ADD_DEVICE _IOWR('s', 1, struct mic_device_desc *)
60
61/*
62 * Copy the number of entries in the iovec and update the used index
63 * if requested by the user.
64 */
65#define MIC_VIRTIO_COPY_DESC _IOWR('s', 2, struct mic_copy_desc *)
66
67/*
68 * Notify virtio device of a config change
69 * The (__u8 *) pointer points to config space values for the device
70 * as they should be written into the device page. The total size
71 * referenced by the pointer should equal the config_len field of struct
72 * mic_device_desc.
73 */
74#define MIC_VIRTIO_CONFIG_CHANGE _IOWR('s', 5, __u8 *)
75
76#endif
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 8fd9ec66121c..b8d6d541d854 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -89,6 +89,7 @@ static char *processor_arch;
89static char *os_build; 89static char *os_build;
90static char *os_version; 90static char *os_version;
91static char *lic_version = "Unknown version"; 91static char *lic_version = "Unknown version";
92static char full_domain_name[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
92static struct utsname uts_buf; 93static struct utsname uts_buf;
93 94
94/* 95/*
@@ -1367,7 +1368,7 @@ setval_error:
1367} 1368}
1368 1369
1369 1370
1370static int 1371static void
1371kvp_get_domain_name(char *buffer, int length) 1372kvp_get_domain_name(char *buffer, int length)
1372{ 1373{
1373 struct addrinfo hints, *info ; 1374 struct addrinfo hints, *info ;
@@ -1381,12 +1382,12 @@ kvp_get_domain_name(char *buffer, int length)
1381 1382
1382 error = getaddrinfo(buffer, NULL, &hints, &info); 1383 error = getaddrinfo(buffer, NULL, &hints, &info);
1383 if (error != 0) { 1384 if (error != 0) {
1384 strcpy(buffer, "getaddrinfo failed\n"); 1385 snprintf(buffer, length, "getaddrinfo failed: 0x%x %s",
1385 return error; 1386 error, gai_strerror(error));
1387 return;
1386 } 1388 }
1387 strcpy(buffer, info->ai_canonname); 1389 snprintf(buffer, length, "%s", info->ai_canonname);
1388 freeaddrinfo(info); 1390 freeaddrinfo(info);
1389 return error;
1390} 1391}
1391 1392
1392static int 1393static int
@@ -1433,7 +1434,6 @@ int main(void)
1433 int pool; 1434 int pool;
1434 char *if_name; 1435 char *if_name;
1435 struct hv_kvp_ipaddr_value *kvp_ip_val; 1436 struct hv_kvp_ipaddr_value *kvp_ip_val;
1436 char *kvp_send_buffer;
1437 char *kvp_recv_buffer; 1437 char *kvp_recv_buffer;
1438 size_t kvp_recv_buffer_len; 1438 size_t kvp_recv_buffer_len;
1439 1439
@@ -1442,17 +1442,21 @@ int main(void)
1442 openlog("KVP", 0, LOG_USER); 1442 openlog("KVP", 0, LOG_USER);
1443 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); 1443 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
1444 1444
1445 kvp_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg); 1445 kvp_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg);
1446 kvp_send_buffer = calloc(1, kvp_recv_buffer_len);
1447 kvp_recv_buffer = calloc(1, kvp_recv_buffer_len); 1446 kvp_recv_buffer = calloc(1, kvp_recv_buffer_len);
1448 if (!(kvp_send_buffer && kvp_recv_buffer)) { 1447 if (!kvp_recv_buffer) {
1449 syslog(LOG_ERR, "Failed to allocate netlink buffers"); 1448 syslog(LOG_ERR, "Failed to allocate netlink buffer");
1450 exit(EXIT_FAILURE); 1449 exit(EXIT_FAILURE);
1451 } 1450 }
1452 /* 1451 /*
1453 * Retrieve OS release information. 1452 * Retrieve OS release information.
1454 */ 1453 */
1455 kvp_get_os_info(); 1454 kvp_get_os_info();
1455 /*
1456 * Cache Fully Qualified Domain Name because getaddrinfo takes an
1457 * unpredictable amount of time to finish.
1458 */
1459 kvp_get_domain_name(full_domain_name, sizeof(full_domain_name));
1456 1460
1457 if (kvp_file_init()) { 1461 if (kvp_file_init()) {
1458 syslog(LOG_ERR, "Failed to initialize the pools"); 1462 syslog(LOG_ERR, "Failed to initialize the pools");
@@ -1488,7 +1492,7 @@ int main(void)
1488 /* 1492 /*
1489 * Register ourselves with the kernel. 1493 * Register ourselves with the kernel.
1490 */ 1494 */
1491 message = (struct cn_msg *)kvp_send_buffer; 1495 message = (struct cn_msg *)kvp_recv_buffer;
1492 message->id.idx = CN_KVP_IDX; 1496 message->id.idx = CN_KVP_IDX;
1493 message->id.val = CN_KVP_VAL; 1497 message->id.val = CN_KVP_VAL;
1494 1498
@@ -1671,8 +1675,7 @@ int main(void)
1671 1675
1672 switch (hv_msg->body.kvp_enum_data.index) { 1676 switch (hv_msg->body.kvp_enum_data.index) {
1673 case FullyQualifiedDomainName: 1677 case FullyQualifiedDomainName:
1674 kvp_get_domain_name(key_value, 1678 strcpy(key_value, full_domain_name);
1675 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1676 strcpy(key_name, "FullyQualifiedDomainName"); 1679 strcpy(key_name, "FullyQualifiedDomainName");
1677 break; 1680 break;
1678 case IntegrationServicesVersion: 1681 case IntegrationServicesVersion:
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index 8611962c672c..8bcb04096eb2 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -140,7 +140,6 @@ int main(void)
140 struct cn_msg *incoming_cn_msg; 140 struct cn_msg *incoming_cn_msg;
141 int op; 141 int op;
142 struct hv_vss_msg *vss_msg; 142 struct hv_vss_msg *vss_msg;
143 char *vss_send_buffer;
144 char *vss_recv_buffer; 143 char *vss_recv_buffer;
145 size_t vss_recv_buffer_len; 144 size_t vss_recv_buffer_len;
146 145
@@ -150,10 +149,9 @@ int main(void)
150 openlog("Hyper-V VSS", 0, LOG_USER); 149 openlog("Hyper-V VSS", 0, LOG_USER);
151 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); 150 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
152 151
153 vss_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg); 152 vss_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg);
154 vss_send_buffer = calloc(1, vss_recv_buffer_len);
155 vss_recv_buffer = calloc(1, vss_recv_buffer_len); 153 vss_recv_buffer = calloc(1, vss_recv_buffer_len);
156 if (!(vss_send_buffer && vss_recv_buffer)) { 154 if (!vss_recv_buffer) {
157 syslog(LOG_ERR, "Failed to allocate netlink buffers"); 155 syslog(LOG_ERR, "Failed to allocate netlink buffers");
158 exit(EXIT_FAILURE); 156 exit(EXIT_FAILURE);
159 } 157 }
@@ -185,7 +183,7 @@ int main(void)
185 /* 183 /*
186 * Register ourselves with the kernel. 184 * Register ourselves with the kernel.
187 */ 185 */
188 message = (struct cn_msg *)vss_send_buffer; 186 message = (struct cn_msg *)vss_recv_buffer;
189 message->id.idx = CN_VSS_IDX; 187 message->id.idx = CN_VSS_IDX;
190 message->id.val = CN_VSS_VAL; 188 message->id.val = CN_VSS_VAL;
191 message->ack = 0; 189 message->ack = 0;