aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig15
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/intel-agp.c1
-rw-r--r--drivers/char/agp/intel-gtt.c10
-rw-r--r--drivers/char/briq_panel.c266
-rw-r--r--drivers/char/hw_random/nomadik-rng.c13
-rw-r--r--drivers/char/hw_random/tx4939-rng.c5
-rw-r--r--drivers/char/nvram.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/ramoops.c1
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/tlclk.c2
-rw-r--r--drivers/char/tpm/Kconfig1
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm_tis.c27
-rw-r--r--drivers/char/ttyprintk.c2
-rw-r--r--drivers/char/viotape.c1041
18 files changed, 32 insertions, 1367 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 43643033a3ae..ee946865d6cb 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -66,21 +66,6 @@ config TTY_PRINTK
66 66
67 If unsure, say N. 67 If unsure, say N.
68 68
69config BRIQ_PANEL
70 tristate 'Total Impact briQ front panel driver'
71 depends on PPC_CHRP
72 ---help---
73 The briQ is a small footprint CHRP computer with a frontpanel VFD, a
74 tristate led and two switches. It is the size of a CDROM drive.
75
76 If you have such one and want anything showing on the VFD then you
77 must answer Y here.
78
79 To compile this driver as a module, choose M here: the
80 module will be called briq_panel.
81
82 It's safe to say N here.
83
84config BFIN_OTP 69config BFIN_OTP
85 tristate "Blackfin On-Chip OTP Memory Support" 70 tristate "Blackfin On-Chip OTP Memory Support"
86 depends on BLACKFIN && (BF51x || BF52x || BF54x) 71 depends on BLACKFIN && (BF51x || BF52x || BF54x)
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 32762ba769c2..0dc5d7ce4864 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o
16obj-$(CONFIG_VIOTAPE) += viotape.o 16obj-$(CONFIG_VIOTAPE) += viotape.o
17obj-$(CONFIG_IBM_BSR) += bsr.o 17obj-$(CONFIG_IBM_BSR) += bsr.o
18obj-$(CONFIG_SGI_MBCS) += mbcs.o 18obj-$(CONFIG_SGI_MBCS) += mbcs.o
19obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
20obj-$(CONFIG_BFIN_OTP) += bfin-otp.o 19obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
21 20
22obj-$(CONFIG_PRINTER) += lp.o 21obj-$(CONFIG_PRINTER) += lp.o
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index b427711be4be..962e75dc4781 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -850,6 +850,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
850 .subvendor = PCI_ANY_ID, \ 850 .subvendor = PCI_ANY_ID, \
851 .subdevice = PCI_ANY_ID, \ 851 .subdevice = PCI_ANY_ID, \
852 } 852 }
853 ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */
853 ID(PCI_DEVICE_ID_INTEL_82443LX_0), 854 ID(PCI_DEVICE_ID_INTEL_82443LX_0),
854 ID(PCI_DEVICE_ID_INTEL_82443BX_0), 855 ID(PCI_DEVICE_ID_INTEL_82443BX_0),
855 ID(PCI_DEVICE_ID_INTEL_82443GX_0), 856 ID(PCI_DEVICE_ID_INTEL_82443GX_0),
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index c92424ca1a55..5cf47ac2d401 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -76,7 +76,6 @@ static struct _intel_private {
76 struct resource ifp_resource; 76 struct resource ifp_resource;
77 int resource_valid; 77 int resource_valid;
78 struct page *scratch_page; 78 struct page *scratch_page;
79 dma_addr_t scratch_page_dma;
80} intel_private; 79} intel_private;
81 80
82#define INTEL_GTT_GEN intel_private.driver->gen 81#define INTEL_GTT_GEN intel_private.driver->gen
@@ -306,9 +305,9 @@ static int intel_gtt_setup_scratch_page(void)
306 if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) 305 if (pci_dma_mapping_error(intel_private.pcidev, dma_addr))
307 return -EINVAL; 306 return -EINVAL;
308 307
309 intel_private.scratch_page_dma = dma_addr; 308 intel_private.base.scratch_page_dma = dma_addr;
310 } else 309 } else
311 intel_private.scratch_page_dma = page_to_phys(page); 310 intel_private.base.scratch_page_dma = page_to_phys(page);
312 311
313 intel_private.scratch_page = page; 312 intel_private.scratch_page = page;
314 313
@@ -631,7 +630,7 @@ static unsigned int intel_gtt_mappable_entries(void)
631static void intel_gtt_teardown_scratch_page(void) 630static void intel_gtt_teardown_scratch_page(void)
632{ 631{
633 set_pages_wb(intel_private.scratch_page, 1); 632 set_pages_wb(intel_private.scratch_page, 1);
634 pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, 633 pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma,
635 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 634 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
636 put_page(intel_private.scratch_page); 635 put_page(intel_private.scratch_page);
637 __free_page(intel_private.scratch_page); 636 __free_page(intel_private.scratch_page);
@@ -681,6 +680,7 @@ static int intel_gtt_init(void)
681 iounmap(intel_private.registers); 680 iounmap(intel_private.registers);
682 return -ENOMEM; 681 return -ENOMEM;
683 } 682 }
683 intel_private.base.gtt = intel_private.gtt;
684 684
685 global_cache_flush(); /* FIXME: ? */ 685 global_cache_flush(); /* FIXME: ? */
686 686
@@ -975,7 +975,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
975 unsigned int i; 975 unsigned int i;
976 976
977 for (i = first_entry; i < (first_entry + num_entries); i++) { 977 for (i = first_entry; i < (first_entry + num_entries); i++) {
978 intel_private.driver->write_entry(intel_private.scratch_page_dma, 978 intel_private.driver->write_entry(intel_private.base.scratch_page_dma,
979 i, 0); 979 i, 0);
980 } 980 }
981 readl(intel_private.gtt+i-1); 981 readl(intel_private.gtt+i-1);
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
deleted file mode 100644
index 095ab90535ce..000000000000
--- a/drivers/char/briq_panel.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * Drivers for the Total Impact PPC based computer "BRIQ"
3 * by Dr. Karsten Jeppesen
4 *
5 */
6
7#include <linux/module.h>
8
9#include <linux/types.h>
10#include <linux/errno.h>
11#include <linux/tty.h>
12#include <linux/timer.h>
13#include <linux/kernel.h>
14#include <linux/wait.h>
15#include <linux/string.h>
16#include <linux/ioport.h>
17#include <linux/delay.h>
18#include <linux/miscdevice.h>
19#include <linux/fs.h>
20#include <linux/mm.h>
21#include <linux/init.h>
22
23#include <asm/uaccess.h>
24#include <asm/io.h>
25#include <asm/prom.h>
26
27#define BRIQ_PANEL_MINOR 156
28#define BRIQ_PANEL_VFD_IOPORT 0x0390
29#define BRIQ_PANEL_LED_IOPORT 0x0398
30#define BRIQ_PANEL_VER "1.1 (04/20/2002)"
31#define BRIQ_PANEL_MSG0 "Loading Linux"
32
33static int vfd_is_open;
34static unsigned char vfd[40];
35static int vfd_cursor;
36static unsigned char ledpb, led;
37
38static void update_vfd(void)
39{
40 int i;
41
42 /* cursor home */
43 outb(0x02, BRIQ_PANEL_VFD_IOPORT);
44 for (i=0; i<20; i++)
45 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1);
46
47 /* cursor to next line */
48 outb(0xc0, BRIQ_PANEL_VFD_IOPORT);
49 for (i=20; i<40; i++)
50 outb(vfd[i], BRIQ_PANEL_VFD_IOPORT + 1);
51
52}
53
54static void set_led(char state)
55{
56 if (state == 'R')
57 led = 0x01;
58 else if (state == 'G')
59 led = 0x02;
60 else if (state == 'Y')
61 led = 0x03;
62 else if (state == 'X')
63 led = 0x00;
64 outb(led, BRIQ_PANEL_LED_IOPORT);
65}
66
67static int briq_panel_open(struct inode *ino, struct file *filep)
68{
69 tty_lock();
70 /* enforce single access, vfd_is_open is protected by BKL */
71 if (vfd_is_open) {
72 tty_unlock();
73 return -EBUSY;
74 }
75 vfd_is_open = 1;
76
77 tty_unlock();
78 return 0;
79}
80
81static int briq_panel_release(struct inode *ino, struct file *filep)
82{
83 if (!vfd_is_open)
84 return -ENODEV;
85
86 vfd_is_open = 0;
87
88 return 0;
89}
90
91static ssize_t briq_panel_read(struct file *file, char __user *buf, size_t count,
92 loff_t *ppos)
93{
94 unsigned short c;
95 unsigned char cp;
96
97 if (!vfd_is_open)
98 return -ENODEV;
99
100 c = (inb(BRIQ_PANEL_LED_IOPORT) & 0x000c) | (ledpb & 0x0003);
101 set_led(' ');
102 /* upper button released */
103 if ((!(ledpb & 0x0004)) && (c & 0x0004)) {
104 cp = ' ';
105 ledpb = c;
106 if (copy_to_user(buf, &cp, 1))
107 return -EFAULT;
108 return 1;
109 }
110 /* lower button released */
111 else if ((!(ledpb & 0x0008)) && (c & 0x0008)) {
112 cp = '\r';
113 ledpb = c;
114 if (copy_to_user(buf, &cp, 1))
115 return -EFAULT;
116 return 1;
117 } else {
118 ledpb = c;
119 return 0;
120 }
121}
122
123static void scroll_vfd( void )
124{
125 int i;
126
127 for (i=0; i<20; i++) {
128 vfd[i] = vfd[i+20];
129 vfd[i+20] = ' ';
130 }
131 vfd_cursor = 20;
132}
133
134static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_t len,
135 loff_t *ppos)
136{
137 size_t indx = len;
138 int i, esc = 0;
139
140 if (!vfd_is_open)
141 return -EBUSY;
142
143 for (;;) {
144 char c;
145 if (!indx)
146 break;
147 if (get_user(c, buf))
148 return -EFAULT;
149 if (esc) {
150 set_led(c);
151 esc = 0;
152 } else if (c == 27) {
153 esc = 1;
154 } else if (c == 12) {
155 /* do a form feed */
156 for (i=0; i<40; i++)
157 vfd[i] = ' ';
158 vfd_cursor = 0;
159 } else if (c == 10) {
160 if (vfd_cursor < 20)
161 vfd_cursor = 20;
162 else if (vfd_cursor < 40)
163 vfd_cursor = 40;
164 else if (vfd_cursor < 60)
165 vfd_cursor = 60;
166 if (vfd_cursor > 59)
167 scroll_vfd();
168 } else {
169 /* just a character */
170 if (vfd_cursor > 39)
171 scroll_vfd();
172 vfd[vfd_cursor++] = c;
173 }
174 indx--;
175 buf++;
176 }
177 update_vfd();
178
179 return len;
180}
181
182static const struct file_operations briq_panel_fops = {
183 .owner = THIS_MODULE,
184 .read = briq_panel_read,
185 .write = briq_panel_write,
186 .open = briq_panel_open,
187 .release = briq_panel_release,
188 .llseek = noop_llseek,
189};
190
191static struct miscdevice briq_panel_miscdev = {
192 BRIQ_PANEL_MINOR,
193 "briq_panel",
194 &briq_panel_fops
195};
196
197static int __init briq_panel_init(void)
198{
199 struct device_node *root = of_find_node_by_path("/");
200 const char *machine;
201 int i;
202
203 machine = of_get_property(root, "model", NULL);
204 if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) {
205 of_node_put(root);
206 return -ENODEV;
207 }
208 of_node_put(root);
209
210 printk(KERN_INFO
211 "briq_panel: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n",
212 BRIQ_PANEL_VER);
213
214 if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel"))
215 return -EBUSY;
216
217 if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) {
218 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
219 return -EBUSY;
220 }
221 ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c;
222
223 if (misc_register(&briq_panel_miscdev) < 0) {
224 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
225 release_region(BRIQ_PANEL_LED_IOPORT, 2);
226 return -EBUSY;
227 }
228
229 outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */
230 outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */
231 outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */
232 outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */
233 for (i=0; i<40; i++)
234 vfd[i]=' ';
235#ifndef MODULE
236 vfd[0] = 'L';
237 vfd[1] = 'o';
238 vfd[2] = 'a';
239 vfd[3] = 'd';
240 vfd[4] = 'i';
241 vfd[5] = 'n';
242 vfd[6] = 'g';
243 vfd[7] = ' ';
244 vfd[8] = '.';
245 vfd[9] = '.';
246 vfd[10] = '.';
247#endif /* !MODULE */
248
249 update_vfd();
250
251 return 0;
252}
253
254static void __exit briq_panel_exit(void)
255{
256 misc_deregister(&briq_panel_miscdev);
257 release_region(BRIQ_PANEL_VFD_IOPORT, 4);
258 release_region(BRIQ_PANEL_LED_IOPORT, 2);
259}
260
261module_init(briq_panel_init);
262module_exit(briq_panel_exit);
263
264MODULE_LICENSE("GPL");
265MODULE_AUTHOR("Karsten Jeppesen <karsten@jeppesens.com>");
266MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");
diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
index 3d3c1e6703b4..96de0249e595 100644
--- a/drivers/char/hw_random/nomadik-rng.c
+++ b/drivers/char/hw_random/nomadik-rng.c
@@ -107,17 +107,6 @@ static struct amba_driver nmk_rng_driver = {
107 .id_table = nmk_rng_ids, 107 .id_table = nmk_rng_ids,
108}; 108};
109 109
110static int __init nmk_rng_init(void) 110module_amba_driver(nmk_rng_driver);
111{
112 return amba_driver_register(&nmk_rng_driver);
113}
114
115static void __devexit nmk_rng_exit(void)
116{
117 amba_driver_unregister(&nmk_rng_driver);
118}
119
120module_init(nmk_rng_init);
121module_exit(nmk_rng_exit);
122 111
123MODULE_LICENSE("GPL"); 112MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
index 0bc0cb70210b..de473ef3882b 100644
--- a/drivers/char/hw_random/tx4939-rng.c
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -115,10 +115,7 @@ static int __init tx4939_rng_probe(struct platform_device *dev)
115 rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); 115 rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
116 if (!rngdev) 116 if (!rngdev)
117 return -ENOMEM; 117 return -ENOMEM;
118 if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r), 118 rngdev->base = devm_request_and_ioremap(&dev->dev, r);
119 dev_name(&dev->dev)))
120 return -EBUSY;
121 rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
122 if (!rngdev->base) 119 if (!rngdev->base)
123 return -EBUSY; 120 return -EBUSY;
124 121
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index da3cfee782dc..eaade8a1ecd7 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -94,7 +94,7 @@
94/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with 94/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
95 * rtc_lock held. Due to the index-port/data-port design of the RTC, we 95 * rtc_lock held. Due to the index-port/data-port design of the RTC, we
96 * don't want two different things trying to get to it at once. (e.g. the 96 * don't want two different things trying to get to it at once. (e.g. the
97 * periodic 11 min sync from time.c vs. this driver.) 97 * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
98 */ 98 */
99 99
100#include <linux/types.h> 100#include <linux/types.h>
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 07f6a5abe372..f6453df4921c 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2484,7 +2484,7 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp)
2484 2484
2485 /* verify range of specified line number */ 2485 /* verify range of specified line number */
2486 line = tty->index; 2486 line = tty->index;
2487 if ((line < 0) || (line >= mgslpc_device_count)) { 2487 if (line >= mgslpc_device_count) {
2488 printk("%s(%d):mgslpc_open with invalid line #%d.\n", 2488 printk("%s(%d):mgslpc_open with invalid line #%d.\n",
2489 __FILE__,__LINE__,line); 2489 __FILE__,__LINE__,line);
2490 return -ENODEV; 2490 return -ENODEV;
@@ -2836,7 +2836,6 @@ static int __init synclink_cs_init(void)
2836 2836
2837 /* Initialize the tty_driver structure */ 2837 /* Initialize the tty_driver structure */
2838 2838
2839 serial_driver->owner = THIS_MODULE;
2840 serial_driver->driver_name = "synclink_cs"; 2839 serial_driver->driver_name = "synclink_cs";
2841 serial_driver->name = "ttySLP"; 2840 serial_driver->name = "ttySLP";
2842 serial_driver->major = ttymajor; 2841 serial_driver->major = ttymajor;
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c
index 9fec3232b736..2a5e45d2a9f8 100644
--- a/drivers/char/ramoops.c
+++ b/drivers/char/ramoops.c
@@ -26,7 +26,6 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/kmsg_dump.h> 27#include <linux/kmsg_dump.h>
28#include <linux/time.h> 28#include <linux/time.h>
29#include <linux/err.h>
30#include <linux/io.h> 29#include <linux/io.h>
31#include <linux/ioport.h> 30#include <linux/ioport.h>
32#include <linux/platform_device.h> 31#include <linux/platform_device.h>
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index ccd124ab7ca7..872e09a02d23 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -57,8 +57,8 @@
57 * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with 57 * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
58 * interrupts disabled. Due to the index-port/data-port (0x70/0x71) 58 * interrupts disabled. Due to the index-port/data-port (0x70/0x71)
59 * design of the RTC, we don't want two different things trying to 59 * design of the RTC, we don't want two different things trying to
60 * get to it at once. (e.g. the periodic 11 min sync from time.c vs. 60 * get to it at once. (e.g. the periodic 11 min sync from
61 * this driver.) 61 * kernel/time/ntp.c vs. this driver.)
62 */ 62 */
63 63
64#include <linux/interrupt.h> 64#include <linux/interrupt.h>
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 0c964cdcc223..ce29e7cce528 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -797,7 +797,7 @@ static int __init tlclk_init(void)
797 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); 797 telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
798 798
799 if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ 799 if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
800 printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n", 800 printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n",
801 telclk_interrupt); 801 telclk_interrupt);
802 ret = -ENXIO; 802 ret = -ENXIO;
803 goto out3; 803 goto out3;
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 7fc75e47e6d0..a048199ce866 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -5,7 +5,6 @@
5menuconfig TCG_TPM 5menuconfig TCG_TPM
6 tristate "TPM Hardware Support" 6 tristate "TPM Hardware Support"
7 depends on HAS_IOMEM 7 depends on HAS_IOMEM
8 depends on EXPERIMENTAL
9 select SECURITYFS 8 select SECURITYFS
10 ---help--- 9 ---help---
11 If you have a TPM security chip in your system, which 10 If you have a TPM security chip in your system, which
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 32362cf35b8d..ad7c7320dd1b 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1221,12 +1221,13 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1221 ret_size = atomic_read(&chip->data_pending); 1221 ret_size = atomic_read(&chip->data_pending);
1222 atomic_set(&chip->data_pending, 0); 1222 atomic_set(&chip->data_pending, 0);
1223 if (ret_size > 0) { /* relay data */ 1223 if (ret_size > 0) { /* relay data */
1224 ssize_t orig_ret_size = ret_size;
1224 if (size < ret_size) 1225 if (size < ret_size)
1225 ret_size = size; 1226 ret_size = size;
1226 1227
1227 mutex_lock(&chip->buffer_mutex); 1228 mutex_lock(&chip->buffer_mutex);
1228 rc = copy_to_user(buf, chip->data_buffer, ret_size); 1229 rc = copy_to_user(buf, chip->data_buffer, ret_size);
1229 memset(chip->data_buffer, 0, ret_size); 1230 memset(chip->data_buffer, 0, orig_ret_size);
1230 if (rc) 1231 if (rc)
1231 ret_size = -EFAULT; 1232 ret_size = -EFAULT;
1232 1233
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 010547138281..b1c5280ac159 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -99,6 +99,8 @@ struct tpm_vendor_specific {
99 wait_queue_head_t int_queue; 99 wait_queue_head_t int_queue;
100}; 100};
101 101
102#define TPM_VID_INTEL 0x8086
103
102struct tpm_chip { 104struct tpm_chip {
103 struct device *dev; /* Device stuff */ 105 struct device *dev; /* Device stuff */
104 106
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index a1748621111b..d2a70cae76df 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -76,7 +76,7 @@ enum tis_defaults {
76#define TPM_RID(l) (0x0F04 | ((l) << 12)) 76#define TPM_RID(l) (0x0F04 | ((l) << 12))
77 77
78static LIST_HEAD(tis_chips); 78static LIST_HEAD(tis_chips);
79static DEFINE_SPINLOCK(tis_lock); 79static DEFINE_MUTEX(tis_lock);
80 80
81#if defined(CONFIG_PNP) && defined(CONFIG_ACPI) 81#if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
82static int is_itpm(struct pnp_dev *dev) 82static int is_itpm(struct pnp_dev *dev)
@@ -367,7 +367,12 @@ static int probe_itpm(struct tpm_chip *chip)
367 0x00, 0x00, 0x00, 0xf1 367 0x00, 0x00, 0x00, 0xf1
368 }; 368 };
369 size_t len = sizeof(cmd_getticks); 369 size_t len = sizeof(cmd_getticks);
370 int rem_itpm = itpm; 370 bool rem_itpm = itpm;
371 u16 vendor = ioread16(chip->vendor.iobase + TPM_DID_VID(0));
372
373 /* probe only iTPMS */
374 if (vendor != TPM_VID_INTEL)
375 return 0;
371 376
372 itpm = 0; 377 itpm = 0;
373 378
@@ -390,9 +395,6 @@ static int probe_itpm(struct tpm_chip *chip)
390out: 395out:
391 itpm = rem_itpm; 396 itpm = rem_itpm;
392 tpm_tis_ready(chip); 397 tpm_tis_ready(chip);
393 /* some TPMs need a break here otherwise they will not work
394 * correctly on the immediately subsequent command */
395 msleep(chip->vendor.timeout_b);
396 release_locality(chip, chip->vendor.locality, 0); 398 release_locality(chip, chip->vendor.locality, 0);
397 399
398 return rc; 400 return rc;
@@ -508,7 +510,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
508 resource_size_t len, unsigned int irq) 510 resource_size_t len, unsigned int irq)
509{ 511{
510 u32 vendor, intfcaps, intmask; 512 u32 vendor, intfcaps, intmask;
511 int rc, i, irq_s, irq_e; 513 int rc, i, irq_s, irq_e, probe;
512 struct tpm_chip *chip; 514 struct tpm_chip *chip;
513 515
514 if (!(chip = tpm_register_hardware(dev, &tpm_tis))) 516 if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
@@ -538,11 +540,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
538 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); 540 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
539 541
540 if (!itpm) { 542 if (!itpm) {
541 itpm = probe_itpm(chip); 543 probe = probe_itpm(chip);
542 if (itpm < 0) { 544 if (probe < 0) {
543 rc = -ENODEV; 545 rc = -ENODEV;
544 goto out_err; 546 goto out_err;
545 } 547 }
548 itpm = (probe == 0) ? 0 : 1;
546 } 549 }
547 550
548 if (itpm) 551 if (itpm)
@@ -689,9 +692,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
689 } 692 }
690 693
691 INIT_LIST_HEAD(&chip->vendor.list); 694 INIT_LIST_HEAD(&chip->vendor.list);
692 spin_lock(&tis_lock); 695 mutex_lock(&tis_lock);
693 list_add(&chip->vendor.list, &tis_chips); 696 list_add(&chip->vendor.list, &tis_chips);
694 spin_unlock(&tis_lock); 697 mutex_unlock(&tis_lock);
695 698
696 699
697 return 0; 700 return 0;
@@ -855,7 +858,7 @@ static void __exit cleanup_tis(void)
855{ 858{
856 struct tpm_vendor_specific *i, *j; 859 struct tpm_vendor_specific *i, *j;
857 struct tpm_chip *chip; 860 struct tpm_chip *chip;
858 spin_lock(&tis_lock); 861 mutex_lock(&tis_lock);
859 list_for_each_entry_safe(i, j, &tis_chips, list) { 862 list_for_each_entry_safe(i, j, &tis_chips, list) {
860 chip = to_tpm_chip(i); 863 chip = to_tpm_chip(i);
861 tpm_remove_hardware(chip->dev); 864 tpm_remove_hardware(chip->dev);
@@ -871,7 +874,7 @@ static void __exit cleanup_tis(void)
871 iounmap(i->iobase); 874 iounmap(i->iobase);
872 list_del(&i->list); 875 list_del(&i->list);
873 } 876 }
874 spin_unlock(&tis_lock); 877 mutex_unlock(&tis_lock);
875#ifdef CONFIG_PNP 878#ifdef CONFIG_PNP
876 if (!force) { 879 if (!force) {
877 pnp_unregister_driver(&tis_pnp_driver); 880 pnp_unregister_driver(&tis_pnp_driver);
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index eedd5474850c..46b77ede84c0 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -184,12 +184,10 @@ static int __init ttyprintk_init(void)
184 if (!ttyprintk_driver) 184 if (!ttyprintk_driver)
185 return ret; 185 return ret;
186 186
187 ttyprintk_driver->owner = THIS_MODULE;
188 ttyprintk_driver->driver_name = "ttyprintk"; 187 ttyprintk_driver->driver_name = "ttyprintk";
189 ttyprintk_driver->name = "ttyprintk"; 188 ttyprintk_driver->name = "ttyprintk";
190 ttyprintk_driver->major = TTYAUX_MAJOR; 189 ttyprintk_driver->major = TTYAUX_MAJOR;
191 ttyprintk_driver->minor_start = 3; 190 ttyprintk_driver->minor_start = 3;
192 ttyprintk_driver->num = 1;
193 ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; 191 ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE;
194 ttyprintk_driver->init_termios = tty_std_termios; 192 ttyprintk_driver->init_termios = tty_std_termios;
195 ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; 193 ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
deleted file mode 100644
index ad6e64a2912d..000000000000
--- a/drivers/char/viotape.c
+++ /dev/null
@@ -1,1041 +0,0 @@
1/* -*- linux-c -*-
2 * drivers/char/viotape.c
3 *
4 * iSeries Virtual Tape
5 *
6 * Authors: Dave Boutcher <boutcher@us.ibm.com>
7 * Ryan Arnold <ryanarn@us.ibm.com>
8 * Colin Devilbiss <devilbis@us.ibm.com>
9 * Stephen Rothwell
10 *
11 * (C) Copyright 2000-2004 IBM Corporation
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) anyu later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 * This routine provides access to tape drives owned and managed by an OS/400
28 * partition running on the same box as this Linux partition.
29 *
30 * All tape operations are performed by sending messages back and forth to
31 * the OS/400 partition. The format of the messages is defined in
32 * iseries/vio.h
33 */
34#include <linux/module.h>
35#include <linux/kernel.h>
36#include <linux/errno.h>
37#include <linux/init.h>
38#include <linux/wait.h>
39#include <linux/spinlock.h>
40#include <linux/mtio.h>
41#include <linux/device.h>
42#include <linux/dma-mapping.h>
43#include <linux/fs.h>
44#include <linux/cdev.h>
45#include <linux/major.h>
46#include <linux/completion.h>
47#include <linux/proc_fs.h>
48#include <linux/seq_file.h>
49#include <linux/mutex.h>
50#include <linux/slab.h>
51
52#include <asm/uaccess.h>
53#include <asm/ioctls.h>
54#include <asm/firmware.h>
55#include <asm/vio.h>
56#include <asm/iseries/vio.h>
57#include <asm/iseries/hv_lp_event.h>
58#include <asm/iseries/hv_call_event.h>
59#include <asm/iseries/hv_lp_config.h>
60
61#define VIOTAPE_VERSION "1.2"
62#define VIOTAPE_MAXREQ 1
63
64#define VIOTAPE_KERN_WARN KERN_WARNING "viotape: "
65#define VIOTAPE_KERN_INFO KERN_INFO "viotape: "
66
67static DEFINE_MUTEX(proc_viotape_mutex);
68static int viotape_numdev;
69
70/*
71 * The minor number follows the conventions of the SCSI tape drives. The
72 * rewind and mode are encoded in the minor #. We use this struct to break
73 * them out
74 */
75struct viot_devinfo_struct {
76 int devno;
77 int mode;
78 int rewind;
79};
80
81#define VIOTAPOP_RESET 0
82#define VIOTAPOP_FSF 1
83#define VIOTAPOP_BSF 2
84#define VIOTAPOP_FSR 3
85#define VIOTAPOP_BSR 4
86#define VIOTAPOP_WEOF 5
87#define VIOTAPOP_REW 6
88#define VIOTAPOP_NOP 7
89#define VIOTAPOP_EOM 8
90#define VIOTAPOP_ERASE 9
91#define VIOTAPOP_SETBLK 10
92#define VIOTAPOP_SETDENSITY 11
93#define VIOTAPOP_SETPOS 12
94#define VIOTAPOP_GETPOS 13
95#define VIOTAPOP_SETPART 14
96#define VIOTAPOP_UNLOAD 15
97
98enum viotaperc {
99 viotape_InvalidRange = 0x0601,
100 viotape_InvalidToken = 0x0602,
101 viotape_DMAError = 0x0603,
102 viotape_UseError = 0x0604,
103 viotape_ReleaseError = 0x0605,
104 viotape_InvalidTape = 0x0606,
105 viotape_InvalidOp = 0x0607,
106 viotape_TapeErr = 0x0608,
107
108 viotape_AllocTimedOut = 0x0640,
109 viotape_BOTEnc = 0x0641,
110 viotape_BlankTape = 0x0642,
111 viotape_BufferEmpty = 0x0643,
112 viotape_CleanCartFound = 0x0644,
113 viotape_CmdNotAllowed = 0x0645,
114 viotape_CmdNotSupported = 0x0646,
115 viotape_DataCheck = 0x0647,
116 viotape_DecompressErr = 0x0648,
117 viotape_DeviceTimeout = 0x0649,
118 viotape_DeviceUnavail = 0x064a,
119 viotape_DeviceBusy = 0x064b,
120 viotape_EndOfMedia = 0x064c,
121 viotape_EndOfTape = 0x064d,
122 viotape_EquipCheck = 0x064e,
123 viotape_InsufficientRs = 0x064f,
124 viotape_InvalidLogBlk = 0x0650,
125 viotape_LengthError = 0x0651,
126 viotape_LibDoorOpen = 0x0652,
127 viotape_LoadFailure = 0x0653,
128 viotape_NotCapable = 0x0654,
129 viotape_NotOperational = 0x0655,
130 viotape_NotReady = 0x0656,
131 viotape_OpCancelled = 0x0657,
132 viotape_PhyLinkErr = 0x0658,
133 viotape_RdyNotBOT = 0x0659,
134 viotape_TapeMark = 0x065a,
135 viotape_WriteProt = 0x065b
136};
137
138static const struct vio_error_entry viotape_err_table[] = {
139 { viotape_InvalidRange, EIO, "Internal error" },
140 { viotape_InvalidToken, EIO, "Internal error" },
141 { viotape_DMAError, EIO, "DMA error" },
142 { viotape_UseError, EIO, "Internal error" },
143 { viotape_ReleaseError, EIO, "Internal error" },
144 { viotape_InvalidTape, EIO, "Invalid tape device" },
145 { viotape_InvalidOp, EIO, "Invalid operation" },
146 { viotape_TapeErr, EIO, "Tape error" },
147 { viotape_AllocTimedOut, EBUSY, "Allocate timed out" },
148 { viotape_BOTEnc, EIO, "Beginning of tape encountered" },
149 { viotape_BlankTape, EIO, "Blank tape" },
150 { viotape_BufferEmpty, EIO, "Buffer empty" },
151 { viotape_CleanCartFound, ENOMEDIUM, "Cleaning cartridge found" },
152 { viotape_CmdNotAllowed, EIO, "Command not allowed" },
153 { viotape_CmdNotSupported, EIO, "Command not supported" },
154 { viotape_DataCheck, EIO, "Data check" },
155 { viotape_DecompressErr, EIO, "Decompression error" },
156 { viotape_DeviceTimeout, EBUSY, "Device timeout" },
157 { viotape_DeviceUnavail, EIO, "Device unavailable" },
158 { viotape_DeviceBusy, EBUSY, "Device busy" },
159 { viotape_EndOfMedia, ENOSPC, "End of media" },
160 { viotape_EndOfTape, ENOSPC, "End of tape" },
161 { viotape_EquipCheck, EIO, "Equipment check" },
162 { viotape_InsufficientRs, EOVERFLOW, "Insufficient tape resources" },
163 { viotape_InvalidLogBlk, EIO, "Invalid logical block location" },
164 { viotape_LengthError, EOVERFLOW, "Length error" },
165 { viotape_LibDoorOpen, EBUSY, "Door open" },
166 { viotape_LoadFailure, ENOMEDIUM, "Load failure" },
167 { viotape_NotCapable, EIO, "Not capable" },
168 { viotape_NotOperational, EIO, "Not operational" },
169 { viotape_NotReady, EIO, "Not ready" },
170 { viotape_OpCancelled, EIO, "Operation cancelled" },
171 { viotape_PhyLinkErr, EIO, "Physical link error" },
172 { viotape_RdyNotBOT, EIO, "Ready but not beginning of tape" },
173 { viotape_TapeMark, EIO, "Tape mark" },
174 { viotape_WriteProt, EROFS, "Write protection error" },
175 { 0, 0, NULL },
176};
177
178/* Maximum number of tapes we support */
179#define VIOTAPE_MAX_TAPE HVMAXARCHITECTEDVIRTUALTAPES
180#define MAX_PARTITIONS 4
181
182/* defines for current tape state */
183#define VIOT_IDLE 0
184#define VIOT_READING 1
185#define VIOT_WRITING 2
186
187/* Our info on the tapes */
188static struct {
189 const char *rsrcname;
190 const char *type;
191 const char *model;
192} viotape_unitinfo[VIOTAPE_MAX_TAPE];
193
194static struct mtget viomtget[VIOTAPE_MAX_TAPE];
195
196static struct class *tape_class;
197
198static struct device *tape_device[VIOTAPE_MAX_TAPE];
199
200/*
201 * maintain the current state of each tape (and partition)
202 * so that we know when to write EOF marks.
203 */
204static struct {
205 unsigned char cur_part;
206 unsigned char part_stat_rwi[MAX_PARTITIONS];
207} state[VIOTAPE_MAX_TAPE];
208
209/* We single-thread */
210static struct semaphore reqSem;
211
212/*
213 * When we send a request, we use this struct to get the response back
214 * from the interrupt handler
215 */
216struct op_struct {
217 void *buffer;
218 dma_addr_t dmaaddr;
219 size_t count;
220 int rc;
221 int non_blocking;
222 struct completion com;
223 struct device *dev;
224 struct op_struct *next;
225};
226
227static spinlock_t op_struct_list_lock;
228static struct op_struct *op_struct_list;
229
230/* forward declaration to resolve interdependence */
231static int chg_state(int index, unsigned char new_state, struct file *file);
232
233/* procfs support */
234static int proc_viotape_show(struct seq_file *m, void *v)
235{
236 int i;
237
238 seq_printf(m, "viotape driver version " VIOTAPE_VERSION "\n");
239 for (i = 0; i < viotape_numdev; i++) {
240 seq_printf(m, "viotape device %d is iSeries resource %10.10s"
241 "type %4.4s, model %3.3s\n",
242 i, viotape_unitinfo[i].rsrcname,
243 viotape_unitinfo[i].type,
244 viotape_unitinfo[i].model);
245 }
246 return 0;
247}
248
249static int proc_viotape_open(struct inode *inode, struct file *file)
250{
251 return single_open(file, proc_viotape_show, NULL);
252}
253
254static const struct file_operations proc_viotape_operations = {
255 .owner = THIS_MODULE,
256 .open = proc_viotape_open,
257 .read = seq_read,
258 .llseek = seq_lseek,
259 .release = single_release,
260};
261
262/* Decode the device minor number into its parts */
263void get_dev_info(struct inode *ino, struct viot_devinfo_struct *devi)
264{
265 devi->devno = iminor(ino) & 0x1F;
266 devi->mode = (iminor(ino) & 0x60) >> 5;
267 /* if bit is set in the minor, do _not_ rewind automatically */
268 devi->rewind = (iminor(ino) & 0x80) == 0;
269}
270
271/* This is called only from the exit and init paths, so no need for locking */
272static void clear_op_struct_pool(void)
273{
274 while (op_struct_list) {
275 struct op_struct *toFree = op_struct_list;
276 op_struct_list = op_struct_list->next;
277 kfree(toFree);
278 }
279}
280
281/* Likewise, this is only called from the init path */
282static int add_op_structs(int structs)
283{
284 int i;
285
286 for (i = 0; i < structs; ++i) {
287 struct op_struct *new_struct =
288 kmalloc(sizeof(*new_struct), GFP_KERNEL);
289 if (!new_struct) {
290 clear_op_struct_pool();
291 return -ENOMEM;
292 }
293 new_struct->next = op_struct_list;
294 op_struct_list = new_struct;
295 }
296 return 0;
297}
298
299/* Allocate an op structure from our pool */
300static struct op_struct *get_op_struct(void)
301{
302 struct op_struct *retval;
303 unsigned long flags;
304
305 spin_lock_irqsave(&op_struct_list_lock, flags);
306 retval = op_struct_list;
307 if (retval)
308 op_struct_list = retval->next;
309 spin_unlock_irqrestore(&op_struct_list_lock, flags);
310 if (retval) {
311 memset(retval, 0, sizeof(*retval));
312 init_completion(&retval->com);
313 }
314
315 return retval;
316}
317
318/* Return an op structure to our pool */
319static void free_op_struct(struct op_struct *op_struct)
320{
321 unsigned long flags;
322
323 spin_lock_irqsave(&op_struct_list_lock, flags);
324 op_struct->next = op_struct_list;
325 op_struct_list = op_struct;
326 spin_unlock_irqrestore(&op_struct_list_lock, flags);
327}
328
329/* Map our tape return codes to errno values */
330int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
331{
332 const struct vio_error_entry *err;
333
334 if (tape_rc == 0)
335 return 0;
336
337 err = vio_lookup_rc(viotape_err_table, tape_rc);
338 printk(VIOTAPE_KERN_WARN "error(%s) 0x%04x on Device %d (%-10s): %s\n",
339 operation, tape_rc, tapeno,
340 viotape_unitinfo[tapeno].rsrcname, err->msg);
341 return -err->errno;
342}
343
344/* Write */
345static ssize_t viotap_write(struct file *file, const char *buf,
346 size_t count, loff_t * ppos)
347{
348 HvLpEvent_Rc hvrc;
349 unsigned short flags = file->f_flags;
350 int noblock = ((flags & O_NONBLOCK) != 0);
351 ssize_t ret;
352 struct viot_devinfo_struct devi;
353 struct op_struct *op = get_op_struct();
354
355 if (op == NULL)
356 return -ENOMEM;
357
358 get_dev_info(file->f_path.dentry->d_inode, &devi);
359
360 /*
361 * We need to make sure we can send a request. We use
362 * a semaphore to keep track of # requests in use. If
363 * we are non-blocking, make sure we don't block on the
364 * semaphore
365 */
366 if (noblock) {
367 if (down_trylock(&reqSem)) {
368 ret = -EWOULDBLOCK;
369 goto free_op;
370 }
371 } else
372 down(&reqSem);
373
374 /* Allocate a DMA buffer */
375 op->dev = tape_device[devi.devno];
376 op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr,
377 GFP_ATOMIC);
378
379 if (op->buffer == NULL) {
380 printk(VIOTAPE_KERN_WARN
381 "error allocating dma buffer for len %ld\n",
382 count);
383 ret = -EFAULT;
384 goto up_sem;
385 }
386
387 /* Copy the data into the buffer */
388 if (copy_from_user(op->buffer, buf, count)) {
389 printk(VIOTAPE_KERN_WARN "tape: error on copy from user\n");
390 ret = -EFAULT;
391 goto free_dma;
392 }
393
394 op->non_blocking = noblock;
395 init_completion(&op->com);
396 op->count = count;
397
398 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
399 HvLpEvent_Type_VirtualIo,
400 viomajorsubtype_tape | viotapewrite,
401 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
402 viopath_sourceinst(viopath_hostLp),
403 viopath_targetinst(viopath_hostLp),
404 (u64)(unsigned long)op, VIOVERSION << 16,
405 ((u64)devi.devno << 48) | op->dmaaddr, count, 0, 0);
406 if (hvrc != HvLpEvent_Rc_Good) {
407 printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
408 (int)hvrc);
409 ret = -EIO;
410 goto free_dma;
411 }
412
413 if (noblock)
414 return count;
415
416 wait_for_completion(&op->com);
417
418 if (op->rc)
419 ret = tape_rc_to_errno(op->rc, "write", devi.devno);
420 else {
421 chg_state(devi.devno, VIOT_WRITING, file);
422 ret = op->count;
423 }
424
425free_dma:
426 dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr);
427up_sem:
428 up(&reqSem);
429free_op:
430 free_op_struct(op);
431 return ret;
432}
433
434/* read */
435static ssize_t viotap_read(struct file *file, char *buf, size_t count,
436 loff_t *ptr)
437{
438 HvLpEvent_Rc hvrc;
439 unsigned short flags = file->f_flags;
440 struct op_struct *op = get_op_struct();
441 int noblock = ((flags & O_NONBLOCK) != 0);
442 ssize_t ret;
443 struct viot_devinfo_struct devi;
444
445 if (op == NULL)
446 return -ENOMEM;
447
448 get_dev_info(file->f_path.dentry->d_inode, &devi);
449
450 /*
451 * We need to make sure we can send a request. We use
452 * a semaphore to keep track of # requests in use. If
453 * we are non-blocking, make sure we don't block on the
454 * semaphore
455 */
456 if (noblock) {
457 if (down_trylock(&reqSem)) {
458 ret = -EWOULDBLOCK;
459 goto free_op;
460 }
461 } else
462 down(&reqSem);
463
464 chg_state(devi.devno, VIOT_READING, file);
465
466 /* Allocate a DMA buffer */
467 op->dev = tape_device[devi.devno];
468 op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr,
469 GFP_ATOMIC);
470 if (op->buffer == NULL) {
471 ret = -EFAULT;
472 goto up_sem;
473 }
474
475 op->count = count;
476 init_completion(&op->com);
477
478 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
479 HvLpEvent_Type_VirtualIo,
480 viomajorsubtype_tape | viotaperead,
481 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
482 viopath_sourceinst(viopath_hostLp),
483 viopath_targetinst(viopath_hostLp),
484 (u64)(unsigned long)op, VIOVERSION << 16,
485 ((u64)devi.devno << 48) | op->dmaaddr, count, 0, 0);
486 if (hvrc != HvLpEvent_Rc_Good) {
487 printk(VIOTAPE_KERN_WARN "tape hv error on op %d\n",
488 (int)hvrc);
489 ret = -EIO;
490 goto free_dma;
491 }
492
493 wait_for_completion(&op->com);
494
495 if (op->rc)
496 ret = tape_rc_to_errno(op->rc, "read", devi.devno);
497 else {
498 ret = op->count;
499 if (ret && copy_to_user(buf, op->buffer, ret)) {
500 printk(VIOTAPE_KERN_WARN "error on copy_to_user\n");
501 ret = -EFAULT;
502 }
503 }
504
505free_dma:
506 dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr);
507up_sem:
508 up(&reqSem);
509free_op:
510 free_op_struct(op);
511 return ret;
512}
513
514/* ioctl */
515static int viotap_ioctl(struct inode *inode, struct file *file,
516 unsigned int cmd, unsigned long arg)
517{
518 HvLpEvent_Rc hvrc;
519 int ret;
520 struct viot_devinfo_struct devi;
521 struct mtop mtc;
522 u32 myOp;
523 struct op_struct *op = get_op_struct();
524
525 if (op == NULL)
526 return -ENOMEM;
527
528 get_dev_info(file->f_path.dentry->d_inode, &devi);
529
530 down(&reqSem);
531
532 ret = -EINVAL;
533
534 switch (cmd) {
535 case MTIOCTOP:
536 ret = -EFAULT;
537 /*
538 * inode is null if and only if we (the kernel)
539 * made the request
540 */
541 if (inode == NULL)
542 memcpy(&mtc, (void *) arg, sizeof(struct mtop));
543 else if (copy_from_user((char *)&mtc, (char *)arg,
544 sizeof(struct mtop)))
545 goto free_op;
546
547 ret = -EIO;
548 switch (mtc.mt_op) {
549 case MTRESET:
550 myOp = VIOTAPOP_RESET;
551 break;
552 case MTFSF:
553 myOp = VIOTAPOP_FSF;
554 break;
555 case MTBSF:
556 myOp = VIOTAPOP_BSF;
557 break;
558 case MTFSR:
559 myOp = VIOTAPOP_FSR;
560 break;
561 case MTBSR:
562 myOp = VIOTAPOP_BSR;
563 break;
564 case MTWEOF:
565 myOp = VIOTAPOP_WEOF;
566 break;
567 case MTREW:
568 myOp = VIOTAPOP_REW;
569 break;
570 case MTNOP:
571 myOp = VIOTAPOP_NOP;
572 break;
573 case MTEOM:
574 myOp = VIOTAPOP_EOM;
575 break;
576 case MTERASE:
577 myOp = VIOTAPOP_ERASE;
578 break;
579 case MTSETBLK:
580 myOp = VIOTAPOP_SETBLK;
581 break;
582 case MTSETDENSITY:
583 myOp = VIOTAPOP_SETDENSITY;
584 break;
585 case MTTELL:
586 myOp = VIOTAPOP_GETPOS;
587 break;
588 case MTSEEK:
589 myOp = VIOTAPOP_SETPOS;
590 break;
591 case MTSETPART:
592 myOp = VIOTAPOP_SETPART;
593 break;
594 case MTOFFL:
595 myOp = VIOTAPOP_UNLOAD;
596 break;
597 default:
598 printk(VIOTAPE_KERN_WARN "MTIOCTOP called "
599 "with invalid op 0x%x\n", mtc.mt_op);
600 goto free_op;
601 }
602
603 /*
604 * if we moved the head, we are no longer
605 * reading or writing
606 */
607 switch (mtc.mt_op) {
608 case MTFSF:
609 case MTBSF:
610 case MTFSR:
611 case MTBSR:
612 case MTTELL:
613 case MTSEEK:
614 case MTREW:
615 chg_state(devi.devno, VIOT_IDLE, file);
616 }
617
618 init_completion(&op->com);
619 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
620 HvLpEvent_Type_VirtualIo,
621 viomajorsubtype_tape | viotapeop,
622 HvLpEvent_AckInd_DoAck,
623 HvLpEvent_AckType_ImmediateAck,
624 viopath_sourceinst(viopath_hostLp),
625 viopath_targetinst(viopath_hostLp),
626 (u64)(unsigned long)op,
627 VIOVERSION << 16,
628 ((u64)devi.devno << 48), 0,
629 (((u64)myOp) << 32) | mtc.mt_count, 0);
630 if (hvrc != HvLpEvent_Rc_Good) {
631 printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
632 (int)hvrc);
633 goto free_op;
634 }
635 wait_for_completion(&op->com);
636 ret = tape_rc_to_errno(op->rc, "tape operation", devi.devno);
637 goto free_op;
638
639 case MTIOCGET:
640 ret = -EIO;
641 init_completion(&op->com);
642 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
643 HvLpEvent_Type_VirtualIo,
644 viomajorsubtype_tape | viotapegetstatus,
645 HvLpEvent_AckInd_DoAck,
646 HvLpEvent_AckType_ImmediateAck,
647 viopath_sourceinst(viopath_hostLp),
648 viopath_targetinst(viopath_hostLp),
649 (u64)(unsigned long)op, VIOVERSION << 16,
650 ((u64)devi.devno << 48), 0, 0, 0);
651 if (hvrc != HvLpEvent_Rc_Good) {
652 printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
653 (int)hvrc);
654 goto free_op;
655 }
656 wait_for_completion(&op->com);
657
658 /* Operation is complete - grab the error code */
659 ret = tape_rc_to_errno(op->rc, "get status", devi.devno);
660 free_op_struct(op);
661 up(&reqSem);
662
663 if ((ret == 0) && copy_to_user((void *)arg,
664 &viomtget[devi.devno],
665 sizeof(viomtget[0])))
666 ret = -EFAULT;
667 return ret;
668 case MTIOCPOS:
669 printk(VIOTAPE_KERN_WARN "Got an (unsupported) MTIOCPOS\n");
670 break;
671 default:
672 printk(VIOTAPE_KERN_WARN "got an unsupported ioctl 0x%0x\n",
673 cmd);
674 break;
675 }
676
677free_op:
678 free_op_struct(op);
679 up(&reqSem);
680 return ret;
681}
682
683static long viotap_unlocked_ioctl(struct file *file,
684 unsigned int cmd, unsigned long arg)
685{
686 long rc;
687
688 mutex_lock(&proc_viotape_mutex);
689 rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
690 mutex_unlock(&proc_viotape_mutex);
691 return rc;
692}
693
694static int viotap_open(struct inode *inode, struct file *file)
695{
696 HvLpEvent_Rc hvrc;
697 struct viot_devinfo_struct devi;
698 int ret;
699 struct op_struct *op = get_op_struct();
700
701 if (op == NULL)
702 return -ENOMEM;
703
704 mutex_lock(&proc_viotape_mutex);
705 get_dev_info(file->f_path.dentry->d_inode, &devi);
706
707 /* Note: We currently only support one mode! */
708 if ((devi.devno >= viotape_numdev) || (devi.mode)) {
709 ret = -ENODEV;
710 goto free_op;
711 }
712
713 init_completion(&op->com);
714
715 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
716 HvLpEvent_Type_VirtualIo,
717 viomajorsubtype_tape | viotapeopen,
718 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
719 viopath_sourceinst(viopath_hostLp),
720 viopath_targetinst(viopath_hostLp),
721 (u64)(unsigned long)op, VIOVERSION << 16,
722 ((u64)devi.devno << 48), 0, 0, 0);
723 if (hvrc != 0) {
724 printk(VIOTAPE_KERN_WARN "bad rc on signalLpEvent %d\n",
725 (int) hvrc);
726 ret = -EIO;
727 goto free_op;
728 }
729
730 wait_for_completion(&op->com);
731 ret = tape_rc_to_errno(op->rc, "open", devi.devno);
732
733free_op:
734 free_op_struct(op);
735 mutex_unlock(&proc_viotape_mutex);
736 return ret;
737}
738
739
740static int viotap_release(struct inode *inode, struct file *file)
741{
742 HvLpEvent_Rc hvrc;
743 struct viot_devinfo_struct devi;
744 int ret = 0;
745 struct op_struct *op = get_op_struct();
746
747 if (op == NULL)
748 return -ENOMEM;
749 init_completion(&op->com);
750
751 get_dev_info(file->f_path.dentry->d_inode, &devi);
752
753 if (devi.devno >= viotape_numdev) {
754 ret = -ENODEV;
755 goto free_op;
756 }
757
758 chg_state(devi.devno, VIOT_IDLE, file);
759
760 if (devi.rewind) {
761 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
762 HvLpEvent_Type_VirtualIo,
763 viomajorsubtype_tape | viotapeop,
764 HvLpEvent_AckInd_DoAck,
765 HvLpEvent_AckType_ImmediateAck,
766 viopath_sourceinst(viopath_hostLp),
767 viopath_targetinst(viopath_hostLp),
768 (u64)(unsigned long)op, VIOVERSION << 16,
769 ((u64)devi.devno << 48), 0,
770 ((u64)VIOTAPOP_REW) << 32, 0);
771 wait_for_completion(&op->com);
772
773 tape_rc_to_errno(op->rc, "rewind", devi.devno);
774 }
775
776 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
777 HvLpEvent_Type_VirtualIo,
778 viomajorsubtype_tape | viotapeclose,
779 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
780 viopath_sourceinst(viopath_hostLp),
781 viopath_targetinst(viopath_hostLp),
782 (u64)(unsigned long)op, VIOVERSION << 16,
783 ((u64)devi.devno << 48), 0, 0, 0);
784 if (hvrc != 0) {
785 printk(VIOTAPE_KERN_WARN "bad rc on signalLpEvent %d\n",
786 (int) hvrc);
787 ret = -EIO;
788 goto free_op;
789 }
790
791 wait_for_completion(&op->com);
792
793 if (op->rc)
794 printk(VIOTAPE_KERN_WARN "close failed\n");
795
796free_op:
797 free_op_struct(op);
798 return ret;
799}
800
801const struct file_operations viotap_fops = {
802 .owner = THIS_MODULE,
803 .read = viotap_read,
804 .write = viotap_write,
805 .unlocked_ioctl = viotap_unlocked_ioctl,
806 .open = viotap_open,
807 .release = viotap_release,
808 .llseek = noop_llseek,
809};
810
811/* Handle interrupt events for tape */
812static void vioHandleTapeEvent(struct HvLpEvent *event)
813{
814 int tapeminor;
815 struct op_struct *op;
816 struct viotapelpevent *tevent = (struct viotapelpevent *)event;
817
818 if (event == NULL) {
819 /* Notification that a partition went away! */
820 if (!viopath_isactive(viopath_hostLp)) {
821 /* TODO! Clean up */
822 }
823 return;
824 }
825
826 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
827 op = (struct op_struct *)event->xCorrelationToken;
828 switch (tapeminor) {
829 case viotapeopen:
830 case viotapeclose:
831 op->rc = tevent->sub_type_result;
832 complete(&op->com);
833 break;
834 case viotaperead:
835 op->rc = tevent->sub_type_result;
836 op->count = tevent->len;
837 complete(&op->com);
838 break;
839 case viotapewrite:
840 if (op->non_blocking) {
841 dma_free_coherent(op->dev, op->count,
842 op->buffer, op->dmaaddr);
843 free_op_struct(op);
844 up(&reqSem);
845 } else {
846 op->rc = tevent->sub_type_result;
847 op->count = tevent->len;
848 complete(&op->com);
849 }
850 break;
851 case viotapeop:
852 case viotapegetpos:
853 case viotapesetpos:
854 case viotapegetstatus:
855 if (op) {
856 op->count = tevent->u.op.count;
857 op->rc = tevent->sub_type_result;
858 if (!op->non_blocking)
859 complete(&op->com);
860 }
861 break;
862 default:
863 printk(VIOTAPE_KERN_WARN "weird ack\n");
864 }
865}
866
867static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
868{
869 int i = vdev->unit_address;
870 int j;
871 struct device_node *node = vdev->dev.of_node;
872
873 if (i >= VIOTAPE_MAX_TAPE)
874 return -ENODEV;
875 if (!node)
876 return -ENODEV;
877
878 if (i >= viotape_numdev)
879 viotape_numdev = i + 1;
880
881 tape_device[i] = &vdev->dev;
882 viotape_unitinfo[i].rsrcname = of_get_property(node,
883 "linux,vio_rsrcname", NULL);
884 viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
885 NULL);
886 viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
887 NULL);
888
889 state[i].cur_part = 0;
890 for (j = 0; j < MAX_PARTITIONS; ++j)
891 state[i].part_stat_rwi[j] = VIOT_IDLE;
892 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
893 "iseries!vt%d", i);
894 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL,
895 "iseries!nvt%d", i);
896 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
897 "resource %10.10s type %4.4s, model %3.3s\n",
898 i, viotape_unitinfo[i].rsrcname,
899 viotape_unitinfo[i].type, viotape_unitinfo[i].model);
900 return 0;
901}
902
903static int viotape_remove(struct vio_dev *vdev)
904{
905 int i = vdev->unit_address;
906
907 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
908 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
909 return 0;
910}
911
912/**
913 * viotape_device_table: Used by vio.c to match devices that we
914 * support.
915 */
916static struct vio_device_id viotape_device_table[] __devinitdata = {
917 { "byte", "IBM,iSeries-viotape" },
918 { "", "" }
919};
920MODULE_DEVICE_TABLE(vio, viotape_device_table);
921
922static struct vio_driver viotape_driver = {
923 .id_table = viotape_device_table,
924 .probe = viotape_probe,
925 .remove = viotape_remove,
926 .driver = {
927 .name = "viotape",
928 .owner = THIS_MODULE,
929 }
930};
931
932
933int __init viotap_init(void)
934{
935 int ret;
936
937 if (!firmware_has_feature(FW_FEATURE_ISERIES))
938 return -ENODEV;
939
940 op_struct_list = NULL;
941 if ((ret = add_op_structs(VIOTAPE_MAXREQ)) < 0) {
942 printk(VIOTAPE_KERN_WARN "couldn't allocate op structs\n");
943 return ret;
944 }
945 spin_lock_init(&op_struct_list_lock);
946
947 sema_init(&reqSem, VIOTAPE_MAXREQ);
948
949 if (viopath_hostLp == HvLpIndexInvalid) {
950 vio_set_hostlp();
951 if (viopath_hostLp == HvLpIndexInvalid) {
952 ret = -ENODEV;
953 goto clear_op;
954 }
955 }
956
957 ret = viopath_open(viopath_hostLp, viomajorsubtype_tape,
958 VIOTAPE_MAXREQ + 2);
959 if (ret) {
960 printk(VIOTAPE_KERN_WARN
961 "error on viopath_open to hostlp %d\n", ret);
962 ret = -EIO;
963 goto clear_op;
964 }
965
966 printk(VIOTAPE_KERN_INFO "vers " VIOTAPE_VERSION
967 ", hosting partition %d\n", viopath_hostLp);
968
969 vio_setHandler(viomajorsubtype_tape, vioHandleTapeEvent);
970
971 ret = register_chrdev(VIOTAPE_MAJOR, "viotape", &viotap_fops);
972 if (ret < 0) {
973 printk(VIOTAPE_KERN_WARN "Error registering viotape device\n");
974 goto clear_handler;
975 }
976
977 tape_class = class_create(THIS_MODULE, "tape");
978 if (IS_ERR(tape_class)) {
979 printk(VIOTAPE_KERN_WARN "Unable to allocat class\n");
980 ret = PTR_ERR(tape_class);
981 goto unreg_chrdev;
982 }
983
984 ret = vio_register_driver(&viotape_driver);
985 if (ret)
986 goto unreg_class;
987
988 proc_create("iSeries/viotape", S_IFREG|S_IRUGO, NULL,
989 &proc_viotape_operations);
990
991 return 0;
992
993unreg_class:
994 class_destroy(tape_class);
995unreg_chrdev:
996 unregister_chrdev(VIOTAPE_MAJOR, "viotape");
997clear_handler:
998 vio_clearHandler(viomajorsubtype_tape);
999 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1000clear_op:
1001 clear_op_struct_pool();
1002 return ret;
1003}
1004
1005/* Give a new state to the tape object */
1006static int chg_state(int index, unsigned char new_state, struct file *file)
1007{
1008 unsigned char *cur_state =
1009 &state[index].part_stat_rwi[state[index].cur_part];
1010 int rc = 0;
1011
1012 /* if the same state, don't bother */
1013 if (*cur_state == new_state)
1014 return 0;
1015
1016 /* write an EOF if changing from writing to some other state */
1017 if (*cur_state == VIOT_WRITING) {
1018 struct mtop write_eof = { MTWEOF, 1 };
1019
1020 rc = viotap_ioctl(NULL, file, MTIOCTOP,
1021 (unsigned long)&write_eof);
1022 }
1023 *cur_state = new_state;
1024 return rc;
1025}
1026
1027/* Cleanup */
1028static void __exit viotap_exit(void)
1029{
1030 remove_proc_entry("iSeries/viotape", NULL);
1031 vio_unregister_driver(&viotape_driver);
1032 class_destroy(tape_class);
1033 unregister_chrdev(VIOTAPE_MAJOR, "viotape");
1034 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1035 vio_clearHandler(viomajorsubtype_tape);
1036 clear_op_struct_pool();
1037}
1038
1039MODULE_LICENSE("GPL");
1040module_init(viotap_init);
1041module_exit(viotap_exit);