diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 25 | ||||
-rw-r--r-- | drivers/char/Makefile | 3 | ||||
-rw-r--r-- | drivers/char/agp/Kconfig | 2 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 9 | ||||
-rw-r--r-- | drivers/char/agp/compat_ioctl.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/frontend.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 19 | ||||
-rw-r--r-- | drivers/char/agp/sgi-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/hpet.c | 10 | ||||
-rw-r--r-- | drivers/char/hvc_lguest.c | 80 | ||||
-rw-r--r-- | drivers/char/ip2/ip2main.c | 3 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 1 | ||||
-rw-r--r-- | drivers/char/mmtimer.c | 1 | ||||
-rw-r--r-- | drivers/char/mspec.c | 1 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 75 |
16 files changed, 180 insertions, 54 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index c8dfd18bea44..b391776e5bf3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -130,6 +130,7 @@ config ROCKETPORT | |||
130 | config CYCLADES | 130 | config CYCLADES |
131 | tristate "Cyclades async mux support" | 131 | tristate "Cyclades async mux support" |
132 | depends on SERIAL_NONSTANDARD && (PCI || ISA) | 132 | depends on SERIAL_NONSTANDARD && (PCI || ISA) |
133 | select FW_LOADER | ||
133 | ---help--- | 134 | ---help--- |
134 | This driver supports Cyclades Z and Y multiserial boards. | 135 | This driver supports Cyclades Z and Y multiserial boards. |
135 | You would need something like this to connect more than two modems to | 136 | You would need something like this to connect more than two modems to |
@@ -726,7 +727,7 @@ config NVRAM | |||
726 | 727 | ||
727 | config RTC | 728 | config RTC |
728 | tristate "Enhanced Real Time Clock Support" | 729 | tristate "Enhanced Real Time Clock Support" |
729 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC64 && (!SPARC32 || PCI) && !FRV && !ARM && !SUPERH && !S390 | 730 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390 |
730 | ---help--- | 731 | ---help--- |
731 | If you say Y here and create a character special file /dev/rtc with | 732 | If you say Y here and create a character special file /dev/rtc with |
732 | major number 10 and minor number 135 using mknod ("man mknod"), you | 733 | major number 10 and minor number 135 using mknod ("man mknod"), you |
@@ -750,6 +751,28 @@ config RTC | |||
750 | To compile this driver as a module, choose M here: the | 751 | To compile this driver as a module, choose M here: the |
751 | module will be called rtc. | 752 | module will be called rtc. |
752 | 753 | ||
754 | config JS_RTC | ||
755 | tristate "Enhanced Real Time Clock Support" | ||
756 | depends on SPARC32 && PCI | ||
757 | ---help--- | ||
758 | If you say Y here and create a character special file /dev/rtc with | ||
759 | major number 10 and minor number 135 using mknod ("man mknod"), you | ||
760 | will get access to the real time clock (or hardware clock) built | ||
761 | into your computer. | ||
762 | |||
763 | Every PC has such a clock built in. It can be used to generate | ||
764 | signals from as low as 1Hz up to 8192Hz, and can also be used | ||
765 | as a 24 hour alarm. It reports status information via the file | ||
766 | /proc/driver/rtc and its behaviour is set by various ioctls on | ||
767 | /dev/rtc. | ||
768 | |||
769 | If you think you have a use for such a device (such as periodic data | ||
770 | sampling), then say Y here, and read <file:Documentation/rtc.txt> | ||
771 | for details. | ||
772 | |||
773 | To compile this driver as a module, choose M here: the | ||
774 | module will be called js-rtc. | ||
775 | |||
753 | config SGI_DS1286 | 776 | config SGI_DS1286 |
754 | tristate "SGI DS1286 RTC support" | 777 | tristate "SGI DS1286 RTC support" |
755 | depends on SGI_IP22 | 778 | depends on SGI_IP22 |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 2bc3a55ee407..d68ddbe70f73 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -108,6 +108,9 @@ obj-$(CONFIG_TCG_TPM) += tpm/ | |||
108 | 108 | ||
109 | obj-$(CONFIG_PS3_FLASH) += ps3flash.o | 109 | obj-$(CONFIG_PS3_FLASH) += ps3flash.o |
110 | 110 | ||
111 | obj-$(CONFIG_JS_RTC) += js-rtc.o | ||
112 | js-rtc-y = rtc.o | ||
113 | |||
111 | # Files generated that shall be removed upon make clean | 114 | # Files generated that shall be removed upon make clean |
112 | clean-files := consolemap_deftbl.c defkeymap.c | 115 | clean-files := consolemap_deftbl.c defkeymap.c |
113 | 116 | ||
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index a9f9c48c2424..713533d8a86e 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -50,7 +50,7 @@ config AGP_ATI | |||
50 | 50 | ||
51 | config AGP_AMD | 51 | config AGP_AMD |
52 | tristate "AMD Irongate, 761, and 762 chipset support" | 52 | tristate "AMD Irongate, 761, and 762 chipset support" |
53 | depends on AGP && X86_32 | 53 | depends on AGP && (X86_32 || ALPHA) |
54 | help | 54 | help |
55 | This option gives you AGP support for the GLX component of | 55 | This option gives you AGP support for the GLX component of |
56 | X on AMD Irongate, 761, and 762 chipsets. | 56 | X on AMD Irongate, 761, and 762 chipsets. |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 780e59e588ad..da7513d7b4e7 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -123,21 +123,16 @@ static int ati_create_gatt_pages(int nr_tables) | |||
123 | 123 | ||
124 | for (i = 0; i < nr_tables; i++) { | 124 | for (i = 0; i < nr_tables; i++) { |
125 | entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); | 125 | entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); |
126 | tables[i] = entry; | ||
126 | if (entry == NULL) { | 127 | if (entry == NULL) { |
127 | while (i > 0) { | ||
128 | kfree(tables[i-1]); | ||
129 | i--; | ||
130 | } | ||
131 | kfree(tables); | ||
132 | retval = -ENOMEM; | 128 | retval = -ENOMEM; |
133 | break; | 129 | break; |
134 | } | 130 | } |
135 | tables[i] = entry; | ||
136 | retval = ati_create_page_map(entry); | 131 | retval = ati_create_page_map(entry); |
137 | if (retval != 0) | 132 | if (retval != 0) |
138 | break; | 133 | break; |
139 | } | 134 | } |
140 | ati_generic_private.num_tables = nr_tables; | 135 | ati_generic_private.num_tables = i; |
141 | ati_generic_private.gatt_pages = tables; | 136 | ati_generic_private.gatt_pages = tables; |
142 | 137 | ||
143 | if (retval != 0) | 138 | if (retval != 0) |
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index fcb4b1bf0d4e..ecd4248861b9 100644 --- a/drivers/char/agp/compat_ioctl.c +++ b/drivers/char/agp/compat_ioctl.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/fs.h> | ||
31 | #include <linux/agpgart.h> | 32 | #include <linux/agpgart.h> |
32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
33 | #include "agp.h" | 34 | #include "agp.h" |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index c7ed617aa7ff..7791e98de51c 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/agpgart.h> | 37 | #include <linux/agpgart.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/fs.h> | ||
40 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index d535c406b319..3db4f4076ed4 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -1170,7 +1170,6 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
1170 | map_page_into_agp(page); | 1170 | map_page_into_agp(page); |
1171 | 1171 | ||
1172 | get_page(page); | 1172 | get_page(page); |
1173 | SetPageLocked(page); | ||
1174 | atomic_inc(&agp_bridge->current_memory_agp); | 1173 | atomic_inc(&agp_bridge->current_memory_agp); |
1175 | return page_address(page); | 1174 | return page_address(page); |
1176 | } | 1175 | } |
@@ -1187,7 +1186,6 @@ void agp_generic_destroy_page(void *addr) | |||
1187 | page = virt_to_page(addr); | 1186 | page = virt_to_page(addr); |
1188 | unmap_page_from_agp(page); | 1187 | unmap_page_from_agp(page); |
1189 | put_page(page); | 1188 | put_page(page); |
1190 | unlock_page(page); | ||
1191 | free_page((unsigned long)addr); | 1189 | free_page((unsigned long)addr); |
1192 | atomic_dec(&agp_bridge->current_memory_agp); | 1190 | atomic_dec(&agp_bridge->current_memory_agp); |
1193 | } | 1191 | } |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index a1240603912c..294cdbf4d44d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -20,7 +20,9 @@ | |||
20 | #define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2 | 20 | #define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2 |
21 | #define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00 | 21 | #define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00 |
22 | #define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02 | 22 | #define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02 |
23 | #define PCI_DEVICE_ID_INTEL_82965GME_HB 0x2A10 | ||
23 | #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 | 24 | #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 |
25 | #define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC | ||
24 | #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE | 26 | #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE |
25 | #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 | 27 | #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 |
26 | #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 | 28 | #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 |
@@ -33,7 +35,8 @@ | |||
33 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ | 35 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ |
34 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ | 36 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ |
35 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ | 37 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ |
36 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB) | 38 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ |
39 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) | ||
37 | 40 | ||
38 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | 41 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ |
39 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | 42 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ |
@@ -213,7 +216,6 @@ static void *i8xx_alloc_pages(void) | |||
213 | } | 216 | } |
214 | global_flush_tlb(); | 217 | global_flush_tlb(); |
215 | get_page(page); | 218 | get_page(page); |
216 | SetPageLocked(page); | ||
217 | atomic_inc(&agp_bridge->current_memory_agp); | 219 | atomic_inc(&agp_bridge->current_memory_agp); |
218 | return page_address(page); | 220 | return page_address(page); |
219 | } | 221 | } |
@@ -229,7 +231,6 @@ static void i8xx_destroy_pages(void *addr) | |||
229 | change_page_attr(page, 4, PAGE_KERNEL); | 231 | change_page_attr(page, 4, PAGE_KERNEL); |
230 | global_flush_tlb(); | 232 | global_flush_tlb(); |
231 | put_page(page); | 233 | put_page(page); |
232 | unlock_page(page); | ||
233 | __free_pages(page, 2); | 234 | __free_pages(page, 2); |
234 | atomic_dec(&agp_bridge->current_memory_agp); | 235 | atomic_dec(&agp_bridge->current_memory_agp); |
235 | } | 236 | } |
@@ -527,6 +528,7 @@ static void intel_i830_init_gtt_entries(void) | |||
527 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || | 528 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || |
528 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || | 529 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || |
529 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || | 530 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || |
531 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || | ||
530 | IS_I965 || IS_G33) | 532 | IS_I965 || IS_G33) |
531 | gtt_entries = MB(48) - KB(size); | 533 | gtt_entries = MB(48) - KB(size); |
532 | else | 534 | else |
@@ -538,6 +540,7 @@ static void intel_i830_init_gtt_entries(void) | |||
538 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || | 540 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || |
539 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || | 541 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || |
540 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || | 542 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || |
543 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || | ||
541 | IS_I965 || IS_G33) | 544 | IS_I965 || IS_G33) |
542 | gtt_entries = MB(64) - KB(size); | 545 | gtt_entries = MB(64) - KB(size); |
543 | else | 546 | else |
@@ -1848,9 +1851,9 @@ static const struct intel_driver_description { | |||
1848 | NULL, &intel_915_driver }, | 1851 | NULL, &intel_915_driver }, |
1849 | { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G", | 1852 | { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G", |
1850 | NULL, &intel_915_driver }, | 1853 | NULL, &intel_915_driver }, |
1851 | { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM", | 1854 | { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 0, "945GM", |
1852 | NULL, &intel_915_driver }, | 1855 | NULL, &intel_915_driver }, |
1853 | { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME", | 1856 | { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME", |
1854 | NULL, &intel_915_driver }, | 1857 | NULL, &intel_915_driver }, |
1855 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", | 1858 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", |
1856 | NULL, &intel_i965_driver }, | 1859 | NULL, &intel_i965_driver }, |
@@ -1860,9 +1863,9 @@ static const struct intel_driver_description { | |||
1860 | NULL, &intel_i965_driver }, | 1863 | NULL, &intel_i965_driver }, |
1861 | { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G", | 1864 | { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G", |
1862 | NULL, &intel_i965_driver }, | 1865 | NULL, &intel_i965_driver }, |
1863 | { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM", | 1866 | { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 0, "965GM", |
1864 | NULL, &intel_i965_driver }, | 1867 | NULL, &intel_i965_driver }, |
1865 | { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE", | 1868 | { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE", |
1866 | NULL, &intel_i965_driver }, | 1869 | NULL, &intel_i965_driver }, |
1867 | { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL }, | 1870 | { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL }, |
1868 | { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL }, | 1871 | { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL }, |
@@ -2051,11 +2054,13 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2051 | ID(PCI_DEVICE_ID_INTEL_82915GM_HB), | 2054 | ID(PCI_DEVICE_ID_INTEL_82915GM_HB), |
2052 | ID(PCI_DEVICE_ID_INTEL_82945G_HB), | 2055 | ID(PCI_DEVICE_ID_INTEL_82945G_HB), |
2053 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), | 2056 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), |
2057 | ID(PCI_DEVICE_ID_INTEL_82945GME_HB), | ||
2054 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), | 2058 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), |
2055 | ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), | 2059 | ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), |
2056 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), | 2060 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), |
2057 | ID(PCI_DEVICE_ID_INTEL_82965G_HB), | 2061 | ID(PCI_DEVICE_ID_INTEL_82965G_HB), |
2058 | ID(PCI_DEVICE_ID_INTEL_82965GM_HB), | 2062 | ID(PCI_DEVICE_ID_INTEL_82965GM_HB), |
2063 | ID(PCI_DEVICE_ID_INTEL_82965GME_HB), | ||
2059 | ID(PCI_DEVICE_ID_INTEL_G33_HB), | 2064 | ID(PCI_DEVICE_ID_INTEL_G33_HB), |
2060 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), | 2065 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
2061 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), | 2066 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index cda608c42bea..98cf8abb3e57 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
@@ -51,7 +51,6 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) | |||
51 | return NULL; | 51 | return NULL; |
52 | 52 | ||
53 | get_page(page); | 53 | get_page(page); |
54 | SetPageLocked(page); | ||
55 | atomic_inc(&agp_bridge->current_memory_agp); | 54 | atomic_inc(&agp_bridge->current_memory_agp); |
56 | return page_address(page); | 55 | return page_address(page); |
57 | } | 56 | } |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index ba0e74ad74bb..77bf4aa217a8 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -73,7 +73,7 @@ static struct clocksource clocksource_hpet = { | |||
73 | .name = "hpet", | 73 | .name = "hpet", |
74 | .rating = 250, | 74 | .rating = 250, |
75 | .read = read_hpet, | 75 | .read = read_hpet, |
76 | .mask = 0xffffffffffffffff, | 76 | .mask = CLOCKSOURCE_MASK(64), |
77 | .mult = 0, /*to be caluclated*/ | 77 | .mult = 0, /*to be caluclated*/ |
78 | .shift = 10, | 78 | .shift = 10, |
79 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 79 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
@@ -1007,9 +1007,15 @@ static int hpet_acpi_remove(struct acpi_device *device, int type) | |||
1007 | return -EINVAL; | 1007 | return -EINVAL; |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | static const struct acpi_device_id hpet_device_ids[] = { | ||
1011 | {"PNP0103", 0}, | ||
1012 | {"", 0}, | ||
1013 | }; | ||
1014 | MODULE_DEVICE_TABLE(acpi, hpet_device_ids); | ||
1015 | |||
1010 | static struct acpi_driver hpet_acpi_driver = { | 1016 | static struct acpi_driver hpet_acpi_driver = { |
1011 | .name = "hpet", | 1017 | .name = "hpet", |
1012 | .ids = "PNP0103", | 1018 | .ids = hpet_device_ids, |
1013 | .ops = { | 1019 | .ops = { |
1014 | .add = hpet_acpi_add, | 1020 | .add = hpet_acpi_add, |
1015 | .remove = hpet_acpi_remove, | 1021 | .remove = hpet_acpi_remove, |
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c index e7b889e404a7..feeccbaec438 100644 --- a/drivers/char/hvc_lguest.c +++ b/drivers/char/hvc_lguest.c | |||
@@ -1,6 +1,22 @@ | |||
1 | /* Simple console for lguest. | 1 | /*D:300 |
2 | * The Guest console driver | ||
2 | * | 3 | * |
3 | * Copyright (C) 2006 Rusty Russell, IBM Corporation | 4 | * This is a trivial console driver: we use lguest's DMA mechanism to send |
5 | * bytes out, and register a DMA buffer to receive bytes in. It is assumed to | ||
6 | * be present and available from the very beginning of boot. | ||
7 | * | ||
8 | * Writing console drivers is one of the few remaining Dark Arts in Linux. | ||
9 | * Fortunately for us, the path of virtual consoles has been well-trodden by | ||
10 | * the PowerPC folks, who wrote "hvc_console.c" to generically support any | ||
11 | * virtual console. We use that infrastructure which only requires us to write | ||
12 | * the basic put_chars and get_chars functions and call the right register | ||
13 | * functions. | ||
14 | :*/ | ||
15 | |||
16 | /*M:002 The console can be flooded: while the Guest is processing input the | ||
17 | * Host can send more. Buffering in the Host could alleviate this, but it is a | ||
18 | * difficult problem in general. :*/ | ||
19 | /* Copyright (C) 2006 Rusty Russell, IBM Corporation | ||
4 | * | 20 | * |
5 | * This program is free software; you can redistribute it and/or modify | 21 | * 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 | 22 | * it under the terms of the GNU General Public License as published by |
@@ -21,49 +37,81 @@ | |||
21 | #include <linux/lguest_bus.h> | 37 | #include <linux/lguest_bus.h> |
22 | #include "hvc_console.h" | 38 | #include "hvc_console.h" |
23 | 39 | ||
40 | /*D:340 This is our single console input buffer, with associated "struct | ||
41 | * lguest_dma" referring to it. Note the 0-terminated length array, and the | ||
42 | * use of physical address for the buffer itself. */ | ||
24 | static char inbuf[256]; | 43 | static char inbuf[256]; |
25 | static struct lguest_dma cons_input = { .used_len = 0, | 44 | static struct lguest_dma cons_input = { .used_len = 0, |
26 | .addr[0] = __pa(inbuf), | 45 | .addr[0] = __pa(inbuf), |
27 | .len[0] = sizeof(inbuf), | 46 | .len[0] = sizeof(inbuf), |
28 | .len[1] = 0 }; | 47 | .len[1] = 0 }; |
29 | 48 | ||
49 | /*D:310 The put_chars() callback is pretty straightforward. | ||
50 | * | ||
51 | * First we put the pointer and length in a "struct lguest_dma": we only have | ||
52 | * one pointer, so we set the second length to 0. Then we use SEND_DMA to send | ||
53 | * the data to (Host) buffers attached to the console key. Usually a device's | ||
54 | * key is a physical address within the device's memory, but because the | ||
55 | * console device doesn't have any associated physical memory, we use the | ||
56 | * LGUEST_CONSOLE_DMA_KEY constant (aka 0). */ | ||
30 | static int put_chars(u32 vtermno, const char *buf, int count) | 57 | static int put_chars(u32 vtermno, const char *buf, int count) |
31 | { | 58 | { |
32 | struct lguest_dma dma; | 59 | struct lguest_dma dma; |
33 | 60 | ||
34 | /* FIXME: what if it's over a page boundary? */ | 61 | /* FIXME: DMA buffers in a "struct lguest_dma" are not allowed |
62 | * to go over page boundaries. This never seems to happen, | ||
63 | * but if it did we'd need to fix this code. */ | ||
35 | dma.len[0] = count; | 64 | dma.len[0] = count; |
36 | dma.len[1] = 0; | 65 | dma.len[1] = 0; |
37 | dma.addr[0] = __pa(buf); | 66 | dma.addr[0] = __pa(buf); |
38 | 67 | ||
39 | lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma); | 68 | lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma); |
69 | /* We're expected to return the amount of data we wrote: all of it. */ | ||
40 | return count; | 70 | return count; |
41 | } | 71 | } |
42 | 72 | ||
73 | /*D:350 get_chars() is the callback from the hvc_console infrastructure when | ||
74 | * an interrupt is received. | ||
75 | * | ||
76 | * Firstly we see if our buffer has been filled: if not, we return. The rest | ||
77 | * of the code deals with the fact that the hvc_console() infrastructure only | ||
78 | * asks us for 16 bytes at a time. We keep a "cons_offset" variable for | ||
79 | * partially-read buffers. */ | ||
43 | static int get_chars(u32 vtermno, char *buf, int count) | 80 | static int get_chars(u32 vtermno, char *buf, int count) |
44 | { | 81 | { |
45 | static int cons_offset; | 82 | static int cons_offset; |
46 | 83 | ||
84 | /* Nothing left to see here... */ | ||
47 | if (!cons_input.used_len) | 85 | if (!cons_input.used_len) |
48 | return 0; | 86 | return 0; |
49 | 87 | ||
88 | /* You want more than we have to give? Well, try wanting less! */ | ||
50 | if (cons_input.used_len - cons_offset < count) | 89 | if (cons_input.used_len - cons_offset < count) |
51 | count = cons_input.used_len - cons_offset; | 90 | count = cons_input.used_len - cons_offset; |
52 | 91 | ||
92 | /* Copy across to their buffer and increment offset. */ | ||
53 | memcpy(buf, inbuf + cons_offset, count); | 93 | memcpy(buf, inbuf + cons_offset, count); |
54 | cons_offset += count; | 94 | cons_offset += count; |
95 | |||
96 | /* Finished? Zero offset, and reset cons_input so Host will use it | ||
97 | * again. */ | ||
55 | if (cons_offset == cons_input.used_len) { | 98 | if (cons_offset == cons_input.used_len) { |
56 | cons_offset = 0; | 99 | cons_offset = 0; |
57 | cons_input.used_len = 0; | 100 | cons_input.used_len = 0; |
58 | } | 101 | } |
59 | return count; | 102 | return count; |
60 | } | 103 | } |
104 | /*:*/ | ||
61 | 105 | ||
62 | static struct hv_ops lguest_cons = { | 106 | static struct hv_ops lguest_cons = { |
63 | .get_chars = get_chars, | 107 | .get_chars = get_chars, |
64 | .put_chars = put_chars, | 108 | .put_chars = put_chars, |
65 | }; | 109 | }; |
66 | 110 | ||
111 | /*D:320 Console drivers are initialized very early so boot messages can go | ||
112 | * out. At this stage, the console is output-only. Our driver checks we're a | ||
113 | * Guest, and if so hands hvc_instantiate() the console number (0), priority | ||
114 | * (0), and the struct hv_ops containing the put_chars() function. */ | ||
67 | static int __init cons_init(void) | 115 | static int __init cons_init(void) |
68 | { | 116 | { |
69 | if (strcmp(paravirt_ops.name, "lguest") != 0) | 117 | if (strcmp(paravirt_ops.name, "lguest") != 0) |
@@ -73,21 +121,46 @@ static int __init cons_init(void) | |||
73 | } | 121 | } |
74 | console_initcall(cons_init); | 122 | console_initcall(cons_init); |
75 | 123 | ||
124 | /*D:370 To set up and manage our virtual console, we call hvc_alloc() and | ||
125 | * stash the result in the private pointer of the "struct lguest_device". | ||
126 | * Since we never remove the console device we never need this pointer again, | ||
127 | * but using ->private is considered good form, and you never know who's going | ||
128 | * to copy your driver. | ||
129 | * | ||
130 | * Once the console is set up, we bind our input buffer ready for input. */ | ||
76 | static int lguestcons_probe(struct lguest_device *lgdev) | 131 | static int lguestcons_probe(struct lguest_device *lgdev) |
77 | { | 132 | { |
78 | int err; | 133 | int err; |
79 | 134 | ||
135 | /* The first argument of hvc_alloc() is the virtual console number, so | ||
136 | * we use zero. The second argument is the interrupt number. | ||
137 | * | ||
138 | * The third argument is a "struct hv_ops" containing the put_chars() | ||
139 | * and get_chars() pointers. The final argument is the output buffer | ||
140 | * size: we use 256 and expect the Host to have room for us to send | ||
141 | * that much. */ | ||
80 | lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256); | 142 | lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256); |
81 | if (IS_ERR(lgdev->private)) | 143 | if (IS_ERR(lgdev->private)) |
82 | return PTR_ERR(lgdev->private); | 144 | return PTR_ERR(lgdev->private); |
83 | 145 | ||
146 | /* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY. | ||
147 | * "cons_input" is that statically-initialized global DMA buffer we saw | ||
148 | * above, and we also give the interrupt we want. */ | ||
84 | err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1, | 149 | err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1, |
85 | lgdev_irq(lgdev)); | 150 | lgdev_irq(lgdev)); |
86 | if (err) | 151 | if (err) |
87 | printk("lguest console: failed to bind buffer.\n"); | 152 | printk("lguest console: failed to bind buffer.\n"); |
88 | return err; | 153 | return err; |
89 | } | 154 | } |
155 | /* Note the use of lgdev_irq() for the interrupt number. We tell hvc_alloc() | ||
156 | * to expect input when this interrupt is triggered, and then tell | ||
157 | * lguest_bind_dma() that is the interrupt to send us when input comes in. */ | ||
90 | 158 | ||
159 | /*D:360 From now on the console driver follows standard Guest driver form: | ||
160 | * register_lguest_driver() registers the device type and probe function, and | ||
161 | * the probe function sets up the device. | ||
162 | * | ||
163 | * The standard "struct lguest_driver": */ | ||
91 | static struct lguest_driver lguestcons_drv = { | 164 | static struct lguest_driver lguestcons_drv = { |
92 | .name = "lguestcons", | 165 | .name = "lguestcons", |
93 | .owner = THIS_MODULE, | 166 | .owner = THIS_MODULE, |
@@ -95,6 +168,7 @@ static struct lguest_driver lguestcons_drv = { | |||
95 | .probe = lguestcons_probe, | 168 | .probe = lguestcons_probe, |
96 | }; | 169 | }; |
97 | 170 | ||
171 | /* The standard init function */ | ||
98 | static int __init hvc_lguest_init(void) | 172 | static int __init hvc_lguest_init(void) |
99 | { | 173 | { |
100 | return register_lguest_driver(&lguestcons_drv); | 174 | return register_lguest_driver(&lguestcons_drv); |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 6005b5225772..8d74b8745e60 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -500,7 +500,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
500 | { | 500 | { |
501 | int i, j, box; | 501 | int i, j, box; |
502 | int err = 0; | 502 | int err = 0; |
503 | int status = 0; | ||
504 | static int loaded; | 503 | static int loaded; |
505 | i2eBordStrPtr pB = NULL; | 504 | i2eBordStrPtr pB = NULL; |
506 | int rc = -1; | 505 | int rc = -1; |
@@ -588,6 +587,8 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
588 | case PCI: | 587 | case PCI: |
589 | #ifdef CONFIG_PCI | 588 | #ifdef CONFIG_PCI |
590 | { | 589 | { |
590 | int status; | ||
591 | |||
591 | pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, | 592 | pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, |
592 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); | 593 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); |
593 | if (pci_dev_i != NULL) { | 594 | if (pci_dev_i != NULL) { |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4edfdda0cf99..96d2f9ee42d6 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -2050,6 +2050,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | |||
2050 | info->si_type = SI_BT; | 2050 | info->si_type = SI_BT; |
2051 | break; | 2051 | break; |
2052 | default: | 2052 | default: |
2053 | kfree(info); | ||
2053 | return; | 2054 | return; |
2054 | } | 2055 | } |
2055 | 2056 | ||
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 6e55cfb9c65a..e60a74c66e3d 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/fs.h> | ||
28 | #include <linux/mmtimer.h> | 29 | #include <linux/mmtimer.h> |
29 | #include <linux/miscdevice.h> | 30 | #include <linux/miscdevice.h> |
30 | #include <linux/posix-timers.h> | 31 | #include <linux/posix-timers.h> |
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index c716ef0dd370..c08a4152ee8f 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
41 | #include <linux/fs.h> | ||
41 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
42 | #include <linux/string.h> | 43 | #include <linux/string.h> |
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 372a37e25620..bbb7f1292665 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $ | 2 | * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $ |
3 | * | 3 | * |
4 | * Device driver for Microgate SyncLink GT serial adapters. | 4 | * Device driver for Microgate SyncLink GT serial adapters. |
5 | * | 5 | * |
@@ -93,7 +93,7 @@ | |||
93 | * module identification | 93 | * module identification |
94 | */ | 94 | */ |
95 | static char *driver_name = "SyncLink GT"; | 95 | static char *driver_name = "SyncLink GT"; |
96 | static char *driver_version = "$Revision: 4.36 $"; | 96 | static char *driver_version = "$Revision: 4.50 $"; |
97 | static char *tty_driver_name = "synclink_gt"; | 97 | static char *tty_driver_name = "synclink_gt"; |
98 | static char *tty_dev_prefix = "ttySLG"; | 98 | static char *tty_dev_prefix = "ttySLG"; |
99 | MODULE_LICENSE("GPL"); | 99 | MODULE_LICENSE("GPL"); |
@@ -477,6 +477,7 @@ static void tx_set_idle(struct slgt_info *info); | |||
477 | static unsigned int free_tbuf_count(struct slgt_info *info); | 477 | static unsigned int free_tbuf_count(struct slgt_info *info); |
478 | static void reset_tbufs(struct slgt_info *info); | 478 | static void reset_tbufs(struct slgt_info *info); |
479 | static void tdma_reset(struct slgt_info *info); | 479 | static void tdma_reset(struct slgt_info *info); |
480 | static void tdma_start(struct slgt_info *info); | ||
480 | static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); | 481 | static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); |
481 | 482 | ||
482 | static void get_signals(struct slgt_info *info); | 483 | static void get_signals(struct slgt_info *info); |
@@ -904,6 +905,8 @@ start: | |||
904 | spin_lock_irqsave(&info->lock,flags); | 905 | spin_lock_irqsave(&info->lock,flags); |
905 | if (!info->tx_active) | 906 | if (!info->tx_active) |
906 | tx_start(info); | 907 | tx_start(info); |
908 | else | ||
909 | tdma_start(info); | ||
907 | spin_unlock_irqrestore(&info->lock,flags); | 910 | spin_unlock_irqrestore(&info->lock,flags); |
908 | } | 911 | } |
909 | 912 | ||
@@ -3871,44 +3874,58 @@ static void tx_start(struct slgt_info *info) | |||
3871 | slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); | 3874 | slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); |
3872 | /* clear tx idle and underrun status bits */ | 3875 | /* clear tx idle and underrun status bits */ |
3873 | wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); | 3876 | wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); |
3874 | |||
3875 | if (!(rd_reg32(info, TDCSR) & BIT0)) { | ||
3876 | /* tx DMA stopped, restart tx DMA */ | ||
3877 | tdma_reset(info); | ||
3878 | /* set 1st descriptor address */ | ||
3879 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); | ||
3880 | switch(info->params.mode) { | ||
3881 | case MGSL_MODE_RAW: | ||
3882 | case MGSL_MODE_MONOSYNC: | ||
3883 | case MGSL_MODE_BISYNC: | ||
3884 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ | ||
3885 | break; | ||
3886 | default: | ||
3887 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ | ||
3888 | } | ||
3889 | } | ||
3890 | |||
3891 | if (info->params.mode == MGSL_MODE_HDLC) | 3877 | if (info->params.mode == MGSL_MODE_HDLC) |
3892 | mod_timer(&info->tx_timer, jiffies + | 3878 | mod_timer(&info->tx_timer, jiffies + |
3893 | msecs_to_jiffies(5000)); | 3879 | msecs_to_jiffies(5000)); |
3894 | } else { | 3880 | } else { |
3895 | tdma_reset(info); | ||
3896 | /* set 1st descriptor address */ | ||
3897 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); | ||
3898 | |||
3899 | slgt_irq_off(info, IRQ_TXDATA); | 3881 | slgt_irq_off(info, IRQ_TXDATA); |
3900 | slgt_irq_on(info, IRQ_TXIDLE); | 3882 | slgt_irq_on(info, IRQ_TXIDLE); |
3901 | /* clear tx idle status bit */ | 3883 | /* clear tx idle status bit */ |
3902 | wr_reg16(info, SSR, IRQ_TXIDLE); | 3884 | wr_reg16(info, SSR, IRQ_TXIDLE); |
3903 | |||
3904 | /* enable tx DMA */ | ||
3905 | wr_reg32(info, TDCSR, BIT0); | ||
3906 | } | 3885 | } |
3907 | 3886 | tdma_start(info); | |
3908 | info->tx_active = 1; | 3887 | info->tx_active = 1; |
3909 | } | 3888 | } |
3910 | } | 3889 | } |
3911 | 3890 | ||
3891 | /* | ||
3892 | * start transmit DMA if inactive and there are unsent buffers | ||
3893 | */ | ||
3894 | static void tdma_start(struct slgt_info *info) | ||
3895 | { | ||
3896 | unsigned int i; | ||
3897 | |||
3898 | if (rd_reg32(info, TDCSR) & BIT0) | ||
3899 | return; | ||
3900 | |||
3901 | /* transmit DMA inactive, check for unsent buffers */ | ||
3902 | i = info->tbuf_start; | ||
3903 | while (!desc_count(info->tbufs[i])) { | ||
3904 | if (++i == info->tbuf_count) | ||
3905 | i = 0; | ||
3906 | if (i == info->tbuf_current) | ||
3907 | return; | ||
3908 | } | ||
3909 | info->tbuf_start = i; | ||
3910 | |||
3911 | /* there are unsent buffers, start transmit DMA */ | ||
3912 | |||
3913 | /* reset needed if previous error condition */ | ||
3914 | tdma_reset(info); | ||
3915 | |||
3916 | /* set 1st descriptor address */ | ||
3917 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); | ||
3918 | switch(info->params.mode) { | ||
3919 | case MGSL_MODE_RAW: | ||
3920 | case MGSL_MODE_MONOSYNC: | ||
3921 | case MGSL_MODE_BISYNC: | ||
3922 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ | ||
3923 | break; | ||
3924 | default: | ||
3925 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ | ||
3926 | } | ||
3927 | } | ||
3928 | |||
3912 | static void tx_stop(struct slgt_info *info) | 3929 | static void tx_stop(struct slgt_info *info) |
3913 | { | 3930 | { |
3914 | unsigned short val; | 3931 | unsigned short val; |
@@ -4642,8 +4659,8 @@ static unsigned int free_tbuf_count(struct slgt_info *info) | |||
4642 | i=0; | 4659 | i=0; |
4643 | } while (i != info->tbuf_current); | 4660 | } while (i != info->tbuf_current); |
4644 | 4661 | ||
4645 | /* last buffer with zero count may be in use, assume it is */ | 4662 | /* if tx DMA active, last zero count buffer is in use */ |
4646 | if (count) | 4663 | if (count && (rd_reg32(info, TDCSR) & BIT0)) |
4647 | --count; | 4664 | --count; |
4648 | 4665 | ||
4649 | return count; | 4666 | return count; |