aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-09-19 20:09:27 -0400
committerPaul Mackerras <paulus@samba.org>2007-09-19 20:09:27 -0400
commit0ce49a3945474fc942ec37c0c0efece60f592f80 (patch)
treef42b821b2d9e2d8775bc22f56d444c2cc7b7b7dd /drivers/char
parent9e4859ef5462193643fd2b3c8ffb298e5a4a4319 (diff)
parenta88a8eff1e6e32d3288986a9d36c6a449c032d3a (diff)
Merge branch 'linux-2.6'
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/agp.h3
-rw-r--r--drivers/char/agp/intel-agp.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c3
-rw-r--r--drivers/char/mspec.c69
-rw-r--r--drivers/char/tty_ioctl.c14
5 files changed, 67 insertions, 24 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 35ab1a9f8e8b..8955e7ff759a 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -176,7 +176,7 @@ struct agp_bridge_data {
176#define I830_GMCH_MEM_MASK 0x1 176#define I830_GMCH_MEM_MASK 0x1
177#define I830_GMCH_MEM_64M 0x1 177#define I830_GMCH_MEM_64M 0x1
178#define I830_GMCH_MEM_128M 0 178#define I830_GMCH_MEM_128M 0
179#define I830_GMCH_GMS_MASK 0xF0 179#define I830_GMCH_GMS_MASK 0x70
180#define I830_GMCH_GMS_DISABLED 0x00 180#define I830_GMCH_GMS_DISABLED 0x00
181#define I830_GMCH_GMS_LOCAL 0x10 181#define I830_GMCH_GMS_LOCAL 0x10
182#define I830_GMCH_GMS_STOLEN_512 0x20 182#define I830_GMCH_GMS_STOLEN_512 0x20
@@ -190,6 +190,7 @@ struct agp_bridge_data {
190#define INTEL_I830_ERRSTS 0x92 190#define INTEL_I830_ERRSTS 0x92
191 191
192/* Intel 855GM/852GM registers */ 192/* Intel 855GM/852GM registers */
193#define I855_GMCH_GMS_MASK 0xF0
193#define I855_GMCH_GMS_STOLEN_0M 0x0 194#define I855_GMCH_GMS_STOLEN_0M 0x0
194#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) 195#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
195#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) 196#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 7c69bf259caa..a5d0e95a227a 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -511,7 +511,7 @@ static void intel_i830_init_gtt_entries(void)
511 */ 511 */
512 if (IS_G33) 512 if (IS_G33)
513 size = 0; 513 size = 0;
514 switch (gmch_ctrl & I830_GMCH_GMS_MASK) { 514 switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
515 case I855_GMCH_GMS_STOLEN_1M: 515 case I855_GMCH_GMS_STOLEN_1M:
516 gtt_entries = MB(1) - KB(size); 516 gtt_entries = MB(1) - KB(size);
517 break; 517 break;
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index f2e5cb1bedf3..1dd3a065f57b 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2215,7 +2215,8 @@ static int ipmi_pci_resume(struct pci_dev *pdev)
2215 2215
2216static struct pci_device_id ipmi_pci_devices[] = { 2216static struct pci_device_id ipmi_pci_devices[] = {
2217 { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, 2217 { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
2218 { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } 2218 { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
2219 { 0, }
2219}; 2220};
2220MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); 2221MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
2221 2222
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index c08a4152ee8f..049a46cc9f87 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -67,7 +67,7 @@
67/* 67/*
68 * Page types allocated by the device. 68 * Page types allocated by the device.
69 */ 69 */
70enum { 70enum mspec_page_type {
71 MSPEC_FETCHOP = 1, 71 MSPEC_FETCHOP = 1,
72 MSPEC_CACHED, 72 MSPEC_CACHED,
73 MSPEC_UNCACHED 73 MSPEC_UNCACHED
@@ -83,15 +83,25 @@ static int is_sn2;
83 * One of these structures is allocated when an mspec region is mmaped. The 83 * One of these structures is allocated when an mspec region is mmaped. The
84 * structure is pointed to by the vma->vm_private_data field in the vma struct. 84 * structure is pointed to by the vma->vm_private_data field in the vma struct.
85 * This structure is used to record the addresses of the mspec pages. 85 * This structure is used to record the addresses of the mspec pages.
86 * This structure is shared by all vma's that are split off from the
87 * original vma when split_vma()'s are done.
88 *
89 * The refcnt is incremented atomically because mm->mmap_sem does not
90 * protect in fork case where multiple tasks share the vma_data.
86 */ 91 */
87struct vma_data { 92struct vma_data {
88 atomic_t refcnt; /* Number of vmas sharing the data. */ 93 atomic_t refcnt; /* Number of vmas sharing the data. */
89 spinlock_t lock; /* Serialize access to the vma. */ 94 spinlock_t lock; /* Serialize access to this structure. */
90 int count; /* Number of pages allocated. */ 95 int count; /* Number of pages allocated. */
91 int type; /* Type of pages allocated. */ 96 enum mspec_page_type type; /* Type of pages allocated. */
97 int flags; /* See VMD_xxx below. */
98 unsigned long vm_start; /* Original (unsplit) base. */
99 unsigned long vm_end; /* Original (unsplit) end. */
92 unsigned long maddr[0]; /* Array of MSPEC addresses. */ 100 unsigned long maddr[0]; /* Array of MSPEC addresses. */
93}; 101};
94 102
103#define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */
104
95/* used on shub2 to clear FOP cache in the HUB */ 105/* used on shub2 to clear FOP cache in the HUB */
96static unsigned long scratch_page[MAX_NUMNODES]; 106static unsigned long scratch_page[MAX_NUMNODES];
97#define SH2_AMO_CACHE_ENTRIES 4 107#define SH2_AMO_CACHE_ENTRIES 4
@@ -129,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len)
129 * mspec_open 139 * mspec_open
130 * 140 *
131 * Called when a device mapping is created by a means other than mmap 141 * Called when a device mapping is created by a means other than mmap
132 * (via fork, etc.). Increments the reference count on the underlying 142 * (via fork, munmap, etc.). Increments the reference count on the
133 * mspec data so it is not freed prematurely. 143 * underlying mspec data so it is not freed prematurely.
134 */ 144 */
135static void 145static void
136mspec_open(struct vm_area_struct *vma) 146mspec_open(struct vm_area_struct *vma)
@@ -151,34 +161,44 @@ static void
151mspec_close(struct vm_area_struct *vma) 161mspec_close(struct vm_area_struct *vma)
152{ 162{
153 struct vma_data *vdata; 163 struct vma_data *vdata;
154 int i, pages, result, vdata_size; 164 int index, last_index, result;
165 unsigned long my_page;
155 166
156 vdata = vma->vm_private_data; 167 vdata = vma->vm_private_data;
157 if (!atomic_dec_and_test(&vdata->refcnt))
158 return;
159 168
160 pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 169 BUG_ON(vma->vm_start < vdata->vm_start || vma->vm_end > vdata->vm_end);
161 vdata_size = sizeof(struct vma_data) + pages * sizeof(long); 170
162 for (i = 0; i < pages; i++) { 171 spin_lock(&vdata->lock);
163 if (vdata->maddr[i] == 0) 172 index = (vma->vm_start - vdata->vm_start) >> PAGE_SHIFT;
173 last_index = (vma->vm_end - vdata->vm_start) >> PAGE_SHIFT;
174 for (; index < last_index; index++) {
175 if (vdata->maddr[index] == 0)
164 continue; 176 continue;
165 /* 177 /*
166 * Clear the page before sticking it back 178 * Clear the page before sticking it back
167 * into the pool. 179 * into the pool.
168 */ 180 */
169 result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE); 181 my_page = vdata->maddr[index];
182 vdata->maddr[index] = 0;
183 spin_unlock(&vdata->lock);
184 result = mspec_zero_block(my_page, PAGE_SIZE);
170 if (!result) 185 if (!result)
171 uncached_free_page(vdata->maddr[i]); 186 uncached_free_page(my_page);
172 else 187 else
173 printk(KERN_WARNING "mspec_close(): " 188 printk(KERN_WARNING "mspec_close(): "
174 "failed to zero page %i\n", 189 "failed to zero page %i\n",
175 result); 190 result);
191 spin_lock(&vdata->lock);
176 } 192 }
193 spin_unlock(&vdata->lock);
177 194
178 if (vdata_size <= PAGE_SIZE) 195 if (!atomic_dec_and_test(&vdata->refcnt))
179 kfree(vdata); 196 return;
180 else 197
198 if (vdata->flags & VMD_VMALLOCED)
181 vfree(vdata); 199 vfree(vdata);
200 else
201 kfree(vdata);
182} 202}
183 203
184 204
@@ -195,7 +215,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
195 int index; 215 int index;
196 struct vma_data *vdata = vma->vm_private_data; 216 struct vma_data *vdata = vma->vm_private_data;
197 217
198 index = (address - vma->vm_start) >> PAGE_SHIFT; 218 BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
219 index = (address - vdata->vm_start) >> PAGE_SHIFT;
199 maddr = (volatile unsigned long) vdata->maddr[index]; 220 maddr = (volatile unsigned long) vdata->maddr[index];
200 if (maddr == 0) { 221 if (maddr == 0) {
201 maddr = uncached_alloc_page(numa_node_id()); 222 maddr = uncached_alloc_page(numa_node_id());
@@ -237,10 +258,11 @@ static struct vm_operations_struct mspec_vm_ops = {
237 * underlying pages. 258 * underlying pages.
238 */ 259 */
239static int 260static int
240mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) 261mspec_mmap(struct file *file, struct vm_area_struct *vma,
262 enum mspec_page_type type)
241{ 263{
242 struct vma_data *vdata; 264 struct vma_data *vdata;
243 int pages, vdata_size; 265 int pages, vdata_size, flags = 0;
244 266
245 if (vma->vm_pgoff != 0) 267 if (vma->vm_pgoff != 0)
246 return -EINVAL; 268 return -EINVAL;
@@ -255,12 +277,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
255 vdata_size = sizeof(struct vma_data) + pages * sizeof(long); 277 vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
256 if (vdata_size <= PAGE_SIZE) 278 if (vdata_size <= PAGE_SIZE)
257 vdata = kmalloc(vdata_size, GFP_KERNEL); 279 vdata = kmalloc(vdata_size, GFP_KERNEL);
258 else 280 else {
259 vdata = vmalloc(vdata_size); 281 vdata = vmalloc(vdata_size);
282 flags = VMD_VMALLOCED;
283 }
260 if (!vdata) 284 if (!vdata)
261 return -ENOMEM; 285 return -ENOMEM;
262 memset(vdata, 0, vdata_size); 286 memset(vdata, 0, vdata_size);
263 287
288 vdata->vm_start = vma->vm_start;
289 vdata->vm_end = vma->vm_end;
290 vdata->flags = flags;
264 vdata->type = type; 291 vdata->type = type;
265 spin_lock_init(&vdata->lock); 292 spin_lock_init(&vdata->lock);
266 vdata->refcnt = ATOMIC_INIT(1); 293 vdata->refcnt = ATOMIC_INIT(1);
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 4a8969cef315..3ee73cf64bd2 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -795,6 +795,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
795 if (L_ICANON(tty)) 795 if (L_ICANON(tty))
796 retval = inq_canon(tty); 796 retval = inq_canon(tty);
797 return put_user(retval, (unsigned int __user *) arg); 797 return put_user(retval, (unsigned int __user *) arg);
798#ifndef TCGETS2
799 case TIOCGLCKTRMIOS:
800 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
801 return -EFAULT;
802 return 0;
803
804 case TIOCSLCKTRMIOS:
805 if (!capable(CAP_SYS_ADMIN))
806 return -EPERM;
807 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
808 return -EFAULT;
809 return 0;
810#else
798 case TIOCGLCKTRMIOS: 811 case TIOCGLCKTRMIOS:
799 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) 812 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
800 return -EFAULT; 813 return -EFAULT;
@@ -806,6 +819,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
806 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg)) 819 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
807 return -EFAULT; 820 return -EFAULT;
808 return 0; 821 return 0;
822#endif
809 823
810 case TIOCPKT: 824 case TIOCPKT:
811 { 825 {