aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
commit6be325719b3e54624397e413efd4b33a997e55a3 (patch)
tree57f321a56794cab2222e179b16731e0d76a4a68a /drivers/staging
parent26d92f9276a56d55511a427fb70bd70886af647a (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig6
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/staging/asus_oled/asus_oled.c12
-rw-r--r--drivers/staging/batman-adv/Kconfig1
-rw-r--r--drivers/staging/batman-adv/send.c4
-rw-r--r--drivers/staging/comedi/comedi.h2
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c7
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c5
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c33
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c4
-rw-r--r--drivers/staging/cx25821/cx25821-video.c6
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c33
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c33
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c34
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c34
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c34
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c34
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c34
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c34
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c32
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c33
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c33
-rw-r--r--drivers/staging/dst/Kconfig67
-rw-r--r--drivers/staging/dst/Makefile3
-rw-r--r--drivers/staging/dst/crypto.c733
-rw-r--r--drivers/staging/dst/dcore.c1004
-rw-r--r--drivers/staging/dst/export.c660
-rw-r--r--drivers/staging/dst/state.c844
-rw-r--r--drivers/staging/dst/thread_pool.c348
-rw-r--r--drivers/staging/dst/trans.c337
-rw-r--r--drivers/staging/et131x/et1310_address_map.h18
-rw-r--r--drivers/staging/et131x/et1310_rx.c6
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c5
-rw-r--r--drivers/staging/hv/Hv.c50
-rw-r--r--drivers/staging/hv/Hv.h6
-rw-r--r--drivers/staging/hv/Vmbus.c12
-rw-r--r--drivers/staging/iio/ring_sw.h1
-rw-r--r--drivers/staging/octeon/Kconfig3
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c204
-rw-r--r--drivers/staging/octeon/ethernet-mdio.h2
-rw-r--r--drivers/staging/octeon/ethernet-proc.c112
-rw-r--r--drivers/staging/octeon/ethernet-rgmii.c52
-rw-r--r--drivers/staging/octeon/ethernet-sgmii.c2
-rw-r--r--drivers/staging/octeon/ethernet-xaui.c2
-rw-r--r--drivers/staging/octeon/ethernet.c23
-rw-r--r--drivers/staging/octeon/octeon-ethernet.h6
-rw-r--r--drivers/staging/panel/Kconfig2
-rw-r--r--drivers/staging/panel/panel.c4
-rw-r--r--drivers/staging/pohmelfs/dir.c2
-rw-r--r--drivers/staging/ramzswap/TODO1
-rw-r--r--drivers/staging/ramzswap/ramzswap_drv.c28
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h10
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c14
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c2
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c10
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211.h12
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211.h12
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_module.c10
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c24
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192e/r8192E_core.c14
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211.h8
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c6
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c16
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c2
-rw-r--r--drivers/staging/rtl8192su/r8192U_core.c10
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/sm7xx/Kconfig15
-rw-r--r--drivers/staging/sm7xx/Makefile3
-rw-r--r--drivers/staging/sm7xx/TODO10
-rw-r--r--drivers/staging/sm7xx/smtc2d.c979
-rw-r--r--drivers/staging/sm7xx/smtc2d.h530
-rw-r--r--drivers/staging/sm7xx/smtcfb.c1253
-rw-r--r--drivers/staging/sm7xx/smtcfb.h793
-rw-r--r--drivers/staging/vt6655/Kconfig2
-rw-r--r--drivers/staging/vt6656/Kconfig2
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c2
83 files changed, 3991 insertions, 4759 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 54e174d28234..94eb86319ff3 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -87,8 +87,6 @@ source "drivers/staging/frontier/Kconfig"
87 87
88source "drivers/staging/dream/Kconfig" 88source "drivers/staging/dream/Kconfig"
89 89
90source "drivers/staging/dst/Kconfig"
91
92source "drivers/staging/pohmelfs/Kconfig" 90source "drivers/staging/pohmelfs/Kconfig"
93 91
94source "drivers/staging/b3dfg/Kconfig" 92source "drivers/staging/b3dfg/Kconfig"
@@ -99,6 +97,8 @@ source "drivers/staging/p9auth/Kconfig"
99 97
100source "drivers/staging/line6/Kconfig" 98source "drivers/staging/line6/Kconfig"
101 99
100source "drivers/gpu/drm/vmwgfx/Kconfig"
101
102source "drivers/gpu/drm/radeon/Kconfig" 102source "drivers/gpu/drm/radeon/Kconfig"
103 103
104source "drivers/gpu/drm/nouveau/Kconfig" 104source "drivers/gpu/drm/nouveau/Kconfig"
@@ -143,5 +143,7 @@ source "drivers/staging/wavelan/Kconfig"
143 143
144source "drivers/staging/netwave/Kconfig" 144source "drivers/staging/netwave/Kconfig"
145 145
146source "drivers/staging/sm7xx/Kconfig"
147
146endif # !STAGING_EXCLUDE_BUILD 148endif # !STAGING_EXCLUDE_BUILD
147endif # STAGING 149endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 069864f4391e..b5e67b889f60 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/
26obj-$(CONFIG_INPUT_MIMIO) += mimio/ 26obj-$(CONFIG_INPUT_MIMIO) += mimio/
27obj-$(CONFIG_TRANZPORT) += frontier/ 27obj-$(CONFIG_TRANZPORT) += frontier/
28obj-$(CONFIG_DREAM) += dream/ 28obj-$(CONFIG_DREAM) += dream/
29obj-$(CONFIG_DST) += dst/
30obj-$(CONFIG_POHMELFS) += pohmelfs/ 29obj-$(CONFIG_POHMELFS) += pohmelfs/
31obj-$(CONFIG_B3DFG) += b3dfg/ 30obj-$(CONFIG_B3DFG) += b3dfg/
32obj-$(CONFIG_IDE_PHISON) += phison/ 31obj-$(CONFIG_IDE_PHISON) += phison/
@@ -53,3 +52,4 @@ obj-$(CONFIG_ARLAN) += arlan/
53obj-$(CONFIG_WAVELAN) += wavelan/ 52obj-$(CONFIG_WAVELAN) += wavelan/
54obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ 53obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
55obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ 54obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
55obj-$(CONFIG_FB_SM7XX) += sm7xx/
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index f4c26572c7df..43c57b7688ab 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -194,9 +194,11 @@ static ssize_t set_enabled(struct device *dev, struct device_attribute *attr,
194{ 194{
195 struct usb_interface *intf = to_usb_interface(dev); 195 struct usb_interface *intf = to_usb_interface(dev);
196 struct asus_oled_dev *odev = usb_get_intfdata(intf); 196 struct asus_oled_dev *odev = usb_get_intfdata(intf);
197 int temp = strict_strtoul(buf, 10, NULL); 197 unsigned long value;
198 if (strict_strtoul(buf, 10, &value))
199 return -EINVAL;
198 200
199 enable_oled(odev, temp); 201 enable_oled(odev, value);
200 202
201 return count; 203 return count;
202} 204}
@@ -207,10 +209,12 @@ static ssize_t class_set_enabled(struct device *device,
207{ 209{
208 struct asus_oled_dev *odev = 210 struct asus_oled_dev *odev =
209 (struct asus_oled_dev *) dev_get_drvdata(device); 211 (struct asus_oled_dev *) dev_get_drvdata(device);
212 unsigned long value;
210 213
211 int temp = strict_strtoul(buf, 10, NULL); 214 if (strict_strtoul(buf, 10, &value))
215 return -EINVAL;
212 216
213 enable_oled(odev, temp); 217 enable_oled(odev, value);
214 218
215 return count; 219 return count;
216} 220}
diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig
index 7632f5760060..1d74dabf9511 100644
--- a/drivers/staging/batman-adv/Kconfig
+++ b/drivers/staging/batman-adv/Kconfig
@@ -4,6 +4,7 @@
4 4
5config BATMAN_ADV 5config BATMAN_ADV
6 tristate "B.A.T.M.A.N. Advanced Meshing Protocol" 6 tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
7 depends on PROC_FS && PACKET
7 default n 8 default n
8 ---help--- 9 ---help---
9 10
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index d724798278d6..eb617508cca4 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -363,8 +363,10 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
363 return; 363 return;
364 364
365 forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); 365 forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC);
366 if (!forw_packet->packet_buff) 366 if (!forw_packet->packet_buff) {
367 kfree(forw_packet);
367 return; 368 return;
369 }
368 370
369 forw_packet->packet_len = packet_len; 371 forw_packet->packet_len = packet_len;
370 memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); 372 memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len);
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index ccc5cdc008c6..b559a9c2f857 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -451,7 +451,7 @@
451 451
452#define COMEDI_CB_EOS 1 /* end of scan */ 452#define COMEDI_CB_EOS 1 /* end of scan */
453#define COMEDI_CB_EOA 2 /* end of acquisition */ 453#define COMEDI_CB_EOA 2 /* end of acquisition */
454#define COMEDI_CB_BLOCK 4 /* DEPRECATED: convenient block size */ 454#define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */
455#define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ 455#define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */
456#define COMEDI_CB_ERROR 16 /* card error during acquisition */ 456#define COMEDI_CB_ERROR 16 /* card error during acquisition */
457#define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ 457#define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 0d2c2eb23b23..bd397840dcba 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -849,8 +849,11 @@ static int jr3_pci_attach(struct comedi_device *dev,
849 } 849 }
850 850
851 devpriv->pci_enabled = 1; 851 devpriv->pci_enabled = 1;
852 devpriv->iobase = 852 devpriv->iobase = ioremap(pci_resource_start(card, 0),
853 ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t)); 853 offsetof(struct jr3_t, channel[devpriv->n_channels]));
854 if (!devpriv->iobase)
855 return -ENOMEM;
856
854 result = alloc_subdevices(dev, devpriv->n_channels); 857 result = alloc_subdevices(dev, devpriv->n_channels);
855 if (result < 0) 858 if (result < 0)
856 goto out; 859 goto out;
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 06c020466298..9a1b559c4b0d 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1,4 +1,4 @@
1#define DRIVER_VERSION "v2.3" 1#define DRIVER_VERSION "v2.4"
2#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" 2#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
3#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" 3#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
4/* 4/*
@@ -81,6 +81,8 @@ sampling rate. If you sample two channels you get 4kHz and so on.
81 * 2.1: changed PWM API 81 * 2.1: changed PWM API
82 * 2.2: added firmware kernel request to fix an udev problem 82 * 2.2: added firmware kernel request to fix an udev problem
83 * 2.3: corrected a bug in bulk timeouts which were far too short 83 * 2.3: corrected a bug in bulk timeouts which were far too short
84 * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
85 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
84 * 86 *
85 */ 87 */
86 88
@@ -532,6 +534,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
532 } 534 }
533 } 535 }
534 /* tell comedi that data is there */ 536 /* tell comedi that data is there */
537 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
535 comedi_event(this_usbduxsub->comedidev, s); 538 comedi_event(this_usbduxsub->comedidev, s);
536} 539}
537 540
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
index f78b8912d905..89c8fe2997fa 100644
--- a/drivers/staging/cx25821/cx25821-audups11.c
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 101
103 lock_kernel(); 102 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
104 list_for_each(list, &cx25821_devlist) { 103 v4l2_type_names[type]);
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH11]
108 && h->video_dev[SRAM_CH11]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120 104
121 /* allocate + initialize per filehandle data */ 105 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 106 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) { 107 if (NULL == fh)
124 unlock_kernel();
125 return -ENOMEM; 108 return -ENOMEM;
126 } 109
110 lock_kernel();
127 111
128 file->private_data = fh; 112 file->private_data = fh;
129 fh->dev = dev; 113 fh->dev = dev;
@@ -427,7 +411,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
427struct video_device cx25821_video_template11 = { 411struct video_device cx25821_video_template11 = {
428 .name = "cx25821-audioupstream", 412 .name = "cx25821-audioupstream",
429 .fops = &video_fops, 413 .fops = &video_fops,
430 .minor = -1,
431 .ioctl_ops = &video_ioctl_ops, 414 .ioctl_ops = &video_ioctl_ops,
432 .tvnorms = CX25821_NORMS, 415 .tvnorms = CX25821_NORMS,
433 .current_norm = V4L2_STD_NTSC_M, 416 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index e4df8134f059..1eb079b3d429 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -860,10 +860,8 @@ int medusa_video_init(struct cx25821_dev *dev)
860 860
861 ret_val = medusa_set_videostandard(dev); 861 ret_val = medusa_set_videostandard(dev);
862 862
863 if (ret_val < 0) { 863 if (ret_val < 0)
864 mutex_unlock(&dev->lock);
865 return -EINVAL; 864 return -EINVAL;
866 }
867 865
868 return 1; 866 return 1;
869} 867}
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 8834bc80a5ab..c7c14c7698a7 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -184,11 +184,11 @@ struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
184 if (NULL == vfd) 184 if (NULL == vfd)
185 return NULL; 185 return NULL;
186 *vfd = *template; 186 *vfd = *template;
187 vfd->minor = -1;
188 vfd->v4l2_dev = &dev->v4l2_dev; 187 vfd->v4l2_dev = &dev->v4l2_dev;
189 vfd->release = video_device_release; 188 vfd->release = video_device_release;
190 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, 189 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
191 cx25821_boards[dev->board].name); 190 cx25821_boards[dev->board].name);
191 video_set_drvdata(vfd, dev);
192 return vfd; 192 return vfd;
193} 193}
194 194
@@ -424,7 +424,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
424void cx25821_videoioctl_unregister(struct cx25821_dev *dev) 424void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
425{ 425{
426 if (dev->ioctl_dev) { 426 if (dev->ioctl_dev) {
427 if (dev->ioctl_dev->minor != -1) 427 if (video_is_registered(dev->ioctl_dev))
428 video_unregister_device(dev->ioctl_dev); 428 video_unregister_device(dev->ioctl_dev);
429 else 429 else
430 video_device_release(dev->ioctl_dev); 430 video_device_release(dev->ioctl_dev);
@@ -438,7 +438,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
438 cx_clear(PCI_INT_MSK, 1); 438 cx_clear(PCI_INT_MSK, 1);
439 439
440 if (dev->video_dev[chan_num]) { 440 if (dev->video_dev[chan_num]) {
441 if (-1 != dev->video_dev[chan_num]->minor) 441 if (video_is_registered(dev->video_dev[chan_num]))
442 video_unregister_device(dev->video_dev[chan_num]); 442 video_unregister_device(dev->video_dev[chan_num]);
443 else 443 else
444 video_device_release(dev->video_dev[chan_num]); 444 video_device_release(dev->video_dev[chan_num]);
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
index 950fac1d7003..ad7a69129118 100644
--- a/drivers/staging/cx25821/cx25821-video0.c
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -94,37 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH00]
109 && h->video_dev[SRAM_CH00]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
128 112
129 file->private_data = fh; 113 file->private_data = fh;
130 fh->dev = dev; 114 fh->dev = dev;
@@ -444,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
444struct video_device cx25821_video_template0 = { 428struct video_device cx25821_video_template0 = {
445 .name = "cx25821-video", 429 .name = "cx25821-video",
446 .fops = &video_fops, 430 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops, 431 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS, 432 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M, 433 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
index a4dddc684adf..e3f3c4ac7908 100644
--- a/drivers/staging/cx25821/cx25821-video1.c
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -94,37 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH01]
109 && h->video_dev[SRAM_CH01]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
128 112
129 file->private_data = fh; 113 file->private_data = fh;
130 fh->dev = dev; 114 fh->dev = dev;
@@ -444,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
444struct video_device cx25821_video_template1 = { 428struct video_device cx25821_video_template1 = {
445 .name = "cx25821-video", 429 .name = "cx25821-video",
446 .fops = &video_fops, 430 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops, 431 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS, 432 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M, 433 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
index 8e04e253f5d9..36fb855a497e 100644
--- a/drivers/staging/cx25821/cx25821-video2.c
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH02]
109 && h->video_dev[SRAM_CH02]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
130 fh->type = type; 115 fh->type = type;
@@ -445,7 +430,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
445struct video_device cx25821_video_template2 = { 430struct video_device cx25821_video_template2 = {
446 .name = "cx25821-video", 431 .name = "cx25821-video",
447 .fops = &video_fops, 432 .fops = &video_fops,
448 .minor = -1,
449 .ioctl_ops = &video_ioctl_ops, 433 .ioctl_ops = &video_ioctl_ops,
450 .tvnorms = CX25821_NORMS, 434 .tvnorms = CX25821_NORMS,
451 .current_norm = V4L2_STD_NTSC_M, 435 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
index 8801a8ead904..1e0f10abdbcd 100644
--- a/drivers/staging/cx25821/cx25821-video3.c
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH03]
109 && h->video_dev[SRAM_CH03]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
130 fh->type = type; 115 fh->type = type;
@@ -444,7 +429,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
444struct video_device cx25821_video_template3 = { 429struct video_device cx25821_video_template3 = {
445 .name = "cx25821-video", 430 .name = "cx25821-video",
446 .fops = &video_fops, 431 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops, 432 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS, 433 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M, 434 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
index ab0d747138ad..0cbe7a79d8c0 100644
--- a/drivers/staging/cx25821/cx25821-video4.c
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH04]
109 && h->video_dev[SRAM_CH04]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
130 fh->type = type; 115 fh->type = type;
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
443struct video_device cx25821_video_template4 = { 428struct video_device cx25821_video_template4 = {
444 .name = "cx25821-video", 429 .name = "cx25821-video",
445 .fops = &video_fops, 430 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops, 431 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS, 432 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M, 433 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
index 7ef0b971f5cf..5dc08adc12e8 100644
--- a/drivers/staging/cx25821/cx25821-video5.c
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH05]
109 && h->video_dev[SRAM_CH05]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
130 fh->type = type; 115 fh->type = type;
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
443struct video_device cx25821_video_template5 = { 428struct video_device cx25821_video_template5 = {
444 .name = "cx25821-video", 429 .name = "cx25821-video",
445 .fops = &video_fops, 430 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops, 431 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS, 432 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M, 433 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
index 3c41b49e2ea9..2938ad3ad3c5 100644
--- a/drivers/staging/cx25821/cx25821-video6.c
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH06]
109 && h->video_dev[SRAM_CH06]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121 105
122 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) { 108 if (NULL == fh)
125 unlock_kernel();
126 return -ENOMEM; 109 return -ENOMEM;
127 } 110
111 lock_kernel();
112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
130 fh->type = type; 115 fh->type = type;
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
443struct video_device cx25821_video_template6 = { 428struct video_device cx25821_video_template6 = {
444 .name = "cx25821-video", 429 .name = "cx25821-video",
445 .fops = &video_fops, 430 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops, 431 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS, 432 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M, 433 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
index 625c9b78a9cf..458e525d72af 100644
--- a/drivers/staging/cx25821/cx25821-video7.c
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -93,37 +93,22 @@ static struct videobuf_queue_ops cx25821_video_qops = {
93 93
94static int video_open(struct file *file) 94static int video_open(struct file *file)
95{ 95{
96 int minor = video_devdata(file)->minor; 96 struct video_device *vdev = video_devdata(file);
97 struct cx25821_dev *h, *dev = NULL; 97 struct cx25821_dev *dev = video_drvdata(file);
98 struct cx25821_fh *fh; 98 struct cx25821_fh *fh;
99 struct list_head *list; 99 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
100 enum v4l2_buf_type type = 0;
101 u32 pix_format; 100 u32 pix_format;
102 101
103 lock_kernel(); 102 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
104 list_for_each(list, &cx25821_devlist) { 103 v4l2_type_names[type]);
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH07]
108 && h->video_dev[SRAM_CH07]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120 104
121 /* allocate + initialize per filehandle data */ 105 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 106 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) { 107 if (NULL == fh)
124 unlock_kernel();
125 return -ENOMEM; 108 return -ENOMEM;
126 } 109
110 lock_kernel();
111
127 file->private_data = fh; 112 file->private_data = fh;
128 fh->dev = dev; 113 fh->dev = dev;
129 fh->type = type; 114 fh->type = type;
@@ -442,7 +427,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
442struct video_device cx25821_video_template7 = { 427struct video_device cx25821_video_template7 = {
443 .name = "cx25821-video", 428 .name = "cx25821-video",
444 .fops = &video_fops, 429 .fops = &video_fops,
445 .minor = -1,
446 .ioctl_ops = &video_ioctl_ops, 430 .ioctl_ops = &video_ioctl_ops,
447 .tvnorms = CX25821_NORMS, 431 .tvnorms = CX25821_NORMS,
448 .current_norm = V4L2_STD_NTSC_M, 432 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
index 2a312ce78c63..1da52b54a454 100644
--- a/drivers/staging/cx25821/cx25821-videoioctl.c
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -94,36 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format; 101 u32 pix_format;
103 102
104 lock_kernel(); 103 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
105 list_for_each(list, &cx25821_devlist) { 104 v4l2_type_names[type]);
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->ioctl_dev && h->ioctl_dev->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120 105
121 /* allocate + initialize per filehandle data */ 106 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 107 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) { 108 if (NULL == fh)
124 unlock_kernel();
125 return -ENOMEM; 109 return -ENOMEM;
126 } 110
111 lock_kernel();
127 112
128 file->private_data = fh; 113 file->private_data = fh;
129 fh->dev = dev; 114 fh->dev = dev;
@@ -489,7 +474,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
489struct video_device cx25821_videoioctl_template = { 474struct video_device cx25821_videoioctl_template = {
490 .name = "cx25821-videoioctl", 475 .name = "cx25821-videoioctl",
491 .fops = &video_fops, 476 .fops = &video_fops,
492 .minor = -1,
493 .ioctl_ops = &video_ioctl_ops, 477 .ioctl_ops = &video_ioctl_ops,
494 .tvnorms = CX25821_NORMS, 478 .tvnorms = CX25821_NORMS,
495 .current_norm = V4L2_STD_NTSC_M, 479 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
index 77b63b060405..b76d9f62c3d1 100644
--- a/drivers/staging/cx25821/cx25821-vidups10.c
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 101
103 lock_kernel(); 102 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
104 list_for_each(list, &cx25821_devlist) { 103 v4l2_type_names[type]);
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH10]
108 && h->video_dev[SRAM_CH10]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120 104
121 /* allocate + initialize per filehandle data */ 105 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 106 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) { 107 if (NULL == fh)
124 unlock_kernel();
125 return -ENOMEM; 108 return -ENOMEM;
126 } 109
110 lock_kernel();
127 111
128 file->private_data = fh; 112 file->private_data = fh;
129 fh->dev = dev; 113 fh->dev = dev;
@@ -428,7 +412,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
428struct video_device cx25821_video_template10 = { 412struct video_device cx25821_video_template10 = {
429 .name = "cx25821-upstream10", 413 .name = "cx25821-upstream10",
430 .fops = &video_fops, 414 .fops = &video_fops,
431 .minor = -1,
432 .ioctl_ops = &video_ioctl_ops, 415 .ioctl_ops = &video_ioctl_ops,
433 .tvnorms = CX25821_NORMS, 416 .tvnorms = CX25821_NORMS,
434 .current_norm = V4L2_STD_NTSC_M, 417 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
index 75c8c1eed2da..1580da3b29aa 100644
--- a/drivers/staging/cx25821/cx25821-vidups9.c
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = {
94 94
95static int video_open(struct file *file) 95static int video_open(struct file *file)
96{ 96{
97 int minor = video_devdata(file)->minor; 97 struct video_device *vdev = video_devdata(file);
98 struct cx25821_dev *h, *dev = NULL; 98 struct cx25821_dev *dev = video_drvdata(file);
99 struct cx25821_fh *fh; 99 struct cx25821_fh *fh;
100 struct list_head *list; 100 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
101 enum v4l2_buf_type type = 0;
102 101
103 lock_kernel(); 102 printk("open dev=%s type=%s\n", video_device_node_name(vdev),
104 list_for_each(list, &cx25821_devlist) { 103 v4l2_type_names[type]);
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH09]
108 && h->video_dev[SRAM_CH09]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120 104
121 /* allocate + initialize per filehandle data */ 105 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 106 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) { 107 if (NULL == fh)
124 unlock_kernel();
125 return -ENOMEM; 108 return -ENOMEM;
126 } 109
110 lock_kernel();
127 111
128 file->private_data = fh; 112 file->private_data = fh;
129 fh->dev = dev; 113 fh->dev = dev;
@@ -426,7 +410,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
426struct video_device cx25821_video_template9 = { 410struct video_device cx25821_video_template9 = {
427 .name = "cx25821-upstream9", 411 .name = "cx25821-upstream9",
428 .fops = &video_fops, 412 .fops = &video_fops,
429 .minor = -1,
430 .ioctl_ops = &video_ioctl_ops, 413 .ioctl_ops = &video_ioctl_ops,
431 .tvnorms = CX25821_NORMS, 414 .tvnorms = CX25821_NORMS,
432 .current_norm = V4L2_STD_NTSC_M, 415 .current_norm = V4L2_STD_NTSC_M,
diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig
deleted file mode 100644
index 448d342ac2a2..000000000000
--- a/drivers/staging/dst/Kconfig
+++ /dev/null
@@ -1,67 +0,0 @@
1config DST
2 tristate "Distributed storage"
3 depends on NET && CRYPTO && SYSFS && BLK_DEV
4 select CONNECTOR
5 ---help---
6 DST is a network block device storage, which can be used to organize
7 exported storage on the remote nodes into the local block device.
8
9 DST works on top of any network media and protocol; it is just a matter
10 of configuration utility to understand the correct addresses. The most
11 common example is TCP over IP, which allows to pass through firewalls and
12 create remote backup storage in a different datacenter. DST requires
13 single port to be enabled on the exporting node and outgoing connections
14 on the local node.
15
16 DST works with in-kernel client and server, which improves performance by
17 eliminating unneded data copies and by not depending on the version
18 of the external IO components. It requires userspace configuration utility
19 though.
20
21 DST uses transaction model, when each store has to be explicitly acked
22 from the remote node to be considered as successfully written. There
23 may be lots of in-flight transactions. When remote host does not ack
24 the transaction it will be resent predefined number of times with specified
25 timeouts between them. All those parameters are configurable. Transactions
26 are marked as failed after all resends complete unsuccessfully; having
27 long enough resend timeout and/or large number of resends allows not to
28 return error to the higher (FS usually) layer in case of short network
29 problems or remote node outages. In case of network RAID setup this means
30 that storage will not degrade until transactions are marked as failed, and
31 thus will not force checksum recalculation and data rebuild. In case of
32 connection failure DST will try to reconnect to the remote node automatically.
33 DST sends ping commands at idle time to detect if remote node is alive.
34
35 Because of transactional model it is possible to use zero-copy sending
36 without worry of data corruption (which in turn could be detected by the
37 strong checksums though).
38
39 DST may fully encrypt the data channel in case of untrusted channel and implement
40 strong checksum of the transferred data. It is possible to configure algorithms
41 and crypto keys; they should match on both sides of the network channel.
42 Crypto processing does not introduce noticeble performance overhead, since DST
43 uses configurable pool of threads to perform crypto processing.
44
45 DST utilizes memory pool model of all its transaction allocations (it is the
46 only additional allocation on the client) and server allocations (bio pools,
47 while pages are allocated from the slab).
48
49 At startup DST performs a simple negotiation with the export node to determine
50 access permissions and size of the exported storage. It can be extended if
51 new parameters should be autonegotiated.
52
53 DST carries block IO flags in the protocol, which allows to transparently implement
54 barriers and sync/flush operations. Those flags are used in the export node where
55 IO against the local storage is performed, which means that sync write will be sync
56 on the remote node too, which in turn improves data integrity and improved resistance
57 to errors and data corruption during power outages or storage damages.
58
59 Homepage: http://www.ioremap.net/projects/dst
60 Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/
61
62config DST_DEBUG
63 bool "DST debug"
64 depends on DST
65 ---help---
66 This option will enable HEAVY debugging of the DST.
67 Turn it on ONLY if you have to debug some really obscure problem.
diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile
deleted file mode 100644
index 3a8b0cf9643e..000000000000
--- a/drivers/staging/dst/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1obj-$(CONFIG_DST) += nst.o
2
3nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c
deleted file mode 100644
index 351295c97a4b..000000000000
--- a/drivers/staging/dst/crypto.c
+++ /dev/null
@@ -1,733 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/bio.h>
17#include <linux/crypto.h>
18#include <linux/dst.h>
19#include <linux/kernel.h>
20#include <linux/scatterlist.h>
21#include <linux/slab.h>
22
23/*
24 * Tricky bastard, but IV can be more complex with time...
25 */
26static inline u64 dst_gen_iv(struct dst_trans *t)
27{
28 return t->gen;
29}
30
31/*
32 * Crypto machinery: hash/cipher support for the given crypto controls.
33 */
34static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key)
35{
36 int err;
37 struct crypto_hash *hash;
38
39 hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC);
40 if (IS_ERR(hash)) {
41 err = PTR_ERR(hash);
42 dprintk("%s: failed to allocate hash '%s', err: %d.\n",
43 __func__, ctl->hash_algo, err);
44 goto err_out_exit;
45 }
46
47 ctl->crypto_attached_size = crypto_hash_digestsize(hash);
48
49 if (!ctl->hash_keysize)
50 return hash;
51
52 err = crypto_hash_setkey(hash, key, ctl->hash_keysize);
53 if (err) {
54 dprintk("%s: failed to set key for hash '%s', err: %d.\n",
55 __func__, ctl->hash_algo, err);
56 goto err_out_free;
57 }
58
59 return hash;
60
61err_out_free:
62 crypto_free_hash(hash);
63err_out_exit:
64 return ERR_PTR(err);
65}
66
67static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl,
68 u8 *key)
69{
70 int err = -EINVAL;
71 struct crypto_ablkcipher *cipher;
72
73 if (!ctl->cipher_keysize)
74 goto err_out_exit;
75
76 cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0);
77 if (IS_ERR(cipher)) {
78 err = PTR_ERR(cipher);
79 dprintk("%s: failed to allocate cipher '%s', err: %d.\n",
80 __func__, ctl->cipher_algo, err);
81 goto err_out_exit;
82 }
83
84 crypto_ablkcipher_clear_flags(cipher, ~0);
85
86 err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize);
87 if (err) {
88 dprintk("%s: failed to set key for cipher '%s', err: %d.\n",
89 __func__, ctl->cipher_algo, err);
90 goto err_out_free;
91 }
92
93 return cipher;
94
95err_out_free:
96 crypto_free_ablkcipher(cipher);
97err_out_exit:
98 return ERR_PTR(err);
99}
100
101/*
102 * Crypto engine has a pool of pages to encrypt data into before sending
103 * it over the network. This pool is freed/allocated here.
104 */
105static void dst_crypto_pages_free(struct dst_crypto_engine *e)
106{
107 unsigned int i;
108
109 for (i = 0; i < e->page_num; ++i)
110 __free_page(e->pages[i]);
111 kfree(e->pages);
112}
113
114static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num)
115{
116 int i;
117
118 e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL);
119 if (!e->pages)
120 return -ENOMEM;
121
122 for (i = 0; i < num; ++i) {
123 e->pages[i] = alloc_page(GFP_KERNEL);
124 if (!e->pages[i])
125 goto err_out_free_pages;
126 }
127
128 e->page_num = num;
129 return 0;
130
131err_out_free_pages:
132 while (--i >= 0)
133 __free_page(e->pages[i]);
134
135 kfree(e->pages);
136 return -ENOMEM;
137}
138
139/*
140 * Initialize crypto engine for given node.
141 * Setup cipher/hash, keys, pool of threads and private data.
142 */
143static int dst_crypto_engine_init(struct dst_crypto_engine *e,
144 struct dst_node *n)
145{
146 int err;
147 struct dst_crypto_ctl *ctl = &n->crypto;
148
149 err = dst_crypto_pages_alloc(e, n->max_pages);
150 if (err)
151 goto err_out_exit;
152
153 e->size = PAGE_SIZE;
154 e->data = kmalloc(e->size, GFP_KERNEL);
155 if (!e->data) {
156 err = -ENOMEM;
157 goto err_out_free_pages;
158 }
159
160 if (ctl->hash_algo[0]) {
161 e->hash = dst_init_hash(ctl, n->hash_key);
162 if (IS_ERR(e->hash)) {
163 err = PTR_ERR(e->hash);
164 e->hash = NULL;
165 goto err_out_free;
166 }
167 }
168
169 if (ctl->cipher_algo[0]) {
170 e->cipher = dst_init_cipher(ctl, n->cipher_key);
171 if (IS_ERR(e->cipher)) {
172 err = PTR_ERR(e->cipher);
173 e->cipher = NULL;
174 goto err_out_free_hash;
175 }
176 }
177
178 return 0;
179
180err_out_free_hash:
181 crypto_free_hash(e->hash);
182err_out_free:
183 kfree(e->data);
184err_out_free_pages:
185 dst_crypto_pages_free(e);
186err_out_exit:
187 return err;
188}
189
190static void dst_crypto_engine_exit(struct dst_crypto_engine *e)
191{
192 if (e->hash)
193 crypto_free_hash(e->hash);
194 if (e->cipher)
195 crypto_free_ablkcipher(e->cipher);
196 dst_crypto_pages_free(e);
197 kfree(e->data);
198}
199
200/*
201 * Waiting for cipher processing to be completed.
202 */
203struct dst_crypto_completion {
204 struct completion complete;
205 int error;
206};
207
208static void dst_crypto_complete(struct crypto_async_request *req, int err)
209{
210 struct dst_crypto_completion *c = req->data;
211
212 if (err == -EINPROGRESS)
213 return;
214
215 dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
216 c->error = err;
217 complete(&c->complete);
218}
219
220static int dst_crypto_process(struct ablkcipher_request *req,
221 struct scatterlist *sg_dst, struct scatterlist *sg_src,
222 void *iv, int enc, unsigned long timeout)
223{
224 struct dst_crypto_completion c;
225 int err;
226
227 init_completion(&c.complete);
228 c.error = -EINPROGRESS;
229
230 ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
231 dst_crypto_complete, &c);
232
233 ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
234
235 if (enc)
236 err = crypto_ablkcipher_encrypt(req);
237 else
238 err = crypto_ablkcipher_decrypt(req);
239
240 switch (err) {
241 case -EINPROGRESS:
242 case -EBUSY:
243 err = wait_for_completion_interruptible_timeout(&c.complete,
244 timeout);
245 if (!err)
246 err = -ETIMEDOUT;
247 else
248 err = c.error;
249 break;
250 default:
251 break;
252 }
253
254 return err;
255}
256
257/*
258 * DST uses generic iteration approach for data crypto processing.
259 * Single block IO request is switched into array of scatterlists,
260 * which are submitted to the crypto processing iterator.
261 *
262 * Input and output iterator initialization are different, since
263 * in output case we can not encrypt data in-place and need a
264 * temporary storage, which is then being sent to the remote peer.
265 */
266static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e,
267 int (*iterator) (struct dst_crypto_engine *e,
268 struct scatterlist *dst,
269 struct scatterlist *src))
270{
271 struct bio_vec *bv;
272 int err, i;
273
274 sg_init_table(e->src, bio->bi_vcnt);
275 sg_init_table(e->dst, bio->bi_vcnt);
276
277 bio_for_each_segment(bv, bio, i) {
278 sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
279 sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset);
280
281 err = iterator(e, &e->dst[i], &e->src[i]);
282 if (err)
283 return err;
284 }
285
286 return 0;
287}
288
289static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e,
290 int (*iterator) (struct dst_crypto_engine *e,
291 struct scatterlist *dst,
292 struct scatterlist *src))
293{
294 struct bio_vec *bv;
295 int err, i;
296
297 sg_init_table(e->src, bio->bi_vcnt);
298 sg_init_table(e->dst, bio->bi_vcnt);
299
300 bio_for_each_segment(bv, bio, i) {
301 sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
302 sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset);
303
304 err = iterator(e, &e->dst[i], &e->src[i]);
305 if (err)
306 return err;
307 }
308
309 return 0;
310}
311
312static int dst_crypt_iterator(struct dst_crypto_engine *e,
313 struct scatterlist *sg_dst, struct scatterlist *sg_src)
314{
315 struct ablkcipher_request *req = e->data;
316 u8 iv[32];
317
318 memset(iv, 0, sizeof(iv));
319
320 memcpy(iv, &e->iv, sizeof(e->iv));
321
322 return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout);
323}
324
325static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio)
326{
327 struct ablkcipher_request *req = e->data;
328
329 memset(req, 0, sizeof(struct ablkcipher_request));
330 ablkcipher_request_set_tfm(req, e->cipher);
331
332 if (e->enc)
333 return dst_trans_iter_out(bio, e, dst_crypt_iterator);
334 else
335 return dst_trans_iter_in(bio, e, dst_crypt_iterator);
336}
337
338static int dst_hash_iterator(struct dst_crypto_engine *e,
339 struct scatterlist *sg_dst, struct scatterlist *sg_src)
340{
341 return crypto_hash_update(e->data, sg_src, sg_src->length);
342}
343
344static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst)
345{
346 struct hash_desc *desc = e->data;
347 int err;
348
349 desc->tfm = e->hash;
350 desc->flags = 0;
351
352 err = crypto_hash_init(desc);
353 if (err)
354 return err;
355
356 err = dst_trans_iter_in(bio, e, dst_hash_iterator);
357 if (err)
358 return err;
359
360 err = crypto_hash_final(desc, dst);
361 if (err)
362 return err;
363
364 return 0;
365}
366
367/*
368 * Initialize/cleanup a crypto thread. The only thing it should
369 * do is to allocate a pool of pages as temporary storage.
370 * And to setup cipher and/or hash.
371 */
372static void *dst_crypto_thread_init(void *data)
373{
374 struct dst_node *n = data;
375 struct dst_crypto_engine *e;
376 int err = -ENOMEM;
377
378 e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL);
379 if (!e)
380 goto err_out_exit;
381 e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist),
382 GFP_KERNEL);
383 if (!e->src)
384 goto err_out_free;
385
386 e->dst = e->src + n->max_pages;
387
388 err = dst_crypto_engine_init(e, n);
389 if (err)
390 goto err_out_free_all;
391
392 return e;
393
394err_out_free_all:
395 kfree(e->src);
396err_out_free:
397 kfree(e);
398err_out_exit:
399 return ERR_PTR(err);
400}
401
402static void dst_crypto_thread_cleanup(void *private)
403{
404 struct dst_crypto_engine *e = private;
405
406 dst_crypto_engine_exit(e);
407 kfree(e->src);
408 kfree(e);
409}
410
411/*
412 * Initialize crypto engine for given node: store keys, create pool
413 * of threads, initialize each one.
414 *
415 * Each thread has unique ID, but 0 and 1 are reserved for receiving and
416 * accepting threads (if export node), so IDs could start from 2, but starting
417 * them from 10 allows easily understand what this thread is for.
418 */
419int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl)
420{
421 void *key = (ctl + 1);
422 int err = -ENOMEM, i;
423 char name[32];
424
425 if (ctl->hash_keysize) {
426 n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL);
427 if (!n->hash_key)
428 goto err_out_exit;
429 memcpy(n->hash_key, key, ctl->hash_keysize);
430 }
431
432 if (ctl->cipher_keysize) {
433 n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL);
434 if (!n->cipher_key)
435 goto err_out_free_hash;
436 memcpy(n->cipher_key, key, ctl->cipher_keysize);
437 }
438 memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl));
439
440 for (i = 0; i < ctl->thread_num; ++i) {
441 snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i);
442 /* Unique ids... */
443 err = thread_pool_add_worker(n->pool, name, i + 10,
444 dst_crypto_thread_init, dst_crypto_thread_cleanup, n);
445 if (err)
446 goto err_out_free_threads;
447 }
448
449 return 0;
450
451err_out_free_threads:
452 while (--i >= 0)
453 thread_pool_del_worker_id(n->pool, i+10);
454
455 if (ctl->cipher_keysize)
456 kfree(n->cipher_key);
457 ctl->cipher_keysize = 0;
458err_out_free_hash:
459 if (ctl->hash_keysize)
460 kfree(n->hash_key);
461 ctl->hash_keysize = 0;
462err_out_exit:
463 return err;
464}
465
466void dst_node_crypto_exit(struct dst_node *n)
467{
468 struct dst_crypto_ctl *ctl = &n->crypto;
469
470 if (ctl->cipher_algo[0] || ctl->hash_algo[0]) {
471 kfree(n->hash_key);
472 kfree(n->cipher_key);
473 }
474}
475
476/*
477 * Thrad pool setup callback. Just stores a transaction in private data.
478 */
479static int dst_trans_crypto_setup(void *crypto_engine, void *trans)
480{
481 struct dst_crypto_engine *e = crypto_engine;
482
483 e->private = trans;
484 return 0;
485}
486
487#if 0
488static void dst_dump_bio(struct bio *bio)
489{
490 u8 *p;
491 struct bio_vec *bv;
492 int i;
493
494 bio_for_each_segment(bv, bio, i) {
495 dprintk("%s: %llu/%u: size: %u, offset: %u, data: ",
496 __func__, bio->bi_sector, bio->bi_size,
497 bv->bv_len, bv->bv_offset);
498
499 p = kmap(bv->bv_page) + bv->bv_offset;
500 for (i = 0; i < bv->bv_len; ++i)
501 printk(KERN_DEBUG "%02x ", p[i]);
502 kunmap(bv->bv_page);
503 printk("\n");
504 }
505}
506#endif
507
508/*
509 * Encrypt/hash data and send it to the network.
510 */
511static int dst_crypto_process_sending(struct dst_crypto_engine *e,
512 struct bio *bio, u8 *hash)
513{
514 int err;
515
516 if (e->cipher) {
517 err = dst_crypt(e, bio);
518 if (err)
519 goto err_out_exit;
520 }
521
522 if (e->hash) {
523 err = dst_hash(e, bio, hash);
524 if (err)
525 goto err_out_exit;
526
527#ifdef CONFIG_DST_DEBUG
528 {
529 unsigned int i;
530
531 /* dst_dump_bio(bio); */
532
533 printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ",
534 __func__, (u64)bio->bi_sector,
535 bio->bi_size, bio_data_dir(bio));
536 for (i = 0; i < crypto_hash_digestsize(e->hash); ++i)
537 printk("%02x ", hash[i]);
538 printk("\n");
539 }
540#endif
541 }
542
543 return 0;
544
545err_out_exit:
546 return err;
547}
548
549/*
550 * Check if received data is valid. Decipher if it is.
551 */
552static int dst_crypto_process_receiving(struct dst_crypto_engine *e,
553 struct bio *bio, u8 *hash, u8 *recv_hash)
554{
555 int err;
556
557 if (e->hash) {
558 int mismatch;
559
560 err = dst_hash(e, bio, hash);
561 if (err)
562 goto err_out_exit;
563
564 mismatch = !!memcmp(recv_hash, hash,
565 crypto_hash_digestsize(e->hash));
566#ifdef CONFIG_DST_DEBUG
567 /* dst_dump_bio(bio); */
568
569 printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d",
570 __func__, (u64)bio->bi_sector, bio->bi_size,
571 bio_data_dir(bio), mismatch);
572 if (mismatch) {
573 unsigned int i;
574
575 printk(", recv/calc: ");
576 for (i = 0; i < crypto_hash_digestsize(e->hash); ++i)
577 printk("%02x/%02x ", recv_hash[i], hash[i]);
578
579 }
580 printk("\n");
581#endif
582 err = -1;
583 if (mismatch)
584 goto err_out_exit;
585 }
586
587 if (e->cipher) {
588 err = dst_crypt(e, bio);
589 if (err)
590 goto err_out_exit;
591 }
592
593 return 0;
594
595err_out_exit:
596 return err;
597}
598
599/*
600 * Thread pool callback to encrypt data and send it to the netowork.
601 */
602static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data)
603{
604 struct dst_crypto_engine *e = crypto_engine;
605 struct dst_trans *t = schedule_data;
606 struct bio *bio = t->bio;
607 int err;
608
609 dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n",
610 __func__, t, t->gen, e->cipher, e->hash);
611
612 e->enc = t->enc;
613 e->iv = dst_gen_iv(t);
614
615 if (bio_data_dir(bio) == WRITE) {
616 err = dst_crypto_process_sending(e, bio, t->cmd.hash);
617 if (err)
618 goto err_out_exit;
619
620 if (e->hash) {
621 t->cmd.csize = crypto_hash_digestsize(e->hash);
622 t->cmd.size += t->cmd.csize;
623 }
624
625 return dst_trans_send(t);
626 } else {
627 u8 *hash = e->data + e->size/2;
628
629 err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash);
630 if (err)
631 goto err_out_exit;
632
633 dst_trans_remove(t);
634 dst_trans_put(t);
635 }
636
637 return 0;
638
639err_out_exit:
640 t->error = err;
641 dst_trans_put(t);
642 return err;
643}
644
645/*
646 * Schedule crypto processing for given transaction.
647 */
648int dst_trans_crypto(struct dst_trans *t)
649{
650 struct dst_node *n = t->n;
651 int err;
652
653 err = thread_pool_schedule(n->pool,
654 dst_trans_crypto_setup, dst_trans_crypto_action,
655 t, MAX_SCHEDULE_TIMEOUT);
656 if (err)
657 goto err_out_exit;
658
659 return 0;
660
661err_out_exit:
662 dst_trans_put(t);
663 return err;
664}
665
666/*
667 * Crypto machinery for the export node.
668 */
669static int dst_export_crypto_setup(void *crypto_engine, void *bio)
670{
671 struct dst_crypto_engine *e = crypto_engine;
672
673 e->private = bio;
674 return 0;
675}
676
677static int dst_export_crypto_action(void *crypto_engine, void *schedule_data)
678{
679 struct dst_crypto_engine *e = crypto_engine;
680 struct bio *bio = schedule_data;
681 struct dst_export_priv *p = bio->bi_private;
682 int err;
683
684 dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n",
685 __func__, e, e->data, (u64)bio->bi_sector,
686 bio->bi_size, bio_data_dir(bio));
687
688 e->enc = (bio_data_dir(bio) == READ);
689 e->iv = p->cmd.id;
690
691 if (bio_data_dir(bio) == WRITE) {
692 u8 *hash = e->data + e->size/2;
693
694 err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash);
695 if (err)
696 goto err_out_exit;
697
698 generic_make_request(bio);
699 } else {
700 err = dst_crypto_process_sending(e, bio, p->cmd.hash);
701 if (err)
702 goto err_out_exit;
703
704 if (e->hash) {
705 p->cmd.csize = crypto_hash_digestsize(e->hash);
706 p->cmd.size += p->cmd.csize;
707 }
708
709 err = dst_export_send_bio(bio);
710 }
711 return 0;
712
713err_out_exit:
714 bio_put(bio);
715 return err;
716}
717
718int dst_export_crypto(struct dst_node *n, struct bio *bio)
719{
720 int err;
721
722 err = thread_pool_schedule(n->pool,
723 dst_export_crypto_setup, dst_export_crypto_action,
724 bio, MAX_SCHEDULE_TIMEOUT);
725 if (err)
726 goto err_out_exit;
727
728 return 0;
729
730err_out_exit:
731 bio_put(bio);
732 return err;
733}
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
deleted file mode 100644
index fd5bd0ea1e0d..000000000000
--- a/drivers/staging/dst/dcore.c
+++ /dev/null
@@ -1,1004 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/blkdev.h>
19#include <linux/bio.h>
20#include <linux/buffer_head.h>
21#include <linux/connector.h>
22#include <linux/dst.h>
23#include <linux/device.h>
24#include <linux/jhash.h>
25#include <linux/idr.h>
26#include <linux/init.h>
27#include <linux/namei.h>
28#include <linux/slab.h>
29#include <linux/socket.h>
30
31#include <linux/in.h>
32#include <linux/in6.h>
33
34#include <net/sock.h>
35
36static int dst_major;
37
38static DEFINE_MUTEX(dst_hash_lock);
39static struct list_head *dst_hashtable;
40static unsigned int dst_hashtable_size = 128;
41module_param(dst_hashtable_size, uint, 0644);
42
43static char dst_name[] = "Dementianting goldfish";
44
45static DEFINE_IDR(dst_index_idr);
46static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL };
47
48/*
49 * DST sysfs tree for device called 'storage':
50 *
51 * /sys/bus/dst/devices/storage/
52 * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025
53 * /sys/bus/dst/devices/storage/size : 800
54 * /sys/bus/dst/devices/storage/name : storage
55 */
56
57static int dst_dev_match(struct device *dev, struct device_driver *drv)
58{
59 return 1;
60}
61
62static struct bus_type dst_dev_bus_type = {
63 .name = "dst",
64 .match = &dst_dev_match,
65};
66
67static void dst_node_release(struct device *dev)
68{
69 struct dst_info *info = container_of(dev, struct dst_info, device);
70
71 kfree(info);
72}
73
74static struct device dst_node_dev = {
75 .bus = &dst_dev_bus_type,
76 .release = &dst_node_release
77};
78
79/*
80 * Setting size of the node after it was changed.
81 */
82static void dst_node_set_size(struct dst_node *n)
83{
84 struct block_device *bdev;
85
86 set_capacity(n->disk, n->size >> 9);
87
88 bdev = bdget_disk(n->disk, 0);
89 if (bdev) {
90 mutex_lock(&bdev->bd_inode->i_mutex);
91 i_size_write(bdev->bd_inode, n->size);
92 mutex_unlock(&bdev->bd_inode->i_mutex);
93 bdput(bdev);
94 }
95}
96
97/*
98 * Distributed storage request processing function.
99 */
100static int dst_request(struct request_queue *q, struct bio *bio)
101{
102 struct dst_node *n = q->queuedata;
103 int err = -EIO;
104
105 if (bio_empty_barrier(bio) && !blk_queue_discard(q)) {
106 /*
107 * This is a dirty^Wnice hack, but if we complete this
108 * operation with -EOPNOTSUPP like intended, XFS
109 * will stuck and freeze the machine. This may be
110 * not particulary XFS problem though, but it is the
111 * only FS which sends empty barrier at umount time
112 * I worked with.
113 *
114 * Empty barriers are not allowed anyway, see 51fd77bd9f512
115 * for example, although later it was changed to
116 * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not
117 * work in this case.
118 */
119 /* err = -EOPNOTSUPP; */
120 err = 0;
121 goto end_io;
122 }
123
124 bio_get(bio);
125
126 return dst_process_bio(n, bio);
127
128end_io:
129 bio_endio(bio, err);
130 return err;
131}
132
133/*
134 * Open/close callbacks for appropriate block device.
135 */
136static int dst_bdev_open(struct block_device *bdev, fmode_t mode)
137{
138 struct dst_node *n = bdev->bd_disk->private_data;
139
140 dst_node_get(n);
141 return 0;
142}
143
144static int dst_bdev_release(struct gendisk *disk, fmode_t mode)
145{
146 struct dst_node *n = disk->private_data;
147
148 dst_node_put(n);
149 return 0;
150}
151
152static struct block_device_operations dst_blk_ops = {
153 .open = dst_bdev_open,
154 .release = dst_bdev_release,
155 .owner = THIS_MODULE,
156};
157
158/*
159 * Block layer binding - disk is created when array is fully configured
160 * by userspace request.
161 */
162static int dst_node_create_disk(struct dst_node *n)
163{
164 int err = -ENOMEM;
165 u32 index = 0;
166
167 n->queue = blk_init_queue(NULL, NULL);
168 if (!n->queue)
169 goto err_out_exit;
170
171 n->queue->queuedata = n;
172 blk_queue_make_request(n->queue, dst_request);
173 blk_queue_max_phys_segments(n->queue, n->max_pages);
174 blk_queue_max_hw_segments(n->queue, n->max_pages);
175
176 err = -ENOMEM;
177 n->disk = alloc_disk(1);
178 if (!n->disk)
179 goto err_out_free_queue;
180
181 if (!(n->state->permissions & DST_PERM_WRITE)) {
182 printk(KERN_INFO "DST node %s attached read-only.\n", n->name);
183 set_disk_ro(n->disk, 1);
184 }
185
186 if (!idr_pre_get(&dst_index_idr, GFP_KERNEL))
187 goto err_out_put;
188
189 mutex_lock(&dst_hash_lock);
190 err = idr_get_new(&dst_index_idr, NULL, &index);
191 mutex_unlock(&dst_hash_lock);
192 if (err)
193 goto err_out_put;
194
195 n->disk->major = dst_major;
196 n->disk->first_minor = index;
197 n->disk->fops = &dst_blk_ops;
198 n->disk->queue = n->queue;
199 n->disk->private_data = n;
200 snprintf(n->disk->disk_name, sizeof(n->disk->disk_name),
201 "dst-%s", n->name);
202
203 return 0;
204
205err_out_put:
206 put_disk(n->disk);
207err_out_free_queue:
208 blk_cleanup_queue(n->queue);
209err_out_exit:
210 return err;
211}
212
213/*
214 * Sysfs machinery: show device's size.
215 */
216static ssize_t dst_show_size(struct device *dev,
217 struct device_attribute *attr, char *buf)
218{
219 struct dst_info *info = container_of(dev, struct dst_info, device);
220
221 return sprintf(buf, "%llu\n", info->size);
222}
223
224/*
225 * Show local exported device.
226 */
227static ssize_t dst_show_local(struct device *dev,
228 struct device_attribute *attr, char *buf)
229{
230 struct dst_info *info = container_of(dev, struct dst_info, device);
231
232 return sprintf(buf, "%s\n", info->local);
233}
234
235/*
236 * Shows type of the remote node - device major/minor number
237 * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes.
238 */
239static ssize_t dst_show_type(struct device *dev,
240 struct device_attribute *attr, char *buf)
241{
242 struct dst_info *info = container_of(dev, struct dst_info, device);
243 int family = info->net.addr.sa_family;
244
245 if (family == AF_INET) {
246 struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr;
247 return sprintf(buf, "%u.%u.%u.%u:%d\n",
248 NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
249 } else if (family == AF_INET6) {
250 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)
251 &info->net.addr;
252 return sprintf(buf,
253 "%pi6:%d\n",
254 &sin->sin6_addr, ntohs(sin->sin6_port));
255 } else {
256 int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */
257 int size, addrlen = info->net.addr.sa_data_len;
258 unsigned char *a = (unsigned char *)&info->net.addr.sa_data;
259 char *buf_orig = buf;
260
261 size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ",
262 family, addrlen);
263 sz -= size;
264 buf += size;
265
266 for (i = 0; i < addrlen; ++i) {
267 if (sz < 3)
268 break;
269
270 size = snprintf(buf, sz, "%02x ", a[i]);
271 sz -= size;
272 buf += size;
273 }
274 buf += sprintf(buf, "\n");
275
276 return buf - buf_orig;
277 }
278 return 0;
279}
280
281static struct device_attribute dst_node_attrs[] = {
282 __ATTR(size, 0444, dst_show_size, NULL),
283 __ATTR(type, 0444, dst_show_type, NULL),
284 __ATTR(local, 0444, dst_show_local, NULL),
285};
286
287static int dst_create_node_attributes(struct dst_node *n)
288{
289 int err, i;
290
291 for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) {
292 err = device_create_file(&n->info->device,
293 &dst_node_attrs[i]);
294 if (err)
295 goto err_out_remove_all;
296 }
297 return 0;
298
299err_out_remove_all:
300 while (--i >= 0)
301 device_remove_file(&n->info->device,
302 &dst_node_attrs[i]);
303
304 return err;
305}
306
307static void dst_remove_node_attributes(struct dst_node *n)
308{
309 int i;
310
311 for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i)
312 device_remove_file(&n->info->device,
313 &dst_node_attrs[i]);
314}
315
316/*
317 * Sysfs cleanup and initialization.
318 * Shows number of useful parameters.
319 */
320static void dst_node_sysfs_exit(struct dst_node *n)
321{
322 if (n->info) {
323 dst_remove_node_attributes(n);
324 device_unregister(&n->info->device);
325 n->info = NULL;
326 }
327}
328
329static int dst_node_sysfs_init(struct dst_node *n)
330{
331 int err;
332
333 n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL);
334 if (!n->info)
335 return -ENOMEM;
336
337 memcpy(&n->info->device, &dst_node_dev, sizeof(struct device));
338 n->info->size = n->size;
339
340 dev_set_name(&n->info->device, "dst-%s", n->name);
341 err = device_register(&n->info->device);
342 if (err) {
343 dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n",
344 n->name, err);
345 goto err_out_exit;
346 }
347
348 dst_create_node_attributes(n);
349
350 return 0;
351
352err_out_exit:
353 kfree(n->info);
354 n->info = NULL;
355 return err;
356}
357
358/*
359 * DST node hash tables machinery.
360 */
361static inline unsigned int dst_hash(char *str, unsigned int size)
362{
363 return jhash(str, size, 0) % dst_hashtable_size;
364}
365
366static void dst_node_remove(struct dst_node *n)
367{
368 mutex_lock(&dst_hash_lock);
369 list_del_init(&n->node_entry);
370 mutex_unlock(&dst_hash_lock);
371}
372
373static void dst_node_add(struct dst_node *n)
374{
375 unsigned hash = dst_hash(n->name, sizeof(n->name));
376
377 mutex_lock(&dst_hash_lock);
378 list_add_tail(&n->node_entry, &dst_hashtable[hash]);
379 mutex_unlock(&dst_hash_lock);
380}
381
382/*
383 * Cleaning node when it is about to be freed.
384 * There are still users of the socket though,
385 * so connection cleanup should be protected.
386 */
387static void dst_node_cleanup(struct dst_node *n)
388{
389 struct dst_state *st = n->state;
390
391 if (!st)
392 return;
393
394 if (n->queue) {
395 blk_cleanup_queue(n->queue);
396
397 mutex_lock(&dst_hash_lock);
398 idr_remove(&dst_index_idr, n->disk->first_minor);
399 mutex_unlock(&dst_hash_lock);
400
401 put_disk(n->disk);
402 }
403
404 if (n->bdev) {
405 sync_blockdev(n->bdev);
406 blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
407 }
408
409 dst_state_lock(st);
410 st->need_exit = 1;
411 dst_state_exit_connected(st);
412 dst_state_unlock(st);
413
414 wake_up(&st->thread_wait);
415
416 dst_state_put(st);
417 n->state = NULL;
418}
419
420/*
421 * Free security attributes attached to given node.
422 */
423static void dst_security_exit(struct dst_node *n)
424{
425 struct dst_secure *s, *tmp;
426
427 list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) {
428 list_del(&s->sec_entry);
429 kfree(s);
430 }
431}
432
433/*
434 * Free node when there are no more users.
435 * Actually node has to be freed on behalf od userspace process,
436 * since there are number of threads, which are embedded in the
437 * node, so they can not exit and free node from there, that is
438 * why there is a wakeup if reference counter is not equal to zero.
439 */
440void dst_node_put(struct dst_node *n)
441{
442 if (unlikely(!n))
443 return;
444
445 dprintk("%s: n: %p, refcnt: %d.\n",
446 __func__, n, atomic_read(&n->refcnt));
447
448 if (atomic_dec_and_test(&n->refcnt)) {
449 dst_node_remove(n);
450 n->trans_scan_timeout = 0;
451 dst_node_cleanup(n);
452 thread_pool_destroy(n->pool);
453 dst_node_sysfs_exit(n);
454 dst_node_crypto_exit(n);
455 dst_security_exit(n);
456 dst_node_trans_exit(n);
457
458 kfree(n);
459
460 dprintk("%s: freed n: %p.\n", __func__, n);
461 } else {
462 wake_up(&n->wait);
463 }
464}
465
466/*
467 * This function finds devices major/minor numbers for given pathname.
468 */
469static int dst_lookup_device(const char *path, dev_t *dev)
470{
471 int err;
472 struct nameidata nd;
473 struct inode *inode;
474
475 err = path_lookup(path, LOOKUP_FOLLOW, &nd);
476 if (err)
477 return err;
478
479 inode = nd.path.dentry->d_inode;
480 if (!inode) {
481 err = -ENOENT;
482 goto out;
483 }
484
485 if (!S_ISBLK(inode->i_mode)) {
486 err = -ENOTBLK;
487 goto out;
488 }
489
490 *dev = inode->i_rdev;
491
492out:
493 path_put(&nd.path);
494 return err;
495}
496
497/*
498 * Setting up export device: lookup by the name, get its size
499 * and setup listening socket, which will accept clients, which
500 * will submit IO for given storage.
501 */
502static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl,
503 struct dst_export_ctl *le)
504{
505 int err;
506 dev_t dev = 0; /* gcc likes to scream here */
507
508 snprintf(n->info->local, sizeof(n->info->local), "%s", le->device);
509
510 err = dst_lookup_device(le->device, &dev);
511 if (err)
512 return err;
513
514 n->bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
515 if (!n->bdev)
516 return -ENODEV;
517
518 if (n->size != 0)
519 n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size);
520 else
521 n->size = n->bdev->bd_inode->i_size;
522
523 n->info->size = n->size;
524 err = dst_node_init_listened(n, le);
525 if (err)
526 goto err_out_cleanup;
527
528 return 0;
529
530err_out_cleanup:
531 blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
532 n->bdev = NULL;
533
534 return err;
535}
536
537/* Empty thread pool callbacks for the network processing threads. */
538static inline void *dst_thread_network_init(void *data)
539{
540 dprintk("%s: data: %p.\n", __func__, data);
541 return data;
542}
543
544static inline void dst_thread_network_cleanup(void *data)
545{
546 dprintk("%s: data: %p.\n", __func__, data);
547}
548
549/*
550 * Allocate DST node and initialize some of its parameters.
551 */
552static struct dst_node *dst_alloc_node(struct dst_ctl *ctl,
553 int (*start)(struct dst_node *),
554 int num)
555{
556 struct dst_node *n;
557 int err;
558
559 n = kzalloc(sizeof(struct dst_node), GFP_KERNEL);
560 if (!n)
561 return NULL;
562
563 INIT_LIST_HEAD(&n->node_entry);
564
565 INIT_LIST_HEAD(&n->security_list);
566 mutex_init(&n->security_lock);
567
568 init_waitqueue_head(&n->wait);
569
570 n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout);
571 if (!n->trans_scan_timeout)
572 n->trans_scan_timeout = HZ;
573
574 n->trans_max_retries = ctl->trans_max_retries;
575 if (!n->trans_max_retries)
576 n->trans_max_retries = 10;
577
578 /*
579 * Pretty much arbitrary default numbers.
580 * 32 matches maximum number of pages in bio originated from ext3 (31).
581 */
582 n->max_pages = ctl->max_pages;
583 if (!n->max_pages)
584 n->max_pages = 32;
585
586 if (n->max_pages > 1024)
587 n->max_pages = 1024;
588
589 n->start = start;
590 n->size = ctl->size;
591
592 atomic_set(&n->refcnt, 1);
593 atomic_long_set(&n->gen, 0);
594 snprintf(n->name, sizeof(n->name), "%s", ctl->name);
595
596 err = dst_node_sysfs_init(n);
597 if (err)
598 goto err_out_free;
599
600 n->pool = thread_pool_create(num, n->name, dst_thread_network_init,
601 dst_thread_network_cleanup, n);
602 if (IS_ERR(n->pool)) {
603 err = PTR_ERR(n->pool);
604 goto err_out_sysfs_exit;
605 }
606
607 dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name);
608
609 return n;
610
611err_out_sysfs_exit:
612 dst_node_sysfs_exit(n);
613err_out_free:
614 kfree(n);
615 return NULL;
616}
617
618/*
619 * Starting a node, connected to the remote server:
620 * register block device and initialize transaction mechanism.
621 * In revers order though.
622 *
623 * It will autonegotiate some parameters with the remote node
624 * and update local if needed.
625 *
626 * Transaction initialization should be the last thing before
627 * starting the node, since transaction should include not only
628 * block IO, but also crypto related data (if any), which are
629 * initialized separately.
630 */
631static int dst_start_remote(struct dst_node *n)
632{
633 int err;
634
635 err = dst_node_trans_init(n, sizeof(struct dst_trans));
636 if (err)
637 return err;
638
639 err = dst_node_create_disk(n);
640 if (err)
641 return err;
642
643 dst_node_set_size(n);
644 add_disk(n->disk);
645
646 dprintk("DST: started remote node '%s', minor: %d.\n",
647 n->name, n->disk->first_minor);
648
649 return 0;
650}
651
652/*
653 * Adding remote node and initialize connection.
654 */
655static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl,
656 void *data, unsigned int size)
657{
658 int err;
659 struct dst_network_ctl *rctl = data;
660
661 if (n)
662 return -EEXIST;
663
664 if (size != sizeof(struct dst_network_ctl))
665 return -EINVAL;
666
667 n = dst_alloc_node(ctl, dst_start_remote, 1);
668 if (!n)
669 return -ENOMEM;
670
671 memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl));
672 err = dst_node_init_connected(n, rctl);
673 if (err)
674 goto err_out_free;
675
676 dst_node_add(n);
677
678 return 0;
679
680err_out_free:
681 dst_node_put(n);
682 return err;
683}
684
685/*
686 * Adding export node: initializing block device and listening socket.
687 */
688static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl,
689 void *data, unsigned int size)
690{
691 int err;
692 struct dst_export_ctl *le = data;
693
694 if (n)
695 return -EEXIST;
696
697 if (size != sizeof(struct dst_export_ctl))
698 return -EINVAL;
699
700 n = dst_alloc_node(ctl, dst_start_export, 2);
701 if (!n)
702 return -EINVAL;
703
704 err = dst_setup_export(n, ctl, le);
705 if (err)
706 goto err_out_free;
707
708 dst_node_add(n);
709
710 return 0;
711
712err_out_free:
713 dst_node_put(n);
714 return err;
715}
716
717static int dst_node_remove_unload(struct dst_node *n)
718{
719 printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n",
720 n->name, n->size);
721
722 if (n->disk)
723 del_gendisk(n->disk);
724
725 dst_node_remove(n);
726 dst_node_sysfs_exit(n);
727
728 /*
729 * This is not a hack. Really.
730 * Node's reference counter allows to implement fine grained
731 * node freeing, but since all transactions (which hold node's
732 * reference counter) are processed in the dedicated thread,
733 * it is possible that reference will hit zero in that thread,
734 * so we will not be able to exit thread and cleanup the node.
735 *
736 * So, we remove disk, so no new activity is possible, and
737 * wait until all pending transaction are completed (either
738 * in receiving thread or by timeout in workqueue), in this
739 * case reference counter will be less or equal to 2 (once set in
740 * dst_alloc_node() and then in connector message parser;
741 * or when we force module unloading, and connector message
742 * parser does not hold a reference, in this case reference
743 * counter will be equal to 1),
744 * and subsequent dst_node_put() calls will free the node.
745 */
746 dprintk("%s: going to sleep with %d refcnt.\n",
747 __func__, atomic_read(&n->refcnt));
748 wait_event(n->wait, atomic_read(&n->refcnt) <= 2);
749
750 dst_node_put(n);
751 return 0;
752}
753
754/*
755 * Remove node from the hash table.
756 */
757static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl,
758 void *data, unsigned int size)
759{
760 if (!n)
761 return -ENODEV;
762
763 return dst_node_remove_unload(n);
764}
765
766/*
767 * Initialize crypto processing for given node.
768 */
769static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl,
770 void *data, unsigned int size)
771{
772 struct dst_crypto_ctl *crypto = data;
773
774 if (!n)
775 return -ENODEV;
776
777 if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize +
778 crypto->cipher_keysize)
779 return -EINVAL;
780
781 if (n->trans_cache)
782 return -EEXIST;
783
784 return dst_node_crypto_init(n, crypto);
785}
786
787/*
788 * Security attributes for given node.
789 */
790static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl,
791 void *data, unsigned int size)
792{
793 struct dst_secure *s;
794
795 if (!n)
796 return -ENODEV;
797
798 if (size != sizeof(struct dst_secure_user))
799 return -EINVAL;
800
801 s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL);
802 if (!s)
803 return -ENOMEM;
804
805 memcpy(&s->sec, data, size);
806
807 mutex_lock(&n->security_lock);
808 list_add_tail(&s->sec_entry, &n->security_list);
809 mutex_unlock(&n->security_lock);
810
811 return 0;
812}
813
814/*
815 * Kill'em all!
816 */
817static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl,
818 void *data, unsigned int size)
819{
820 int err;
821
822 if (!n)
823 return -ENODEV;
824
825 if (n->trans_cache)
826 return 0;
827
828 err = n->start(n);
829 if (err)
830 return err;
831
832 printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size);
833 return 0;
834}
835
836typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl,
837 void *data, unsigned int size);
838
839/*
840 * List of userspace commands.
841 */
842static dst_command_func dst_commands[] = {
843 [DST_ADD_REMOTE] = &dst_add_remote,
844 [DST_ADD_EXPORT] = &dst_add_export,
845 [DST_DEL_NODE] = &dst_del_node,
846 [DST_CRYPTO] = &dst_crypto_init,
847 [DST_SECURITY] = &dst_security_init,
848 [DST_START] = &dst_start_node,
849};
850
851/*
852 * Configuration parser.
853 */
854static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
855{
856 struct dst_ctl *ctl;
857 int err;
858 struct dst_ctl_ack ack;
859 struct dst_node *n = NULL, *tmp;
860 unsigned int hash;
861
862 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
863 err = -EPERM;
864 goto out;
865 }
866
867 if (msg->len < sizeof(struct dst_ctl)) {
868 err = -EBADMSG;
869 goto out;
870 }
871
872 ctl = (struct dst_ctl *)msg->data;
873
874 if (ctl->cmd >= DST_CMD_MAX) {
875 err = -EINVAL;
876 goto out;
877 }
878 hash = dst_hash(ctl->name, sizeof(ctl->name));
879
880 mutex_lock(&dst_hash_lock);
881 list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) {
882 if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) {
883 n = tmp;
884 dst_node_get(n);
885 break;
886 }
887 }
888 mutex_unlock(&dst_hash_lock);
889
890 err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl),
891 msg->len - sizeof(struct dst_ctl));
892
893 dst_node_put(n);
894out:
895 memcpy(&ack.msg, msg, sizeof(struct cn_msg));
896
897 ack.msg.ack = msg->ack + 1;
898 ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg);
899
900 ack.error = err;
901
902 cn_netlink_send(&ack.msg, 0, GFP_KERNEL);
903}
904
905/*
906 * Global initialization: sysfs, hash table, block device registration,
907 * connector and various caches.
908 */
909static int __init dst_sysfs_init(void)
910{
911 return bus_register(&dst_dev_bus_type);
912}
913
914static void dst_sysfs_exit(void)
915{
916 bus_unregister(&dst_dev_bus_type);
917}
918
919static int __init dst_hashtable_init(void)
920{
921 unsigned int i;
922
923 dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head),
924 GFP_KERNEL);
925 if (!dst_hashtable)
926 return -ENOMEM;
927
928 for (i = 0; i < dst_hashtable_size; ++i)
929 INIT_LIST_HEAD(&dst_hashtable[i]);
930
931 return 0;
932}
933
934static void dst_hashtable_exit(void)
935{
936 unsigned int i;
937 struct dst_node *n, *tmp;
938
939 for (i = 0; i < dst_hashtable_size; ++i) {
940 list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) {
941 dst_node_remove_unload(n);
942 }
943 }
944
945 kfree(dst_hashtable);
946}
947
948static int __init dst_sys_init(void)
949{
950 int err = -ENOMEM;
951
952 err = dst_hashtable_init();
953 if (err)
954 goto err_out_exit;
955
956 err = dst_export_init();
957 if (err)
958 goto err_out_hashtable_exit;
959
960 err = register_blkdev(dst_major, DST_NAME);
961 if (err < 0)
962 goto err_out_export_exit;
963 if (err)
964 dst_major = err;
965
966 err = dst_sysfs_init();
967 if (err)
968 goto err_out_unregister;
969
970 err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback);
971 if (err)
972 goto err_out_sysfs_exit;
973
974 printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name);
975
976 return 0;
977
978err_out_sysfs_exit:
979 dst_sysfs_exit();
980err_out_unregister:
981 unregister_blkdev(dst_major, DST_NAME);
982err_out_export_exit:
983 dst_export_exit();
984err_out_hashtable_exit:
985 dst_hashtable_exit();
986err_out_exit:
987 return err;
988}
989
990static void __exit dst_sys_exit(void)
991{
992 cn_del_callback(&cn_dst_id);
993 unregister_blkdev(dst_major, DST_NAME);
994 dst_hashtable_exit();
995 dst_sysfs_exit();
996 dst_export_exit();
997}
998
999module_init(dst_sys_init);
1000module_exit(dst_sys_exit);
1001
1002MODULE_DESCRIPTION("Distributed storage");
1003MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
1004MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
deleted file mode 100644
index c324230e8b60..000000000000
--- a/drivers/staging/dst/export.c
+++ /dev/null
@@ -1,660 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/blkdev.h>
17#include <linux/bio.h>
18#include <linux/dst.h>
19#include <linux/in.h>
20#include <linux/in6.h>
21#include <linux/poll.h>
22#include <linux/slab.h>
23#include <linux/socket.h>
24
25#include <net/sock.h>
26
27/*
28 * Export bioset is used for server block IO requests.
29 */
30static struct bio_set *dst_bio_set;
31
32int __init dst_export_init(void)
33{
34 int err = -ENOMEM;
35
36 dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv));
37 if (!dst_bio_set)
38 goto err_out_exit;
39
40 return 0;
41
42err_out_exit:
43 return err;
44}
45
46void dst_export_exit(void)
47{
48 bioset_free(dst_bio_set);
49}
50
51/*
52 * When client connects and autonegotiates with the server node,
53 * its permissions are checked in a security attributes and sent
54 * back.
55 */
56static unsigned int dst_check_permissions(struct dst_state *main,
57 struct dst_state *st)
58{
59 struct dst_node *n = main->node;
60 struct dst_secure *sentry;
61 struct dst_secure_user *s;
62 struct saddr *sa = &st->ctl.addr;
63 unsigned int perm = 0;
64
65 mutex_lock(&n->security_lock);
66 list_for_each_entry(sentry, &n->security_list, sec_entry) {
67 s = &sentry->sec;
68
69 if (s->addr.sa_family != sa->sa_family)
70 continue;
71
72 if (s->addr.sa_data_len != sa->sa_data_len)
73 continue;
74
75 /*
76 * This '2' below is a port field. This may be very wrong to do
77 * in atalk for example though. If there will be any need
78 * to extent protocol to something else, I can create
79 * per-family helpers and use them instead of this memcmp.
80 */
81 if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2,
82 sa->sa_data_len - 2))
83 continue;
84
85 perm = s->permissions;
86 }
87 mutex_unlock(&n->security_lock);
88
89 return perm;
90}
91
92/*
93 * Accept new client: allocate appropriate network state and check permissions.
94 */
95static struct dst_state *dst_accept_client(struct dst_state *st)
96{
97 unsigned int revents = 0;
98 unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
99 unsigned int mask = err_mask | POLLIN;
100 struct dst_node *n = st->node;
101 int err = 0;
102 struct socket *sock = NULL;
103 struct dst_state *new;
104
105 while (!err && !sock) {
106 revents = dst_state_poll(st);
107
108 if (!(revents & mask)) {
109 DEFINE_WAIT(wait);
110
111 for (;;) {
112 prepare_to_wait(&st->thread_wait,
113 &wait, TASK_INTERRUPTIBLE);
114 if (!n->trans_scan_timeout || st->need_exit)
115 break;
116
117 revents = dst_state_poll(st);
118
119 if (revents & mask)
120 break;
121
122 if (signal_pending(current))
123 break;
124
125 /*
126 * Magic HZ? Polling check above is not safe in
127 * all cases (like socket reset in BH context),
128 * so it is simpler just to postpone it to the
129 * process context instead of implementing
130 * special locking there.
131 */
132 schedule_timeout(HZ);
133 }
134 finish_wait(&st->thread_wait, &wait);
135 }
136
137 err = -ECONNRESET;
138 dst_state_lock(st);
139
140 dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n",
141 __func__, st, revents, revents & err_mask,
142 revents & POLLIN);
143
144 if (revents & err_mask) {
145 dprintk("%s: revents: %x, socket: %p, err: %d.\n",
146 __func__, revents, st->socket, err);
147 err = -ECONNRESET;
148 }
149
150 if (!n->trans_scan_timeout || st->need_exit)
151 err = -ENODEV;
152
153 if (st->socket && (revents & POLLIN))
154 err = kernel_accept(st->socket, &sock, 0);
155
156 dst_state_unlock(st);
157 }
158
159 if (err)
160 goto err_out_exit;
161
162 new = dst_state_alloc(st->node);
163 if (IS_ERR(new)) {
164 err = -ENOMEM;
165 goto err_out_release;
166 }
167 new->socket = sock;
168
169 new->ctl.addr.sa_data_len = sizeof(struct sockaddr);
170 err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr,
171 (int *)&new->ctl.addr.sa_data_len);
172 if (err)
173 goto err_out_put;
174
175 new->permissions = dst_check_permissions(st, new);
176 if (new->permissions == 0) {
177 err = -EPERM;
178 dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
179 "Client is not allowed to connect");
180 goto err_out_put;
181 }
182
183 err = dst_poll_init(new);
184 if (err)
185 goto err_out_put;
186
187 dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
188 "Connected client");
189
190 return new;
191
192err_out_put:
193 dst_state_put(new);
194err_out_release:
195 sock_release(sock);
196err_out_exit:
197 return ERR_PTR(err);
198}
199
200/*
201 * Each server's block request sometime finishes.
202 * Usually it happens in hard irq context of the appropriate controller,
203 * so to play good with all cases we just queue BIO into the queue
204 * and wake up processing thread, which gets completed request and
205 * send (encrypting if needed) it back to the client (if it was a read
206 * request), or sends back reply that writing successfully completed.
207 */
208static int dst_export_process_request_queue(struct dst_state *st)
209{
210 unsigned long flags;
211 struct dst_export_priv *p = NULL;
212 struct bio *bio;
213 int err = 0;
214
215 while (!list_empty(&st->request_list)) {
216 spin_lock_irqsave(&st->request_lock, flags);
217 if (!list_empty(&st->request_list)) {
218 p = list_first_entry(&st->request_list,
219 struct dst_export_priv, request_entry);
220 list_del(&p->request_entry);
221 }
222 spin_unlock_irqrestore(&st->request_lock, flags);
223
224 if (!p)
225 break;
226
227 bio = p->bio;
228
229 if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ))
230 err = dst_export_crypto(st->node, bio);
231 else
232 err = dst_export_send_bio(bio);
233
234 if (err)
235 break;
236 }
237
238 return err;
239}
240
241/*
242 * Cleanup export state.
243 * It has to wait until all requests are finished,
244 * and then free them all.
245 */
246static void dst_state_cleanup_export(struct dst_state *st)
247{
248 struct dst_export_priv *p;
249 unsigned long flags;
250
251 /*
252 * This loop waits for all pending bios to be completed and freed.
253 */
254 while (atomic_read(&st->refcnt) > 1) {
255 dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n",
256 __func__, st, atomic_read(&st->refcnt),
257 list_empty(&st->request_list));
258 wait_event_timeout(st->thread_wait,
259 (atomic_read(&st->refcnt) == 1) ||
260 !list_empty(&st->request_list),
261 HZ/2);
262
263 while (!list_empty(&st->request_list)) {
264 p = NULL;
265 spin_lock_irqsave(&st->request_lock, flags);
266 if (!list_empty(&st->request_list)) {
267 p = list_first_entry(&st->request_list,
268 struct dst_export_priv, request_entry);
269 list_del(&p->request_entry);
270 }
271 spin_unlock_irqrestore(&st->request_lock, flags);
272
273 if (p)
274 bio_put(p->bio);
275
276 dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: "
277 "%p.\n", __func__, st, atomic_read(&st->refcnt),
278 list_empty(&st->request_list), p);
279 }
280 }
281
282 dst_state_put(st);
283}
284
285/*
286 * Client accepting thread.
287 * Not only accepts new connection, but also schedules receiving thread
288 * and performs request completion described above.
289 */
290static int dst_accept(void *init_data, void *schedule_data)
291{
292 struct dst_state *main_st = schedule_data;
293 struct dst_node *n = init_data;
294 struct dst_state *st;
295 int err;
296
297 while (n->trans_scan_timeout && !main_st->need_exit) {
298 dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n);
299 st = dst_accept_client(main_st);
300 if (IS_ERR(st))
301 continue;
302
303 err = dst_state_schedule_receiver(st);
304 if (!err) {
305 while (n->trans_scan_timeout) {
306 err = wait_event_interruptible_timeout(st->thread_wait,
307 !list_empty(&st->request_list) ||
308 !n->trans_scan_timeout ||
309 st->need_exit,
310 HZ);
311
312 if (!n->trans_scan_timeout || st->need_exit)
313 break;
314
315 if (list_empty(&st->request_list))
316 continue;
317
318 err = dst_export_process_request_queue(st);
319 if (err)
320 break;
321 }
322
323 st->need_exit = 1;
324 wake_up(&st->thread_wait);
325 }
326
327 dst_state_cleanup_export(st);
328 }
329
330 dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st);
331
332 dst_state_lock(main_st);
333 dst_poll_exit(main_st);
334 dst_state_socket_release(main_st);
335 dst_state_unlock(main_st);
336 dst_state_put(main_st);
337 dprintk("%s: freed listening socket st: %p.\n", __func__, main_st);
338
339 return 0;
340}
341
342int dst_start_export(struct dst_node *n)
343{
344 if (list_empty(&n->security_list)) {
345 printk(KERN_ERR "You are trying to export node '%s' "
346 "without security attributes.\nNo clients will "
347 "be allowed to connect. Exiting.\n", n->name);
348 return -EINVAL;
349 }
350 return dst_node_trans_init(n, sizeof(struct dst_export_priv));
351}
352
353/*
354 * Initialize listening state and schedule accepting thread.
355 */
356int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le)
357{
358 struct dst_state *st;
359 int err = -ENOMEM;
360 struct dst_network_ctl *ctl = &le->ctl;
361
362 memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl));
363
364 st = dst_state_alloc(n);
365 if (IS_ERR(st)) {
366 err = PTR_ERR(st);
367 goto err_out_exit;
368 }
369 memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl));
370
371 err = dst_state_socket_create(st);
372 if (err)
373 goto err_out_put;
374
375 st->socket->sk->sk_reuse = 1;
376
377 err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr,
378 ctl->addr.sa_data_len);
379 if (err)
380 goto err_out_socket_release;
381
382 err = kernel_listen(st->socket, 1024);
383 if (err)
384 goto err_out_socket_release;
385 n->state = st;
386
387 err = dst_poll_init(st);
388 if (err)
389 goto err_out_socket_release;
390
391 dst_state_get(st);
392
393 err = thread_pool_schedule(n->pool, dst_thread_setup,
394 dst_accept, st, MAX_SCHEDULE_TIMEOUT);
395 if (err)
396 goto err_out_poll_exit;
397
398 return 0;
399
400err_out_poll_exit:
401 dst_poll_exit(st);
402err_out_socket_release:
403 dst_state_socket_release(st);
404err_out_put:
405 dst_state_put(st);
406err_out_exit:
407 n->state = NULL;
408 return err;
409}
410
411/*
412 * Free bio and related private data.
413 * Also drop a reference counter for appropriate state,
414 * which waits when there are no more block IOs in-flight.
415 */
416static void dst_bio_destructor(struct bio *bio)
417{
418 struct bio_vec *bv;
419 struct dst_export_priv *priv = bio->bi_private;
420 int i;
421
422 bio_for_each_segment(bv, bio, i) {
423 if (!bv->bv_page)
424 break;
425
426 __free_page(bv->bv_page);
427 }
428
429 if (priv)
430 dst_state_put(priv->state);
431 bio_free(bio, dst_bio_set);
432}
433
434/*
435 * Block IO completion. Queue request to be sent back to
436 * the client (or just confirmation).
437 */
438static void dst_bio_end_io(struct bio *bio, int err)
439{
440 struct dst_export_priv *p = bio->bi_private;
441 struct dst_state *st = p->state;
442 unsigned long flags;
443
444 spin_lock_irqsave(&st->request_lock, flags);
445 list_add_tail(&p->request_entry, &st->request_list);
446 spin_unlock_irqrestore(&st->request_lock, flags);
447
448 wake_up(&st->thread_wait);
449}
450
451/*
452 * Allocate read request for the server.
453 */
454static int dst_export_read_request(struct bio *bio, unsigned int total_size)
455{
456 unsigned int size;
457 struct page *page;
458 int err;
459
460 while (total_size) {
461 err = -ENOMEM;
462 page = alloc_page(GFP_KERNEL);
463 if (!page)
464 goto err_out_exit;
465
466 size = min_t(unsigned int, PAGE_SIZE, total_size);
467
468 err = bio_add_page(bio, page, size, 0);
469 dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n",
470 __func__, (u64)bio->bi_sector, bio->bi_size,
471 size, err);
472 if (err <= 0)
473 goto err_out_free_page;
474
475 total_size -= size;
476 }
477
478 return 0;
479
480err_out_free_page:
481 __free_page(page);
482err_out_exit:
483 return err;
484}
485
486/*
487 * Allocate write request for the server.
488 * Should not only get pages, but also read data from the network.
489 */
490static int dst_export_write_request(struct dst_state *st,
491 struct bio *bio, unsigned int total_size)
492{
493 unsigned int size;
494 struct page *page;
495 void *data;
496 int err;
497
498 while (total_size) {
499 err = -ENOMEM;
500 page = alloc_page(GFP_KERNEL);
501 if (!page)
502 goto err_out_exit;
503
504 data = kmap(page);
505 if (!data)
506 goto err_out_free_page;
507
508 size = min_t(unsigned int, PAGE_SIZE, total_size);
509
510 err = dst_data_recv(st, data, size);
511 if (err)
512 goto err_out_unmap_page;
513
514 err = bio_add_page(bio, page, size, 0);
515 if (err <= 0)
516 goto err_out_unmap_page;
517
518 kunmap(page);
519
520 total_size -= size;
521 }
522
523 return 0;
524
525err_out_unmap_page:
526 kunmap(page);
527err_out_free_page:
528 __free_page(page);
529err_out_exit:
530 return err;
531}
532
533/*
534 * Groovy, we've gotten an IO request from the client.
535 * Allocate BIO from the bioset, private data from the mempool
536 * and lots of pages for IO.
537 */
538int dst_process_io(struct dst_state *st)
539{
540 struct dst_node *n = st->node;
541 struct dst_cmd *cmd = st->data;
542 struct bio *bio;
543 struct dst_export_priv *priv;
544 int err = -ENOMEM;
545
546 if (unlikely(!n->bdev)) {
547 err = -EINVAL;
548 goto err_out_exit;
549 }
550
551 bio = bio_alloc_bioset(GFP_KERNEL,
552 PAGE_ALIGN(cmd->size) >> PAGE_SHIFT,
553 dst_bio_set);
554 if (!bio)
555 goto err_out_exit;
556
557 priv = (struct dst_export_priv *)(((void *)bio) -
558 sizeof (struct dst_export_priv));
559
560 priv->state = dst_state_get(st);
561 priv->bio = bio;
562
563 bio->bi_private = priv;
564 bio->bi_end_io = dst_bio_end_io;
565 bio->bi_destructor = dst_bio_destructor;
566 bio->bi_bdev = n->bdev;
567
568 /*
569 * Server side is only interested in two low bits:
570 * uptodate (set by itself actually) and rw block
571 */
572 bio->bi_flags |= cmd->flags & 3;
573
574 bio->bi_rw = cmd->rw;
575 bio->bi_size = 0;
576 bio->bi_sector = cmd->sector;
577
578 dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id);
579
580 priv->cmd.flags = 0;
581 priv->cmd.size = cmd->size;
582
583 if (bio_data_dir(bio) == WRITE) {
584 err = dst_recv_cdata(st, priv->cmd.hash);
585 if (err)
586 goto err_out_free;
587
588 err = dst_export_write_request(st, bio, cmd->size);
589 if (err)
590 goto err_out_free;
591
592 if (dst_need_crypto(n))
593 return dst_export_crypto(n, bio);
594 } else {
595 err = dst_export_read_request(bio, cmd->size);
596 if (err)
597 goto err_out_free;
598 }
599
600 dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n",
601 __func__, (u64)bio->bi_sector, bio->bi_size,
602 bio->bi_rw, bio_data_dir(bio),
603 bio->bi_flags, bio->bi_phys_segments);
604
605 generic_make_request(bio);
606
607 return 0;
608
609err_out_free:
610 bio_put(bio);
611err_out_exit:
612 return err;
613}
614
615/*
616 * Ok, block IO is ready, let's send it back to the client...
617 */
618int dst_export_send_bio(struct bio *bio)
619{
620 struct dst_export_priv *p = bio->bi_private;
621 struct dst_state *st = p->state;
622 struct dst_cmd *cmd = &p->cmd;
623 int err;
624
625 dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n",
626 __func__, cmd->id, (u64)bio->bi_sector, bio->bi_size,
627 cmd->csize, bio->bi_flags, bio->bi_rw);
628
629 dst_convert_cmd(cmd);
630
631 dst_state_lock(st);
632 if (!st->socket) {
633 err = -ECONNRESET;
634 goto err_out_unlock;
635 }
636
637 if (bio_data_dir(bio) == WRITE) {
638 /* ... or just confirmation that writing has completed. */
639 cmd->size = cmd->csize = 0;
640 err = dst_data_send_header(st->socket, cmd,
641 sizeof(struct dst_cmd), 0);
642 if (err)
643 goto err_out_unlock;
644 } else {
645 err = dst_send_bio(st, cmd, bio);
646 if (err)
647 goto err_out_unlock;
648 }
649
650 dst_state_unlock(st);
651
652 bio_put(bio);
653 return 0;
654
655err_out_unlock:
656 dst_state_unlock(st);
657
658 bio_put(bio);
659 return err;
660}
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c
deleted file mode 100644
index 02a05e6c48c3..000000000000
--- a/drivers/staging/dst/state.c
+++ /dev/null
@@ -1,844 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/buffer_head.h>
17#include <linux/blkdev.h>
18#include <linux/bio.h>
19#include <linux/connector.h>
20#include <linux/dst.h>
21#include <linux/device.h>
22#include <linux/in.h>
23#include <linux/in6.h>
24#include <linux/socket.h>
25#include <linux/slab.h>
26
27#include <net/sock.h>
28
29/*
30 * Polling machinery.
31 */
32
33struct dst_poll_helper {
34 poll_table pt;
35 struct dst_state *st;
36};
37
38static int dst_queue_wake(wait_queue_t *wait, unsigned mode,
39 int sync, void *key)
40{
41 struct dst_state *st = container_of(wait, struct dst_state, wait);
42
43 wake_up(&st->thread_wait);
44 return 1;
45}
46
47static void dst_queue_func(struct file *file, wait_queue_head_t *whead,
48 poll_table *pt)
49{
50 struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st;
51
52 st->whead = whead;
53 init_waitqueue_func_entry(&st->wait, dst_queue_wake);
54 add_wait_queue(whead, &st->wait);
55}
56
57void dst_poll_exit(struct dst_state *st)
58{
59 if (st->whead) {
60 remove_wait_queue(st->whead, &st->wait);
61 st->whead = NULL;
62 }
63}
64
65int dst_poll_init(struct dst_state *st)
66{
67 struct dst_poll_helper ph;
68
69 ph.st = st;
70 init_poll_funcptr(&ph.pt, &dst_queue_func);
71
72 st->socket->ops->poll(NULL, st->socket, &ph.pt);
73 return 0;
74}
75
76/*
77 * Header receiving function - may block.
78 */
79static int dst_data_recv_header(struct socket *sock,
80 void *data, unsigned int size, int block)
81{
82 struct msghdr msg;
83 struct kvec iov;
84 int err;
85
86 iov.iov_base = data;
87 iov.iov_len = size;
88
89 msg.msg_iov = (struct iovec *)&iov;
90 msg.msg_iovlen = 1;
91 msg.msg_name = NULL;
92 msg.msg_namelen = 0;
93 msg.msg_control = NULL;
94 msg.msg_controllen = 0;
95 msg.msg_flags = (block) ? MSG_WAITALL : MSG_DONTWAIT;
96
97 err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len,
98 msg.msg_flags);
99 if (err != size)
100 return -1;
101
102 return 0;
103}
104
105/*
106 * Header sending function - may block.
107 */
108int dst_data_send_header(struct socket *sock,
109 void *data, unsigned int size, int more)
110{
111 struct msghdr msg;
112 struct kvec iov;
113 int err;
114
115 iov.iov_base = data;
116 iov.iov_len = size;
117
118 msg.msg_iov = (struct iovec *)&iov;
119 msg.msg_iovlen = 1;
120 msg.msg_name = NULL;
121 msg.msg_namelen = 0;
122 msg.msg_control = NULL;
123 msg.msg_controllen = 0;
124 msg.msg_flags = MSG_WAITALL | (more ? MSG_MORE : 0);
125
126 err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
127 if (err != size) {
128 dprintk("%s: size: %u, more: %d, err: %d.\n",
129 __func__, size, more, err);
130 return -1;
131 }
132
133 return 0;
134}
135
136/*
137 * Block autoconfiguration: request size of the storage and permissions.
138 */
139static int dst_request_remote_config(struct dst_state *st)
140{
141 struct dst_node *n = st->node;
142 int err = -EINVAL;
143 struct dst_cmd *cmd = st->data;
144
145 memset(cmd, 0, sizeof(struct dst_cmd));
146 cmd->cmd = DST_CFG;
147
148 dst_convert_cmd(cmd);
149
150 err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
151 if (err)
152 goto out;
153
154 err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1);
155 if (err)
156 goto out;
157
158 dst_convert_cmd(cmd);
159
160 if (cmd->cmd != DST_CFG) {
161 err = -EINVAL;
162 dprintk("%s: checking result: cmd: %d, size reported: %llu.\n",
163 __func__, cmd->cmd, cmd->sector);
164 goto out;
165 }
166
167 if (n->size != 0)
168 n->size = min_t(loff_t, n->size, cmd->sector);
169 else
170 n->size = cmd->sector;
171
172 n->info->size = n->size;
173 st->permissions = cmd->rw;
174
175out:
176 dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n",
177 __func__, n, err, n->size, st->permissions);
178 return err;
179}
180
181/*
182 * Socket machinery.
183 */
184
185#define DST_DEFAULT_TIMEO 20000
186
187int dst_state_socket_create(struct dst_state *st)
188{
189 int err;
190 struct socket *sock;
191 struct dst_network_ctl *ctl = &st->ctl;
192
193 err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock);
194 if (err < 0)
195 return err;
196
197 sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo =
198 msecs_to_jiffies(DST_DEFAULT_TIMEO);
199 sock->sk->sk_allocation = GFP_NOIO;
200
201 st->socket = st->read_socket = sock;
202 return 0;
203}
204
205void dst_state_socket_release(struct dst_state *st)
206{
207 dprintk("%s: st: %p, socket: %p, n: %p.\n",
208 __func__, st, st->socket, st->node);
209 if (st->socket) {
210 sock_release(st->socket);
211 st->socket = NULL;
212 st->read_socket = NULL;
213 }
214}
215
216void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str)
217{
218 if (sk->ops->family == AF_INET) {
219 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
220 printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n", str,
221 NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
222 } else if (sk->ops->family == AF_INET6) {
223 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
224 printk(KERN_INFO "%s %pi6:%d",
225 str, &sin->sin6_addr, ntohs(sin->sin6_port));
226 }
227}
228
229void dst_state_exit_connected(struct dst_state *st)
230{
231 if (st->socket) {
232 dst_poll_exit(st);
233 st->socket->ops->shutdown(st->socket, 2);
234
235 dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr,
236 "Disconnected peer");
237 dst_state_socket_release(st);
238 }
239}
240
241static int dst_state_init_connected(struct dst_state *st)
242{
243 int err;
244 struct dst_network_ctl *ctl = &st->ctl;
245
246 err = dst_state_socket_create(st);
247 if (err)
248 goto err_out_exit;
249
250 err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr,
251 st->ctl.addr.sa_data_len, 0);
252 if (err)
253 goto err_out_release;
254
255 err = dst_poll_init(st);
256 if (err)
257 goto err_out_release;
258
259 dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr,
260 "Connected to peer");
261
262 return 0;
263
264err_out_release:
265 dst_state_socket_release(st);
266err_out_exit:
267 return err;
268}
269
270/*
271 * State reset is used to reconnect to the remote peer.
272 * May fail, but who cares, we will try again later.
273 */
274static inline void dst_state_reset_nolock(struct dst_state *st)
275{
276 dst_state_exit_connected(st);
277 dst_state_init_connected(st);
278}
279
280static inline void dst_state_reset(struct dst_state *st)
281{
282 dst_state_lock(st);
283 dst_state_reset_nolock(st);
284 dst_state_unlock(st);
285}
286
287/*
288 * Basic network sending/receiving functions.
289 * Blocked mode is used.
290 */
291static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size)
292{
293 struct msghdr msg;
294 struct kvec iov;
295 int err;
296
297 BUG_ON(!size);
298
299 iov.iov_base = buf;
300 iov.iov_len = size;
301
302 msg.msg_iov = (struct iovec *)&iov;
303 msg.msg_iovlen = 1;
304 msg.msg_name = NULL;
305 msg.msg_namelen = 0;
306 msg.msg_control = NULL;
307 msg.msg_controllen = 0;
308 msg.msg_flags = MSG_DONTWAIT;
309
310 err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
311 msg.msg_flags);
312 if (err <= 0) {
313 dprintk("%s: failed to recv data: size: %llu, err: %d.\n",
314 __func__, size, err);
315 if (err == 0)
316 err = -ECONNRESET;
317
318 dst_state_exit_connected(st);
319 }
320
321 return err;
322}
323
324/*
325 * Ping command to early detect failed nodes.
326 */
327static int dst_send_ping(struct dst_state *st)
328{
329 struct dst_cmd *cmd = st->data;
330 int err = -ECONNRESET;
331
332 dst_state_lock(st);
333 if (st->socket) {
334 memset(cmd, 0, sizeof(struct dst_cmd));
335
336 cmd->cmd = __cpu_to_be32(DST_PING);
337
338 err = dst_data_send_header(st->socket, cmd,
339 sizeof(struct dst_cmd), 0);
340 }
341 dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__,
342 st, st->socket, err);
343 dst_state_unlock(st);
344
345 return err;
346}
347
348/*
349 * Receiving function, which should either return error or read
350 * whole block request. If there was no traffic for a one second,
351 * send a ping, since remote node may die.
352 */
353int dst_data_recv(struct dst_state *st, void *data, unsigned int size)
354{
355 unsigned int revents = 0;
356 unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
357 unsigned int mask = err_mask | POLLIN;
358 struct dst_node *n = st->node;
359 int err = 0;
360
361 while (size && !err) {
362 revents = dst_state_poll(st);
363
364 if (!(revents & mask)) {
365 DEFINE_WAIT(wait);
366
367 for (;;) {
368 prepare_to_wait(&st->thread_wait, &wait,
369 TASK_INTERRUPTIBLE);
370 if (!n->trans_scan_timeout || st->need_exit)
371 break;
372
373 revents = dst_state_poll(st);
374
375 if (revents & mask)
376 break;
377
378 if (signal_pending(current))
379 break;
380
381 if (!schedule_timeout(HZ)) {
382 err = dst_send_ping(st);
383 if (err)
384 return err;
385 }
386
387 continue;
388 }
389 finish_wait(&st->thread_wait, &wait);
390 }
391
392 err = -ECONNRESET;
393 dst_state_lock(st);
394
395 if (st->socket && (st->read_socket == st->socket) &&
396 (revents & POLLIN)) {
397 err = dst_data_recv_raw(st, data, size);
398 if (err > 0) {
399 data += err;
400 size -= err;
401 err = 0;
402 }
403 }
404
405 if (revents & err_mask || !st->socket) {
406 dprintk("%s: revents: %x, socket: %p, size: %u, "
407 "err: %d.\n", __func__, revents,
408 st->socket, size, err);
409 err = -ECONNRESET;
410 }
411
412 dst_state_unlock(st);
413
414 if (!n->trans_scan_timeout)
415 err = -ENODEV;
416 }
417
418 return err;
419}
420
421/*
422 * Send block autoconf reply.
423 */
424static int dst_process_cfg(struct dst_state *st)
425{
426 struct dst_node *n = st->node;
427 struct dst_cmd *cmd = st->data;
428 int err;
429
430 cmd->sector = n->size;
431 cmd->rw = st->permissions;
432
433 dst_convert_cmd(cmd);
434
435 dst_state_lock(st);
436 err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
437 dst_state_unlock(st);
438
439 return err;
440}
441
442/*
443 * Receive block IO from the network.
444 */
445static int dst_recv_bio(struct dst_state *st, struct bio *bio,
446 unsigned int total_size)
447{
448 struct bio_vec *bv;
449 int i, err;
450 void *data;
451 unsigned int sz;
452
453 bio_for_each_segment(bv, bio, i) {
454 sz = min(total_size, bv->bv_len);
455
456 dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, "
457 "off: %u.\n", __func__, (u64)bio->bi_sector,
458 bio->bi_size, total_size, bv->bv_len, sz,
459 bv->bv_offset);
460
461 data = kmap(bv->bv_page) + bv->bv_offset;
462 err = dst_data_recv(st, data, sz);
463 kunmap(bv->bv_page);
464
465 bv->bv_len = sz;
466
467 if (err)
468 return err;
469
470 total_size -= sz;
471 if (total_size == 0)
472 break;
473 }
474
475 return 0;
476}
477
478/*
479 * Our block IO has just completed and arrived: get it.
480 */
481static int dst_process_io_response(struct dst_state *st)
482{
483 struct dst_node *n = st->node;
484 struct dst_cmd *cmd = st->data;
485 struct dst_trans *t;
486 int err = 0;
487 struct bio *bio;
488
489 mutex_lock(&n->trans_lock);
490 t = dst_trans_search(n, cmd->id);
491 mutex_unlock(&n->trans_lock);
492
493 if (!t)
494 goto err_out_exit;
495
496 bio = t->bio;
497
498 dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n",
499 __func__, (u64)bio->bi_sector, bio->bi_size, cmd->size,
500 cmd->csize, bio_data_dir(bio));
501
502 if (bio_data_dir(bio) == READ) {
503 if (bio->bi_size != cmd->size - cmd->csize)
504 goto err_out_exit;
505
506 if (dst_need_crypto(n)) {
507 err = dst_recv_cdata(st, t->cmd.hash);
508 if (err)
509 goto err_out_exit;
510 }
511
512 err = dst_recv_bio(st, t->bio, bio->bi_size);
513 if (err)
514 goto err_out_exit;
515
516 if (dst_need_crypto(n))
517 return dst_trans_crypto(t);
518 } else {
519 err = -EBADMSG;
520 if (cmd->size || cmd->csize)
521 goto err_out_exit;
522 }
523
524 dst_trans_remove(t);
525 dst_trans_put(t);
526
527 return 0;
528
529err_out_exit:
530 return err;
531}
532
533/*
534 * Receive crypto data.
535 */
536int dst_recv_cdata(struct dst_state *st, void *cdata)
537{
538 struct dst_cmd *cmd = st->data;
539 struct dst_node *n = st->node;
540 struct dst_crypto_ctl *c = &n->crypto;
541 int err;
542
543 if (cmd->csize != c->crypto_attached_size) {
544 dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, "
545 "csize: %u != digest size %u.\n",
546 __func__, cmd->cmd, cmd->sector, cmd->size,
547 cmd->csize, c->crypto_attached_size);
548 err = -EINVAL;
549 goto err_out_exit;
550 }
551
552 err = dst_data_recv(st, cdata, cmd->csize);
553 if (err)
554 goto err_out_exit;
555
556 cmd->size -= cmd->csize;
557 return 0;
558
559err_out_exit:
560 return err;
561}
562
563/*
564 * Receive the command and start its processing.
565 */
566static int dst_recv_processing(struct dst_state *st)
567{
568 int err = -EINTR;
569 struct dst_cmd *cmd = st->data;
570
571 /*
572 * If socket will be reset after this statement, then
573 * dst_data_recv() will just fail and loop will
574 * start again, so it can be done without any locks.
575 *
576 * st->read_socket is needed to prevents state machine
577 * breaking between this data reading and subsequent one
578 * in protocol specific functions during connection reset.
579 * In case of reset we have to read next command and do
580 * not expect data for old command to magically appear in
581 * new connection.
582 */
583 st->read_socket = st->socket;
584 err = dst_data_recv(st, cmd, sizeof(struct dst_cmd));
585 if (err)
586 goto out_exit;
587
588 dst_convert_cmd(cmd);
589
590 dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, "
591 "sector: %llu, flags: %llx, rw: %llx.\n",
592 __func__, cmd->cmd, cmd->size,
593 cmd->csize, cmd->id, cmd->sector,
594 cmd->flags, cmd->rw);
595
596 /*
597 * This should catch protocol breakage and random garbage
598 * instead of commands.
599 */
600 if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) {
601 err = -EBADMSG;
602 goto out_exit;
603 }
604
605 err = -EPROTO;
606 switch (cmd->cmd) {
607 case DST_IO_RESPONSE:
608 err = dst_process_io_response(st);
609 break;
610 case DST_IO:
611 err = dst_process_io(st);
612 break;
613 case DST_CFG:
614 err = dst_process_cfg(st);
615 break;
616 case DST_PING:
617 err = 0;
618 break;
619 default:
620 break;
621 }
622
623out_exit:
624 return err;
625}
626
627/*
628 * Receiving thread. For the client node we should try to reconnect,
629 * for accepted client we just drop the state and expect it to reconnect.
630 */
631static int dst_recv(void *init_data, void *schedule_data)
632{
633 struct dst_state *st = schedule_data;
634 struct dst_node *n = init_data;
635 int err = 0;
636
637 dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n",
638 __func__, st, n, n->trans_scan_timeout, st->need_exit);
639
640 while (n->trans_scan_timeout && !st->need_exit) {
641 err = dst_recv_processing(st);
642 if (err < 0) {
643 if (!st->ctl.type)
644 break;
645
646 if (!n->trans_scan_timeout || st->need_exit)
647 break;
648
649 dst_state_reset(st);
650 msleep(1000);
651 }
652 }
653
654 st->need_exit = 1;
655 wake_up(&st->thread_wait);
656
657 dprintk("%s: freeing receiving socket st: %p.\n", __func__, st);
658 dst_state_lock(st);
659 dst_state_exit_connected(st);
660 dst_state_unlock(st);
661 dst_state_put(st);
662
663 dprintk("%s: freed receiving socket st: %p.\n", __func__, st);
664
665 return err;
666}
667
668/*
669 * Network state dies here and borns couple of lines below.
670 * This object is the main network state processing engine:
671 * sending, receiving, reconnections, all network related
672 * tasks are handled on behalf of the state.
673 */
674static void dst_state_free(struct dst_state *st)
675{
676 dprintk("%s: st: %p.\n", __func__, st);
677 if (st->cleanup)
678 st->cleanup(st);
679 kfree(st->data);
680 kfree(st);
681}
682
683struct dst_state *dst_state_alloc(struct dst_node *n)
684{
685 struct dst_state *st;
686 int err = -ENOMEM;
687
688 st = kzalloc(sizeof(struct dst_state), GFP_KERNEL);
689 if (!st)
690 goto err_out_exit;
691
692 st->node = n;
693 st->need_exit = 0;
694
695 st->size = PAGE_SIZE;
696 st->data = kmalloc(st->size, GFP_KERNEL);
697 if (!st->data)
698 goto err_out_free;
699
700 spin_lock_init(&st->request_lock);
701 INIT_LIST_HEAD(&st->request_list);
702
703 mutex_init(&st->state_lock);
704 init_waitqueue_head(&st->thread_wait);
705
706 /*
707 * One for processing thread, another one for node itself.
708 */
709 atomic_set(&st->refcnt, 2);
710
711 dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node);
712
713 return st;
714
715err_out_free:
716 kfree(st);
717err_out_exit:
718 return ERR_PTR(err);
719}
720
721int dst_state_schedule_receiver(struct dst_state *st)
722{
723 return thread_pool_schedule_private(st->node->pool, dst_thread_setup,
724 dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node);
725}
726
727/*
728 * Initialize client's connection to the remote peer: allocate state,
729 * connect and perform block IO autoconfiguration.
730 */
731int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r)
732{
733 struct dst_state *st;
734 int err = -ENOMEM;
735
736 st = dst_state_alloc(n);
737 if (IS_ERR(st)) {
738 err = PTR_ERR(st);
739 goto err_out_exit;
740 }
741 memcpy(&st->ctl, r, sizeof(struct dst_network_ctl));
742
743 err = dst_state_init_connected(st);
744 if (err)
745 goto err_out_free_data;
746
747 err = dst_request_remote_config(st);
748 if (err)
749 goto err_out_exit_connected;
750 n->state = st;
751
752 err = dst_state_schedule_receiver(st);
753 if (err)
754 goto err_out_exit_connected;
755
756 return 0;
757
758err_out_exit_connected:
759 dst_state_exit_connected(st);
760err_out_free_data:
761 dst_state_free(st);
762err_out_exit:
763 n->state = NULL;
764 return err;
765}
766
767void dst_state_put(struct dst_state *st)
768{
769 dprintk("%s: st: %p, refcnt: %d.\n",
770 __func__, st, atomic_read(&st->refcnt));
771 if (atomic_dec_and_test(&st->refcnt))
772 dst_state_free(st);
773}
774
775/*
776 * Send block IO to the network one by one using zero-copy ->sendpage().
777 */
778int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio)
779{
780 struct bio_vec *bv;
781 struct dst_crypto_ctl *c = &st->node->crypto;
782 int err, i = 0;
783 int flags = MSG_WAITALL;
784
785 err = dst_data_send_header(st->socket, cmd,
786 sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt);
787 if (err)
788 goto err_out_exit;
789
790 bio_for_each_segment(bv, bio, i) {
791 if (i < bio->bi_vcnt - 1)
792 flags |= MSG_MORE;
793
794 err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset,
795 bv->bv_len, flags);
796 if (err <= 0)
797 goto err_out_exit;
798 }
799
800 return 0;
801
802err_out_exit:
803 dprintk("%s: %d/%d, flags: %x, err: %d.\n",
804 __func__, i, bio->bi_vcnt, flags, err);
805 return err;
806}
807
808/*
809 * Send transaction to the remote peer.
810 */
811int dst_trans_send(struct dst_trans *t)
812{
813 int err;
814 struct dst_state *st = t->n->state;
815 struct bio *bio = t->bio;
816
817 dst_convert_cmd(&t->cmd);
818
819 dst_state_lock(st);
820 if (!st->socket) {
821 err = dst_state_init_connected(st);
822 if (err)
823 goto err_out_unlock;
824 }
825
826 if (bio_data_dir(bio) == WRITE) {
827 err = dst_send_bio(st, &t->cmd, t->bio);
828 } else {
829 err = dst_data_send_header(st->socket, &t->cmd,
830 sizeof(struct dst_cmd), 0);
831 }
832 if (err)
833 goto err_out_reset;
834
835 dst_state_unlock(st);
836 return 0;
837
838err_out_reset:
839 dst_state_reset_nolock(st);
840err_out_unlock:
841 dst_state_unlock(st);
842
843 return err;
844}
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c
deleted file mode 100644
index 29a82b2602f3..000000000000
--- a/drivers/staging/dst/thread_pool.c
+++ /dev/null
@@ -1,348 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/kernel.h>
17#include <linux/dst.h>
18#include <linux/kthread.h>
19#include <linux/slab.h>
20
21/*
22 * Thread pool abstraction allows to schedule a work to be performed
23 * on behalf of kernel thread. One does not operate with threads itself,
24 * instead user provides setup and cleanup callbacks for thread pool itself,
25 * and action and cleanup callbacks for each submitted work.
26 *
27 * Each worker has private data initialized at creation time and data,
28 * provided by user at scheduling time.
29 *
30 * When action is being performed, thread can not be used by other users,
31 * instead they will sleep until there is free thread to pick their work.
32 */
33struct thread_pool_worker {
34 struct list_head worker_entry;
35
36 struct task_struct *thread;
37
38 struct thread_pool *pool;
39
40 int error;
41 int has_data;
42 int need_exit;
43 unsigned int id;
44
45 wait_queue_head_t wait;
46
47 void *private;
48 void *schedule_data;
49
50 int (*action)(void *private, void *schedule_data);
51 void (*cleanup)(void *private);
52};
53
54static void thread_pool_exit_worker(struct thread_pool_worker *w)
55{
56 kthread_stop(w->thread);
57
58 w->cleanup(w->private);
59 kfree(w);
60}
61
62/*
63 * Called to mark thread as ready and allow users to schedule new work.
64 */
65static void thread_pool_worker_make_ready(struct thread_pool_worker *w)
66{
67 struct thread_pool *p = w->pool;
68
69 mutex_lock(&p->thread_lock);
70
71 if (!w->need_exit) {
72 list_move_tail(&w->worker_entry, &p->ready_list);
73 w->has_data = 0;
74 mutex_unlock(&p->thread_lock);
75
76 wake_up(&p->wait);
77 } else {
78 p->thread_num--;
79 list_del(&w->worker_entry);
80 mutex_unlock(&p->thread_lock);
81
82 thread_pool_exit_worker(w);
83 }
84}
85
86/*
87 * Thread action loop: waits until there is new work.
88 */
89static int thread_pool_worker_func(void *data)
90{
91 struct thread_pool_worker *w = data;
92
93 while (!kthread_should_stop()) {
94 wait_event_interruptible(w->wait,
95 kthread_should_stop() || w->has_data);
96
97 if (kthread_should_stop())
98 break;
99
100 if (!w->has_data)
101 continue;
102
103 w->action(w->private, w->schedule_data);
104 thread_pool_worker_make_ready(w);
105 }
106
107 return 0;
108}
109
110/*
111 * Remove single worker without specifying which one.
112 */
113void thread_pool_del_worker(struct thread_pool *p)
114{
115 struct thread_pool_worker *w = NULL;
116
117 while (!w && p->thread_num) {
118 wait_event(p->wait, !list_empty(&p->ready_list) ||
119 !p->thread_num);
120
121 dprintk("%s: locking list_empty: %d, thread_num: %d.\n",
122 __func__, list_empty(&p->ready_list),
123 p->thread_num);
124
125 mutex_lock(&p->thread_lock);
126 if (!list_empty(&p->ready_list)) {
127 w = list_first_entry(&p->ready_list,
128 struct thread_pool_worker,
129 worker_entry);
130
131 dprintk("%s: deleting w: %p, thread_num: %d, "
132 "list: %p [%p.%p].\n", __func__,
133 w, p->thread_num, &p->ready_list,
134 p->ready_list.prev, p->ready_list.next);
135
136 p->thread_num--;
137 list_del(&w->worker_entry);
138 }
139 mutex_unlock(&p->thread_lock);
140 }
141
142 if (w)
143 thread_pool_exit_worker(w);
144 dprintk("%s: deleted w: %p, thread_num: %d.\n",
145 __func__, w, p->thread_num);
146}
147
148/*
149 * Remove a worker with given ID.
150 */
151void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id)
152{
153 struct thread_pool_worker *w;
154 int found = 0;
155
156 mutex_lock(&p->thread_lock);
157 list_for_each_entry(w, &p->ready_list, worker_entry) {
158 if (w->id == id) {
159 found = 1;
160 p->thread_num--;
161 list_del(&w->worker_entry);
162 break;
163 }
164 }
165
166 if (!found) {
167 list_for_each_entry(w, &p->active_list, worker_entry) {
168 if (w->id == id) {
169 w->need_exit = 1;
170 break;
171 }
172 }
173 }
174 mutex_unlock(&p->thread_lock);
175
176 if (found)
177 thread_pool_exit_worker(w);
178}
179
180/*
181 * Add new worker thread with given parameters.
182 * If initialization callback fails, return error.
183 */
184int thread_pool_add_worker(struct thread_pool *p,
185 char *name,
186 unsigned int id,
187 void *(*init)(void *private),
188 void (*cleanup)(void *private),
189 void *private)
190{
191 struct thread_pool_worker *w;
192 int err = -ENOMEM;
193
194 w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL);
195 if (!w)
196 goto err_out_exit;
197
198 w->pool = p;
199 init_waitqueue_head(&w->wait);
200 w->cleanup = cleanup;
201 w->id = id;
202
203 w->thread = kthread_run(thread_pool_worker_func, w, "%s", name);
204 if (IS_ERR(w->thread)) {
205 err = PTR_ERR(w->thread);
206 goto err_out_free;
207 }
208
209 w->private = init(private);
210 if (IS_ERR(w->private)) {
211 err = PTR_ERR(w->private);
212 goto err_out_stop_thread;
213 }
214
215 mutex_lock(&p->thread_lock);
216 list_add_tail(&w->worker_entry, &p->ready_list);
217 p->thread_num++;
218 mutex_unlock(&p->thread_lock);
219
220 return 0;
221
222err_out_stop_thread:
223 kthread_stop(w->thread);
224err_out_free:
225 kfree(w);
226err_out_exit:
227 return err;
228}
229
230/*
231 * Destroy the whole pool.
232 */
233void thread_pool_destroy(struct thread_pool *p)
234{
235 while (p->thread_num) {
236 dprintk("%s: num: %d.\n", __func__, p->thread_num);
237 thread_pool_del_worker(p);
238 }
239
240 kfree(p);
241}
242
243/*
244 * Create a pool with given number of threads.
245 * They will have sequential IDs started from zero.
246 */
247struct thread_pool *thread_pool_create(int num, char *name,
248 void *(*init)(void *private),
249 void (*cleanup)(void *private),
250 void *private)
251{
252 struct thread_pool_worker *w, *tmp;
253 struct thread_pool *p;
254 int err = -ENOMEM;
255 int i;
256
257 p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL);
258 if (!p)
259 goto err_out_exit;
260
261 init_waitqueue_head(&p->wait);
262 mutex_init(&p->thread_lock);
263 INIT_LIST_HEAD(&p->ready_list);
264 INIT_LIST_HEAD(&p->active_list);
265 p->thread_num = 0;
266
267 for (i = 0; i < num; ++i) {
268 err = thread_pool_add_worker(p, name, i, init,
269 cleanup, private);
270 if (err)
271 goto err_out_free_all;
272 }
273
274 return p;
275
276err_out_free_all:
277 list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
278 list_del(&w->worker_entry);
279 thread_pool_exit_worker(w);
280 }
281 kfree(p);
282err_out_exit:
283 return ERR_PTR(err);
284}
285
286/*
287 * Schedule execution of the action on a given thread,
288 * provided ID pointer has to match previously stored
289 * private data.
290 */
291int thread_pool_schedule_private(struct thread_pool *p,
292 int (*setup)(void *private, void *data),
293 int (*action)(void *private, void *data),
294 void *data, long timeout, void *id)
295{
296 struct thread_pool_worker *w, *tmp, *worker = NULL;
297 int err = 0;
298
299 while (!worker && !err) {
300 timeout = wait_event_interruptible_timeout(p->wait,
301 !list_empty(&p->ready_list),
302 timeout);
303
304 if (!timeout) {
305 err = -ETIMEDOUT;
306 break;
307 }
308
309 worker = NULL;
310 mutex_lock(&p->thread_lock);
311 list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
312 if (id && id != w->private)
313 continue;
314
315 worker = w;
316
317 list_move_tail(&w->worker_entry, &p->active_list);
318
319 err = setup(w->private, data);
320 if (!err) {
321 w->schedule_data = data;
322 w->action = action;
323 w->has_data = 1;
324 wake_up(&w->wait);
325 } else {
326 list_move_tail(&w->worker_entry,
327 &p->ready_list);
328 }
329
330 break;
331 }
332 mutex_unlock(&p->thread_lock);
333 }
334
335 return err;
336}
337
338/*
339 * Schedule execution on arbitrary thread from the pool.
340 */
341int thread_pool_schedule(struct thread_pool *p,
342 int (*setup)(void *private, void *data),
343 int (*action)(void *private, void *data),
344 void *data, long timeout)
345{
346 return thread_pool_schedule_private(p, setup,
347 action, data, timeout, NULL);
348}
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c
deleted file mode 100644
index 1c36a6bc31d5..000000000000
--- a/drivers/staging/dst/trans.c
+++ /dev/null
@@ -1,337 +0,0 @@
1/*
2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
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
16#include <linux/bio.h>
17#include <linux/dst.h>
18#include <linux/slab.h>
19#include <linux/mempool.h>
20
21/*
22 * Transaction memory pool size.
23 */
24static int dst_mempool_num = 32;
25module_param(dst_mempool_num, int, 0644);
26
27/*
28 * Transaction tree management.
29 */
30static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new)
31{
32 if (gen < new)
33 return 1;
34 if (gen > new)
35 return -1;
36 return 0;
37}
38
39struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen)
40{
41 struct rb_root *root = &node->trans_root;
42 struct rb_node *n = root->rb_node;
43 struct dst_trans *t, *ret = NULL;
44 int cmp;
45
46 while (n) {
47 t = rb_entry(n, struct dst_trans, trans_entry);
48
49 cmp = dst_trans_cmp(t->gen, gen);
50 if (cmp < 0)
51 n = n->rb_left;
52 else if (cmp > 0)
53 n = n->rb_right;
54 else {
55 ret = t;
56 break;
57 }
58 }
59
60 dprintk("%s: %s transaction: id: %llu.\n", __func__,
61 (ret) ? "found" : "not found", gen);
62
63 return ret;
64}
65
66static int dst_trans_insert(struct dst_trans *new)
67{
68 struct rb_root *root = &new->n->trans_root;
69 struct rb_node **n = &root->rb_node, *parent = NULL;
70 struct dst_trans *ret = NULL, *t;
71 int cmp;
72
73 while (*n) {
74 parent = *n;
75
76 t = rb_entry(parent, struct dst_trans, trans_entry);
77
78 cmp = dst_trans_cmp(t->gen, new->gen);
79 if (cmp < 0)
80 n = &parent->rb_left;
81 else if (cmp > 0)
82 n = &parent->rb_right;
83 else {
84 ret = t;
85 break;
86 }
87 }
88
89 new->send_time = jiffies;
90 if (ret) {
91 printk(KERN_DEBUG "%s: exist: old: gen: %llu, bio: %llu/%u, "
92 "send_time: %lu, new: gen: %llu, bio: %llu/%u, "
93 "send_time: %lu.\n", __func__,
94 ret->gen, (u64)ret->bio->bi_sector,
95 ret->bio->bi_size, ret->send_time,
96 new->gen, (u64)new->bio->bi_sector,
97 new->bio->bi_size, new->send_time);
98 return -EEXIST;
99 }
100
101 rb_link_node(&new->trans_entry, parent, n);
102 rb_insert_color(&new->trans_entry, root);
103
104 dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
105 __func__, new->gen, (u64)new->bio->bi_sector,
106 new->bio->bi_size, new->send_time);
107
108 return 0;
109}
110
111int dst_trans_remove_nolock(struct dst_trans *t)
112{
113 struct dst_node *n = t->n;
114
115 if (t->trans_entry.rb_parent_color) {
116 rb_erase(&t->trans_entry, &n->trans_root);
117 t->trans_entry.rb_parent_color = 0;
118 }
119 return 0;
120}
121
122int dst_trans_remove(struct dst_trans *t)
123{
124 int ret;
125 struct dst_node *n = t->n;
126
127 mutex_lock(&n->trans_lock);
128 ret = dst_trans_remove_nolock(t);
129 mutex_unlock(&n->trans_lock);
130
131 return ret;
132}
133
134/*
135 * When transaction is completed and there are no more users,
136 * we complete appriate block IO request with given error status.
137 */
138void dst_trans_put(struct dst_trans *t)
139{
140 if (atomic_dec_and_test(&t->refcnt)) {
141 struct bio *bio = t->bio;
142
143 dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n",
144 __func__, t, t->gen, bio);
145
146 bio_endio(bio, t->error);
147 bio_put(bio);
148
149 dst_node_put(t->n);
150 mempool_free(t, t->n->trans_pool);
151 }
152}
153
154/*
155 * Process given block IO request: allocate transaction, insert it into the tree
156 * and send/schedule crypto processing.
157 */
158int dst_process_bio(struct dst_node *n, struct bio *bio)
159{
160 struct dst_trans *t;
161 int err = -ENOMEM;
162
163 t = mempool_alloc(n->trans_pool, GFP_NOFS);
164 if (!t)
165 goto err_out_exit;
166
167 t->n = dst_node_get(n);
168 t->bio = bio;
169 t->error = 0;
170 t->retries = 0;
171 atomic_set(&t->refcnt, 1);
172 t->gen = atomic_long_inc_return(&n->gen);
173
174 t->enc = bio_data_dir(bio);
175 dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen);
176
177 mutex_lock(&n->trans_lock);
178 err = dst_trans_insert(t);
179 mutex_unlock(&n->trans_lock);
180 if (err)
181 goto err_out_free;
182
183 dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n",
184 __func__, t->gen, (u64)bio->bi_sector,
185 bio->bi_size, t->enc, dst_need_crypto(n));
186
187 if (dst_need_crypto(n) && t->enc)
188 dst_trans_crypto(t);
189 else
190 dst_trans_send(t);
191
192 return 0;
193
194err_out_free:
195 dst_node_put(n);
196 mempool_free(t, n->trans_pool);
197err_out_exit:
198 bio_endio(bio, err);
199 bio_put(bio);
200 return err;
201}
202
203/*
204 * Scan for timeout/stale transactions.
205 * Each transaction is being resent multiple times before error completion.
206 */
207static void dst_trans_scan(struct work_struct *work)
208{
209 struct dst_node *n = container_of(work, struct dst_node,
210 trans_work.work);
211 struct rb_node *rb_node;
212 struct dst_trans *t;
213 unsigned long timeout = n->trans_scan_timeout;
214 int num = 10 * n->trans_max_retries;
215
216 mutex_lock(&n->trans_lock);
217
218 for (rb_node = rb_first(&n->trans_root); rb_node; ) {
219 t = rb_entry(rb_node, struct dst_trans, trans_entry);
220
221 if (timeout && time_after(t->send_time + timeout, jiffies)
222 && t->retries == 0)
223 break;
224#if 0
225 dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n",
226 __func__, t, t->gen, n->name,
227 t->retries, n->trans_max_retries);
228#endif
229 if (--num == 0)
230 break;
231
232 dst_trans_get(t);
233
234 rb_node = rb_next(rb_node);
235
236 if (timeout && (++t->retries < n->trans_max_retries)) {
237 dst_trans_send(t);
238 } else {
239 t->error = -ETIMEDOUT;
240 dst_trans_remove_nolock(t);
241 dst_trans_put(t);
242 }
243
244 dst_trans_put(t);
245 }
246
247 mutex_unlock(&n->trans_lock);
248
249 /*
250 * If no timeout specified then system is in the middle of exiting
251 * process, so no need to reschedule scanning process again.
252 */
253 if (timeout) {
254 if (!num)
255 timeout = HZ;
256 schedule_delayed_work(&n->trans_work, timeout);
257 }
258}
259
260/*
261 * Flush all transactions and mark them as timed out.
262 * Destroy transaction pools.
263 */
264void dst_node_trans_exit(struct dst_node *n)
265{
266 struct dst_trans *t;
267 struct rb_node *rb_node;
268
269 if (!n->trans_cache)
270 return;
271
272 dprintk("%s: n: %p, cancelling the work.\n", __func__, n);
273 cancel_delayed_work_sync(&n->trans_work);
274 flush_scheduled_work();
275 dprintk("%s: n: %p, work has been cancelled.\n", __func__, n);
276
277 for (rb_node = rb_first(&n->trans_root); rb_node; ) {
278 t = rb_entry(rb_node, struct dst_trans, trans_entry);
279
280 dprintk("%s: t: %p, gen: %llu, n: %s.\n",
281 __func__, t, t->gen, n->name);
282
283 rb_node = rb_next(rb_node);
284
285 t->error = -ETIMEDOUT;
286 dst_trans_remove_nolock(t);
287 dst_trans_put(t);
288 }
289
290 mempool_destroy(n->trans_pool);
291 kmem_cache_destroy(n->trans_cache);
292}
293
294/*
295 * Initialize transaction storage for given node.
296 * Transaction stores not only control information,
297 * but also network command and crypto data (if needed)
298 * to reduce number of allocations. Thus transaction size
299 * differs from node to node.
300 */
301int dst_node_trans_init(struct dst_node *n, unsigned int size)
302{
303 /*
304 * We need this, since node with given name can be dropped from the
305 * hash table, but be still alive, so subsequent creation of the node
306 * with the same name may collide with existing cache name.
307 */
308
309 snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n);
310
311 n->trans_cache = kmem_cache_create(n->cache_name,
312 size + n->crypto.crypto_attached_size,
313 0, 0, NULL);
314 if (!n->trans_cache)
315 goto err_out_exit;
316
317 n->trans_pool = mempool_create_slab_pool(dst_mempool_num,
318 n->trans_cache);
319 if (!n->trans_pool)
320 goto err_out_cache_destroy;
321
322 mutex_init(&n->trans_lock);
323 n->trans_root = RB_ROOT;
324
325 INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan);
326 schedule_delayed_work(&n->trans_work, n->trans_scan_timeout);
327
328 dprintk("%s: n: %p, size: %u, crypto: %u.\n",
329 __func__, n, size, n->crypto.crypto_attached_size);
330
331 return 0;
332
333err_out_cache_destroy:
334 kmem_cache_destroy(n->trans_cache);
335err_out_exit:
336 return -ENOMEM;
337}
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index 6da843cc343c..e715e4dcb523 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -203,11 +203,14 @@ typedef struct _GLOBAL_t { /* Location: */
203 * 9-0: pr ndes 203 * 9-0: pr ndes
204 */ 204 */
205 205
206#define ET_DMA10_MASK 0x3FF /* 10 bit mask for DMA10W types */ 206#define ET_DMA12_MASK 0x0FFF /* 12 bit mask for DMA12W types */
207#define ET_DMA10_WRAP 0x400 207#define ET_DMA12_WRAP 0x1000
208#define ET_DMA4_MASK 0x00F /* 4 bit mask for DMA4W types */ 208#define ET_DMA10_MASK 0x03FF /* 10 bit mask for DMA10W types */
209#define ET_DMA4_WRAP 0x010 209#define ET_DMA10_WRAP 0x0400
210 210#define ET_DMA4_MASK 0x000F /* 4 bit mask for DMA4W types */
211#define ET_DMA4_WRAP 0x0010
212
213#define INDEX12(x) ((x) & ET_DMA12_MASK)
211#define INDEX10(x) ((x) & ET_DMA10_MASK) 214#define INDEX10(x) ((x) & ET_DMA10_MASK)
212#define INDEX4(x) ((x) & ET_DMA4_MASK) 215#define INDEX4(x) ((x) & ET_DMA4_MASK)
213 216
@@ -216,6 +219,11 @@ extern inline void add_10bit(u32 *v, int n)
216 *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP); 219 *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP);
217} 220}
218 221
222extern inline void add_12bit(u32 *v, int n)
223{
224 *v = INDEX12(*v + n) | (*v & ET_DMA12_WRAP);
225}
226
219/* 227/*
220 * 10bit DMA with wrap 228 * 10bit DMA with wrap
221 * txdma tx queue write address reg in txdma address map at 0x1010 229 * txdma tx queue write address reg in txdma address map at 0x1010
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 3ddc9b12b8db..81c1a7478ad6 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -831,10 +831,10 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
831 831
832 /* Indicate that we have used this PSR entry. */ 832 /* Indicate that we have used this PSR entry. */
833 /* FIXME wrap 12 */ 833 /* FIXME wrap 12 */
834 rx_local->local_psr_full = (rx_local->local_psr_full + 1) & 0xFFF; 834 add_12bit(&rx_local->local_psr_full, 1);
835 if (rx_local->local_psr_full > rx_local->PsrNumEntries - 1) { 835 if ((rx_local->local_psr_full & 0xFFF) > rx_local->PsrNumEntries - 1) {
836 /* Clear psr full and toggle the wrap bit */ 836 /* Clear psr full and toggle the wrap bit */
837 rx_local->local_psr_full &= 0xFFF; 837 rx_local->local_psr_full &= ~0xFFF;
838 rx_local->local_psr_full ^= 0x1000; 838 rx_local->local_psr_full ^= 0x1000;
839 } 839 }
840 840
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index b18d8e2d4c5e..3af79242313e 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -1787,7 +1787,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1787static struct video_device go7007_template = { 1787static struct video_device go7007_template = {
1788 .name = "go7007", 1788 .name = "go7007",
1789 .fops = &go7007_fops, 1789 .fops = &go7007_fops,
1790 .minor = -1,
1791 .release = go7007_vfl_release, 1790 .release = go7007_vfl_release,
1792 .ioctl_ops = &video_ioctl_ops, 1791 .ioctl_ops = &video_ioctl_ops,
1793 .tvnorms = V4L2_STD_ALL, 1792 .tvnorms = V4L2_STD_ALL,
@@ -1817,8 +1816,8 @@ int go7007_v4l2_init(struct go7007 *go)
1817 } 1816 }
1818 video_set_drvdata(go->video_dev, go); 1817 video_set_drvdata(go->video_dev, go);
1819 ++go->ref_count; 1818 ++go->ref_count;
1820 printk(KERN_INFO "%s: registered device video%d [v4l2]\n", 1819 printk(KERN_INFO "%s: registered device %s [v4l2]\n",
1821 go->video_dev->name, go->video_dev->num); 1820 go->video_dev->name, video_device_node_name(go->video_dev));
1822 1821
1823 return 0; 1822 return 0;
1824} 1823}
diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c
index c5b6613f2f2f..c2809f2a2ce0 100644
--- a/drivers/staging/hv/Hv.c
+++ b/drivers/staging/hv/Hv.c
@@ -386,7 +386,7 @@ u16 HvSignalEvent(void)
386 * retrieve the initialized message and event pages. Otherwise, we create and 386 * retrieve the initialized message and event pages. Otherwise, we create and
387 * initialize the message and event pages. 387 * initialize the message and event pages.
388 */ 388 */
389int HvSynicInit(u32 irqVector) 389void HvSynicInit(void *irqarg)
390{ 390{
391 u64 version; 391 u64 version;
392 union hv_synic_simp simp; 392 union hv_synic_simp simp;
@@ -394,13 +394,14 @@ int HvSynicInit(u32 irqVector)
394 union hv_synic_sint sharedSint; 394 union hv_synic_sint sharedSint;
395 union hv_synic_scontrol sctrl; 395 union hv_synic_scontrol sctrl;
396 u64 guestID; 396 u64 guestID;
397 int ret = 0; 397 u32 irqVector = *((u32 *)(irqarg));
398 int cpu = smp_processor_id();
398 399
399 DPRINT_ENTER(VMBUS); 400 DPRINT_ENTER(VMBUS);
400 401
401 if (!gHvContext.HypercallPage) { 402 if (!gHvContext.HypercallPage) {
402 DPRINT_EXIT(VMBUS); 403 DPRINT_EXIT(VMBUS);
403 return ret; 404 return;
404 } 405 }
405 406
406 /* Check the version */ 407 /* Check the version */
@@ -425,27 +426,27 @@ int HvSynicInit(u32 irqVector)
425 */ 426 */
426 rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID); 427 rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
427 if (guestID == HV_LINUX_GUEST_ID) { 428 if (guestID == HV_LINUX_GUEST_ID) {
428 gHvContext.synICMessagePage[0] = 429 gHvContext.synICMessagePage[cpu] =
429 phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT); 430 phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
430 gHvContext.synICEventPage[0] = 431 gHvContext.synICEventPage[cpu] =
431 phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT); 432 phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
432 } else { 433 } else {
433 DPRINT_ERR(VMBUS, "unknown guest id!!"); 434 DPRINT_ERR(VMBUS, "unknown guest id!!");
434 goto Cleanup; 435 goto Cleanup;
435 } 436 }
436 DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p", 437 DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
437 gHvContext.synICMessagePage[0], 438 gHvContext.synICMessagePage[cpu],
438 gHvContext.synICEventPage[0]); 439 gHvContext.synICEventPage[cpu]);
439 } else { 440 } else {
440 gHvContext.synICMessagePage[0] = osd_PageAlloc(1); 441 gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
441 if (gHvContext.synICMessagePage[0] == NULL) { 442 if (gHvContext.synICMessagePage[cpu] == NULL) {
442 DPRINT_ERR(VMBUS, 443 DPRINT_ERR(VMBUS,
443 "unable to allocate SYNIC message page!!"); 444 "unable to allocate SYNIC message page!!");
444 goto Cleanup; 445 goto Cleanup;
445 } 446 }
446 447
447 gHvContext.synICEventPage[0] = osd_PageAlloc(1); 448 gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
448 if (gHvContext.synICEventPage[0] == NULL) { 449 if (gHvContext.synICEventPage[cpu] == NULL) {
449 DPRINT_ERR(VMBUS, 450 DPRINT_ERR(VMBUS,
450 "unable to allocate SYNIC event page!!"); 451 "unable to allocate SYNIC event page!!");
451 goto Cleanup; 452 goto Cleanup;
@@ -454,7 +455,7 @@ int HvSynicInit(u32 irqVector)
454 /* Setup the Synic's message page */ 455 /* Setup the Synic's message page */
455 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); 456 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
456 simp.SimpEnabled = 1; 457 simp.SimpEnabled = 1;
457 simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0]) 458 simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
458 >> PAGE_SHIFT; 459 >> PAGE_SHIFT;
459 460
460 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", 461 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
@@ -465,7 +466,7 @@ int HvSynicInit(u32 irqVector)
465 /* Setup the Synic's event page */ 466 /* Setup the Synic's event page */
466 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); 467 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
467 siefp.SiefpEnabled = 1; 468 siefp.SiefpEnabled = 1;
468 siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0]) 469 siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
469 >> PAGE_SHIFT; 470 >> PAGE_SHIFT;
470 471
471 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", 472 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
@@ -501,32 +502,30 @@ int HvSynicInit(u32 irqVector)
501 502
502 DPRINT_EXIT(VMBUS); 503 DPRINT_EXIT(VMBUS);
503 504
504 return ret; 505 return;
505 506
506Cleanup: 507Cleanup:
507 ret = -1;
508
509 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { 508 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
510 if (gHvContext.synICEventPage[0]) 509 if (gHvContext.synICEventPage[cpu])
511 osd_PageFree(gHvContext.synICEventPage[0], 1); 510 osd_PageFree(gHvContext.synICEventPage[cpu], 1);
512 511
513 if (gHvContext.synICMessagePage[0]) 512 if (gHvContext.synICMessagePage[cpu])
514 osd_PageFree(gHvContext.synICMessagePage[0], 1); 513 osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
515 } 514 }
516 515
517 DPRINT_EXIT(VMBUS); 516 DPRINT_EXIT(VMBUS);
518 517 return;
519 return ret;
520} 518}
521 519
522/** 520/**
523 * HvSynicCleanup - Cleanup routine for HvSynicInit(). 521 * HvSynicCleanup - Cleanup routine for HvSynicInit().
524 */ 522 */
525void HvSynicCleanup(void) 523void HvSynicCleanup(void *arg)
526{ 524{
527 union hv_synic_sint sharedSint; 525 union hv_synic_sint sharedSint;
528 union hv_synic_simp simp; 526 union hv_synic_simp simp;
529 union hv_synic_siefp siefp; 527 union hv_synic_siefp siefp;
528 int cpu = smp_processor_id();
530 529
531 DPRINT_ENTER(VMBUS); 530 DPRINT_ENTER(VMBUS);
532 531
@@ -539,6 +538,7 @@ void HvSynicCleanup(void)
539 538
540 sharedSint.Masked = 1; 539 sharedSint.Masked = 1;
541 540
541 /* Need to correctly cleanup in the case of SMP!!! */
542 /* Disable the interrupt */ 542 /* Disable the interrupt */
543 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); 543 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
544 544
@@ -560,8 +560,8 @@ void HvSynicCleanup(void)
560 560
561 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); 561 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
562 562
563 osd_PageFree(gHvContext.synICMessagePage[0], 1); 563 osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
564 osd_PageFree(gHvContext.synICEventPage[0], 1); 564 osd_PageFree(gHvContext.synICEventPage[cpu], 1);
565 } 565 }
566 566
567 DPRINT_EXIT(VMBUS); 567 DPRINT_EXIT(VMBUS);
diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h
index 5379e4bfc56e..fce4b5cdac30 100644
--- a/drivers/staging/hv/Hv.h
+++ b/drivers/staging/hv/Hv.h
@@ -93,7 +93,7 @@ static const struct hv_guid VMBUS_SERVICE_ID = {
93 }, 93 },
94}; 94};
95 95
96#define MAX_NUM_CPUS 1 96#define MAX_NUM_CPUS 32
97 97
98 98
99struct hv_input_signal_event_buffer { 99struct hv_input_signal_event_buffer {
@@ -137,8 +137,8 @@ extern u16 HvPostMessage(union hv_connection_id connectionId,
137 137
138extern u16 HvSignalEvent(void); 138extern u16 HvSignalEvent(void);
139 139
140extern int HvSynicInit(u32 irqVector); 140extern void HvSynicInit(void *irqarg);
141 141
142extern void HvSynicCleanup(void); 142extern void HvSynicCleanup(void *arg);
143 143
144#endif /* __HV_H__ */ 144#endif /* __HV_H__ */
diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
index a4dd06f6d459..35a023e9f9d1 100644
--- a/drivers/staging/hv/Vmbus.c
+++ b/drivers/staging/hv/Vmbus.c
@@ -129,7 +129,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
129 129
130 /* strcpy(dev->name, "vmbus"); */ 130 /* strcpy(dev->name, "vmbus"); */
131 /* SynIC setup... */ 131 /* SynIC setup... */
132 ret = HvSynicInit(*irqvector); 132 on_each_cpu(HvSynicInit, (void *)irqvector, 1);
133 133
134 /* Connect to VMBus in the root partition */ 134 /* Connect to VMBus in the root partition */
135 ret = VmbusConnect(); 135 ret = VmbusConnect();
@@ -150,7 +150,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev)
150 DPRINT_ENTER(VMBUS); 150 DPRINT_ENTER(VMBUS);
151 VmbusChannelReleaseUnattachedChannels(); 151 VmbusChannelReleaseUnattachedChannels();
152 VmbusDisconnect(); 152 VmbusDisconnect();
153 HvSynicCleanup(); 153 on_each_cpu(HvSynicCleanup, NULL, 1);
154 DPRINT_EXIT(VMBUS); 154 DPRINT_EXIT(VMBUS);
155 155
156 return ret; 156 return ret;
@@ -173,7 +173,8 @@ static void VmbusOnCleanup(struct hv_driver *drv)
173 */ 173 */
174static void VmbusOnMsgDPC(struct hv_driver *drv) 174static void VmbusOnMsgDPC(struct hv_driver *drv)
175{ 175{
176 void *page_addr = gHvContext.synICMessagePage[0]; 176 int cpu = smp_processor_id();
177 void *page_addr = gHvContext.synICMessagePage[cpu];
177 struct hv_message *msg = (struct hv_message *)page_addr + 178 struct hv_message *msg = (struct hv_message *)page_addr +
178 VMBUS_MESSAGE_SINT; 179 VMBUS_MESSAGE_SINT;
179 struct hv_message *copied; 180 struct hv_message *copied;
@@ -230,11 +231,12 @@ static void VmbusOnEventDPC(struct hv_driver *drv)
230static int VmbusOnISR(struct hv_driver *drv) 231static int VmbusOnISR(struct hv_driver *drv)
231{ 232{
232 int ret = 0; 233 int ret = 0;
234 int cpu = smp_processor_id();
233 void *page_addr; 235 void *page_addr;
234 struct hv_message *msg; 236 struct hv_message *msg;
235 union hv_synic_event_flags *event; 237 union hv_synic_event_flags *event;
236 238
237 page_addr = gHvContext.synICMessagePage[0]; 239 page_addr = gHvContext.synICMessagePage[cpu];
238 msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; 240 msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
239 241
240 DPRINT_ENTER(VMBUS); 242 DPRINT_ENTER(VMBUS);
@@ -248,7 +250,7 @@ static int VmbusOnISR(struct hv_driver *drv)
248 } 250 }
249 251
250 /* TODO: Check if there are events to be process */ 252 /* TODO: Check if there are events to be process */
251 page_addr = gHvContext.synICEventPage[0]; 253 page_addr = gHvContext.synICEventPage[cpu];
252 event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; 254 event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
253 255
254 /* Since we are a child, we only need to check bit 0 */ 256 /* Since we are a child, we only need to check bit 0 */
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index f0b86f02cd80..fd677f008365 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -29,7 +29,6 @@
29 * driver requests - some may support multiple options */ 29 * driver requests - some may support multiple options */
30 30
31 31
32#include <linux/autoconf.h>
33#include "iio.h" 32#include "iio.h"
34#include "ring_generic.h" 33#include "ring_generic.h"
35 34
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
index 536e2382de54..638ad6b35891 100644
--- a/drivers/staging/octeon/Kconfig
+++ b/drivers/staging/octeon/Kconfig
@@ -1,7 +1,8 @@
1config OCTEON_ETHERNET 1config OCTEON_ETHERNET
2 tristate "Cavium Networks Octeon Ethernet support" 2 tristate "Cavium Networks Octeon Ethernet support"
3 depends on CPU_CAVIUM_OCTEON 3 depends on CPU_CAVIUM_OCTEON
4 select MII 4 select PHYLIB
5 select MDIO_OCTEON
5 help 6 help
6 This driver supports the builtin ethernet ports on Cavium 7 This driver supports the builtin ethernet ports on Cavium
7 Networks' products in the Octeon family. This driver supports the 8 Networks' products in the Octeon family. This driver supports the
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 31a58e508924..05a5cc0f43ed 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -26,7 +26,8 @@
26**********************************************************************/ 26**********************************************************************/
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/ethtool.h> 28#include <linux/ethtool.h>
29#include <linux/mii.h> 29#include <linux/phy.h>
30
30#include <net/dst.h> 31#include <net/dst.h>
31 32
32#include <asm/octeon/octeon.h> 33#include <asm/octeon/octeon.h>
@@ -34,86 +35,12 @@
34#include "ethernet-defines.h" 35#include "ethernet-defines.h"
35#include "octeon-ethernet.h" 36#include "octeon-ethernet.h"
36#include "ethernet-mdio.h" 37#include "ethernet-mdio.h"
38#include "ethernet-util.h"
37 39
38#include "cvmx-helper-board.h" 40#include "cvmx-helper-board.h"
39 41
40#include "cvmx-smix-defs.h" 42#include "cvmx-smix-defs.h"
41 43
42DECLARE_MUTEX(mdio_sem);
43
44/**
45 * Perform an MII read. Called by the generic MII routines
46 *
47 * @dev: Device to perform read for
48 * @phy_id: The MII phy id
49 * @location: Register location to read
50 * Returns Result from the read or zero on failure
51 */
52static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
53{
54 union cvmx_smix_cmd smi_cmd;
55 union cvmx_smix_rd_dat smi_rd;
56
57 smi_cmd.u64 = 0;
58 smi_cmd.s.phy_op = 1;
59 smi_cmd.s.phy_adr = phy_id;
60 smi_cmd.s.reg_adr = location;
61 cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
62
63 do {
64 if (!in_interrupt())
65 yield();
66 smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
67 } while (smi_rd.s.pending);
68
69 if (smi_rd.s.val)
70 return smi_rd.s.dat;
71 else
72 return 0;
73}
74
75static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
76 int location)
77{
78 return 0xffff;
79}
80
81/**
82 * Perform an MII write. Called by the generic MII routines
83 *
84 * @dev: Device to perform write for
85 * @phy_id: The MII phy id
86 * @location: Register location to write
87 * @val: Value to write
88 */
89static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
90 int val)
91{
92 union cvmx_smix_cmd smi_cmd;
93 union cvmx_smix_wr_dat smi_wr;
94
95 smi_wr.u64 = 0;
96 smi_wr.s.dat = val;
97 cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
98
99 smi_cmd.u64 = 0;
100 smi_cmd.s.phy_op = 0;
101 smi_cmd.s.phy_adr = phy_id;
102 smi_cmd.s.reg_adr = location;
103 cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
104
105 do {
106 if (!in_interrupt())
107 yield();
108 smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
109 } while (smi_wr.s.pending);
110}
111
112static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
113 int location, int val)
114{
115}
116
117static void cvm_oct_get_drvinfo(struct net_device *dev, 44static void cvm_oct_get_drvinfo(struct net_device *dev,
118 struct ethtool_drvinfo *info) 45 struct ethtool_drvinfo *info)
119{ 46{
@@ -125,49 +52,37 @@ static void cvm_oct_get_drvinfo(struct net_device *dev,
125static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 52static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
126{ 53{
127 struct octeon_ethernet *priv = netdev_priv(dev); 54 struct octeon_ethernet *priv = netdev_priv(dev);
128 int ret;
129 55
130 down(&mdio_sem); 56 if (priv->phydev)
131 ret = mii_ethtool_gset(&priv->mii_info, cmd); 57 return phy_ethtool_gset(priv->phydev, cmd);
132 up(&mdio_sem);
133 58
134 return ret; 59 return -EINVAL;
135} 60}
136 61
137static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 62static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
138{ 63{
139 struct octeon_ethernet *priv = netdev_priv(dev); 64 struct octeon_ethernet *priv = netdev_priv(dev);
140 int ret;
141 65
142 down(&mdio_sem); 66 if (!capable(CAP_NET_ADMIN))
143 ret = mii_ethtool_sset(&priv->mii_info, cmd); 67 return -EPERM;
144 up(&mdio_sem); 68
69 if (priv->phydev)
70 return phy_ethtool_sset(priv->phydev, cmd);
145 71
146 return ret; 72 return -EINVAL;
147} 73}
148 74
149static int cvm_oct_nway_reset(struct net_device *dev) 75static int cvm_oct_nway_reset(struct net_device *dev)
150{ 76{
151 struct octeon_ethernet *priv = netdev_priv(dev); 77 struct octeon_ethernet *priv = netdev_priv(dev);
152 int ret;
153 78
154 down(&mdio_sem); 79 if (!capable(CAP_NET_ADMIN))
155 ret = mii_nway_restart(&priv->mii_info); 80 return -EPERM;
156 up(&mdio_sem);
157 81
158 return ret; 82 if (priv->phydev)
159} 83 return phy_start_aneg(priv->phydev);
160 84
161static u32 cvm_oct_get_link(struct net_device *dev) 85 return -EINVAL;
162{
163 struct octeon_ethernet *priv = netdev_priv(dev);
164 u32 ret;
165
166 down(&mdio_sem);
167 ret = mii_link_ok(&priv->mii_info);
168 up(&mdio_sem);
169
170 return ret;
171} 86}
172 87
173const struct ethtool_ops cvm_oct_ethtool_ops = { 88const struct ethtool_ops cvm_oct_ethtool_ops = {
@@ -175,7 +90,7 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
175 .get_settings = cvm_oct_get_settings, 90 .get_settings = cvm_oct_get_settings,
176 .set_settings = cvm_oct_set_settings, 91 .set_settings = cvm_oct_set_settings,
177 .nway_reset = cvm_oct_nway_reset, 92 .nway_reset = cvm_oct_nway_reset,
178 .get_link = cvm_oct_get_link, 93 .get_link = ethtool_op_get_link,
179 .get_sg = ethtool_op_get_sg, 94 .get_sg = ethtool_op_get_sg,
180 .get_tx_csum = ethtool_op_get_tx_csum, 95 .get_tx_csum = ethtool_op_get_tx_csum,
181}; 96};
@@ -191,41 +106,78 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
191int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 106int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
192{ 107{
193 struct octeon_ethernet *priv = netdev_priv(dev); 108 struct octeon_ethernet *priv = netdev_priv(dev);
194 struct mii_ioctl_data *data = if_mii(rq);
195 unsigned int duplex_chg;
196 int ret;
197 109
198 down(&mdio_sem); 110 if (!netif_running(dev))
199 ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg); 111 return -EINVAL;
200 up(&mdio_sem); 112
113 if (!priv->phydev)
114 return -EINVAL;
115
116 return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
117}
201 118
202 return ret; 119static void cvm_oct_adjust_link(struct net_device *dev)
120{
121 struct octeon_ethernet *priv = netdev_priv(dev);
122 cvmx_helper_link_info_t link_info;
123
124 if (priv->last_link != priv->phydev->link) {
125 priv->last_link = priv->phydev->link;
126 link_info.u64 = 0;
127 link_info.s.link_up = priv->last_link ? 1 : 0;
128 link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0;
129 link_info.s.speed = priv->phydev->speed;
130 cvmx_helper_link_set( priv->port, link_info);
131 if (priv->last_link) {
132 netif_carrier_on(dev);
133 if (priv->queue != -1)
134 DEBUGPRINT("%s: %u Mbps %s duplex, "
135 "port %2d, queue %2d\n",
136 dev->name, priv->phydev->speed,
137 priv->phydev->duplex ?
138 "Full" : "Half",
139 priv->port, priv->queue);
140 else
141 DEBUGPRINT("%s: %u Mbps %s duplex, "
142 "port %2d, POW\n",
143 dev->name, priv->phydev->speed,
144 priv->phydev->duplex ?
145 "Full" : "Half",
146 priv->port);
147 } else {
148 netif_carrier_off(dev);
149 DEBUGPRINT("%s: Link down\n", dev->name);
150 }
151 }
203} 152}
204 153
154
205/** 155/**
206 * Setup the MDIO device structures 156 * Setup the PHY
207 * 157 *
208 * @dev: Device to setup 158 * @dev: Device to setup
209 * 159 *
210 * Returns Zero on success, negative on failure 160 * Returns Zero on success, negative on failure
211 */ 161 */
212int cvm_oct_mdio_setup_device(struct net_device *dev) 162int cvm_oct_phy_setup_device(struct net_device *dev)
213{ 163{
214 struct octeon_ethernet *priv = netdev_priv(dev); 164 struct octeon_ethernet *priv = netdev_priv(dev);
215 int phy_id = cvmx_helper_board_get_mii_address(priv->port); 165
216 if (phy_id != -1) { 166 int phy_addr = cvmx_helper_board_get_mii_address(priv->port);
217 priv->mii_info.dev = dev; 167 if (phy_addr != -1) {
218 priv->mii_info.phy_id = phy_id; 168 char phy_id[20];
219 priv->mii_info.phy_id_mask = 0xff; 169
220 priv->mii_info.supports_gmii = 1; 170 snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", phy_addr);
221 priv->mii_info.reg_num_mask = 0x1f; 171
222 priv->mii_info.mdio_read = cvm_oct_mdio_read; 172 priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0,
223 priv->mii_info.mdio_write = cvm_oct_mdio_write; 173 PHY_INTERFACE_MODE_GMII);
224 } else { 174
225 /* Supply dummy MDIO routines so the kernel won't crash 175 if (IS_ERR(priv->phydev)) {
226 if the user tries to read them */ 176 priv->phydev = NULL;
227 priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read; 177 return -1;
228 priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write; 178 }
179 priv->last_link = 0;
180 phy_start_aneg(priv->phydev);
229 } 181 }
230 return 0; 182 return 0;
231} 183}
diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
index b3328aeec2df..55d0614a7cd9 100644
--- a/drivers/staging/octeon/ethernet-mdio.h
+++ b/drivers/staging/octeon/ethernet-mdio.h
@@ -43,4 +43,4 @@
43 43
44extern const struct ethtool_ops cvm_oct_ethtool_ops; 44extern const struct ethtool_ops cvm_oct_ethtool_ops;
45int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 45int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
46int cvm_oct_mdio_setup_device(struct net_device *dev); 46int cvm_oct_phy_setup_device(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-proc.c b/drivers/staging/octeon/ethernet-proc.c
index 8fa88fc419b7..16308d484d3b 100644
--- a/drivers/staging/octeon/ethernet-proc.c
+++ b/drivers/staging/octeon/ethernet-proc.c
@@ -25,7 +25,6 @@
25 * Contact Cavium Networks for more information 25 * Contact Cavium Networks for more information
26**********************************************************************/ 26**********************************************************************/
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/mii.h>
29#include <linux/seq_file.h> 28#include <linux/seq_file.h>
30#include <linux/proc_fs.h> 29#include <linux/proc_fs.h>
31#include <net/dst.h> 30#include <net/dst.h>
@@ -38,112 +37,6 @@
38#include "cvmx-helper.h" 37#include "cvmx-helper.h"
39#include "cvmx-pip.h" 38#include "cvmx-pip.h"
40 39
41static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
42 int phy_id, int offset)
43{
44 struct octeon_ethernet *priv = netdev_priv(dev);
45
46 priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
47 return ((uint64_t) priv->mii_info.
48 mdio_read(dev, phy_id,
49 0x1e) << 16) | (uint64_t) priv->mii_info.
50 mdio_read(dev, phy_id, 0x1f);
51}
52
53static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
54{
55 static const int ports[] = { 0, 1, 2, 3, 9, -1 };
56 struct net_device *dev = cvm_oct_device[0];
57 int index = 0;
58
59 while (ports[index] != -1) {
60
61 /* Latch port */
62 struct octeon_ethernet *priv = netdev_priv(dev);
63
64 priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
65 0xdc00 | ports[index]);
66 seq_printf(m, "\nSwitch Port %d\n", ports[index]);
67 seq_printf(m, "InGoodOctets: %12llu\t"
68 "OutOctets: %12llu\t"
69 "64 Octets: %12llu\n",
70 cvm_oct_stats_read_switch(dev, 0x1b,
71 0x00) |
72 (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
73 cvm_oct_stats_read_switch(dev, 0x1b,
74 0x0E) |
75 (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
76 cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
77
78 seq_printf(m, "InBadOctets: %12llu\t"
79 "OutUnicast: %12llu\t"
80 "65-127 Octets: %12llu\n",
81 cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
82 cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
83 cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
84
85 seq_printf(m, "InUnicast: %12llu\t"
86 "OutBroadcasts: %12llu\t"
87 "128-255 Octets: %12llu\n",
88 cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
89 cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
90 cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
91
92 seq_printf(m, "InBroadcasts: %12llu\t"
93 "OutMulticasts: %12llu\t"
94 "256-511 Octets: %12llu\n",
95 cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
96 cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
97 cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
98
99 seq_printf(m, "InMulticasts: %12llu\t"
100 "OutPause: %12llu\t"
101 "512-1023 Octets:%12llu\n",
102 cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
103 cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
104 cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
105
106 seq_printf(m, "InPause: %12llu\t"
107 "Excessive: %12llu\t"
108 "1024-Max Octets:%12llu\n",
109 cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
110 cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
111 cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
112
113 seq_printf(m, "InUndersize: %12llu\t"
114 "Collisions: %12llu\n",
115 cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
116 cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
117
118 seq_printf(m, "InFragments: %12llu\t"
119 "Deferred: %12llu\n",
120 cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
121 cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
122
123 seq_printf(m, "InOversize: %12llu\t"
124 "Single: %12llu\n",
125 cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
126 cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
127
128 seq_printf(m, "InJabber: %12llu\t"
129 "Multiple: %12llu\n",
130 cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
131 cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
132
133 seq_printf(m, "In RxErr: %12llu\t"
134 "OutFCSErr: %12llu\n",
135 cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
136 cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
137
138 seq_printf(m, "InFCSErr: %12llu\t"
139 "Late: %12llu\n",
140 cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
141 cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
142 index++;
143 }
144 return 0;
145}
146
147/** 40/**
148 * User is reading /proc/octeon_ethernet_stats 41 * User is reading /proc/octeon_ethernet_stats
149 * 42 *
@@ -215,11 +108,6 @@ static int cvm_oct_stats_show(struct seq_file *m, void *v)
215 } 108 }
216 } 109 }
217 110
218 if (cvm_oct_device[0]) {
219 priv = netdev_priv(cvm_oct_device[0]);
220 if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
221 cvm_oct_stats_switch_show(m, v);
222 }
223 return 0; 111 return 0;
224} 112}
225 113
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index fbaa465d2fac..3820f1ec11d1 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -147,32 +147,36 @@ static void cvm_oct_rgmii_poll(struct net_device *dev)
147 cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), 147 cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
148 gmxx_rxx_int_reg.u64); 148 gmxx_rxx_int_reg.u64);
149 } 149 }
150 150 if (priv->phydev == NULL) {
151 link_info = cvmx_helper_link_autoconf(priv->port); 151 link_info = cvmx_helper_link_autoconf(priv->port);
152 priv->link_info = link_info.u64; 152 priv->link_info = link_info.u64;
153 }
153 spin_unlock_irqrestore(&global_register_lock, flags); 154 spin_unlock_irqrestore(&global_register_lock, flags);
154 155
155 /* Tell Linux */ 156 if (priv->phydev == NULL) {
156 if (link_info.s.link_up) { 157 /* Tell core. */
157 158 if (link_info.s.link_up) {
158 if (!netif_carrier_ok(dev)) 159 if (!netif_carrier_ok(dev))
159 netif_carrier_on(dev); 160 netif_carrier_on(dev);
160 if (priv->queue != -1) 161 if (priv->queue != -1)
161 DEBUGPRINT 162 DEBUGPRINT("%s: %u Mbps %s duplex, "
162 ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", 163 "port %2d, queue %2d\n",
163 dev->name, link_info.s.speed, 164 dev->name, link_info.s.speed,
164 (link_info.s.full_duplex) ? "Full" : "Half", 165 (link_info.s.full_duplex) ?
165 priv->port, priv->queue); 166 "Full" : "Half",
166 else 167 priv->port, priv->queue);
167 DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", 168 else
168 dev->name, link_info.s.speed, 169 DEBUGPRINT("%s: %u Mbps %s duplex, "
169 (link_info.s.full_duplex) ? "Full" : "Half", 170 "port %2d, POW\n",
170 priv->port); 171 dev->name, link_info.s.speed,
171 } else { 172 (link_info.s.full_duplex) ?
172 173 "Full" : "Half",
173 if (netif_carrier_ok(dev)) 174 priv->port);
174 netif_carrier_off(dev); 175 } else {
175 DEBUGPRINT("%s: Link down\n", dev->name); 176 if (netif_carrier_ok(dev))
177 netif_carrier_off(dev);
178 DEBUGPRINT("%s: Link down\n", dev->name);
179 }
176 } 180 }
177} 181}
178 182
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
index 2b54996bd85d..6061d01eca2d 100644
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -113,7 +113,7 @@ int cvm_oct_sgmii_init(struct net_device *dev)
113 struct octeon_ethernet *priv = netdev_priv(dev); 113 struct octeon_ethernet *priv = netdev_priv(dev);
114 cvm_oct_common_init(dev); 114 cvm_oct_common_init(dev);
115 dev->netdev_ops->ndo_stop(dev); 115 dev->netdev_ops->ndo_stop(dev);
116 if (!octeon_is_simulation()) 116 if (!octeon_is_simulation() && priv->phydev == NULL)
117 priv->poll = cvm_oct_sgmii_poll; 117 priv->poll = cvm_oct_sgmii_poll;
118 118
119 /* FIXME: Need autoneg logic */ 119 /* FIXME: Need autoneg logic */
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
index 0c2e7cc40f35..ee3dc41b2c53 100644
--- a/drivers/staging/octeon/ethernet-xaui.c
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -112,7 +112,7 @@ int cvm_oct_xaui_init(struct net_device *dev)
112 struct octeon_ethernet *priv = netdev_priv(dev); 112 struct octeon_ethernet *priv = netdev_priv(dev);
113 cvm_oct_common_init(dev); 113 cvm_oct_common_init(dev);
114 dev->netdev_ops->ndo_stop(dev); 114 dev->netdev_ops->ndo_stop(dev);
115 if (!octeon_is_simulation()) 115 if (!octeon_is_simulation() && priv->phydev == NULL)
116 priv->poll = cvm_oct_xaui_poll; 116 priv->poll = cvm_oct_xaui_poll;
117 117
118 return 0; 118 return 0;
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 492c5029992d..4cfd4b136b32 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -30,7 +30,7 @@
30#include <linux/netdevice.h> 30#include <linux/netdevice.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/mii.h> 33#include <linux/phy.h>
34 34
35#include <net/dst.h> 35#include <net/dst.h>
36 36
@@ -132,8 +132,6 @@ static struct timer_list cvm_oct_poll_timer;
132 */ 132 */
133struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS]; 133struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
134 134
135extern struct semaphore mdio_sem;
136
137/** 135/**
138 * Periodic timer tick for slow management operations 136 * Periodic timer tick for slow management operations
139 * 137 *
@@ -160,13 +158,8 @@ static void cvm_do_timer(unsigned long arg)
160 goto out; 158 goto out;
161 159
162 priv = netdev_priv(cvm_oct_device[port]); 160 priv = netdev_priv(cvm_oct_device[port]);
163 if (priv->poll) { 161 if (priv->poll)
164 /* skip polling if we don't get the lock */ 162 priv->poll(cvm_oct_device[port]);
165 if (!down_trylock(&mdio_sem)) {
166 priv->poll(cvm_oct_device[port]);
167 up(&mdio_sem);
168 }
169 }
170 163
171 queues_per_port = cvmx_pko_get_num_queues(port); 164 queues_per_port = cvmx_pko_get_num_queues(port);
172 /* Drain any pending packets in the free list */ 165 /* Drain any pending packets in the free list */
@@ -524,7 +517,7 @@ int cvm_oct_common_init(struct net_device *dev)
524 dev->features |= NETIF_F_LLTX; 517 dev->features |= NETIF_F_LLTX;
525 SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); 518 SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
526 519
527 cvm_oct_mdio_setup_device(dev); 520 cvm_oct_phy_setup_device(dev);
528 dev->netdev_ops->ndo_set_mac_address(dev, &sa); 521 dev->netdev_ops->ndo_set_mac_address(dev, &sa);
529 dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); 522 dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
530 523
@@ -540,7 +533,10 @@ int cvm_oct_common_init(struct net_device *dev)
540 533
541void cvm_oct_common_uninit(struct net_device *dev) 534void cvm_oct_common_uninit(struct net_device *dev)
542{ 535{
543 /* Currently nothing to do */ 536 struct octeon_ethernet *priv = netdev_priv(dev);
537
538 if (priv->phydev)
539 phy_disconnect(priv->phydev);
544} 540}
545 541
546static const struct net_device_ops cvm_oct_npi_netdev_ops = { 542static const struct net_device_ops cvm_oct_npi_netdev_ops = {
@@ -627,6 +623,8 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
627#endif 623#endif
628}; 624};
629 625
626extern void octeon_mdiobus_force_mod_depencency(void);
627
630/** 628/**
631 * Module/ driver initialization. Creates the linux network 629 * Module/ driver initialization. Creates the linux network
632 * devices. 630 * devices.
@@ -640,6 +638,7 @@ static int __init cvm_oct_init_module(void)
640 int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; 638 int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
641 int qos; 639 int qos;
642 640
641 octeon_mdiobus_force_mod_depencency();
643 pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); 642 pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
644 643
645 if (OCTEON_IS_MODEL(OCTEON_CN52XX)) 644 if (OCTEON_IS_MODEL(OCTEON_CN52XX))
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index 3aef9878fc0a..402a15b9bb0e 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -50,9 +50,9 @@ struct octeon_ethernet {
50 /* List of outstanding tx buffers per queue */ 50 /* List of outstanding tx buffers per queue */
51 struct sk_buff_head tx_free_list[16]; 51 struct sk_buff_head tx_free_list[16];
52 /* Device statistics */ 52 /* Device statistics */
53 struct net_device_stats stats 53 struct net_device_stats stats;
54; /* Generic MII info structure */ 54 struct phy_device *phydev;
55 struct mii_if_info mii_info; 55 unsigned int last_link;
56 /* Last negotiated link state */ 56 /* Last negotiated link state */
57 uint64_t link_info; 57 uint64_t link_info;
58 /* Called periodically to check link status */ 58 /* Called periodically to check link status */
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig
index 3abe7c9d558d..3defa0133f2e 100644
--- a/drivers/staging/panel/Kconfig
+++ b/drivers/staging/panel/Kconfig
@@ -47,7 +47,7 @@ config PANEL_PROFILE
47config PANEL_KEYPAD 47config PANEL_KEYPAD
48 depends on PANEL && PANEL_PROFILE="0" 48 depends on PANEL && PANEL_PROFILE="0"
49 int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)" 49 int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)"
50 range 0 4 50 range 0 3
51 default 0 51 default 0
52 ---help--- 52 ---help---
53 This enables and configures a keypad connected to the parallel port. 53 This enables and configures a keypad connected to the parallel port.
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 4ce399b6d237..95c93e82ccec 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -55,7 +55,7 @@
55#include <linux/list.h> 55#include <linux/list.h>
56#include <linux/notifier.h> 56#include <linux/notifier.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/utsrelease.h> 58#include <generated/utsrelease.h>
59 59
60#include <linux/io.h> 60#include <linux/io.h>
61#include <asm/uaccess.h> 61#include <asm/uaccess.h>
@@ -378,7 +378,7 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
378 378
379#ifdef CONFIG_PANEL_LCD_CHARSET 379#ifdef CONFIG_PANEL_LCD_CHARSET
380#undef DEFAULT_LCD_CHARSET 380#undef DEFAULT_LCD_CHARSET
381#define DEFAULT_LCD_CHARSET 381#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET
382#endif 382#endif
383 383
384#endif /* DEFAULT_PROFILE == 0 */ 384#endif /* DEFAULT_PROFILE == 0 */
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
index 6c5b261e9f06..aacd25bfb0cb 100644
--- a/drivers/staging/pohmelfs/dir.c
+++ b/drivers/staging/pohmelfs/dir.c
@@ -722,8 +722,6 @@ static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
722 if (inode->i_nlink) 722 if (inode->i_nlink)
723 inode_dec_link_count(inode); 723 inode_dec_link_count(inode);
724 } 724 }
725 dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n",
726 __func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash));
727 725
728 return err; 726 return err;
729} 727}
diff --git a/drivers/staging/ramzswap/TODO b/drivers/staging/ramzswap/TODO
index bac40d6cb9f1..8d64e28fac0e 100644
--- a/drivers/staging/ramzswap/TODO
+++ b/drivers/staging/ramzswap/TODO
@@ -1,6 +1,5 @@
1TODO: 1TODO:
2 - Add support for swap notifiers 2 - Add support for swap notifiers
3 - Remove CONFIG_ARM hack
4 3
5Please send patches to Greg Kroah-Hartman <greg@kroah.com> and 4Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
6Nitin Gupta <ngupta@vflare.org> 5Nitin Gupta <ngupta@vflare.org>
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index b839f05efbce..989fac5b01b3 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -222,28 +222,6 @@ out:
222 return ret; 222 return ret;
223} 223}
224 224
225static void ramzswap_flush_dcache_page(struct page *page)
226{
227#ifdef CONFIG_ARM
228 int flag = 0;
229 /*
230 * Ugly hack to get flush_dcache_page() work on ARM.
231 * page_mapping(page) == NULL after clearing this swap cache flag.
232 * Without clearing this flag, flush_dcache_page() will simply set
233 * "PG_dcache_dirty" bit and return.
234 */
235 if (PageSwapCache(page)) {
236 flag = 1;
237 ClearPageSwapCache(page);
238 }
239#endif
240 flush_dcache_page(page);
241#ifdef CONFIG_ARM
242 if (flag)
243 SetPageSwapCache(page);
244#endif
245}
246
247void ramzswap_ioctl_get_stats(struct ramzswap *rzs, 225void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
248 struct ramzswap_ioctl_stats *s) 226 struct ramzswap_ioctl_stats *s)
249{ 227{
@@ -655,7 +633,7 @@ static int handle_zero_page(struct bio *bio)
655 memset(user_mem, 0, PAGE_SIZE); 633 memset(user_mem, 0, PAGE_SIZE);
656 kunmap_atomic(user_mem, KM_USER0); 634 kunmap_atomic(user_mem, KM_USER0);
657 635
658 ramzswap_flush_dcache_page(page); 636 flush_dcache_page(page);
659 637
660 set_bit(BIO_UPTODATE, &bio->bi_flags); 638 set_bit(BIO_UPTODATE, &bio->bi_flags);
661 bio_endio(bio, 0); 639 bio_endio(bio, 0);
@@ -679,7 +657,7 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
679 kunmap_atomic(user_mem, KM_USER0); 657 kunmap_atomic(user_mem, KM_USER0);
680 kunmap_atomic(cmem, KM_USER1); 658 kunmap_atomic(cmem, KM_USER1);
681 659
682 ramzswap_flush_dcache_page(page); 660 flush_dcache_page(page);
683 661
684 set_bit(BIO_UPTODATE, &bio->bi_flags); 662 set_bit(BIO_UPTODATE, &bio->bi_flags);
685 bio_endio(bio, 0); 663 bio_endio(bio, 0);
@@ -779,7 +757,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
779 goto out; 757 goto out;
780 } 758 }
781 759
782 ramzswap_flush_dcache_page(page); 760 flush_dcache_page(page);
783 761
784 set_bit(BIO_UPTODATE, &bio->bi_flags); 762 set_bit(BIO_UPTODATE, &bio->bi_flags);
785 bio_endio(bio, 0); 763 bio_endio(bio, 0);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 3222c22152fb..0d490c164db6 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -1318,13 +1318,13 @@ extern int ieee80211_encrypt_fragment(
1318 struct sk_buff *frag, 1318 struct sk_buff *frag,
1319 int hdr_len); 1319 int hdr_len);
1320 1320
1321extern int ieee80211_xmit(struct sk_buff *skb, 1321extern int ieee80211_rtl_xmit(struct sk_buff *skb,
1322 struct net_device *dev); 1322 struct net_device *dev);
1323extern void ieee80211_txb_free(struct ieee80211_txb *); 1323extern void ieee80211_txb_free(struct ieee80211_txb *);
1324 1324
1325 1325
1326/* ieee80211_rx.c */ 1326/* ieee80211_rx.c */
1327extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 1327extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1328 struct ieee80211_rx_stats *rx_stats); 1328 struct ieee80211_rx_stats *rx_stats);
1329extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, 1329extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1330 struct ieee80211_hdr_4addr *header, 1330 struct ieee80211_hdr_4addr *header,
@@ -1376,8 +1376,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
1376extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); 1376extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
1377extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); 1377extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
1378extern void ieee80211_reset_queue(struct ieee80211_device *ieee); 1378extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
1379extern void ieee80211_wake_queue(struct ieee80211_device *ieee); 1379extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
1380extern void ieee80211_stop_queue(struct ieee80211_device *ieee); 1380extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
1381extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); 1381extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
1382extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); 1382extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
1383extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); 1383extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
@@ -1385,7 +1385,7 @@ extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct
1385extern void notify_wx_assoc_event(struct ieee80211_device *ieee); 1385extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
1386extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); 1386extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
1387extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn); 1387extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
1388extern void ieee80211_start_scan(struct ieee80211_device *ieee); 1388extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
1389 1389
1390//Add for RF power on power off by lizhaoming 080512 1390//Add for RF power on power off by lizhaoming 080512
1391extern void SendDisassociation(struct ieee80211_device *ieee, 1391extern void SendDisassociation(struct ieee80211_device *ieee,
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index f882dd8cf9b5..9128c181bc7d 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -469,7 +469,7 @@ drop:
469/* All received frames are sent to this function. @skb contains the frame in 469/* All received frames are sent to this function. @skb contains the frame in
470 * IEEE 802.11 format, i.e., in the format it was sent over air. 470 * IEEE 802.11 format, i.e., in the format it was sent over air.
471 * This function is called only as a tasklet (software IRQ). */ 471 * This function is called only as a tasklet (software IRQ). */
472int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 472int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
473 struct ieee80211_rx_stats *rx_stats) 473 struct ieee80211_rx_stats *rx_stats)
474{ 474{
475 struct net_device *dev = ieee->dev; 475 struct net_device *dev = ieee->dev;
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index 1fe19c39d702..c7c645af0ebb 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -689,7 +689,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
689} 689}
690 690
691/* called with ieee->lock held */ 691/* called with ieee->lock held */
692void ieee80211_start_scan(struct ieee80211_device *ieee) 692void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
693{ 693{
694 if(IS_DOT11D_ENABLE(ieee) ) 694 if(IS_DOT11D_ENABLE(ieee) )
695 { 695 {
@@ -1196,7 +1196,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
1196 } 1196 }
1197} 1197}
1198 1198
1199void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) 1199void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1200{ 1200{
1201 u8 *c; 1201 u8 *c;
1202 struct sk_buff *skb; 1202 struct sk_buff *skb;
@@ -1898,7 +1898,7 @@ associate_complete:
1898 1898
1899 ieee80211_associate_step2(ieee); 1899 ieee80211_associate_step2(ieee);
1900 }else{ 1900 }else{
1901 ieee80211_auth_challenge(ieee, challenge, chlen); 1901 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
1902 } 1902 }
1903 }else{ 1903 }else{
1904 ieee->softmac_stats.rx_auth_rs_err++; 1904 ieee->softmac_stats.rx_auth_rs_err++;
@@ -2047,7 +2047,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee)
2047 2047
2048} 2048}
2049 2049
2050void ieee80211_wake_queue(struct ieee80211_device *ieee) 2050void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2051{ 2051{
2052 2052
2053 unsigned long flags; 2053 unsigned long flags;
@@ -2089,7 +2089,7 @@ exit :
2089} 2089}
2090 2090
2091 2091
2092void ieee80211_stop_queue(struct ieee80211_device *ieee) 2092void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2093{ 2093{
2094 //unsigned long flags; 2094 //unsigned long flags;
2095 //spin_lock_irqsave(&ieee->lock,flags); 2095 //spin_lock_irqsave(&ieee->lock,flags);
@@ -2301,7 +2301,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
2301//#else 2301//#else
2302 if (ieee->state == IEEE80211_NOLINK){ 2302 if (ieee->state == IEEE80211_NOLINK){
2303 ieee->actscanning = true; 2303 ieee->actscanning = true;
2304 ieee80211_start_scan(ieee); 2304 ieee80211_rtl_start_scan(ieee);
2305 } 2305 }
2306//#endif 2306//#endif
2307 spin_unlock_irqrestore(&ieee->lock, flags); 2307 spin_unlock_irqrestore(&ieee->lock, flags);
@@ -2357,7 +2357,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work)
2357 if(ieee->state == IEEE80211_NOLINK){ 2357 if(ieee->state == IEEE80211_NOLINK){
2358 ieee->beinretry = false; 2358 ieee->beinretry = false;
2359 ieee->actscanning = true; 2359 ieee->actscanning = true;
2360 ieee80211_start_scan(ieee); 2360 ieee80211_rtl_start_scan(ieee);
2361 } 2361 }
2362 //YJ,add,080828, notify os here 2362 //YJ,add,080828, notify os here
2363 if(ieee->state == IEEE80211_NOLINK) 2363 if(ieee->state == IEEE80211_NOLINK)
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index dde1f2e0cf32..69bd02164b0c 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -304,7 +304,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
304} 304}
305 305
306/* SKBs are added to the ieee->tx_queue. */ 306/* SKBs are added to the ieee->tx_queue. */
307int ieee80211_xmit(struct sk_buff *skb, 307int ieee80211_rtl_xmit(struct sk_buff *skb,
308 struct net_device *dev) 308 struct net_device *dev)
309{ 309{
310 struct ieee80211_device *ieee = netdev_priv(dev); 310 struct ieee80211_device *ieee = netdev_priv(dev);
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 57c62b0a402f..e0f13efdb15a 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -1811,7 +1811,7 @@ void rtl8180_rx(struct net_device *dev)
1811 if(priv->rx_skb->len > 4) 1811 if(priv->rx_skb->len > 4)
1812 skb_trim(priv->rx_skb,priv->rx_skb->len-4); 1812 skb_trim(priv->rx_skb,priv->rx_skb->len-4);
1813#ifndef RX_DONT_PASS_UL 1813#ifndef RX_DONT_PASS_UL
1814 if(!ieee80211_rx(priv->ieee80211, 1814 if(!ieee80211_rtl_rx(priv->ieee80211,
1815 priv->rx_skb, &stats)){ 1815 priv->rx_skb, &stats)){
1816#endif // RX_DONT_PASS_UL 1816#endif // RX_DONT_PASS_UL
1817 1817
@@ -1917,11 +1917,11 @@ rate)
1917 if (!check_nic_enought_desc(dev, priority)){ 1917 if (!check_nic_enought_desc(dev, priority)){
1918 DMESGW("Error: no descriptor left by previous TX (avail %d) ", 1918 DMESGW("Error: no descriptor left by previous TX (avail %d) ",
1919 get_curr_tx_free_desc(dev, priority)); 1919 get_curr_tx_free_desc(dev, priority));
1920 ieee80211_stop_queue(priv->ieee80211); 1920 ieee80211_rtl_stop_queue(priv->ieee80211);
1921 } 1921 }
1922 rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate); 1922 rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate);
1923 if (!check_nic_enought_desc(dev, priority)) 1923 if (!check_nic_enought_desc(dev, priority))
1924 ieee80211_stop_queue(priv->ieee80211); 1924 ieee80211_rtl_stop_queue(priv->ieee80211);
1925 1925
1926 spin_unlock_irqrestore(&priv->tx_lock,flags); 1926 spin_unlock_irqrestore(&priv->tx_lock,flags);
1927} 1927}
@@ -3680,7 +3680,7 @@ static const struct net_device_ops rtl8180_netdev_ops = {
3680 .ndo_set_mac_address = r8180_set_mac_adr, 3680 .ndo_set_mac_address = r8180_set_mac_adr,
3681 .ndo_validate_addr = eth_validate_addr, 3681 .ndo_validate_addr = eth_validate_addr,
3682 .ndo_change_mtu = eth_change_mtu, 3682 .ndo_change_mtu = eth_change_mtu,
3683 .ndo_start_xmit = ieee80211_xmit, 3683 .ndo_start_xmit = ieee80211_rtl_xmit,
3684}; 3684};
3685 3685
3686static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, 3686static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
@@ -3900,7 +3900,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri)
3900 spin_unlock_irqrestore(&priv->tx_lock,flags); 3900 spin_unlock_irqrestore(&priv->tx_lock,flags);
3901 3901
3902 if(enough_desc) 3902 if(enough_desc)
3903 ieee80211_wake_queue(priv->ieee80211); 3903 ieee80211_rtl_wake_queue(priv->ieee80211);
3904} 3904}
3905 3905
3906void rtl8180_tx_isr(struct net_device *dev, int pri,short error) 3906void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 536cb6e8e796..124cde356cbc 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -377,7 +377,7 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
377 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq); 377 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
378 //printk("start scan============================>\n"); 378 //printk("start scan============================>\n");
379 ieee80211_softmac_ips_scan_syncro(priv->ieee80211); 379 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
380//ieee80211_start_scan(priv->ieee80211); 380//ieee80211_rtl_start_scan(priv->ieee80211);
381 /* intentionally forget to up sem */ 381 /* intentionally forget to up sem */
382// up(&priv->ieee80211->wx_sem); 382// up(&priv->ieee80211->wx_sem);
383 ret = 0; 383 ret = 0;
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h
index 97137ddefff4..3ba9e9e90bda 100644
--- a/drivers/staging/rtl8192e/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211.h
@@ -303,8 +303,8 @@ enum _ReasonCode{
303#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl 303#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl
304 304
305#define ieee80211_get_beacon ieee80211_get_beacon_rsl 305#define ieee80211_get_beacon ieee80211_get_beacon_rsl
306#define ieee80211_wake_queue ieee80211_wake_queue_rsl 306#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl
307#define ieee80211_stop_queue ieee80211_stop_queue_rsl 307#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl
308#define ieee80211_reset_queue ieee80211_reset_queue_rsl 308#define ieee80211_reset_queue ieee80211_reset_queue_rsl
309#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl 309#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl
310#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl 310#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
@@ -2435,13 +2435,13 @@ extern int ieee80211_encrypt_fragment(
2435 struct sk_buff *frag, 2435 struct sk_buff *frag,
2436 int hdr_len); 2436 int hdr_len);
2437 2437
2438extern int ieee80211_xmit(struct sk_buff *skb, 2438extern int ieee80211_rtl_xmit(struct sk_buff *skb,
2439 struct net_device *dev); 2439 struct net_device *dev);
2440extern void ieee80211_txb_free(struct ieee80211_txb *); 2440extern void ieee80211_txb_free(struct ieee80211_txb *);
2441 2441
2442 2442
2443/* ieee80211_rx.c */ 2443/* ieee80211_rx.c */
2444extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 2444extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
2445 struct ieee80211_rx_stats *rx_stats); 2445 struct ieee80211_rx_stats *rx_stats);
2446extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, 2446extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2447 struct ieee80211_hdr_4addr *header, 2447 struct ieee80211_hdr_4addr *header,
@@ -2502,8 +2502,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
2502extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); 2502extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
2503extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); 2503extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
2504extern void ieee80211_reset_queue(struct ieee80211_device *ieee); 2504extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
2505extern void ieee80211_wake_queue(struct ieee80211_device *ieee); 2505extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
2506extern void ieee80211_stop_queue(struct ieee80211_device *ieee); 2506extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
2507extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); 2507extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
2508extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); 2508extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
2509extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); 2509extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
index 83c8452de378..aa76390487bb 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
@@ -333,8 +333,8 @@ enum _ReasonCode{
333#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl 333#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl
334 334
335#define ieee80211_get_beacon ieee80211_get_beacon_rsl 335#define ieee80211_get_beacon ieee80211_get_beacon_rsl
336#define ieee80211_wake_queue ieee80211_wake_queue_rsl 336#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl
337#define ieee80211_stop_queue ieee80211_stop_queue_rsl 337#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl
338#define ieee80211_reset_queue ieee80211_reset_queue_rsl 338#define ieee80211_reset_queue ieee80211_reset_queue_rsl
339#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl 339#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl
340#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl 340#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
@@ -2546,13 +2546,13 @@ extern int ieee80211_encrypt_fragment(
2546 struct sk_buff *frag, 2546 struct sk_buff *frag,
2547 int hdr_len); 2547 int hdr_len);
2548 2548
2549extern int ieee80211_xmit(struct sk_buff *skb, 2549extern int ieee80211_rtl_xmit(struct sk_buff *skb,
2550 struct net_device *dev); 2550 struct net_device *dev);
2551extern void ieee80211_txb_free(struct ieee80211_txb *); 2551extern void ieee80211_txb_free(struct ieee80211_txb *);
2552 2552
2553 2553
2554/* ieee80211_rx.c */ 2554/* ieee80211_rx.c */
2555extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 2555extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
2556 struct ieee80211_rx_stats *rx_stats); 2556 struct ieee80211_rx_stats *rx_stats);
2557extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, 2557extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2558 struct ieee80211_hdr_4addr *header, 2558 struct ieee80211_hdr_4addr *header,
@@ -2613,8 +2613,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
2613extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); 2613extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
2614extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); 2614extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
2615extern void ieee80211_reset_queue(struct ieee80211_device *ieee); 2615extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
2616extern void ieee80211_wake_queue(struct ieee80211_device *ieee); 2616extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
2617extern void ieee80211_stop_queue(struct ieee80211_device *ieee); 2617extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
2618extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); 2618extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
2619extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); 2619extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
2620extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); 2620extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
index 2644155737a8..f43a7db5c78b 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
@@ -119,7 +119,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
119 ieee = (struct ieee80211_device *)dev->priv; 119 ieee = (struct ieee80211_device *)dev->priv;
120#endif 120#endif
121#if 0 121#if 0
122 dev->hard_start_xmit = ieee80211_xmit; 122 dev->hard_start_xmit = ieee80211_rtl_xmit;
123#endif 123#endif
124 124
125 memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); 125 memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
@@ -333,7 +333,7 @@ extern void ieee80211_crypto_ccmp_exit(void);
333extern int ieee80211_crypto_wep_init(void); 333extern int ieee80211_crypto_wep_init(void);
334extern void ieee80211_crypto_wep_exit(void); 334extern void ieee80211_crypto_wep_exit(void);
335 335
336int __init ieee80211_init(void) 336int __init ieee80211_rtl_init(void)
337{ 337{
338 struct proc_dir_entry *e; 338 struct proc_dir_entry *e;
339 int retval; 339 int retval;
@@ -389,7 +389,7 @@ int __init ieee80211_init(void)
389 return 0; 389 return 0;
390} 390}
391 391
392void __exit ieee80211_exit(void) 392void __exit ieee80211_rtl_exit(void)
393{ 393{
394 if (ieee80211_proc) { 394 if (ieee80211_proc) {
395 remove_proc_entry("debug_level", ieee80211_proc); 395 remove_proc_entry("debug_level", ieee80211_proc);
@@ -412,8 +412,8 @@ module_param(debug, int, 0444);
412MODULE_PARM_DESC(debug, "debug output mask"); 412MODULE_PARM_DESC(debug, "debug output mask");
413 413
414 414
415//module_exit(ieee80211_exit); 415//module_exit(ieee80211_rtl_exit);
416//module_init(ieee80211_init); 416//module_init(ieee80211_rtl_init);
417#endif 417#endif
418#endif 418#endif
419 419
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
index 5dc478b86375..06d91715143c 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
@@ -923,7 +923,7 @@ u8 parse_subframe(struct sk_buff *skb,
923/* All received frames are sent to this function. @skb contains the frame in 923/* All received frames are sent to this function. @skb contains the frame in
924 * IEEE 802.11 format, i.e., in the format it was sent over air. 924 * IEEE 802.11 format, i.e., in the format it was sent over air.
925 * This function is called only as a tasklet (software IRQ). */ 925 * This function is called only as a tasklet (software IRQ). */
926int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 926int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
927 struct ieee80211_rx_stats *rx_stats) 927 struct ieee80211_rx_stats *rx_stats)
928{ 928{
929 struct net_device *dev = ieee->dev; 929 struct net_device *dev = ieee->dev;
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index 593d22825184..6d1ddec39f0e 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -684,7 +684,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
684} 684}
685 685
686/* called with ieee->lock held */ 686/* called with ieee->lock held */
687void ieee80211_start_scan(struct ieee80211_device *ieee) 687void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
688{ 688{
689#ifdef ENABLE_DOT11D 689#ifdef ENABLE_DOT11D
690 if(IS_DOT11D_ENABLE(ieee) ) 690 if(IS_DOT11D_ENABLE(ieee) )
@@ -1430,7 +1430,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
1430 } 1430 }
1431} 1431}
1432 1432
1433void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) 1433void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1434{ 1434{
1435 u8 *c; 1435 u8 *c;
1436 struct sk_buff *skb; 1436 struct sk_buff *skb;
@@ -2262,7 +2262,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2262 2262
2263 ieee80211_associate_step2(ieee); 2263 ieee80211_associate_step2(ieee);
2264 }else{ 2264 }else{
2265 ieee80211_auth_challenge(ieee, challenge, chlen); 2265 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
2266 } 2266 }
2267 }else{ 2267 }else{
2268 ieee->softmac_stats.rx_auth_rs_err++; 2268 ieee->softmac_stats.rx_auth_rs_err++;
@@ -2376,7 +2376,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
2376 * to check it any more. 2376 * to check it any more.
2377 * */ 2377 * */
2378 //printk("error:no descriptor left@queue_index %d\n", queue_index); 2378 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2379 //ieee80211_stop_queue(ieee); 2379 //ieee80211_rtl_stop_queue(ieee);
2380#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE 2380#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2381 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); 2381 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2382#else 2382#else
@@ -2440,7 +2440,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee)
2440 2440
2441} 2441}
2442 2442
2443void ieee80211_wake_queue(struct ieee80211_device *ieee) 2443void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2444{ 2444{
2445 2445
2446 unsigned long flags; 2446 unsigned long flags;
@@ -2481,7 +2481,7 @@ exit :
2481} 2481}
2482 2482
2483 2483
2484void ieee80211_stop_queue(struct ieee80211_device *ieee) 2484void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2485{ 2485{
2486 //unsigned long flags; 2486 //unsigned long flags;
2487 //spin_lock_irqsave(&ieee->lock,flags); 2487 //spin_lock_irqsave(&ieee->lock,flags);
@@ -2706,7 +2706,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
2706 2706
2707 if (ieee->state == IEEE80211_NOLINK){ 2707 if (ieee->state == IEEE80211_NOLINK){
2708 ieee->actscanning = true; 2708 ieee->actscanning = true;
2709 ieee80211_start_scan(ieee); 2709 ieee80211_rtl_start_scan(ieee);
2710 } 2710 }
2711 spin_unlock_irqrestore(&ieee->lock, flags); 2711 spin_unlock_irqrestore(&ieee->lock, flags);
2712} 2712}
@@ -2775,7 +2775,7 @@ void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
2775 { 2775 {
2776 ieee->is_roaming= false; 2776 ieee->is_roaming= false;
2777 ieee->actscanning = true; 2777 ieee->actscanning = true;
2778 ieee80211_start_scan(ieee); 2778 ieee80211_rtl_start_scan(ieee);
2779 } 2779 }
2780 spin_unlock_irqrestore(&ieee->lock, flags); 2780 spin_unlock_irqrestore(&ieee->lock, flags);
2781 2781
@@ -3497,8 +3497,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee)
3497 3497
3498#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) 3498#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3499//EXPORT_SYMBOL(ieee80211_get_beacon); 3499//EXPORT_SYMBOL(ieee80211_get_beacon);
3500//EXPORT_SYMBOL(ieee80211_wake_queue); 3500//EXPORT_SYMBOL(ieee80211_rtl_wake_queue);
3501//EXPORT_SYMBOL(ieee80211_stop_queue); 3501//EXPORT_SYMBOL(ieee80211_rtl_stop_queue);
3502//EXPORT_SYMBOL(ieee80211_reset_queue); 3502//EXPORT_SYMBOL(ieee80211_reset_queue);
3503//EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); 3503//EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3504//EXPORT_SYMBOL(ieee80211_softmac_start_protocol); 3504//EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
@@ -3518,8 +3518,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee)
3518//EXPORT_SYMBOL(ieee80211_start_scan_syncro); 3518//EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3519#else 3519#else
3520EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); 3520EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
3521EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue); 3521EXPORT_SYMBOL_NOVERS(ieee80211_rtl_wake_queue);
3522EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue); 3522EXPORT_SYMBOL_NOVERS(ieee80211_rtl_stop_queue);
3523EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); 3523EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
3524EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); 3524EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
3525EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); 3525EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
index 103b33c093f5..798fb4154c25 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
@@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u
604 } 604 }
605} 605}
606 606
607int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) 607int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
608{ 608{
609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) 609#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
610 struct ieee80211_device *ieee = netdev_priv(dev); 610 struct ieee80211_device *ieee = netdev_priv(dev);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
index 4e34a1f4c66b..3441b72dd8fa 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
@@ -976,7 +976,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
976 { 976 {
977 if (len != ie[1]+2) 977 if (len != ie[1]+2)
978 { 978 {
979 printk("len:%d, ie:%d\n", len, ie[1]); 979 printk("len:%zu, ie:%d\n", len, ie[1]);
980 return -EINVAL; 980 return -EINVAL;
981 } 981 }
982 buf = kmalloc(len, GFP_KERNEL); 982 buf = kmalloc(len, GFP_KERNEL);
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
index 98b3bb6b6d69..e41e8a0c739c 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
@@ -382,7 +382,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
382 382
383 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 383 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
384 { 384 {
385 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 385 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
386 return -1; 386 return -1;
387 } 387 }
388 388
@@ -481,7 +481,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
481 481
482 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 482 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
483 { 483 {
484 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 484 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
485 return -1; 485 return -1;
486 } 486 }
487 rsp = ( struct ieee80211_hdr_3addr*)skb->data; 487 rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -611,7 +611,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
611 611
612 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) 612 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
613 { 613 {
614 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); 614 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6));
615 return -1; 615 return -1;
616 } 616 }
617 617
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index ff8fe7e32a92..0ca5d8b4f746 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -5795,7 +5795,7 @@ static void rtl8192_rx(struct net_device *dev)
5795 stats.fragoffset = 0; 5795 stats.fragoffset = 0;
5796 stats.ntotalfrag = 1; 5796 stats.ntotalfrag = 1;
5797 5797
5798 if(!ieee80211_rx(priv->ieee80211, skb, &stats)){ 5798 if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){
5799 dev_kfree_skb_any(skb); 5799 dev_kfree_skb_any(skb);
5800 } else { 5800 } else {
5801 priv->stats.rxok++; 5801 priv->stats.rxok++;
@@ -5837,7 +5837,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
5837 .ndo_do_ioctl = rtl8192_ioctl, 5837 .ndo_do_ioctl = rtl8192_ioctl,
5838 .ndo_set_multicast_list = r8192_set_multicast, 5838 .ndo_set_multicast_list = r8192_set_multicast,
5839 .ndo_set_mac_address = r8192_set_mac_adr, 5839 .ndo_set_mac_address = r8192_set_mac_adr,
5840 .ndo_start_xmit = ieee80211_xmit, 5840 .ndo_start_xmit = ieee80211_rtl_xmit,
5841}; 5841};
5842 5842
5843/**************************************************************************** 5843/****************************************************************************
@@ -6121,14 +6121,14 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6121 RT_TRACE(COMP_DOWN, "wlan driver removed\n"); 6121 RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6122} 6122}
6123 6123
6124extern int ieee80211_init(void); 6124extern int ieee80211_rtl_init(void);
6125extern void ieee80211_exit(void); 6125extern void ieee80211_rtl_exit(void);
6126 6126
6127static int __init rtl8192_pci_module_init(void) 6127static int __init rtl8192_pci_module_init(void)
6128{ 6128{
6129 int retval; 6129 int retval;
6130 6130
6131 retval = ieee80211_init(); 6131 retval = ieee80211_rtl_init();
6132 if (retval) 6132 if (retval)
6133 return retval; 6133 return retval;
6134 6134
@@ -6153,7 +6153,7 @@ static void __exit rtl8192_pci_module_exit(void)
6153 6153
6154 RT_TRACE(COMP_DOWN, "Exiting"); 6154 RT_TRACE(COMP_DOWN, "Exiting");
6155 rtl8192_proc_module_remove(); 6155 rtl8192_proc_module_remove();
6156 ieee80211_exit(); 6156 ieee80211_rtl_exit();
6157} 6157}
6158 6158
6159//warning message WB 6159//warning message WB
@@ -6313,7 +6313,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6313 spin_unlock_irqrestore(&priv->tx_lock,flags); 6313 spin_unlock_irqrestore(&priv->tx_lock,flags);
6314 6314
6315 if(enough_desc) 6315 if(enough_desc)
6316 ieee80211_wake_queue(priv->ieee80211); 6316 ieee80211_rtl_wake_queue(priv->ieee80211);
6317#endif 6317#endif
6318} 6318}
6319 6319
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
index f22d024b1c39..9a4c858b0666 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
@@ -1721,13 +1721,13 @@ extern int ieee80211_encrypt_fragment(
1721 struct sk_buff *frag, 1721 struct sk_buff *frag,
1722 int hdr_len); 1722 int hdr_len);
1723 1723
1724extern int rtl8192_ieee80211_xmit(struct sk_buff *skb, 1724extern int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb,
1725 struct net_device *dev); 1725 struct net_device *dev);
1726extern void ieee80211_txb_free(struct ieee80211_txb *); 1726extern void ieee80211_txb_free(struct ieee80211_txb *);
1727 1727
1728 1728
1729/* ieee80211_rx.c */ 1729/* ieee80211_rx.c */
1730extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 1730extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1731 struct ieee80211_rx_stats *rx_stats); 1731 struct ieee80211_rx_stats *rx_stats);
1732extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, 1732extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1733 struct ieee80211_hdr_4addr *header, 1733 struct ieee80211_hdr_4addr *header,
@@ -1783,8 +1783,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
1783extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); 1783extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
1784extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); 1784extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
1785extern void ieee80211_reset_queue(struct ieee80211_device *ieee); 1785extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
1786extern void ieee80211_wake_queue(struct ieee80211_device *ieee); 1786extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
1787extern void ieee80211_stop_queue(struct ieee80211_device *ieee); 1787extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
1788extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); 1788extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
1789extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); 1789extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
1790extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); 1790extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
index ac223cef1d33..fecfa120ff48 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
@@ -208,7 +208,7 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
208 * 208 *
209 * Responsible for handling management control frames 209 * Responsible for handling management control frames
210 * 210 *
211 * Called by ieee80211_rx */ 211 * Called by ieee80211_rtl_rx */
212static inline int 212static inline int
213ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, 213ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
214 struct ieee80211_rx_stats *rx_stats, u16 type, 214 struct ieee80211_rx_stats *rx_stats, u16 type,
@@ -289,7 +289,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
289 return 0; 289 return 0;
290} 290}
291 291
292/* Called only as a tasklet (software IRQ), by ieee80211_rx */ 292/* Called only as a tasklet (software IRQ), by ieee80211_rtl_rx */
293static inline int 293static inline int
294ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, 294ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
295 struct ieee80211_crypt_data *crypt) 295 struct ieee80211_crypt_data *crypt)
@@ -858,7 +858,7 @@ u8 parse_subframe(struct sk_buff *skb,
858/* All received frames are sent to this function. @skb contains the frame in 858/* All received frames are sent to this function. @skb contains the frame in
859 * IEEE 802.11 format, i.e., in the format it was sent over air. 859 * IEEE 802.11 format, i.e., in the format it was sent over air.
860 * This function is called only as a tasklet (software IRQ). */ 860 * This function is called only as a tasklet (software IRQ). */
861int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 861int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
862 struct ieee80211_rx_stats *rx_stats) 862 struct ieee80211_rx_stats *rx_stats)
863{ 863{
864 struct net_device *dev = ieee->dev; 864 struct net_device *dev = ieee->dev;
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index 203c0a5cc8c1..95d4f84dcf3f 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -610,7 +610,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
610} 610}
611 611
612/* called with ieee->lock held */ 612/* called with ieee->lock held */
613void ieee80211_start_scan(struct ieee80211_device *ieee) 613void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
614{ 614{
615 if(IS_DOT11D_ENABLE(ieee) ) 615 if(IS_DOT11D_ENABLE(ieee) )
616 { 616 {
@@ -1281,7 +1281,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
1281 } 1281 }
1282} 1282}
1283 1283
1284void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) 1284void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1285{ 1285{
1286 u8 *c; 1286 u8 *c;
1287 struct sk_buff *skb; 1287 struct sk_buff *skb;
@@ -2054,7 +2054,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2054 2054
2055 ieee80211_associate_step2(ieee); 2055 ieee80211_associate_step2(ieee);
2056 }else{ 2056 }else{
2057 ieee80211_auth_challenge(ieee, challenge, chlen); 2057 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
2058 } 2058 }
2059 }else{ 2059 }else{
2060 ieee->softmac_stats.rx_auth_rs_err++; 2060 ieee->softmac_stats.rx_auth_rs_err++;
@@ -2162,7 +2162,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
2162 * to check it any more. 2162 * to check it any more.
2163 * */ 2163 * */
2164 //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index)); 2164 //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index));
2165 //ieee80211_stop_queue(ieee); 2165 //ieee80211_rtl_stop_queue(ieee);
2166 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); 2166 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2167 }else{ 2167 }else{
2168 ieee->softmac_data_hard_start_xmit( 2168 ieee->softmac_data_hard_start_xmit(
@@ -2222,7 +2222,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee)
2222 2222
2223} 2223}
2224 2224
2225void ieee80211_wake_queue(struct ieee80211_device *ieee) 2225void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2226{ 2226{
2227 2227
2228 unsigned long flags; 2228 unsigned long flags;
@@ -2263,7 +2263,7 @@ exit :
2263} 2263}
2264 2264
2265 2265
2266void ieee80211_stop_queue(struct ieee80211_device *ieee) 2266void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2267{ 2267{
2268 //unsigned long flags; 2268 //unsigned long flags;
2269 //spin_lock_irqsave(&ieee->lock,flags); 2269 //spin_lock_irqsave(&ieee->lock,flags);
@@ -2479,7 +2479,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
2479 2479
2480 if (ieee->state == IEEE80211_NOLINK){ 2480 if (ieee->state == IEEE80211_NOLINK){
2481 ieee->actscanning = true; 2481 ieee->actscanning = true;
2482 ieee80211_start_scan(ieee); 2482 ieee80211_rtl_start_scan(ieee);
2483 } 2483 }
2484 spin_unlock_irqrestore(&ieee->lock, flags); 2484 spin_unlock_irqrestore(&ieee->lock, flags);
2485} 2485}
@@ -2552,7 +2552,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work)
2552 if(ieee->state == IEEE80211_NOLINK) 2552 if(ieee->state == IEEE80211_NOLINK)
2553 { 2553 {
2554 ieee->actscanning = true; 2554 ieee->actscanning = true;
2555 ieee80211_start_scan(ieee); 2555 ieee80211_rtl_start_scan(ieee);
2556 } 2556 }
2557 spin_unlock_irqrestore(&ieee->lock, flags); 2557 spin_unlock_irqrestore(&ieee->lock, flags);
2558 2558
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
index 60621d6b2a6b..4d54e1e62d22 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
@@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u
604 } 604 }
605} 605}
606 606
607int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) 607int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
608{ 608{
609 struct ieee80211_device *ieee = netdev_priv(dev); 609 struct ieee80211_device *ieee = netdev_priv(dev);
610 struct ieee80211_txb *txb = NULL; 610 struct ieee80211_txb *txb = NULL;
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
index 66274d7666ff..ccb9d5b8cd44 100644
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ b/drivers/staging/rtl8192su/r8192U_core.c
@@ -126,6 +126,8 @@ static struct usb_device_id rtl8192_usb_id_tbl[] = {
126 {USB_DEVICE(0x2001, 0x3301)}, 126 {USB_DEVICE(0x2001, 0x3301)},
127 /* Zinwell */ 127 /* Zinwell */
128 {USB_DEVICE(0x5a57, 0x0290)}, 128 {USB_DEVICE(0x5a57, 0x0290)},
129 /* Guillemot */
130 {USB_DEVICE(0x06f8, 0xe031)},
129 //92SU 131 //92SU
130 {USB_DEVICE(0x0bda, 0x8172)}, 132 {USB_DEVICE(0x0bda, 0x8172)},
131 {} 133 {}
@@ -1501,7 +1503,7 @@ static void rtl8192_rx_isr(struct urb *urb)
1501 urb->context = skb; 1503 urb->context = skb;
1502 skb_queue_tail(&priv->rx_queue, skb); 1504 skb_queue_tail(&priv->rx_queue, skb);
1503 err = usb_submit_urb(urb, GFP_ATOMIC); 1505 err = usb_submit_urb(urb, GFP_ATOMIC);
1504 if(err && err != EPERM) 1506 if(err && err != -EPERM)
1505 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status); 1507 printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
1506} 1508}
1507 1509
@@ -7155,7 +7157,7 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb)
7155 unicast_packet = true; 7157 unicast_packet = true;
7156 } 7158 }
7157 7159
7158 if(!ieee80211_rx(priv->ieee80211,skb, &stats)) { 7160 if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) {
7159 dev_kfree_skb_any(skb); 7161 dev_kfree_skb_any(skb);
7160 } else { 7162 } else {
7161 // priv->stats.rxoktotal++; //YJ,test,090108 7163 // priv->stats.rxoktotal++; //YJ,test,090108
@@ -7426,7 +7428,7 @@ static const struct net_device_ops rtl8192_netdev_ops = {
7426 .ndo_set_mac_address = r8192_set_mac_adr, 7428 .ndo_set_mac_address = r8192_set_mac_adr,
7427 .ndo_validate_addr = eth_validate_addr, 7429 .ndo_validate_addr = eth_validate_addr,
7428 .ndo_change_mtu = eth_change_mtu, 7430 .ndo_change_mtu = eth_change_mtu,
7429 .ndo_start_xmit = rtl8192_ieee80211_xmit, 7431 .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit,
7430}; 7432};
7431 7433
7432static int __devinit rtl8192_usb_probe(struct usb_interface *intf, 7434static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
@@ -7619,7 +7621,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri)
7619 spin_unlock_irqrestore(&priv->tx_lock,flags); 7621 spin_unlock_irqrestore(&priv->tx_lock,flags);
7620 7622
7621 if(enough_desc) 7623 if(enough_desc)
7622 ieee80211_wake_queue(priv->ieee80211); 7624 ieee80211_rtl_wake_queue(priv->ieee80211);
7623} 7625}
7624 7626
7625void EnableHWSecurityConfig8192(struct net_device *dev) 7627void EnableHWSecurityConfig8192(struct net_device *dev)
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
index d397f1d68eb7..5f12d62658c9 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
@@ -845,7 +845,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
845 { 845 {
846 if (len != ie[1]+2) 846 if (len != ie[1]+2)
847 { 847 {
848 printk("len:%d, ie:%d\n", len, ie[1]); 848 printk("len:%zu, ie:%d\n", len, ie[1]);
849 return -EINVAL; 849 return -EINVAL;
850 } 850 }
851 buf = kmalloc(len, GFP_KERNEL); 851 buf = kmalloc(len, GFP_KERNEL);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index 26af43bb8390..512a57aebde3 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -340,7 +340,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
340 340
341 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 341 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
342 { 342 {
343 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 343 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
344 return -1; 344 return -1;
345 } 345 }
346 346
@@ -439,7 +439,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
439 439
440 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 440 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
441 { 441 {
442 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 442 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9));
443 return -1; 443 return -1;
444 } 444 }
445 rsp = ( struct ieee80211_hdr_3addr*)skb->data; 445 rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -569,7 +569,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
569 569
570 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) 570 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
571 { 571 {
572 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); 572 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6));
573 return -1; 573 return -1;
574 } 574 }
575 575
diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig
new file mode 100644
index 000000000000..204dbfc3c38b
--- /dev/null
+++ b/drivers/staging/sm7xx/Kconfig
@@ -0,0 +1,15 @@
1config FB_SM7XX
2 tristate "Silicon Motion SM7XX Frame Buffer Support"
3 depends on FB
4 select FB_CFB_FILLRECT
5 select FB_CFB_COPYAREA
6 select FB_CFB_IMAGEBLIT
7 help
8 Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
9
10config FB_SM7XX_ACCEL
11 bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
12 depends on FB_SM7XX && EXPERIMENTAL
13 help
14 This will compile the Trident frame buffer device with
15 acceleration functions.
diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile
new file mode 100644
index 000000000000..f43cb9106305
--- /dev/null
+++ b/drivers/staging/sm7xx/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_FB_SM7XX) += sm7xx.o
2
3sm7xx-y := smtcfb.o
diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO
new file mode 100644
index 000000000000..1f61f5e11cf5
--- /dev/null
+++ b/drivers/staging/sm7xx/TODO
@@ -0,0 +1,10 @@
1TODO:
2- Dual head support
3- use kernel coding style
4- checkpatch.pl clean
5- refine the code and remove unused code
6- use kernel framebuffer mode setting instead of hard code
7- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c
8
9Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
10Teddy Wang <teddy.wang@siliconmotion.com.cn>.
diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c
new file mode 100644
index 000000000000..133b86c6a678
--- /dev/null
+++ b/drivers/staging/sm7xx/smtc2d.c
@@ -0,0 +1,979 @@
1/*
2 * Silicon Motion SM7XX 2D drawing engine functions.
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Author: Boyod boyod.yang@siliconmotion.com.cn
6 *
7 * Copyright (C) 2009 Lemote, Inc.
8 * Author: Wu Zhangjin, wuzj@lemote.com
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 *
14 * Version 0.10.26192.21.01
15 * - Add PowerPC support
16 * - Add 2D support for Lynx -
17 * Verified on 2.6.19.2
18 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
19 */
20
21unsigned char smtc_de_busy;
22
23void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
24{
25 writel(nData, smtc_2DBaseAddress + nOffset);
26}
27
28unsigned long SMTC_read2Dreg(unsigned long nOffset)
29{
30 return readl(smtc_2DBaseAddress + nOffset);
31}
32
33void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
34{
35 writel(nData, smtc_2Ddataport + nOffset);
36}
37
38/**********************************************************************
39 *
40 * deInit
41 *
42 * Purpose
43 * Drawing engine initialization.
44 *
45 **********************************************************************/
46
47void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
48 unsigned int bpp)
49{
50 /* Get current power configuration. */
51 unsigned char clock;
52 clock = smtc_seqr(0x21);
53
54 /* initialize global 'mutex lock' variable */
55 smtc_de_busy = 0;
56
57 /* Enable 2D Drawing Engine */
58 smtc_seqw(0x21, clock & 0xF8);
59
60 SMTC_write2Dreg(DE_CLIP_TL,
61 FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
62 FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
63 FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
64 FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
65
66 if (bpp >= 24) {
67 SMTC_write2Dreg(DE_PITCH,
68 FIELD_VALUE(0, DE_PITCH, DESTINATION,
69 nModeWidth * 3) | FIELD_VALUE(0,
70 DE_PITCH,
71 SOURCE,
72 nModeWidth
73 * 3));
74 } else {
75 SMTC_write2Dreg(DE_PITCH,
76 FIELD_VALUE(0, DE_PITCH, DESTINATION,
77 nModeWidth) | FIELD_VALUE(0,
78 DE_PITCH,
79 SOURCE,
80 nModeWidth));
81 }
82
83 SMTC_write2Dreg(DE_WINDOW_WIDTH,
84 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
85 nModeWidth) | FIELD_VALUE(0,
86 DE_WINDOW_WIDTH,
87 SOURCE,
88 nModeWidth));
89
90 switch (bpp) {
91 case 8:
92 SMTC_write2Dreg(DE_STRETCH_FORMAT,
93 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
94 NORMAL) | FIELD_VALUE(0,
95 DE_STRETCH_FORMAT,
96 PATTERN_Y,
97 0) |
98 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
99 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
100 PIXEL_FORMAT,
101 8) | FIELD_SET(0,
102 DE_STRETCH_FORMAT,
103 ADDRESSING,
104 XY) |
105 FIELD_VALUE(0, DE_STRETCH_FORMAT,
106 SOURCE_HEIGHT, 3));
107 break;
108 case 24:
109 SMTC_write2Dreg(DE_STRETCH_FORMAT,
110 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
111 NORMAL) | FIELD_VALUE(0,
112 DE_STRETCH_FORMAT,
113 PATTERN_Y,
114 0) |
115 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
116 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
117 PIXEL_FORMAT,
118 24) | FIELD_SET(0,
119 DE_STRETCH_FORMAT,
120 ADDRESSING,
121 XY) |
122 FIELD_VALUE(0, DE_STRETCH_FORMAT,
123 SOURCE_HEIGHT, 3));
124 break;
125 case 16:
126 default:
127 SMTC_write2Dreg(DE_STRETCH_FORMAT,
128 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
129 NORMAL) | FIELD_VALUE(0,
130 DE_STRETCH_FORMAT,
131 PATTERN_Y,
132 0) |
133 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
134 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
135 PIXEL_FORMAT,
136 16) | FIELD_SET(0,
137 DE_STRETCH_FORMAT,
138 ADDRESSING,
139 XY) |
140 FIELD_VALUE(0, DE_STRETCH_FORMAT,
141 SOURCE_HEIGHT, 3));
142 break;
143 }
144
145 SMTC_write2Dreg(DE_MASKS,
146 FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
147 FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
148 SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
149 FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
150 0xFFFFFF));
151 SMTC_write2Dreg(DE_COLOR_COMPARE,
152 FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
153}
154
155void deVerticalLine(unsigned long dst_base,
156 unsigned long dst_pitch,
157 unsigned long nX,
158 unsigned long nY,
159 unsigned long dst_height, unsigned long nColor)
160{
161 deWaitForNotBusy();
162
163 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
164 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
165 dst_base));
166
167 SMTC_write2Dreg(DE_PITCH,
168 FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
169 FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
170
171 SMTC_write2Dreg(DE_WINDOW_WIDTH,
172 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
173 dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
174 SOURCE,
175 dst_pitch));
176
177 SMTC_write2Dreg(DE_FOREGROUND,
178 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
179
180 SMTC_write2Dreg(DE_DESTINATION,
181 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
182 FIELD_VALUE(0, DE_DESTINATION, X, nX) |
183 FIELD_VALUE(0, DE_DESTINATION, Y, nY));
184
185 SMTC_write2Dreg(DE_DIMENSION,
186 FIELD_VALUE(0, DE_DIMENSION, X, 1) |
187 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
188
189 SMTC_write2Dreg(DE_CONTROL,
190 FIELD_SET(0, DE_CONTROL, STATUS, START) |
191 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
192 FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
193 FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
194 FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
195 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
196 FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
197 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
198 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
199
200 smtc_de_busy = 1;
201}
202
203void deHorizontalLine(unsigned long dst_base,
204 unsigned long dst_pitch,
205 unsigned long nX,
206 unsigned long nY,
207 unsigned long dst_width, unsigned long nColor)
208{
209 deWaitForNotBusy();
210
211 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
212 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
213 dst_base));
214
215 SMTC_write2Dreg(DE_PITCH,
216 FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
217 FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
218
219 SMTC_write2Dreg(DE_WINDOW_WIDTH,
220 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
221 dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
222 SOURCE,
223 dst_pitch));
224 SMTC_write2Dreg(DE_FOREGROUND,
225 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
226 SMTC_write2Dreg(DE_DESTINATION,
227 FIELD_SET(0, DE_DESTINATION, WRAP,
228 DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
229 nX) | FIELD_VALUE(0,
230 DE_DESTINATION,
231 Y,
232 nY));
233 SMTC_write2Dreg(DE_DIMENSION,
234 FIELD_VALUE(0, DE_DIMENSION, X,
235 dst_width) | FIELD_VALUE(0, DE_DIMENSION,
236 Y_ET, 1));
237 SMTC_write2Dreg(DE_CONTROL,
238 FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
239 DE_CONTROL,
240 DIRECTION,
241 RIGHT_TO_LEFT)
242 | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
243 DE_CONTROL,
244 STEP_X,
245 POSITIVE)
246 | FIELD_SET(0, DE_CONTROL, STEP_Y,
247 NEGATIVE) | FIELD_SET(0, DE_CONTROL,
248 LAST_PIXEL,
249 OFF) | FIELD_SET(0,
250 DE_CONTROL,
251 COMMAND,
252 SHORT_STROKE)
253 | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
254 ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
255 0x0C));
256
257 smtc_de_busy = 1;
258}
259
260void deLine(unsigned long dst_base,
261 unsigned long dst_pitch,
262 unsigned long nX1,
263 unsigned long nY1,
264 unsigned long nX2, unsigned long nY2, unsigned long nColor)
265{
266 unsigned long nCommand =
267 FIELD_SET(0, DE_CONTROL, STATUS, START) |
268 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
269 FIELD_SET(0, DE_CONTROL, MAJOR, X) |
270 FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
271 FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
272 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
273 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
274 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
275 unsigned long DeltaX;
276 unsigned long DeltaY;
277
278 /* Calculate delta X */
279 if (nX1 <= nX2)
280 DeltaX = nX2 - nX1;
281 else {
282 DeltaX = nX1 - nX2;
283 nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
284 }
285
286 /* Calculate delta Y */
287 if (nY1 <= nY2)
288 DeltaY = nY2 - nY1;
289 else {
290 DeltaY = nY1 - nY2;
291 nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
292 }
293
294 /* Determine the major axis */
295 if (DeltaX < DeltaY)
296 nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
297
298 /* Vertical line? */
299 if (nX1 == nX2)
300 deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
301
302 /* Horizontal line? */
303 else if (nY1 == nY2)
304 deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
305 DeltaX, nColor);
306
307 /* Diagonal line? */
308 else if (DeltaX == DeltaY) {
309 deWaitForNotBusy();
310
311 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
312 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
313 ADDRESS, dst_base));
314
315 SMTC_write2Dreg(DE_PITCH,
316 FIELD_VALUE(0, DE_PITCH, DESTINATION,
317 dst_pitch) | FIELD_VALUE(0,
318 DE_PITCH,
319 SOURCE,
320 dst_pitch));
321
322 SMTC_write2Dreg(DE_WINDOW_WIDTH,
323 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
324 dst_pitch) | FIELD_VALUE(0,
325 DE_WINDOW_WIDTH,
326 SOURCE,
327 dst_pitch));
328
329 SMTC_write2Dreg(DE_FOREGROUND,
330 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
331
332 SMTC_write2Dreg(DE_DESTINATION,
333 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
334 FIELD_VALUE(0, DE_DESTINATION, X, 1) |
335 FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
336
337 SMTC_write2Dreg(DE_DIMENSION,
338 FIELD_VALUE(0, DE_DIMENSION, X, 1) |
339 FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
340
341 SMTC_write2Dreg(DE_CONTROL,
342 FIELD_SET(nCommand, DE_CONTROL, COMMAND,
343 SHORT_STROKE));
344 }
345
346 /* Generic line */
347 else {
348 unsigned int k1, k2, et, w;
349 if (DeltaX < DeltaY) {
350 k1 = 2 * DeltaX;
351 et = k1 - DeltaY;
352 k2 = et - DeltaY;
353 w = DeltaY + 1;
354 } else {
355 k1 = 2 * DeltaY;
356 et = k1 - DeltaX;
357 k2 = et - DeltaX;
358 w = DeltaX + 1;
359 }
360
361 deWaitForNotBusy();
362
363 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
364 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
365 ADDRESS, dst_base));
366
367 SMTC_write2Dreg(DE_PITCH,
368 FIELD_VALUE(0, DE_PITCH, DESTINATION,
369 dst_pitch) | FIELD_VALUE(0,
370 DE_PITCH,
371 SOURCE,
372 dst_pitch));
373
374 SMTC_write2Dreg(DE_WINDOW_WIDTH,
375 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
376 dst_pitch) | FIELD_VALUE(0,
377 DE_WINDOW_WIDTH,
378 SOURCE,
379 dst_pitch));
380
381 SMTC_write2Dreg(DE_FOREGROUND,
382 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
383
384 SMTC_write2Dreg(DE_SOURCE,
385 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
386 FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
387 FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
388
389 SMTC_write2Dreg(DE_DESTINATION,
390 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
391 FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
392 FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
393
394 SMTC_write2Dreg(DE_DIMENSION,
395 FIELD_VALUE(0, DE_DIMENSION, X, w) |
396 FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
397
398 SMTC_write2Dreg(DE_CONTROL,
399 FIELD_SET(nCommand, DE_CONTROL, COMMAND,
400 LINE_DRAW));
401 }
402
403 smtc_de_busy = 1;
404}
405
406void deFillRect(unsigned long dst_base,
407 unsigned long dst_pitch,
408 unsigned long dst_X,
409 unsigned long dst_Y,
410 unsigned long dst_width,
411 unsigned long dst_height, unsigned long nColor)
412{
413 deWaitForNotBusy();
414
415 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
416 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
417 dst_base));
418
419 if (dst_pitch) {
420 SMTC_write2Dreg(DE_PITCH,
421 FIELD_VALUE(0, DE_PITCH, DESTINATION,
422 dst_pitch) | FIELD_VALUE(0,
423 DE_PITCH,
424 SOURCE,
425 dst_pitch));
426
427 SMTC_write2Dreg(DE_WINDOW_WIDTH,
428 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
429 dst_pitch) | FIELD_VALUE(0,
430 DE_WINDOW_WIDTH,
431 SOURCE,
432 dst_pitch));
433 }
434
435 SMTC_write2Dreg(DE_FOREGROUND,
436 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
437
438 SMTC_write2Dreg(DE_DESTINATION,
439 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
440 FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
441 FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
442
443 SMTC_write2Dreg(DE_DIMENSION,
444 FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
445 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
446
447 SMTC_write2Dreg(DE_CONTROL,
448 FIELD_SET(0, DE_CONTROL, STATUS, START) |
449 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
450 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
451 FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
452 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
453 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
454
455 smtc_de_busy = 1;
456}
457
458/**********************************************************************
459 *
460 * deRotatePattern
461 *
462 * Purpose
463 * Rotate the given pattern if necessary
464 *
465 * Parameters
466 * [in]
467 * pPattern - Pointer to DE_SURFACE structure containing
468 * pattern attributes
469 * patternX - X position (0-7) of pattern origin
470 * patternY - Y position (0-7) of pattern origin
471 *
472 * [out]
473 * pattern_dstaddr - Pointer to pre-allocated buffer containing
474 * rotated pattern
475 *
476 **********************************************************************/
477void deRotatePattern(unsigned char *pattern_dstaddr,
478 unsigned long pattern_src_addr,
479 unsigned long pattern_BPP,
480 unsigned long pattern_stride, int patternX, int patternY)
481{
482 unsigned int i;
483 unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
484 unsigned int x, y;
485 unsigned char *pjPatByte;
486
487 if (pattern_dstaddr != NULL) {
488 deWaitForNotBusy();
489
490 if (patternX || patternY) {
491 /* Rotate pattern */
492 pjPatByte = (unsigned char *)pattern;
493
494 switch (pattern_BPP) {
495 case 8:
496 {
497 for (y = 0; y < 8; y++) {
498 unsigned char *pjBuffer =
499 pattern_dstaddr +
500 ((patternY + y) & 7) * 8;
501 for (x = 0; x < 8; x++) {
502 pjBuffer[(patternX +
503 x) & 7] =
504 pjPatByte[x];
505 }
506 pjPatByte += pattern_stride;
507 }
508 break;
509 }
510
511 case 16:
512 {
513 for (y = 0; y < 8; y++) {
514 unsigned short *pjBuffer =
515 (unsigned short *)
516 pattern_dstaddr +
517 ((patternY + y) & 7) * 8;
518 for (x = 0; x < 8; x++) {
519 pjBuffer[(patternX +
520 x) & 7] =
521 ((unsigned short *)
522 pjPatByte)[x];
523 }
524 pjPatByte += pattern_stride;
525 }
526 break;
527 }
528
529 case 32:
530 {
531 for (y = 0; y < 8; y++) {
532 unsigned long *pjBuffer =
533 (unsigned long *)
534 pattern_dstaddr +
535 ((patternY + y) & 7) * 8;
536 for (x = 0; x < 8; x++) {
537 pjBuffer[(patternX +
538 x) & 7] =
539 ((unsigned long *)
540 pjPatByte)[x];
541 }
542 pjPatByte += pattern_stride;
543 }
544 break;
545 }
546 }
547 } else {
548 /*Don't rotate,just copy pattern into pattern_dstaddr*/
549 for (i = 0; i < (pattern_BPP * 2); i++) {
550 ((unsigned long *)pattern_dstaddr)[i] =
551 pattern[i];
552 }
553 }
554
555 }
556}
557
558/**********************************************************************
559 *
560 * deCopy
561 *
562 * Purpose
563 * Copy a rectangular area of the source surface to a destination surface
564 *
565 * Remarks
566 * Source bitmap must have the same color depth (BPP) as the destination
567 * bitmap.
568 *
569**********************************************************************/
570void deCopy(unsigned long dst_base,
571 unsigned long dst_pitch,
572 unsigned long dst_BPP,
573 unsigned long dst_X,
574 unsigned long dst_Y,
575 unsigned long dst_width,
576 unsigned long dst_height,
577 unsigned long src_base,
578 unsigned long src_pitch,
579 unsigned long src_X,
580 unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
581{
582 unsigned long nDirection = 0;
583 unsigned long nTransparent = 0;
584 /* Direction of ROP2 operation:
585 * 1 = Left to Right,
586 * (-1) = Right to Left
587 */
588 unsigned long opSign = 1;
589 /* xWidth is in pixels */
590 unsigned long xWidth = 192 / (dst_BPP / 8);
591 unsigned long de_ctrl = 0;
592
593 deWaitForNotBusy();
594
595 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
596 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
597 dst_base));
598
599 SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
600 FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
601 src_base));
602
603 if (dst_pitch && src_pitch) {
604 SMTC_write2Dreg(DE_PITCH,
605 FIELD_VALUE(0, DE_PITCH, DESTINATION,
606 dst_pitch) | FIELD_VALUE(0,
607 DE_PITCH,
608 SOURCE,
609 src_pitch));
610
611 SMTC_write2Dreg(DE_WINDOW_WIDTH,
612 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
613 dst_pitch) | FIELD_VALUE(0,
614 DE_WINDOW_WIDTH,
615 SOURCE,
616 src_pitch));
617 }
618
619 /* Set transparent bits if necessary */
620 if (pTransp != NULL) {
621 nTransparent =
622 pTransp->match | pTransp->select | pTransp->control;
623
624 /* Set color compare register */
625 SMTC_write2Dreg(DE_COLOR_COMPARE,
626 FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
627 pTransp->color));
628 }
629
630 /* Determine direction of operation */
631 if (src_Y < dst_Y) {
632 /* +----------+
633 |S |
634 | +----------+
635 | | | |
636 | | | |
637 +---|------+ |
638 | D |
639 +----------+ */
640
641 nDirection = BOTTOM_TO_TOP;
642 } else if (src_Y > dst_Y) {
643 /* +----------+
644 |D |
645 | +----------+
646 | | | |
647 | | | |
648 +---|------+ |
649 | S |
650 +----------+ */
651
652 nDirection = TOP_TO_BOTTOM;
653 } else {
654 /* src_Y == dst_Y */
655
656 if (src_X <= dst_X) {
657 /* +------+---+------+
658 |S | | D|
659 | | | |
660 | | | |
661 | | | |
662 +------+---+------+ */
663
664 nDirection = RIGHT_TO_LEFT;
665 } else {
666 /* src_X > dst_X */
667
668 /* +------+---+------+
669 |D | | S|
670 | | | |
671 | | | |
672 | | | |
673 +------+---+------+ */
674
675 nDirection = LEFT_TO_RIGHT;
676 }
677 }
678
679 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
680 src_X += dst_width - 1;
681 src_Y += dst_height - 1;
682 dst_X += dst_width - 1;
683 dst_Y += dst_height - 1;
684 opSign = (-1);
685 }
686
687 if (dst_BPP >= 24) {
688 src_X *= 3;
689 src_Y *= 3;
690 dst_X *= 3;
691 dst_Y *= 3;
692 dst_width *= 3;
693 if ((nDirection == BOTTOM_TO_TOP)
694 || (nDirection == RIGHT_TO_LEFT)) {
695 src_X += 2;
696 dst_X += 2;
697 }
698 }
699
700 /* Workaround for 192 byte hw bug */
701 if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
702 /*
703 * Perform the ROP2 operation in chunks of (xWidth *
704 * dst_height)
705 */
706 while (1) {
707 deWaitForNotBusy();
708
709 SMTC_write2Dreg(DE_SOURCE,
710 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
711 FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
712 FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
713
714 SMTC_write2Dreg(DE_DESTINATION,
715 FIELD_SET(0, DE_DESTINATION, WRAP,
716 DISABLE) | FIELD_VALUE(0,
717 DE_DESTINATION,
718 X,
719 dst_X)
720 | FIELD_VALUE(0, DE_DESTINATION, Y,
721 dst_Y));
722
723 SMTC_write2Dreg(DE_DIMENSION,
724 FIELD_VALUE(0, DE_DIMENSION, X,
725 xWidth) | FIELD_VALUE(0,
726 DE_DIMENSION,
727 Y_ET,
728 dst_height));
729
730 de_ctrl =
731 FIELD_VALUE(0, DE_CONTROL, ROP,
732 nROP2) | nTransparent | FIELD_SET(0,
733 DE_CONTROL,
734 ROP_SELECT,
735 ROP2)
736 | FIELD_SET(0, DE_CONTROL, COMMAND,
737 BITBLT) | ((nDirection ==
738 1) ? FIELD_SET(0,
739 DE_CONTROL,
740 DIRECTION,
741 RIGHT_TO_LEFT)
742 : FIELD_SET(0, DE_CONTROL,
743 DIRECTION,
744 LEFT_TO_RIGHT)) |
745 FIELD_SET(0, DE_CONTROL, STATUS, START);
746
747 SMTC_write2Dreg(DE_CONTROL, de_ctrl);
748
749 src_X += (opSign * xWidth);
750 dst_X += (opSign * xWidth);
751 dst_width -= xWidth;
752
753 if (dst_width <= 0) {
754 /* ROP2 operation is complete */
755 break;
756 }
757
758 if (xWidth > dst_width)
759 xWidth = dst_width;
760 }
761 } else {
762 deWaitForNotBusy();
763 SMTC_write2Dreg(DE_SOURCE,
764 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
765 FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
766 FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
767
768 SMTC_write2Dreg(DE_DESTINATION,
769 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
770 FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
771 FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
772
773 SMTC_write2Dreg(DE_DIMENSION,
774 FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
775 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
776
777 de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
778 nTransparent |
779 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
780 FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
781 ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
782 RIGHT_TO_LEFT)
783 : FIELD_SET(0, DE_CONTROL, DIRECTION,
784 LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
785 STATUS, START);
786 SMTC_write2Dreg(DE_CONTROL, de_ctrl);
787 }
788
789 smtc_de_busy = 1;
790}
791
792/*
793 * This function sets the pixel format that will apply to the 2D Engine.
794 */
795void deSetPixelFormat(unsigned long bpp)
796{
797 unsigned long de_format;
798
799 de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
800
801 switch (bpp) {
802 case 8:
803 de_format =
804 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
805 break;
806 default:
807 case 16:
808 de_format =
809 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
810 break;
811 case 32:
812 de_format =
813 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
814 break;
815 }
816
817 SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
818}
819
820/*
821 * System memory to Video memory monochrome expansion.
822 *
823 * Source is monochrome image in system memory. This function expands the
824 * monochrome data to color image in video memory.
825 */
826
827long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
828 long srcDelta,
829 unsigned long startBit,
830 unsigned long dBase,
831 unsigned long dPitch,
832 unsigned long bpp,
833 unsigned long dx, unsigned long dy,
834 unsigned long width, unsigned long height,
835 unsigned long fColor,
836 unsigned long bColor,
837 unsigned long rop2) {
838 unsigned long bytePerPixel;
839 unsigned long ulBytesPerScan;
840 unsigned long ul4BytesPerScan;
841 unsigned long ulBytesRemain;
842 unsigned long de_ctrl = 0;
843 unsigned char ajRemain[4];
844 long i, j;
845
846 bytePerPixel = bpp / 8;
847
848 /* Just make sure the start bit is within legal range */
849 startBit &= 7;
850
851 ulBytesPerScan = (width + startBit + 7) / 8;
852 ul4BytesPerScan = ulBytesPerScan & ~3;
853 ulBytesRemain = ulBytesPerScan & 3;
854
855 if (smtc_de_busy)
856 deWaitForNotBusy();
857
858 /*
859 * 2D Source Base. Use 0 for HOST Blt.
860 */
861
862 SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
863
864 /*
865 * 2D Destination Base.
866 *
867 * It is an address offset (128 bit aligned) from the beginning of
868 * frame buffer.
869 */
870
871 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
872
873 if (dPitch) {
874
875 /*
876 * Program pitch (distance between the 1st points of two
877 * adjacent lines).
878 *
879 * Note that input pitch is BYTE value, but the 2D Pitch
880 * register uses pixel values. Need Byte to pixel convertion.
881 */
882
883 SMTC_write2Dreg(DE_PITCH,
884 FIELD_VALUE(0, DE_PITCH, DESTINATION,
885 dPitch /
886 bytePerPixel) | FIELD_VALUE(0,
887 DE_PITCH,
888 SOURCE,
889 dPitch /
890 bytePerPixel));
891
892 /* Screen Window width in Pixels.
893 *
894 * 2D engine uses this value to calculate the linear address in
895 * frame buffer for a given point.
896 */
897
898 SMTC_write2Dreg(DE_WINDOW_WIDTH,
899 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
900 (dPitch /
901 bytePerPixel)) | FIELD_VALUE(0,
902 DE_WINDOW_WIDTH,
903 SOURCE,
904 (dPitch
905 /
906 bytePerPixel)));
907 }
908 /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
909 * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
910 */
911
912 SMTC_write2Dreg(DE_SOURCE,
913 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
914 FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
915 FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
916
917 SMTC_write2Dreg(DE_DESTINATION,
918 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
919 FIELD_VALUE(0, DE_DESTINATION, X, dx) |
920 FIELD_VALUE(0, DE_DESTINATION, Y, dy));
921
922 SMTC_write2Dreg(DE_DIMENSION,
923 FIELD_VALUE(0, DE_DIMENSION, X, width) |
924 FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
925
926 SMTC_write2Dreg(DE_FOREGROUND, fColor);
927 SMTC_write2Dreg(DE_BACKGROUND, bColor);
928
929 if (bpp)
930 deSetPixelFormat(bpp);
931 /* Set the pixel format of the destination */
932
933 de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
934 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
935 FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
936 FIELD_SET(0, DE_CONTROL, HOST, MONO) |
937 FIELD_SET(0, DE_CONTROL, STATUS, START);
938
939 SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
940
941 /* Write MONO data (line by line) to 2D Engine data port */
942 for (i = 0; i < height; i++) {
943 /* For each line, send the data in chunks of 4 bytes */
944 for (j = 0; j < (ul4BytesPerScan / 4); j++)
945 SMTC_write2Ddataport(0,
946 *(unsigned long *)(pSrcbuf +
947 (j * 4)));
948
949 if (ulBytesRemain) {
950 memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
951 ulBytesRemain);
952 SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
953 }
954
955 pSrcbuf += srcDelta;
956 }
957 smtc_de_busy = 1;
958
959 return 0;
960}
961
962/*
963 * This function gets the transparency status from DE_CONTROL register.
964 * It returns a double word with the transparent fields properly set,
965 * while other fields are 0.
966 */
967unsigned long deGetTransparency(void)
968{
969 unsigned long de_ctrl;
970
971 de_ctrl = SMTC_read2Dreg(DE_CONTROL);
972
973 de_ctrl &=
974 FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
975 FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
976 FIELD_MASK(DE_CONTROL_TRANSPARENCY);
977
978 return de_ctrl;
979}
diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h
new file mode 100644
index 000000000000..38d0c335322b
--- /dev/null
+++ b/drivers/staging/sm7xx/smtc2d.h
@@ -0,0 +1,530 @@
1/*
2 * Silicon Motion SM712 2D drawing engine functions.
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Author: Ge Wang, gewang@siliconmotion.com
6 *
7 * Copyright (C) 2009 Lemote, Inc.
8 * Author: Wu Zhangjin, wuzj@lemote.com
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 */
14
15#ifndef NULL
16#define NULL 0
17#endif
18
19/* Internal macros */
20
21#define _F_START(f) (0 ? f)
22#define _F_END(f) (1 ? f)
23#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
24#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
25#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
26#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
27
28/* Global macros */
29
30#define FIELD_GET(x, reg, field) \
31( \
32 _F_NORMALIZE((x), reg ## _ ## field) \
33)
34
35#define FIELD_SET(x, reg, field, value) \
36( \
37 (x & ~_F_MASK(reg ## _ ## field)) \
38 | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
39)
40
41#define FIELD_VALUE(x, reg, field, value) \
42( \
43 (x & ~_F_MASK(reg ## _ ## field)) \
44 | _F_DENORMALIZE(value, reg ## _ ## field) \
45)
46
47#define FIELD_CLEAR(reg, field) \
48( \
49 ~_F_MASK(reg ## _ ## field) \
50)
51
52/* Field Macros */
53
54#define FIELD_START(field) (0 ? field)
55#define FIELD_END(field) (1 ? field)
56#define FIELD_SIZE(field) \
57 (1 + FIELD_END(field) - FIELD_START(field))
58
59#define FIELD_MASK(field) \
60 (((1 << (FIELD_SIZE(field)-1)) \
61 | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
62 << FIELD_START(field))
63
64#define FIELD_NORMALIZE(reg, field) \
65 (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
66
67#define FIELD_DENORMALIZE(field, value) \
68 (((value) << FIELD_START(field)) & FIELD_MASK(field))
69
70#define FIELD_INIT(reg, field, value) \
71 FIELD_DENORMALIZE(reg ## _ ## field, \
72 reg ## _ ## field ## _ ## value)
73
74#define FIELD_INIT_VAL(reg, field, value) \
75 (FIELD_DENORMALIZE(reg ## _ ## field, value))
76
77#define FIELD_VAL_SET(x, r, f, v) ({ \
78 x = (x & ~FIELD_MASK(r ## _ ## f)) \
79 | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
80})
81
82#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
83
84/* Transparent info definition */
85typedef struct {
86 unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
87 unsigned long select; /* Transparency controlled by SRC/DST */
88 unsigned long control; /* ENABLE/DISABLE transparency */
89 unsigned long color; /* Transparent color */
90} Transparent, *pTransparent;
91
92#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
93#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
94#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
95#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
96#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
97#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
98
99#define PATTERN_WIDTH 8
100#define PATTERN_HEIGHT 8
101
102#define TOP_TO_BOTTOM 0
103#define BOTTOM_TO_TOP 1
104#define RIGHT_TO_LEFT BOTTOM_TO_TOP
105#define LEFT_TO_RIGHT TOP_TO_BOTTOM
106
107/* Constants used in Transparent structure */
108#define MATCH_OPAQUE 0x00000000
109#define MATCH_TRANSPARENT 0x00000400
110#define SOURCE 0x00000000
111#define DESTINATION 0x00000200
112
113/* 2D registers. */
114
115#define DE_SOURCE 0x000000
116#define DE_SOURCE_WRAP 31 : 31
117#define DE_SOURCE_WRAP_DISABLE 0
118#define DE_SOURCE_WRAP_ENABLE 1
119#define DE_SOURCE_X_K1 29 : 16
120#define DE_SOURCE_Y_K2 15 : 0
121
122#define DE_DESTINATION 0x000004
123#define DE_DESTINATION_WRAP 31 : 31
124#define DE_DESTINATION_WRAP_DISABLE 0
125#define DE_DESTINATION_WRAP_ENABLE 1
126#define DE_DESTINATION_X 28 : 16
127#define DE_DESTINATION_Y 15 : 0
128
129#define DE_DIMENSION 0x000008
130#define DE_DIMENSION_X 28 : 16
131#define DE_DIMENSION_Y_ET 15 : 0
132
133#define DE_CONTROL 0x00000C
134#define DE_CONTROL_STATUS 31 : 31
135#define DE_CONTROL_STATUS_STOP 0
136#define DE_CONTROL_STATUS_START 1
137#define DE_CONTROL_PATTERN 30 : 30
138#define DE_CONTROL_PATTERN_MONO 0
139#define DE_CONTROL_PATTERN_COLOR 1
140#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
141#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
142#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
143#define DE_CONTROL_QUICK_START 28 : 28
144#define DE_CONTROL_QUICK_START_DISABLE 0
145#define DE_CONTROL_QUICK_START_ENABLE 1
146#define DE_CONTROL_DIRECTION 27 : 27
147#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
148#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
149#define DE_CONTROL_MAJOR 26 : 26
150#define DE_CONTROL_MAJOR_X 0
151#define DE_CONTROL_MAJOR_Y 1
152#define DE_CONTROL_STEP_X 25 : 25
153#define DE_CONTROL_STEP_X_POSITIVE 1
154#define DE_CONTROL_STEP_X_NEGATIVE 0
155#define DE_CONTROL_STEP_Y 24 : 24
156#define DE_CONTROL_STEP_Y_POSITIVE 1
157#define DE_CONTROL_STEP_Y_NEGATIVE 0
158#define DE_CONTROL_STRETCH 23 : 23
159#define DE_CONTROL_STRETCH_DISABLE 0
160#define DE_CONTROL_STRETCH_ENABLE 1
161#define DE_CONTROL_HOST 22 : 22
162#define DE_CONTROL_HOST_COLOR 0
163#define DE_CONTROL_HOST_MONO 1
164#define DE_CONTROL_LAST_PIXEL 21 : 21
165#define DE_CONTROL_LAST_PIXEL_OFF 0
166#define DE_CONTROL_LAST_PIXEL_ON 1
167#define DE_CONTROL_COMMAND 20 : 16
168#define DE_CONTROL_COMMAND_BITBLT 0
169#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
170#define DE_CONTROL_COMMAND_DE_TILE 2
171#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
172#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
173#define DE_CONTROL_COMMAND_RLE_STRIP 5
174#define DE_CONTROL_COMMAND_SHORT_STROKE 6
175#define DE_CONTROL_COMMAND_LINE_DRAW 7
176#define DE_CONTROL_COMMAND_HOST_WRITE 8
177#define DE_CONTROL_COMMAND_HOST_READ 9
178#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
179#define DE_CONTROL_COMMAND_ROTATE 11
180#define DE_CONTROL_COMMAND_FONT 12
181#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
182#define DE_CONTROL_ROP_SELECT 15 : 15
183#define DE_CONTROL_ROP_SELECT_ROP3 0
184#define DE_CONTROL_ROP_SELECT_ROP2 1
185#define DE_CONTROL_ROP2_SOURCE 14 : 14
186#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
187#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
188#define DE_CONTROL_MONO_DATA 13 : 12
189#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
190#define DE_CONTROL_MONO_DATA_8_PACKED 1
191#define DE_CONTROL_MONO_DATA_16_PACKED 2
192#define DE_CONTROL_MONO_DATA_32_PACKED 3
193#define DE_CONTROL_REPEAT_ROTATE 11 : 11
194#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
195#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
196#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
197#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
198#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
199#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
200#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
201#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
202#define DE_CONTROL_TRANSPARENCY 8 : 8
203#define DE_CONTROL_TRANSPARENCY_DISABLE 0
204#define DE_CONTROL_TRANSPARENCY_ENABLE 1
205#define DE_CONTROL_ROP 7 : 0
206
207/* Pseudo fields. */
208
209#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
210#define DE_CONTROL_SHORT_STROKE_DIR_225 0
211#define DE_CONTROL_SHORT_STROKE_DIR_135 1
212#define DE_CONTROL_SHORT_STROKE_DIR_315 2
213#define DE_CONTROL_SHORT_STROKE_DIR_45 3
214#define DE_CONTROL_SHORT_STROKE_DIR_270 4
215#define DE_CONTROL_SHORT_STROKE_DIR_90 5
216#define DE_CONTROL_SHORT_STROKE_DIR_180 8
217#define DE_CONTROL_SHORT_STROKE_DIR_0 10
218#define DE_CONTROL_ROTATION 25 : 24
219#define DE_CONTROL_ROTATION_0 0
220#define DE_CONTROL_ROTATION_270 1
221#define DE_CONTROL_ROTATION_90 2
222#define DE_CONTROL_ROTATION_180 3
223
224#define DE_PITCH 0x000010
225#define DE_PITCH_DESTINATION 28 : 16
226#define DE_PITCH_SOURCE 12 : 0
227
228#define DE_FOREGROUND 0x000014
229#define DE_FOREGROUND_COLOR 31 : 0
230
231#define DE_BACKGROUND 0x000018
232#define DE_BACKGROUND_COLOR 31 : 0
233
234#define DE_STRETCH_FORMAT 0x00001C
235#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
236#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
237#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
238#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
239#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
240#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
241#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
242#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
243#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
244#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
245#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
246#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
247#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
248#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
249
250#define DE_COLOR_COMPARE 0x000020
251#define DE_COLOR_COMPARE_COLOR 23 : 0
252
253#define DE_COLOR_COMPARE_MASK 0x000024
254#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
255
256#define DE_MASKS 0x000028
257#define DE_MASKS_BYTE_MASK 31 : 16
258#define DE_MASKS_BIT_MASK 15 : 0
259
260#define DE_CLIP_TL 0x00002C
261#define DE_CLIP_TL_TOP 31 : 16
262#define DE_CLIP_TL_STATUS 13 : 13
263#define DE_CLIP_TL_STATUS_DISABLE 0
264#define DE_CLIP_TL_STATUS_ENABLE 1
265#define DE_CLIP_TL_INHIBIT 12 : 12
266#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
267#define DE_CLIP_TL_INHIBIT_INSIDE 1
268#define DE_CLIP_TL_LEFT 11 : 0
269
270#define DE_CLIP_BR 0x000030
271#define DE_CLIP_BR_BOTTOM 31 : 16
272#define DE_CLIP_BR_RIGHT 12 : 0
273
274#define DE_MONO_PATTERN_LOW 0x000034
275#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
276
277#define DE_MONO_PATTERN_HIGH 0x000038
278#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
279
280#define DE_WINDOW_WIDTH 0x00003C
281#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
282#define DE_WINDOW_WIDTH_SOURCE 12 : 0
283
284#define DE_WINDOW_SOURCE_BASE 0x000040
285#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
286#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
287#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
288#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
289#define DE_WINDOW_SOURCE_BASE_CS_0 0
290#define DE_WINDOW_SOURCE_BASE_CS_1 1
291#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
292
293#define DE_WINDOW_DESTINATION_BASE 0x000044
294#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
295#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
296#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
297#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
298#define DE_WINDOW_DESTINATION_BASE_CS_0 0
299#define DE_WINDOW_DESTINATION_BASE_CS_1 1
300#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
301
302#define DE_ALPHA 0x000048
303#define DE_ALPHA_VALUE 7 : 0
304
305#define DE_WRAP 0x00004C
306#define DE_WRAP_X 31 : 16
307#define DE_WRAP_Y 15 : 0
308
309#define DE_STATUS 0x000050
310#define DE_STATUS_CSC 1 : 1
311#define DE_STATUS_CSC_CLEAR 0
312#define DE_STATUS_CSC_NOT_ACTIVE 0
313#define DE_STATUS_CSC_ACTIVE 1
314#define DE_STATUS_2D 0 : 0
315#define DE_STATUS_2D_CLEAR 0
316#define DE_STATUS_2D_NOT_ACTIVE 0
317#define DE_STATUS_2D_ACTIVE 1
318
319/* Color Space Conversion registers. */
320
321#define CSC_Y_SOURCE_BASE 0x0000C8
322#define CSC_Y_SOURCE_BASE_EXT 27 : 27
323#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
324#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
325#define CSC_Y_SOURCE_BASE_CS 26 : 26
326#define CSC_Y_SOURCE_BASE_CS_0 0
327#define CSC_Y_SOURCE_BASE_CS_1 1
328#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
329
330#define CSC_CONSTANTS 0x0000CC
331#define CSC_CONSTANTS_Y 31 : 24
332#define CSC_CONSTANTS_R 23 : 16
333#define CSC_CONSTANTS_G 15 : 8
334#define CSC_CONSTANTS_B 7 : 0
335
336#define CSC_Y_SOURCE_X 0x0000D0
337#define CSC_Y_SOURCE_X_INTEGER 26 : 16
338#define CSC_Y_SOURCE_X_FRACTION 15 : 3
339
340#define CSC_Y_SOURCE_Y 0x0000D4
341#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
342#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
343
344#define CSC_U_SOURCE_BASE 0x0000D8
345#define CSC_U_SOURCE_BASE_EXT 27 : 27
346#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
347#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
348#define CSC_U_SOURCE_BASE_CS 26 : 26
349#define CSC_U_SOURCE_BASE_CS_0 0
350#define CSC_U_SOURCE_BASE_CS_1 1
351#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
352
353#define CSC_V_SOURCE_BASE 0x0000DC
354#define CSC_V_SOURCE_BASE_EXT 27 : 27
355#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
356#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
357#define CSC_V_SOURCE_BASE_CS 26 : 26
358#define CSC_V_SOURCE_BASE_CS_0 0
359#define CSC_V_SOURCE_BASE_CS_1 1
360#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
361
362#define CSC_SOURCE_DIMENSION 0x0000E0
363#define CSC_SOURCE_DIMENSION_X 31 : 16
364#define CSC_SOURCE_DIMENSION_Y 15 : 0
365
366#define CSC_SOURCE_PITCH 0x0000E4
367#define CSC_SOURCE_PITCH_Y 31 : 16
368#define CSC_SOURCE_PITCH_UV 15 : 0
369
370#define CSC_DESTINATION 0x0000E8
371#define CSC_DESTINATION_WRAP 31 : 31
372#define CSC_DESTINATION_WRAP_DISABLE 0
373#define CSC_DESTINATION_WRAP_ENABLE 1
374#define CSC_DESTINATION_X 27 : 16
375#define CSC_DESTINATION_Y 11 : 0
376
377#define CSC_DESTINATION_DIMENSION 0x0000EC
378#define CSC_DESTINATION_DIMENSION_X 31 : 16
379#define CSC_DESTINATION_DIMENSION_Y 15 : 0
380
381#define CSC_DESTINATION_PITCH 0x0000F0
382#define CSC_DESTINATION_PITCH_X 31 : 16
383#define CSC_DESTINATION_PITCH_Y 15 : 0
384
385#define CSC_SCALE_FACTOR 0x0000F4
386#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
387#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
388
389#define CSC_DESTINATION_BASE 0x0000F8
390#define CSC_DESTINATION_BASE_EXT 27 : 27
391#define CSC_DESTINATION_BASE_EXT_LOCAL 0
392#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
393#define CSC_DESTINATION_BASE_CS 26 : 26
394#define CSC_DESTINATION_BASE_CS_0 0
395#define CSC_DESTINATION_BASE_CS_1 1
396#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
397
398#define CSC_CONTROL 0x0000FC
399#define CSC_CONTROL_STATUS 31 : 31
400#define CSC_CONTROL_STATUS_STOP 0
401#define CSC_CONTROL_STATUS_START 1
402#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
403#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
404#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
405#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
406#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
407#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
408#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
409#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
410#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
411#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
412#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
413#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
414#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
415#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
416#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
417#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
418#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
419#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
420#define CSC_CONTROL_BYTE_ORDER 23 : 23
421#define CSC_CONTROL_BYTE_ORDER_YUYV 0
422#define CSC_CONTROL_BYTE_ORDER_UYVY 1
423
424#define DE_DATA_PORT_501 0x110000
425#define DE_DATA_PORT_712 0x400000
426#define DE_DATA_PORT_722 0x6000
427
428/* point to virtual Memory Map IO starting address */
429extern char *smtc_RegBaseAddress;
430/* point to virtual video memory starting address */
431extern char *smtc_VRAMBaseAddress;
432extern unsigned char smtc_de_busy;
433
434extern unsigned long memRead32(unsigned long nOffset);
435extern void memWrite32(unsigned long nOffset, unsigned long nData);
436extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
437
438/* 2D functions */
439extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
440 unsigned int bpp);
441
442extern void deWaitForNotBusy(void);
443
444extern void deVerticalLine(unsigned long dst_base,
445 unsigned long dst_pitch,
446 unsigned long nX,
447 unsigned long nY,
448 unsigned long dst_height,
449 unsigned long nColor);
450
451extern void deHorizontalLine(unsigned long dst_base,
452 unsigned long dst_pitch,
453 unsigned long nX,
454 unsigned long nY,
455 unsigned long dst_width,
456 unsigned long nColor);
457
458extern void deLine(unsigned long dst_base,
459 unsigned long dst_pitch,
460 unsigned long nX1,
461 unsigned long nY1,
462 unsigned long nX2,
463 unsigned long nY2,
464 unsigned long nColor);
465
466extern void deFillRect(unsigned long dst_base,
467 unsigned long dst_pitch,
468 unsigned long dst_X,
469 unsigned long dst_Y,
470 unsigned long dst_width,
471 unsigned long dst_height,
472 unsigned long nColor);
473
474extern void deRotatePattern(unsigned char *pattern_dstaddr,
475 unsigned long pattern_src_addr,
476 unsigned long pattern_BPP,
477 unsigned long pattern_stride,
478 int patternX,
479 int patternY);
480
481extern void deCopy(unsigned long dst_base,
482 unsigned long dst_pitch,
483 unsigned long dst_BPP,
484 unsigned long dst_X,
485 unsigned long dst_Y,
486 unsigned long dst_width,
487 unsigned long dst_height,
488 unsigned long src_base,
489 unsigned long src_pitch,
490 unsigned long src_X,
491 unsigned long src_Y,
492 pTransparent pTransp,
493 unsigned char nROP2);
494
495/*
496 * System memory to Video memory monochrome expansion.
497 *
498 * Source is monochrome image in system memory. This function expands the
499 * monochrome data to color image in video memory.
500 *
501 * @pSrcbuf: pointer to start of source buffer in system memory
502 * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
503 * down and -ive mean button up
504 * @startBit: Mono data can start at any bit in a byte, this value should
505 * be 0 to 7
506 * @dBase: Address of destination : offset in frame buffer
507 * @dPitch: Pitch value of destination surface in BYTE
508 * @bpp: Color depth of destination surface
509 * @dx, dy: Starting coordinate of destination surface
510 * @width, height: width and height of rectange in pixel value
511 * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
512 * the monochrome data)
513 * @rop2: ROP value
514 */
515
516extern long deSystemMem2VideoMemMonoBlt(
517 const char *pSrcbuf,
518 long srcDelta,
519 unsigned long startBit,
520 unsigned long dBase,
521 unsigned long dPitch,
522 unsigned long bpp,
523 unsigned long dx, unsigned long dy,
524 unsigned long width, unsigned long height,
525 unsigned long fColor,
526 unsigned long bColor,
527 unsigned long rop2);
528
529extern unsigned long deGetTransparency(void);
530extern void deSetPixelFormat(unsigned long bpp);
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
new file mode 100644
index 000000000000..161dbc9c1397
--- /dev/null
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -0,0 +1,1253 @@
1/*
2 * Silicon Motion SM7XX frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzj@lemote.com
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive for
13 * more details.
14 *
15 * Version 0.10.26192.21.01
16 * - Add PowerPC/Big endian support
17 * - Add 2D support for Lynx
18 * - Verified on2.6.19.2 Boyod.yang <boyod.yang@siliconmotion.com.cn>
19 *
20 * Version 0.09.2621.00.01
21 * - Only support Linux Kernel's version 2.6.21.
22 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
23 *
24 * Version 0.09
25 * - Only support Linux Kernel's version 2.6.12.
26 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
27 */
28
29#ifndef __KERNEL__
30#define __KERNEL__
31#endif
32
33#include <linux/io.h>
34#include <linux/fb.h>
35#include <linux/pci.h>
36#include <linux/init.h>
37#include <linux/uaccess.h>
38#include <linux/console.h>
39#include <linux/screen_info.h>
40
41#ifdef CONFIG_PM
42#include <linux/pm.h>
43#endif
44
45struct screen_info smtc_screen_info;
46
47#include "smtcfb.h"
48#include "smtc2d.h"
49
50#ifdef DEBUG
51#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
52#else
53#define smdbg(format, arg...)
54#endif
55
56/*
57* Private structure
58*/
59struct smtcfb_info {
60 /*
61 * The following is a pointer to be passed into the
62 * functions below. The modules outside the main
63 * voyager.c driver have no knowledge as to what
64 * is within this structure.
65 */
66 struct fb_info fb;
67 struct display_switch *dispsw;
68 struct pci_dev *dev;
69 signed int currcon;
70
71 struct {
72 u8 red, green, blue;
73 } palette[NR_RGB];
74
75 u_int palette_size;
76};
77
78struct par_info {
79 /*
80 * Hardware
81 */
82 u16 chipID;
83 unsigned char __iomem *m_pMMIO;
84 char __iomem *m_pLFB;
85 char *m_pDPR;
86 char *m_pVPR;
87 char *m_pCPR;
88
89 u_int width;
90 u_int height;
91 u_int hz;
92 u_long BaseAddressInVRAM;
93 u8 chipRevID;
94};
95
96struct vesa_mode_table {
97 char mode_index[6];
98 u16 lfb_width;
99 u16 lfb_height;
100 u16 lfb_depth;
101};
102
103static struct vesa_mode_table vesa_mode[] = {
104 {"0x301", 640, 480, 8},
105 {"0x303", 800, 600, 8},
106 {"0x305", 1024, 768, 8},
107 {"0x307", 1280, 1024, 8},
108
109 {"0x311", 640, 480, 16},
110 {"0x314", 800, 600, 16},
111 {"0x317", 1024, 768, 16},
112 {"0x31A", 1280, 1024, 16},
113
114 {"0x312", 640, 480, 24},
115 {"0x315", 800, 600, 24},
116 {"0x318", 1024, 768, 24},
117 {"0x31B", 1280, 1024, 24},
118};
119
120char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
121char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
122
123char *smtc_2DBaseAddress; /* 2D engine starting address */
124char *smtc_2Ddataport; /* 2D data port offset */
125short smtc_2Dacceleration;
126
127static u32 colreg[17];
128static struct par_info hw; /* hardware information */
129
130u16 smtc_ChipIDs[] = {
131 0x710,
132 0x712,
133 0x720
134};
135
136#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
137
138void deWaitForNotBusy(void)
139{
140 unsigned long i = 0x1000000;
141 while (i--) {
142 if ((smtc_seqr(0x16) & 0x18) == 0x10)
143 break;
144 }
145 smtc_de_busy = 0;
146}
147
148static void sm712_set_timing(struct smtcfb_info *sfb,
149 struct par_info *ppar_info)
150{
151 int i = 0, j = 0;
152 u32 m_nScreenStride;
153
154 smdbg("\nppar_info->width = %d ppar_info->height = %d"
155 "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n",
156 ppar_info->width, ppar_info->height,
157 sfb->fb.var.bits_per_pixel, ppar_info->hz);
158
159 for (j = 0; j < numVGAModes; j++) {
160 if (VGAMode[j].mmSizeX == ppar_info->width &&
161 VGAMode[j].mmSizeY == ppar_info->height &&
162 VGAMode[j].bpp == sfb->fb.var.bits_per_pixel &&
163 VGAMode[j].hz == ppar_info->hz) {
164
165 smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY ="
166 "%d VGAMode[j].bpp = %d"
167 "VGAMode[j].hz=%d\n",
168 VGAMode[j].mmSizeX, VGAMode[j].mmSizeY,
169 VGAMode[j].bpp, VGAMode[j].hz);
170
171 smdbg("VGAMode index=%d\n", j);
172
173 smtc_mmiowb(0x0, 0x3c6);
174
175 smtc_seqw(0, 0x1);
176
177 smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2);
178
179 /* init SEQ register SR00 - SR04 */
180 for (i = 0; i < SIZE_SR00_SR04; i++)
181 smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]);
182
183 /* init SEQ register SR10 - SR24 */
184 for (i = 0; i < SIZE_SR10_SR24; i++)
185 smtc_seqw(i + 0x10,
186 VGAMode[j].Init_SR10_SR24[i]);
187
188 /* init SEQ register SR30 - SR75 */
189 for (i = 0; i < SIZE_SR30_SR75; i++)
190 if (((i + 0x30) != 0x62) \
191 && ((i + 0x30) != 0x6a) \
192 && ((i + 0x30) != 0x6b))
193 smtc_seqw(i + 0x30,
194 VGAMode[j].Init_SR30_SR75[i]);
195
196 /* init SEQ register SR80 - SR93 */
197 for (i = 0; i < SIZE_SR80_SR93; i++)
198 smtc_seqw(i + 0x80,
199 VGAMode[j].Init_SR80_SR93[i]);
200
201 /* init SEQ register SRA0 - SRAF */
202 for (i = 0; i < SIZE_SRA0_SRAF; i++)
203 smtc_seqw(i + 0xa0,
204 VGAMode[j].Init_SRA0_SRAF[i]);
205
206 /* init Graphic register GR00 - GR08 */
207 for (i = 0; i < SIZE_GR00_GR08; i++)
208 smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]);
209
210 /* init Attribute register AR00 - AR14 */
211 for (i = 0; i < SIZE_AR00_AR14; i++)
212 smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]);
213
214 /* init CRTC register CR00 - CR18 */
215 for (i = 0; i < SIZE_CR00_CR18; i++)
216 smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]);
217
218 /* init CRTC register CR30 - CR4D */
219 for (i = 0; i < SIZE_CR30_CR4D; i++)
220 smtc_crtcw(i + 0x30,
221 VGAMode[j].Init_CR30_CR4D[i]);
222
223 /* init CRTC register CR90 - CRA7 */
224 for (i = 0; i < SIZE_CR90_CRA7; i++)
225 smtc_crtcw(i + 0x90,
226 VGAMode[j].Init_CR90_CRA7[i]);
227 }
228 }
229 smtc_mmiowb(0x67, 0x3c2);
230
231 /* set VPR registers */
232 writel(0x0, ppar_info->m_pVPR + 0x0C);
233 writel(0x0, ppar_info->m_pVPR + 0x40);
234
235 /* set data width */
236 m_nScreenStride =
237 (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64;
238 switch (sfb->fb.var.bits_per_pixel) {
239 case 8:
240 writel(0x0, ppar_info->m_pVPR + 0x0);
241 break;
242 case 16:
243 writel(0x00020000, ppar_info->m_pVPR + 0x0);
244 break;
245 case 24:
246 writel(0x00040000, ppar_info->m_pVPR + 0x0);
247 break;
248 case 32:
249 writel(0x00030000, ppar_info->m_pVPR + 0x0);
250 break;
251 }
252 writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride),
253 ppar_info->m_pVPR + 0x10);
254
255}
256
257static void sm712_setpalette(int regno, unsigned red, unsigned green,
258 unsigned blue, struct fb_info *info)
259{
260 struct par_info *cur_par = (struct par_info *)info->par;
261
262 if (cur_par->BaseAddressInVRAM)
263 /*
264 * second display palette for dual head. Enable CRT RAM, 6-bit
265 * RAM
266 */
267 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20);
268 else
269 /* primary display palette. Enable LCD RAM only, 6-bit RAM */
270 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
271 smtc_mmiowb(regno, dac_reg);
272 smtc_mmiowb(red >> 10, dac_val);
273 smtc_mmiowb(green >> 10, dac_val);
274 smtc_mmiowb(blue >> 10, dac_val);
275}
276
277static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info
278 *ppar_info)
279{
280 switch (ppar_info->chipID) {
281 case 0x710:
282 case 0x712:
283 case 0x720:
284 sm712_set_timing(sfb, ppar_info);
285 break;
286 }
287}
288
289static struct fb_var_screeninfo smtcfb_var = {
290 .xres = 1024,
291 .yres = 600,
292 .xres_virtual = 1024,
293 .yres_virtual = 600,
294 .bits_per_pixel = 16,
295 .red = {16, 8, 0},
296 .green = {8, 8, 0},
297 .blue = {0, 8, 0},
298 .activate = FB_ACTIVATE_NOW,
299 .height = -1,
300 .width = -1,
301 .vmode = FB_VMODE_NONINTERLACED,
302};
303
304static struct fb_fix_screeninfo smtcfb_fix = {
305 .id = "sm712fb",
306 .type = FB_TYPE_PACKED_PIXELS,
307 .visual = FB_VISUAL_TRUECOLOR,
308 .line_length = 800 * 3,
309 .accel = FB_ACCEL_SMI_LYNX,
310};
311
312/* chan_to_field
313 *
314 * convert a colour value into a field position
315 *
316 * from pxafb.c
317 */
318
319static inline unsigned int chan_to_field(unsigned int chan,
320 struct fb_bitfield *bf)
321{
322 chan &= 0xffff;
323 chan >>= 16 - bf->length;
324 return chan << bf->offset;
325}
326
327static int smtcfb_blank(int blank_mode, struct fb_info *info)
328{
329 /* clear DPMS setting */
330 switch (blank_mode) {
331 case FB_BLANK_UNBLANK:
332 /* Screen On: HSync: On, VSync : On */
333 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
334 smtc_seqw(0x6a, 0x16);
335 smtc_seqw(0x6b, 0x02);
336 smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
337 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
338 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
339 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
340 smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
341 break;
342 case FB_BLANK_NORMAL:
343 /* Screen Off: HSync: On, VSync : On Soft blank */
344 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
345 smtc_seqw(0x6a, 0x16);
346 smtc_seqw(0x6b, 0x02);
347 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
348 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
349 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
350 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
351 break;
352 case FB_BLANK_VSYNC_SUSPEND:
353 /* Screen On: HSync: On, VSync : Off */
354 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
355 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
356 smtc_seqw(0x6a, 0x0c);
357 smtc_seqw(0x6b, 0x02);
358 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
359 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
360 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
361 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
362 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
363 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
364 break;
365 case FB_BLANK_HSYNC_SUSPEND:
366 /* Screen On: HSync: Off, VSync : On */
367 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
368 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
369 smtc_seqw(0x6a, 0x0c);
370 smtc_seqw(0x6b, 0x02);
371 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
372 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
373 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
374 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
375 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
376 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
377 break;
378 case FB_BLANK_POWERDOWN:
379 /* Screen On: HSync: Off, VSync : Off */
380 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
381 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
382 smtc_seqw(0x6a, 0x0c);
383 smtc_seqw(0x6b, 0x02);
384 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
385 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
386 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
387 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
388 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
389 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
399 unsigned blue, unsigned trans, struct fb_info *info)
400{
401 struct smtcfb_info *sfb = (struct smtcfb_info *)info;
402 u32 val;
403
404 if (regno > 255)
405 return 1;
406
407 switch (sfb->fb.fix.visual) {
408 case FB_VISUAL_DIRECTCOLOR:
409 case FB_VISUAL_TRUECOLOR:
410 /*
411 * 16/32 bit true-colour, use pseuo-palette for 16 base color
412 */
413 if (regno < 16) {
414 if (sfb->fb.var.bits_per_pixel == 16) {
415 u32 *pal = sfb->fb.pseudo_palette;
416 val = chan_to_field(red, &sfb->fb.var.red);
417 val |= chan_to_field(green, \
418 &sfb->fb.var.green);
419 val |= chan_to_field(blue, &sfb->fb.var.blue);
420#ifdef __BIG_ENDIAN
421 pal[regno] =
422 ((red & 0xf800) >> 8) |
423 ((green & 0xe000) >> 13) |
424 ((green & 0x1c00) << 3) |
425 ((blue & 0xf800) >> 3);
426#else
427 pal[regno] = val;
428#endif
429 } else {
430 u32 *pal = sfb->fb.pseudo_palette;
431 val = chan_to_field(red, &sfb->fb.var.red);
432 val |= chan_to_field(green, \
433 &sfb->fb.var.green);
434 val |= chan_to_field(blue, &sfb->fb.var.blue);
435#ifdef __BIG_ENDIAN
436 val =
437 (val & 0xff00ff00 >> 8) |
438 (val & 0x00ff00ff << 8);
439#endif
440 pal[regno] = val;
441 }
442 }
443 break;
444
445 case FB_VISUAL_PSEUDOCOLOR:
446 /* color depth 8 bit */
447 sm712_setpalette(regno, red, green, blue, info);
448 break;
449
450 default:
451 return 1; /* unknown type */
452 }
453
454 return 0;
455
456}
457
458#ifdef __BIG_ENDIAN
459static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t
460 count, loff_t *ppos)
461{
462 unsigned long p = *ppos;
463
464 u32 *buffer, *dst;
465 u32 __iomem *src;
466 int c, i, cnt = 0, err = 0;
467 unsigned long total_size;
468
469 if (!info || !info->screen_base)
470 return -ENODEV;
471
472 if (info->state != FBINFO_STATE_RUNNING)
473 return -EPERM;
474
475 total_size = info->screen_size;
476
477 if (total_size == 0)
478 total_size = info->fix.smem_len;
479
480 if (p >= total_size)
481 return 0;
482
483 if (count >= total_size)
484 count = total_size;
485
486 if (count + p > total_size)
487 count = total_size - p;
488
489 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
490 if (!buffer)
491 return -ENOMEM;
492
493 src = (u32 __iomem *) (info->screen_base + p);
494
495 if (info->fbops->fb_sync)
496 info->fbops->fb_sync(info);
497
498 while (count) {
499 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
500 dst = buffer;
501 for (i = c >> 2; i--;) {
502 *dst = fb_readl(src++);
503 *dst =
504 (*dst & 0xff00ff00 >> 8) |
505 (*dst & 0x00ff00ff << 8);
506 dst++;
507 }
508 if (c & 3) {
509 u8 *dst8 = (u8 *) dst;
510 u8 __iomem *src8 = (u8 __iomem *) src;
511
512 for (i = c & 3; i--;) {
513 if (i & 1) {
514 *dst8++ = fb_readb(++src8);
515 } else {
516 *dst8++ = fb_readb(--src8);
517 src8 += 2;
518 }
519 }
520 src = (u32 __iomem *) src8;
521 }
522
523 if (copy_to_user(buf, buffer, c)) {
524 err = -EFAULT;
525 break;
526 }
527 *ppos += c;
528 buf += c;
529 cnt += c;
530 count -= c;
531 }
532
533 kfree(buffer);
534
535 return (err) ? err : cnt;
536}
537
538static ssize_t
539smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
540 loff_t *ppos)
541{
542 unsigned long p = *ppos;
543
544 u32 *buffer, *src;
545 u32 __iomem *dst;
546 int c, i, cnt = 0, err = 0;
547 unsigned long total_size;
548
549 if (!info || !info->screen_base)
550 return -ENODEV;
551
552 if (info->state != FBINFO_STATE_RUNNING)
553 return -EPERM;
554
555 total_size = info->screen_size;
556
557 if (total_size == 0)
558 total_size = info->fix.smem_len;
559
560 if (p > total_size)
561 return -EFBIG;
562
563 if (count > total_size) {
564 err = -EFBIG;
565 count = total_size;
566 }
567
568 if (count + p > total_size) {
569 if (!err)
570 err = -ENOSPC;
571
572 count = total_size - p;
573 }
574
575 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
576 if (!buffer)
577 return -ENOMEM;
578
579 dst = (u32 __iomem *) (info->screen_base + p);
580
581 if (info->fbops->fb_sync)
582 info->fbops->fb_sync(info);
583
584 while (count) {
585 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
586 src = buffer;
587
588 if (copy_from_user(src, buf, c)) {
589 err = -EFAULT;
590 break;
591 }
592
593 for (i = c >> 2; i--;) {
594 fb_writel((*src & 0xff00ff00 >> 8) |
595 (*src & 0x00ff00ff << 8), dst++);
596 src++;
597 }
598 if (c & 3) {
599 u8 *src8 = (u8 *) src;
600 u8 __iomem *dst8 = (u8 __iomem *) dst;
601
602 for (i = c & 3; i--;) {
603 if (i & 1) {
604 fb_writeb(*src8++, ++dst8);
605 } else {
606 fb_writeb(*src8++, --dst8);
607 dst8 += 2;
608 }
609 }
610 dst = (u32 __iomem *) dst8;
611 }
612
613 *ppos += c;
614 buf += c;
615 cnt += c;
616 count -= c;
617 }
618
619 kfree(buffer);
620
621 return (cnt) ? cnt : err;
622}
623#endif /* ! __BIG_ENDIAN */
624
625#include "smtc2d.c"
626
627void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
628{
629 struct par_info *p = (struct par_info *)info->par;
630
631 if (smtc_2Dacceleration) {
632 if (!area->width || !area->height)
633 return;
634
635 deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
636 area->dx, area->dy, area->width, area->height,
637 p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
638
639 } else
640 cfb_copyarea(info, area);
641}
642
643void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
644{
645 struct par_info *p = (struct par_info *)info->par;
646
647 if (smtc_2Dacceleration) {
648 if (!rect->width || !rect->height)
649 return;
650 if (info->var.bits_per_pixel >= 24)
651 deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
652 rect->dy * 3, rect->width * 3, rect->height,
653 rect->color);
654 else
655 deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
656 rect->width, rect->height, rect->color);
657 } else
658 cfb_fillrect(info, rect);
659}
660
661void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
662{
663 struct par_info *p = (struct par_info *)info->par;
664 u32 bg_col = 0, fg_col = 0;
665
666 if ((smtc_2Dacceleration) && (image->depth == 1)) {
667 if (smtc_de_busy)
668 deWaitForNotBusy();
669
670 switch (info->var.bits_per_pixel) {
671 case 8:
672 bg_col = image->bg_color;
673 fg_col = image->fg_color;
674 break;
675 case 16:
676 bg_col =
677 ((u32 *) (info->pseudo_palette))[image->bg_color];
678 fg_col =
679 ((u32 *) (info->pseudo_palette))[image->fg_color];
680 break;
681 case 32:
682 bg_col =
683 ((u32 *) (info->pseudo_palette))[image->bg_color];
684 fg_col =
685 ((u32 *) (info->pseudo_palette))[image->fg_color];
686 break;
687 }
688
689 deSystemMem2VideoMemMonoBlt(
690 image->data,
691 image->width / 8,
692 0,
693 p->BaseAddressInVRAM,
694 0,
695 0,
696 image->dx, image->dy,
697 image->width, image->height,
698 fg_col, bg_col,
699 0x0C);
700
701 } else
702 cfb_imageblit(info, image);
703}
704
705static struct fb_ops smtcfb_ops = {
706 .owner = THIS_MODULE,
707 .fb_setcolreg = smtc_setcolreg,
708 .fb_blank = smtcfb_blank,
709 .fb_fillrect = smtcfb_fillrect,
710 .fb_imageblit = smtcfb_imageblit,
711 .fb_copyarea = smtcfb_copyarea,
712#ifdef __BIG_ENDIAN
713 .fb_read = smtcfb_read,
714 .fb_write = smtcfb_write,
715#endif
716
717};
718
719void smtcfb_setmode(struct smtcfb_info *sfb)
720{
721 switch (sfb->fb.var.bits_per_pixel) {
722 case 32:
723 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
724 sfb->fb.fix.line_length = sfb->fb.var.xres * 4;
725 sfb->fb.var.red.length = 8;
726 sfb->fb.var.green.length = 8;
727 sfb->fb.var.blue.length = 8;
728 sfb->fb.var.red.offset = 16;
729 sfb->fb.var.green.offset = 8;
730 sfb->fb.var.blue.offset = 0;
731
732 break;
733 case 8:
734 sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
735 sfb->fb.fix.line_length = sfb->fb.var.xres;
736 sfb->fb.var.red.offset = 5;
737 sfb->fb.var.red.length = 3;
738 sfb->fb.var.green.offset = 2;
739 sfb->fb.var.green.length = 3;
740 sfb->fb.var.blue.offset = 0;
741 sfb->fb.var.blue.length = 2;
742 break;
743 case 24:
744 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
745 sfb->fb.fix.line_length = sfb->fb.var.xres * 3;
746 sfb->fb.var.red.length = 8;
747 sfb->fb.var.green.length = 8;
748 sfb->fb.var.blue.length = 8;
749
750 sfb->fb.var.red.offset = 16;
751 sfb->fb.var.green.offset = 8;
752 sfb->fb.var.blue.offset = 0;
753
754 break;
755 case 16:
756 default:
757 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
758 sfb->fb.fix.line_length = sfb->fb.var.xres * 2;
759
760 sfb->fb.var.red.length = 5;
761 sfb->fb.var.green.length = 6;
762 sfb->fb.var.blue.length = 5;
763
764 sfb->fb.var.red.offset = 11;
765 sfb->fb.var.green.offset = 5;
766 sfb->fb.var.blue.offset = 0;
767
768 break;
769 }
770
771 hw.width = sfb->fb.var.xres;
772 hw.height = sfb->fb.var.yres;
773 hw.hz = 60;
774 smtc_set_timing(sfb, &hw);
775 if (smtc_2Dacceleration) {
776 printk("2D acceleration enabled!\n");
777 /* Init smtc drawing engine */
778 deInit(sfb->fb.var.xres, sfb->fb.var.yres,
779 sfb->fb.var.bits_per_pixel);
780 }
781}
782
783/*
784 * Alloc struct smtcfb_info and assign the default value
785 */
786static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev,
787 char *name)
788{
789 struct smtcfb_info *sfb;
790
791 sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL);
792
793 if (!sfb)
794 return NULL;
795
796 memset(sfb, 0, sizeof(struct smtcfb_info));
797
798 sfb->currcon = -1;
799 sfb->dev = dev;
800
801 /*** Init sfb->fb with default value ***/
802 sfb->fb.flags = FBINFO_FLAG_DEFAULT;
803 sfb->fb.fbops = &smtcfb_ops;
804 sfb->fb.var = smtcfb_var;
805 sfb->fb.fix = smtcfb_fix;
806
807 strcpy(sfb->fb.fix.id, name);
808
809 sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
810 sfb->fb.fix.type_aux = 0;
811 sfb->fb.fix.xpanstep = 0;
812 sfb->fb.fix.ypanstep = 0;
813 sfb->fb.fix.ywrapstep = 0;
814 sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX;
815
816 sfb->fb.var.nonstd = 0;
817 sfb->fb.var.activate = FB_ACTIVATE_NOW;
818 sfb->fb.var.height = -1;
819 sfb->fb.var.width = -1;
820 /* text mode acceleration */
821 sfb->fb.var.accel_flags = FB_ACCELF_TEXT;
822 sfb->fb.var.vmode = FB_VMODE_NONINTERLACED;
823 sfb->fb.par = &hw;
824 sfb->fb.pseudo_palette = colreg;
825
826 return sfb;
827}
828
829/*
830 * Unmap in the memory mapped IO registers
831 */
832
833static void smtc_unmap_mmio(struct smtcfb_info *sfb)
834{
835 if (sfb && smtc_RegBaseAddress)
836 smtc_RegBaseAddress = NULL;
837}
838
839/*
840 * Map in the screen memory
841 */
842
843static int smtc_map_smem(struct smtcfb_info *sfb,
844 struct pci_dev *dev, u_long smem_len)
845{
846 if (sfb->fb.var.bits_per_pixel == 32) {
847#ifdef __BIG_ENDIAN
848 sfb->fb.fix.smem_start = pci_resource_start(dev, 0)
849 + 0x800000;
850#else
851 sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
852#endif
853 } else {
854 sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
855 }
856
857 sfb->fb.fix.smem_len = smem_len;
858
859 sfb->fb.screen_base = smtc_VRAMBaseAddress;
860
861 if (!sfb->fb.screen_base) {
862 printk(KERN_INFO "%s: unable to map screen memory\n",
863 sfb->fb.fix.id);
864 return -ENOMEM;
865 }
866
867 return 0;
868}
869
870/*
871 * Unmap in the screen memory
872 *
873 */
874static void smtc_unmap_smem(struct smtcfb_info *sfb)
875{
876 if (sfb && sfb->fb.screen_base) {
877 iounmap(sfb->fb.screen_base);
878 sfb->fb.screen_base = NULL;
879 }
880}
881
882/*
883 * We need to wake up the LynxEM+, and make sure its in linear memory mode.
884 */
885static inline void sm7xx_init_hw(void)
886{
887 outb_p(0x18, 0x3c4);
888 outb_p(0x11, 0x3c5);
889}
890
891static void smtc_free_fb_info(struct smtcfb_info *sfb)
892{
893 if (sfb) {
894 fb_alloc_cmap(&sfb->fb.cmap, 0, 0);
895 kfree(sfb);
896 }
897}
898
899/*
900 * sm712vga_setup - process command line options, get vga parameter
901 * @options: string of options
902 * Returns zero.
903 *
904 */
905static int __init __maybe_unused sm712vga_setup(char *options)
906{
907 int index;
908
909 if (!options || !*options) {
910 smdbg("\n No vga parameter\n");
911 return -EINVAL;
912 }
913
914 smtc_screen_info.lfb_width = 0;
915 smtc_screen_info.lfb_height = 0;
916 smtc_screen_info.lfb_depth = 0;
917
918 smdbg("\nsm712vga_setup = %s\n", options);
919
920 for (index = 0;
921 index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table));
922 index++) {
923 if (strstr(options, vesa_mode[index].mode_index)) {
924 smtc_screen_info.lfb_width = vesa_mode[index].lfb_width;
925 smtc_screen_info.lfb_height =
926 vesa_mode[index].lfb_height;
927 smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth;
928 return 0;
929 }
930 }
931
932 return -1;
933}
934__setup("vga=", sm712vga_setup);
935
936/* Jason (08/13/2009)
937 * Original init function changed to probe method to be used by pci_drv
938 * process used to detect chips replaced with kernel process in pci_drv
939 */
940static int __init smtcfb_pci_probe(struct pci_dev *pdev,
941 const struct pci_device_id *ent)
942{
943 struct smtcfb_info *sfb;
944 u_long smem_size = 0x00800000; /* default 8MB */
945 char name[16];
946 int err;
947 unsigned long pFramebufferPhysical;
948
949 printk(KERN_INFO
950 "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n");
951
952 err = pci_enable_device(pdev); /* enable SMTC chip */
953
954 if (err)
955 return err;
956 err = -ENOMEM;
957
958 hw.chipID = ent->device;
959 sprintf(name, "sm%Xfb", hw.chipID);
960
961 sfb = smtc_alloc_fb_info(pdev, name);
962
963 if (!sfb)
964 goto failed;
965 /* Jason (08/13/2009)
966 * Store fb_info to be further used when suspending and resuming
967 */
968 pci_set_drvdata(pdev, sfb);
969
970 sm7xx_init_hw();
971
972 /*get mode parameter from smtc_screen_info */
973 if (smtc_screen_info.lfb_width != 0) {
974 sfb->fb.var.xres = smtc_screen_info.lfb_width;
975 sfb->fb.var.yres = smtc_screen_info.lfb_height;
976 sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth;
977 } else {
978 /* default resolution 1024x600 16bit mode */
979 sfb->fb.var.xres = SCREEN_X_RES;
980 sfb->fb.var.yres = SCREEN_Y_RES;
981 sfb->fb.var.bits_per_pixel = SCREEN_BPP;
982 }
983
984#ifdef __BIG_ENDIAN
985 if (sfb->fb.var.bits_per_pixel == 24)
986 sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32);
987#endif
988 /* Map address and memory detection */
989 pFramebufferPhysical = pci_resource_start(pdev, 0);
990 pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID);
991
992 switch (hw.chipID) {
993 case 0x710:
994 case 0x712:
995 sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000;
996 sfb->fb.fix.mmio_len = 0x00400000;
997 smem_size = SM712_VIDEOMEMORYSIZE;
998#ifdef __BIG_ENDIAN
999 hw.m_pLFB = (smtc_VRAMBaseAddress =
1000 ioremap(pFramebufferPhysical, 0x00c00000));
1001#else
1002 hw.m_pLFB = (smtc_VRAMBaseAddress =
1003 ioremap(pFramebufferPhysical, 0x00800000));
1004#endif
1005 hw.m_pMMIO = (smtc_RegBaseAddress =
1006 smtc_VRAMBaseAddress + 0x00700000);
1007 smtc_2DBaseAddress = (hw.m_pDPR =
1008 smtc_VRAMBaseAddress + 0x00408000);
1009 smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
1010 hw.m_pVPR = hw.m_pLFB + 0x0040c000;
1011#ifdef __BIG_ENDIAN
1012 if (sfb->fb.var.bits_per_pixel == 32) {
1013 smtc_VRAMBaseAddress += 0x800000;
1014 hw.m_pLFB += 0x800000;
1015 printk(KERN_INFO
1016 "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n",
1017 smtc_VRAMBaseAddress, hw.m_pLFB);
1018 }
1019#endif
1020 if (!smtc_RegBaseAddress) {
1021 printk(KERN_INFO
1022 "%s: unable to map memory mapped IO\n",
1023 sfb->fb.fix.id);
1024 return -ENOMEM;
1025 }
1026
1027 /* set MCLK = 14.31818 * (0x16 / 0x2) */
1028 smtc_seqw(0x6a, 0x16);
1029 smtc_seqw(0x6b, 0x02);
1030 smtc_seqw(0x62, 0x3e);
1031 /* enable PCI burst */
1032 smtc_seqw(0x17, 0x20);
1033 /* enable word swap */
1034#ifdef __BIG_ENDIAN
1035 if (sfb->fb.var.bits_per_pixel == 32)
1036 smtc_seqw(0x17, 0x30);
1037#endif
1038#ifdef CONFIG_FB_SM7XX_ACCEL
1039 smtc_2Dacceleration = 1;
1040#endif
1041 break;
1042 case 0x720:
1043 sfb->fb.fix.mmio_start = pFramebufferPhysical;
1044 sfb->fb.fix.mmio_len = 0x00200000;
1045 smem_size = SM722_VIDEOMEMORYSIZE;
1046 smtc_2DBaseAddress = (hw.m_pDPR =
1047 ioremap(pFramebufferPhysical, 0x00a00000));
1048 hw.m_pLFB = (smtc_VRAMBaseAddress =
1049 smtc_2DBaseAddress + 0x00200000);
1050 hw.m_pMMIO = (smtc_RegBaseAddress =
1051 smtc_2DBaseAddress + 0x000c0000);
1052 smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
1053 hw.m_pVPR = smtc_2DBaseAddress + 0x800;
1054
1055 smtc_seqw(0x62, 0xff);
1056 smtc_seqw(0x6a, 0x0d);
1057 smtc_seqw(0x6b, 0x02);
1058 smtc_2Dacceleration = 0;
1059 break;
1060 default:
1061 printk(KERN_INFO
1062 "No valid Silicon Motion display chip was detected!\n");
1063
1064 smtc_free_fb_info(sfb);
1065 return err;
1066 }
1067
1068 /* can support 32 bpp */
1069 if (15 == sfb->fb.var.bits_per_pixel)
1070 sfb->fb.var.bits_per_pixel = 16;
1071
1072 sfb->fb.var.xres_virtual = sfb->fb.var.xres;
1073 sfb->fb.var.yres_virtual = sfb->fb.var.yres;
1074 err = smtc_map_smem(sfb, pdev, smem_size);
1075 if (err)
1076 goto failed;
1077
1078 smtcfb_setmode(sfb);
1079 /* Primary display starting from 0 postion */
1080 hw.BaseAddressInVRAM = 0;
1081 sfb->fb.par = &hw;
1082
1083 err = register_framebuffer(&sfb->fb);
1084 if (err < 0)
1085 goto failed;
1086
1087 printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode"
1088 "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID,
1089 sfb->fb.var.xres, sfb->fb.var.yres,
1090 sfb->fb.var.bits_per_pixel);
1091
1092 return 0;
1093
1094 failed:
1095 printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n");
1096
1097 smtc_unmap_smem(sfb);
1098 smtc_unmap_mmio(sfb);
1099 smtc_free_fb_info(sfb);
1100
1101 return err;
1102}
1103
1104
1105/* Jason (08/11/2009) PCI_DRV wrapper essential structs */
1106static struct pci_device_id smtcfb_pci_table[] = {
1107 {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1108 {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1109 {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1110 {0,}
1111};
1112
1113
1114/* Jason (08/14/2009)
1115 * do some clean up when the driver module is removed
1116 */
1117static void __devexit smtcfb_pci_remove(struct pci_dev *pdev)
1118{
1119 struct smtcfb_info *sfb;
1120
1121 sfb = pci_get_drvdata(pdev);
1122 pci_set_drvdata(pdev, NULL);
1123 smtc_unmap_smem(sfb);
1124 smtc_unmap_mmio(sfb);
1125 unregister_framebuffer(&sfb->fb);
1126 smtc_free_fb_info(sfb);
1127}
1128
1129/* Jason (08/14/2009)
1130 * suspend function, called when the suspend event is triggered
1131 */
1132static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg)
1133{
1134 struct smtcfb_info *sfb;
1135 int retv;
1136
1137 sfb = pci_get_drvdata(pdev);
1138
1139 /* set the hw in sleep mode use externel clock and self memory refresh
1140 * so that we can turn off internal PLLs later on
1141 */
1142 smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
1143 smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
1144
1145 switch (msg.event) {
1146 case PM_EVENT_FREEZE:
1147 case PM_EVENT_PRETHAW:
1148 pdev->dev.power.power_state = msg;
1149 return 0;
1150 }
1151
1152 /* when doing suspend, call fb apis and pci apis */
1153 if (msg.event == PM_EVENT_SUSPEND) {
1154 acquire_console_sem();
1155 fb_set_suspend(&sfb->fb, 1);
1156 release_console_sem();
1157 retv = pci_save_state(pdev);
1158 pci_disable_device(pdev);
1159 retv = pci_choose_state(pdev, msg);
1160 retv = pci_set_power_state(pdev, retv);
1161 }
1162
1163 pdev->dev.power.power_state = msg;
1164
1165 /* additionaly turn off all function blocks including internal PLLs */
1166 smtc_seqw(0x21, 0xff);
1167
1168 return 0;
1169}
1170
1171static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
1172{
1173 struct smtcfb_info *sfb;
1174 int retv;
1175
1176 sfb = pci_get_drvdata(pdev);
1177
1178 /* when resuming, restore pci data and fb cursor */
1179 if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
1180 retv = pci_set_power_state(pdev, PCI_D0);
1181 retv = pci_restore_state(pdev);
1182 if (pci_enable_device(pdev))
1183 return -1;
1184 pci_set_master(pdev);
1185 }
1186
1187 /* reinit hardware */
1188 sm7xx_init_hw();
1189 switch (hw.chipID) {
1190 case 0x710:
1191 case 0x712:
1192 /* set MCLK = 14.31818 * (0x16 / 0x2) */
1193 smtc_seqw(0x6a, 0x16);
1194 smtc_seqw(0x6b, 0x02);
1195 smtc_seqw(0x62, 0x3e);
1196 /* enable PCI burst */
1197 smtc_seqw(0x17, 0x20);
1198#ifdef __BIG_ENDIAN
1199 if (sfb->fb.var.bits_per_pixel == 32)
1200 smtc_seqw(0x17, 0x30);
1201#endif
1202 break;
1203 case 0x720:
1204 smtc_seqw(0x62, 0xff);
1205 smtc_seqw(0x6a, 0x0d);
1206 smtc_seqw(0x6b, 0x02);
1207 break;
1208 }
1209
1210 smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
1211 smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
1212
1213 smtcfb_setmode(sfb);
1214
1215 acquire_console_sem();
1216 fb_set_suspend(&sfb->fb, 0);
1217 release_console_sem();
1218
1219 return 0;
1220}
1221
1222/* Jason (08/13/2009)
1223 * pci_driver struct used to wrap the original driver
1224 * so that it can be registered into the kernel and
1225 * the proper method would be called when suspending and resuming
1226 */
1227static struct pci_driver smtcfb_driver = {
1228 .name = "smtcfb",
1229 .id_table = smtcfb_pci_table,
1230 .probe = smtcfb_pci_probe,
1231 .remove = __devexit_p(smtcfb_pci_remove),
1232#ifdef CONFIG_PM
1233 .suspend = smtcfb_suspend,
1234 .resume = smtcfb_resume,
1235#endif
1236};
1237
1238static int __init smtcfb_init(void)
1239{
1240 return pci_register_driver(&smtcfb_driver);
1241}
1242
1243static void __exit smtcfb_exit(void)
1244{
1245 pci_unregister_driver(&smtcfb_driver);
1246}
1247
1248module_init(smtcfb_init);
1249module_exit(smtcfb_exit);
1250
1251MODULE_AUTHOR("Siliconmotion ");
1252MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
1253MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h
new file mode 100644
index 000000000000..7f2c34138215
--- /dev/null
+++ b/drivers/staging/sm7xx/smtcfb.h
@@ -0,0 +1,793 @@
1/*
2 * Silicon Motion SM712 frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzj@lemote.com
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive for
13 * more details.
14 */
15
16#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008"
17
18#define NR_PALETTE 256
19#define NR_RGB 2
20
21#define FB_ACCEL_SMI_LYNX 88
22
23#ifdef __BIG_ENDIAN
24#define PC_VGA 0
25#else
26#define PC_VGA 1
27#endif
28
29#define SCREEN_X_RES 1024
30#define SCREEN_Y_RES 600
31#define SCREEN_BPP 16
32
33#ifndef FIELD_OFFSET
34#define FIELD_OFSFET(type, field) \
35 ((unsigned long) (PUCHAR) & (((type *)0)->field))
36#endif
37
38/*Assume SM712 graphics chip has 4MB VRAM */
39#define SM712_VIDEOMEMORYSIZE 0x00400000
40/*Assume SM722 graphics chip has 8MB VRAM */
41#define SM722_VIDEOMEMORYSIZE 0x00800000
42
43#define dac_reg (0x3c8)
44#define dac_val (0x3c9)
45
46extern char *smtc_RegBaseAddress;
47#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg)
48#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg)
49#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg)
50
51#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg)
52#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg)
53#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg)
54
55#define SIZE_SR00_SR04 (0x04 - 0x00 + 1)
56#define SIZE_SR10_SR24 (0x24 - 0x10 + 1)
57#define SIZE_SR30_SR75 (0x75 - 0x30 + 1)
58#define SIZE_SR80_SR93 (0x93 - 0x80 + 1)
59#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1)
60#define SIZE_GR00_GR08 (0x08 - 0x00 + 1)
61#define SIZE_AR00_AR14 (0x14 - 0x00 + 1)
62#define SIZE_CR00_CR18 (0x18 - 0x00 + 1)
63#define SIZE_CR30_CR4D (0x4D - 0x30 + 1)
64#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1)
65#define SIZE_VPR (0x6C + 1)
66#define SIZE_DPR (0x44 + 1)
67
68static inline void smtc_crtcw(int reg, int val)
69{
70 smtc_mmiowb(reg, 0x3d4);
71 smtc_mmiowb(val, 0x3d5);
72}
73
74static inline unsigned int smtc_crtcr(int reg)
75{
76 smtc_mmiowb(reg, 0x3d4);
77 return smtc_mmiorb(0x3d5);
78}
79
80static inline void smtc_grphw(int reg, int val)
81{
82 smtc_mmiowb(reg, 0x3ce);
83 smtc_mmiowb(val, 0x3cf);
84}
85
86static inline unsigned int smtc_grphr(int reg)
87{
88 smtc_mmiowb(reg, 0x3ce);
89 return smtc_mmiorb(0x3cf);
90}
91
92static inline void smtc_attrw(int reg, int val)
93{
94 smtc_mmiorb(0x3da);
95 smtc_mmiowb(reg, 0x3c0);
96 smtc_mmiorb(0x3c1);
97 smtc_mmiowb(val, 0x3c0);
98}
99
100static inline void smtc_seqw(int reg, int val)
101{
102 smtc_mmiowb(reg, 0x3c4);
103 smtc_mmiowb(val, 0x3c5);
104}
105
106static inline unsigned int smtc_seqr(int reg)
107{
108 smtc_mmiowb(reg, 0x3c4);
109 return smtc_mmiorb(0x3c5);
110}
111
112/* The next structure holds all information relevant for a specific video mode.
113 */
114
115struct ModeInit {
116 int mmSizeX;
117 int mmSizeY;
118 int bpp;
119 int hz;
120 unsigned char Init_MISC;
121 unsigned char Init_SR00_SR04[SIZE_SR00_SR04];
122 unsigned char Init_SR10_SR24[SIZE_SR10_SR24];
123 unsigned char Init_SR30_SR75[SIZE_SR30_SR75];
124 unsigned char Init_SR80_SR93[SIZE_SR80_SR93];
125 unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF];
126 unsigned char Init_GR00_GR08[SIZE_GR00_GR08];
127 unsigned char Init_AR00_AR14[SIZE_AR00_AR14];
128 unsigned char Init_CR00_CR18[SIZE_CR00_CR18];
129 unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D];
130 unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7];
131};
132
133/**********************************************************************
134 SM712 Mode table.
135 **********************************************************************/
136struct ModeInit VGAMode[] = {
137 {
138 /* mode#0: 640 x 480 16Bpp 60Hz */
139 640, 480, 16, 60,
140 /* Init_MISC */
141 0xE3,
142 { /* Init_SR0_SR4 */
143 0x03, 0x01, 0x0F, 0x00, 0x0E,
144 },
145 { /* Init_SR10_SR24 */
146 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
147 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0xC4, 0x30, 0x02, 0x01, 0x01,
149 },
150 { /* Init_SR30_SR75 */
151 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
152 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
153 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
154 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
155 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
156 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
157 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
158 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
159 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
160 },
161 { /* Init_SR80_SR93 */
162 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
163 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
164 0x00, 0x00, 0x00, 0x00,
165 },
166 { /* Init_SRA0_SRAF */
167 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
168 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
169 },
170 { /* Init_GR00_GR08 */
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
172 0xFF,
173 },
174 { /* Init_AR00_AR14 */
175 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
176 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
177 0x41, 0x00, 0x0F, 0x00, 0x00,
178 },
179 { /* Init_CR00_CR18 */
180 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
181 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
183 0xFF,
184 },
185 { /* Init_CR30_CR4D */
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
187 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
188 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
189 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
190 },
191 { /* Init_CR90_CRA7 */
192 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
193 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
194 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
195 },
196 },
197 {
198 /* mode#1: 640 x 480 24Bpp 60Hz */
199 640, 480, 24, 60,
200 /* Init_MISC */
201 0xE3,
202 { /* Init_SR0_SR4 */
203 0x03, 0x01, 0x0F, 0x00, 0x0E,
204 },
205 { /* Init_SR10_SR24 */
206 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
207 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0xC4, 0x30, 0x02, 0x01, 0x01,
209 },
210 { /* Init_SR30_SR75 */
211 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
212 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
213 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
214 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
215 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
216 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
217 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
218 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
219 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
220 },
221 { /* Init_SR80_SR93 */
222 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
223 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
224 0x00, 0x00, 0x00, 0x00,
225 },
226 { /* Init_SRA0_SRAF */
227 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
228 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
229 },
230 { /* Init_GR00_GR08 */
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
232 0xFF,
233 },
234 { /* Init_AR00_AR14 */
235 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
236 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
237 0x41, 0x00, 0x0F, 0x00, 0x00,
238 },
239 { /* Init_CR00_CR18 */
240 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
241 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
243 0xFF,
244 },
245 { /* Init_CR30_CR4D */
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
247 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
248 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
249 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
250 },
251 { /* Init_CR90_CRA7 */
252 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
253 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
254 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
255 },
256 },
257 {
258 /* mode#0: 640 x 480 32Bpp 60Hz */
259 640, 480, 32, 60,
260 /* Init_MISC */
261 0xE3,
262 { /* Init_SR0_SR4 */
263 0x03, 0x01, 0x0F, 0x00, 0x0E,
264 },
265 { /* Init_SR10_SR24 */
266 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
267 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0xC4, 0x30, 0x02, 0x01, 0x01,
269 },
270 { /* Init_SR30_SR75 */
271 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
272 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
273 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
274 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
275 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
276 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
277 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
278 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
279 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
280 },
281 { /* Init_SR80_SR93 */
282 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
283 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
284 0x00, 0x00, 0x00, 0x00,
285 },
286 { /* Init_SRA0_SRAF */
287 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
288 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
289 },
290 { /* Init_GR00_GR08 */
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
292 0xFF,
293 },
294 { /* Init_AR00_AR14 */
295 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
296 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
297 0x41, 0x00, 0x0F, 0x00, 0x00,
298 },
299 { /* Init_CR00_CR18 */
300 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
301 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
303 0xFF,
304 },
305 { /* Init_CR30_CR4D */
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
307 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
308 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
309 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
310 },
311 { /* Init_CR90_CRA7 */
312 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
313 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
314 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
315 },
316 },
317
318 { /* mode#2: 800 x 600 16Bpp 60Hz */
319 800, 600, 16, 60,
320 /* Init_MISC */
321 0x2B,
322 { /* Init_SR0_SR4 */
323 0x03, 0x01, 0x0F, 0x03, 0x0E,
324 },
325 { /* Init_SR10_SR24 */
326 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
327 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0xC4, 0x30, 0x02, 0x01, 0x01,
329 },
330 { /* Init_SR30_SR75 */
331 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
332 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
333 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
334 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
335 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
336 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
337 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
338 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
339 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
340 },
341 { /* Init_SR80_SR93 */
342 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
343 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
344 0x00, 0x00, 0x00, 0x00,
345 },
346 { /* Init_SRA0_SRAF */
347 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
348 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
349 },
350 { /* Init_GR00_GR08 */
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
352 0xFF,
353 },
354 { /* Init_AR00_AR14 */
355 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
356 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
357 0x41, 0x00, 0x0F, 0x00, 0x00,
358 },
359 { /* Init_CR00_CR18 */
360 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
361 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
363 0xFF,
364 },
365 { /* Init_CR30_CR4D */
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
367 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
368 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
369 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
370 },
371 { /* Init_CR90_CRA7 */
372 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
373 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
374 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
375 },
376 },
377 { /* mode#3: 800 x 600 24Bpp 60Hz */
378 800, 600, 24, 60,
379 0x2B,
380 { /* Init_SR0_SR4 */
381 0x03, 0x01, 0x0F, 0x03, 0x0E,
382 },
383 { /* Init_SR10_SR24 */
384 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
385 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0xC4, 0x30, 0x02, 0x01, 0x01,
387 },
388 { /* Init_SR30_SR75 */
389 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
390 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
391 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
392 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
393 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
394 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
395 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
396 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
397 0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
398 },
399 { /* Init_SR80_SR93 */
400 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
401 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
402 0x00, 0x00, 0x00, 0x00,
403 },
404 { /* Init_SRA0_SRAF */
405 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
406 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
407 },
408 { /* Init_GR00_GR08 */
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
410 0xFF,
411 },
412 { /* Init_AR00_AR14 */
413 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
414 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
415 0x41, 0x00, 0x0F, 0x00, 0x00,
416 },
417 { /* Init_CR00_CR18 */
418 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
419 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
421 0xFF,
422 },
423 { /* Init_CR30_CR4D */
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
425 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
426 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
427 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
428 },
429 { /* Init_CR90_CRA7 */
430 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
431 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
432 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
433 },
434 },
435 { /* mode#7: 800 x 600 32Bpp 60Hz */
436 800, 600, 32, 60,
437 /* Init_MISC */
438 0x2B,
439 { /* Init_SR0_SR4 */
440 0x03, 0x01, 0x0F, 0x03, 0x0E,
441 },
442 { /* Init_SR10_SR24 */
443 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
444 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
445 0xC4, 0x30, 0x02, 0x01, 0x01,
446 },
447 { /* Init_SR30_SR75 */
448 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
449 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
450 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
451 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
452 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
453 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
454 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
455 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
456 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
457 },
458 { /* Init_SR80_SR93 */
459 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
460 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
461 0x00, 0x00, 0x00, 0x00,
462 },
463 { /* Init_SRA0_SRAF */
464 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
465 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
466 },
467 { /* Init_GR00_GR08 */
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
469 0xFF,
470 },
471 { /* Init_AR00_AR14 */
472 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
473 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
474 0x41, 0x00, 0x0F, 0x00, 0x00,
475 },
476 { /* Init_CR00_CR18 */
477 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
478 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
480 0xFF,
481 },
482 { /* Init_CR30_CR4D */
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
484 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
485 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
486 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
487 },
488 { /* Init_CR90_CRA7 */
489 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
490 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
491 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
492 },
493 },
494 /* We use 1024x768 table to light 1024x600 panel for lemote */
495 { /* mode#4: 1024 x 600 16Bpp 60Hz */
496 1024, 600, 16, 60,
497 /* Init_MISC */
498 0xEB,
499 { /* Init_SR0_SR4 */
500 0x03, 0x01, 0x0F, 0x00, 0x0E,
501 },
502 { /* Init_SR10_SR24 */
503 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
504 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0xC4, 0x30, 0x02, 0x00, 0x01,
506 },
507 { /* Init_SR30_SR75 */
508 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
509 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
510 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
511 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
512 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
513 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
514 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
515 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
516 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
517 },
518 { /* Init_SR80_SR93 */
519 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
520 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
521 0x00, 0x00, 0x00, 0x00,
522 },
523 { /* Init_SRA0_SRAF */
524 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
525 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
526 },
527 { /* Init_GR00_GR08 */
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
529 0xFF,
530 },
531 { /* Init_AR00_AR14 */
532 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
533 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
534 0x41, 0x00, 0x0F, 0x00, 0x00,
535 },
536 { /* Init_CR00_CR18 */
537 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
538 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
540 0xFF,
541 },
542 { /* Init_CR30_CR4D */
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
544 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
545 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
546 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
547 },
548 { /* Init_CR90_CRA7 */
549 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
550 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
551 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
552 },
553 },
554 { /* mode#5: 1024 x 768 24Bpp 60Hz */
555 1024, 768, 24, 60,
556 /* Init_MISC */
557 0xEB,
558 { /* Init_SR0_SR4 */
559 0x03, 0x01, 0x0F, 0x03, 0x0E,
560 },
561 { /* Init_SR10_SR24 */
562 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
563 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0xC4, 0x30, 0x02, 0x01, 0x01,
565 },
566 { /* Init_SR30_SR75 */
567 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
568 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
569 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
570 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
571 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
572 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
573 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
574 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
575 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
576 },
577 { /* Init_SR80_SR93 */
578 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
579 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
580 0x00, 0x00, 0x00, 0x00,
581 },
582 { /* Init_SRA0_SRAF */
583 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
584 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
585 },
586 { /* Init_GR00_GR08 */
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
588 0xFF,
589 },
590 { /* Init_AR00_AR14 */
591 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
592 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
593 0x41, 0x00, 0x0F, 0x00, 0x00,
594 },
595 { /* Init_CR00_CR18 */
596 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
597 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
599 0xFF,
600 },
601 { /* Init_CR30_CR4D */
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
603 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
604 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
605 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
606 },
607 { /* Init_CR90_CRA7 */
608 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
609 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
610 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
611 },
612 },
613 { /* mode#4: 1024 x 768 32Bpp 60Hz */
614 1024, 768, 32, 60,
615 /* Init_MISC */
616 0xEB,
617 { /* Init_SR0_SR4 */
618 0x03, 0x01, 0x0F, 0x03, 0x0E,
619 },
620 { /* Init_SR10_SR24 */
621 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
622 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0xC4, 0x32, 0x02, 0x01, 0x01,
624 },
625 { /* Init_SR30_SR75 */
626 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
627 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
628 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
629 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
630 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
631 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
632 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
633 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
634 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
635 },
636 { /* Init_SR80_SR93 */
637 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
638 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
639 0x00, 0x00, 0x00, 0x00,
640 },
641 { /* Init_SRA0_SRAF */
642 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
643 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
644 },
645 { /* Init_GR00_GR08 */
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
647 0xFF,
648 },
649 { /* Init_AR00_AR14 */
650 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
651 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
652 0x41, 0x00, 0x0F, 0x00, 0x00,
653 },
654 { /* Init_CR00_CR18 */
655 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
656 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
658 0xFF,
659 },
660 { /* Init_CR30_CR4D */
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
662 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
663 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
664 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
665 },
666 { /* Init_CR90_CRA7 */
667 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
668 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
669 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
670 },
671 },
672 { /* mode#6: 320 x 240 16Bpp 60Hz */
673 320, 240, 16, 60,
674 /* Init_MISC */
675 0xEB,
676 { /* Init_SR0_SR4 */
677 0x03, 0x01, 0x0F, 0x03, 0x0E,
678 },
679 { /* Init_SR10_SR24 */
680 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
681 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0xC4, 0x32, 0x02, 0x01, 0x01,
683 },
684 { /* Init_SR30_SR75 */
685 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
686 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
687 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
688 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
689 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
690 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
691 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
692 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
693 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
694 },
695 { /* Init_SR80_SR93 */
696 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
697 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
698 0x00, 0x00, 0x00, 0x00,
699 },
700 { /* Init_SRA0_SRAF */
701 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
702 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
703 },
704 { /* Init_GR00_GR08 */
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
706 0xFF,
707 },
708 { /* Init_AR00_AR14 */
709 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
710 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
711 0x41, 0x00, 0x0F, 0x00, 0x00,
712 },
713 { /* Init_CR00_CR18 */
714 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
715 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
717 0xFF,
718 },
719 { /* Init_CR30_CR4D */
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
721 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
722 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
723 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
724 },
725 { /* Init_CR90_CRA7 */
726 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
727 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
728 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
729 },
730 },
731
732 { /* mode#8: 320 x 240 32Bpp 60Hz */
733 320, 240, 32, 60,
734 /* Init_MISC */
735 0xEB,
736 { /* Init_SR0_SR4 */
737 0x03, 0x01, 0x0F, 0x03, 0x0E,
738 },
739 { /* Init_SR10_SR24 */
740 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
741 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0xC4, 0x32, 0x02, 0x01, 0x01,
743 },
744 { /* Init_SR30_SR75 */
745 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
746 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
747 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
748 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
749 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
750 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
751 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
752 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
753 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
754 },
755 { /* Init_SR80_SR93 */
756 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
757 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
758 0x00, 0x00, 0x00, 0x00,
759 },
760 { /* Init_SRA0_SRAF */
761 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
762 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
763 },
764 { /* Init_GR00_GR08 */
765 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
766 0xFF,
767 },
768 { /* Init_AR00_AR14 */
769 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
770 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
771 0x41, 0x00, 0x0F, 0x00, 0x00,
772 },
773 { /* Init_CR00_CR18 */
774 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
775 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
777 0xFF,
778 },
779 { /* Init_CR30_CR4D */
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
781 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
782 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
783 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
784 },
785 { /* Init_CR90_CRA7 */
786 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
787 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
788 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
789 },
790 },
791};
792
793#define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit))
diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig
index 825bbc4fc3fa..061e730df2d0 100644
--- a/drivers/staging/vt6655/Kconfig
+++ b/drivers/staging/vt6655/Kconfig
@@ -1,6 +1,6 @@
1config VT6655 1config VT6655
2 tristate "VIA Technologies VT6655 support" 2 tristate "VIA Technologies VT6655 support"
3 depends on PCI 3 depends on PCI && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 ---help--- 6 ---help---
diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig
index 87bcd269310c..1055b526c532 100644
--- a/drivers/staging/vt6656/Kconfig
+++ b/drivers/staging/vt6656/Kconfig
@@ -1,6 +1,6 @@
1config VT6656 1config VT6656
2 tristate "VIA Technologies VT6656 support" 2 tristate "VIA Technologies VT6656 support"
3 depends on USB 3 depends on USB && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 ---help--- 6 ---help---
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index 7d76a7f92a33..aaa70ed57710 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -439,7 +439,7 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks)
439 } 439 }
440 } 440 }
441 *nfchunks = 0; 441 *nfchunks = 0;
442 memset(fchunk, 0, sizeof(fchunk)); 442 memset(fchunk, 0, sizeof(*fchunk));
443 443
444} 444}
445 445