diff options
Diffstat (limited to 'drivers/char')
84 files changed, 2921 insertions, 2382 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index caff85149b9d..122254155ae1 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -350,7 +350,7 @@ config STALDRV | |||
350 | 350 | ||
351 | config STALLION | 351 | config STALLION |
352 | tristate "Stallion EasyIO or EC8/32 support" | 352 | tristate "Stallion EasyIO or EC8/32 support" |
353 | depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) | 353 | depends on STALDRV && (ISA || EISA || PCI) |
354 | help | 354 | help |
355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion | 355 | If you have an EasyIO or EasyConnection 8/32 multiport Stallion |
356 | card, then this is for you; say Y. Make sure to read | 356 | card, then this is for you; say Y. Make sure to read |
@@ -361,7 +361,7 @@ config STALLION | |||
361 | 361 | ||
362 | config ISTALLION | 362 | config ISTALLION |
363 | tristate "Stallion EC8/64, ONboard, Brumby support" | 363 | tristate "Stallion EC8/64, ONboard, Brumby support" |
364 | depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) | 364 | depends on STALDRV && (ISA || EISA || PCI) |
365 | help | 365 | help |
366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion | 366 | If you have an EasyConnection 8/64, ONboard, Brumby or Stallion |
367 | serial multiport card, say Y here. Make sure to read | 367 | serial multiport card, say Y here. Make sure to read |
@@ -1043,15 +1043,6 @@ config HPET | |||
1043 | open selects one of the timers supported by the HPET. The timers are | 1043 | open selects one of the timers supported by the HPET. The timers are |
1044 | non-periodic and/or periodic. | 1044 | non-periodic and/or periodic. |
1045 | 1045 | ||
1046 | config HPET_RTC_IRQ | ||
1047 | bool | ||
1048 | default HPET_EMULATE_RTC | ||
1049 | depends on RTC && HPET | ||
1050 | help | ||
1051 | If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It | ||
1052 | is assumed the platform called hpet_alloc with the RTC IRQ values for | ||
1053 | the HPET timers. | ||
1054 | |||
1055 | config HPET_MMAP | 1046 | config HPET_MMAP |
1056 | bool "Allow mmap of HPET" | 1047 | bool "Allow mmap of HPET" |
1057 | default y | 1048 | default y |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 6850f6da7576..1a4247dccac4 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -7,7 +7,7 @@ | |||
7 | # | 7 | # |
8 | FONTMAPFILE = cp437.uni | 8 | FONTMAPFILE = cp437.uni |
9 | 9 | ||
10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o | 10 | obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o |
11 | 11 | ||
12 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 12 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
13 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 13 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 4bada0e8b812..46f507531177 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -116,7 +116,9 @@ struct agp_bridge_driver { | |||
116 | struct agp_memory *(*alloc_by_type) (size_t, int); | 116 | struct agp_memory *(*alloc_by_type) (size_t, int); |
117 | void (*free_by_type)(struct agp_memory *); | 117 | void (*free_by_type)(struct agp_memory *); |
118 | void *(*agp_alloc_page)(struct agp_bridge_data *); | 118 | void *(*agp_alloc_page)(struct agp_bridge_data *); |
119 | int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t); | ||
119 | void (*agp_destroy_page)(void *, int flags); | 120 | void (*agp_destroy_page)(void *, int flags); |
121 | void (*agp_destroy_pages)(struct agp_memory *); | ||
120 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
121 | void (*chipset_flush)(struct agp_bridge_data *); | 123 | void (*chipset_flush)(struct agp_bridge_data *); |
122 | }; | 124 | }; |
@@ -277,7 +279,10 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); | |||
277 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); | 279 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); |
278 | void agp_generic_free_by_type(struct agp_memory *curr); | 280 | void agp_generic_free_by_type(struct agp_memory *curr); |
279 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge); | 281 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge); |
282 | int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge, | ||
283 | struct agp_memory *memory, size_t page_count); | ||
280 | void agp_generic_destroy_page(void *addr, int flags); | 284 | void agp_generic_destroy_page(void *addr, int flags); |
285 | void agp_generic_destroy_pages(struct agp_memory *memory); | ||
281 | void agp_free_key(int key); | 286 | void agp_free_key(int key); |
282 | int agp_num_entries(void); | 287 | int agp_num_entries(void); |
283 | u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); | 288 | u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 31dcd9142d54..dc8d1a90971f 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void) | |||
417 | module_init(agp_ali_init); | 417 | module_init(agp_ali_init); |
418 | module_exit(agp_ali_cleanup); | 418 | module_exit(agp_ali_cleanup); |
419 | 419 | ||
420 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 420 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
421 | MODULE_LICENSE("GPL and additional rights"); | 421 | MODULE_LICENSE("GPL and additional rights"); |
422 | 422 | ||
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index 5da89f6c6c25..5ea4da8e9954 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c | |||
@@ -143,7 +143,9 @@ struct agp_bridge_driver alpha_core_agp_driver = { | |||
143 | .alloc_by_type = agp_generic_alloc_by_type, | 143 | .alloc_by_type = agp_generic_alloc_by_type, |
144 | .free_by_type = agp_generic_free_by_type, | 144 | .free_by_type = agp_generic_free_by_type, |
145 | .agp_alloc_page = agp_generic_alloc_page, | 145 | .agp_alloc_page = agp_generic_alloc_page, |
146 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
146 | .agp_destroy_page = agp_generic_destroy_page, | 147 | .agp_destroy_page = agp_generic_destroy_page, |
148 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
147 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 149 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
148 | }; | 150 | }; |
149 | 151 | ||
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e280531843be..3f98254b911f 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -223,12 +223,14 @@ static int amd_irongate_configure(void) | |||
223 | 223 | ||
224 | current_size = A_SIZE_LVL2(agp_bridge->current_size); | 224 | current_size = A_SIZE_LVL2(agp_bridge->current_size); |
225 | 225 | ||
226 | /* Get the memory mapped registers */ | 226 | if (!amd_irongate_private.registers) { |
227 | pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); | 227 | /* Get the memory mapped registers */ |
228 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 228 | pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); |
229 | amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); | 229 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
230 | if (!amd_irongate_private.registers) | 230 | amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); |
231 | return -ENOMEM; | 231 | if (!amd_irongate_private.registers) |
232 | return -ENOMEM; | ||
233 | } | ||
232 | 234 | ||
233 | /* Write out the address of the gatt table */ | 235 | /* Write out the address of the gatt table */ |
234 | writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); | 236 | writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); |
@@ -386,7 +388,9 @@ static const struct agp_bridge_driver amd_irongate_driver = { | |||
386 | .alloc_by_type = agp_generic_alloc_by_type, | 388 | .alloc_by_type = agp_generic_alloc_by_type, |
387 | .free_by_type = agp_generic_free_by_type, | 389 | .free_by_type = agp_generic_free_by_type, |
388 | .agp_alloc_page = agp_generic_alloc_page, | 390 | .agp_alloc_page = agp_generic_alloc_page, |
391 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
389 | .agp_destroy_page = agp_generic_destroy_page, | 392 | .agp_destroy_page = agp_generic_destroy_page, |
393 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
390 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 394 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
391 | }; | 395 | }; |
392 | 396 | ||
@@ -490,6 +494,26 @@ static void __devexit agp_amdk7_remove(struct pci_dev *pdev) | |||
490 | agp_put_bridge(bridge); | 494 | agp_put_bridge(bridge); |
491 | } | 495 | } |
492 | 496 | ||
497 | #ifdef CONFIG_PM | ||
498 | |||
499 | static int agp_amdk7_suspend(struct pci_dev *pdev, pm_message_t state) | ||
500 | { | ||
501 | pci_save_state(pdev); | ||
502 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int agp_amdk7_resume(struct pci_dev *pdev) | ||
508 | { | ||
509 | pci_set_power_state(pdev, PCI_D0); | ||
510 | pci_restore_state(pdev); | ||
511 | |||
512 | return amd_irongate_driver.configure(); | ||
513 | } | ||
514 | |||
515 | #endif /* CONFIG_PM */ | ||
516 | |||
493 | /* must be the same order as name table above */ | 517 | /* must be the same order as name table above */ |
494 | static struct pci_device_id agp_amdk7_pci_table[] = { | 518 | static struct pci_device_id agp_amdk7_pci_table[] = { |
495 | { | 519 | { |
@@ -526,6 +550,10 @@ static struct pci_driver agp_amdk7_pci_driver = { | |||
526 | .id_table = agp_amdk7_pci_table, | 550 | .id_table = agp_amdk7_pci_table, |
527 | .probe = agp_amdk7_probe, | 551 | .probe = agp_amdk7_probe, |
528 | .remove = agp_amdk7_remove, | 552 | .remove = agp_amdk7_remove, |
553 | #ifdef CONFIG_PM | ||
554 | .suspend = agp_amdk7_suspend, | ||
555 | .resume = agp_amdk7_resume, | ||
556 | #endif | ||
529 | }; | 557 | }; |
530 | 558 | ||
531 | static int __init agp_amdk7_init(void) | 559 | static int __init agp_amdk7_init(void) |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 7495c522d8e4..52f4361eb6e4 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -224,7 +224,9 @@ static const struct agp_bridge_driver amd_8151_driver = { | |||
224 | .alloc_by_type = agp_generic_alloc_by_type, | 224 | .alloc_by_type = agp_generic_alloc_by_type, |
225 | .free_by_type = agp_generic_free_by_type, | 225 | .free_by_type = agp_generic_free_by_type, |
226 | .agp_alloc_page = agp_generic_alloc_page, | 226 | .agp_alloc_page = agp_generic_alloc_page, |
227 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
227 | .agp_destroy_page = agp_generic_destroy_page, | 228 | .agp_destroy_page = agp_generic_destroy_page, |
229 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
228 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 230 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
229 | }; | 231 | }; |
230 | 232 | ||
@@ -770,6 +772,6 @@ module_init(agp_amd64_init); | |||
770 | module_exit(agp_amd64_cleanup); | 772 | module_exit(agp_amd64_cleanup); |
771 | #endif | 773 | #endif |
772 | 774 | ||
773 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen"); | 775 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); |
774 | module_param(agp_try_unsupported, bool, 0); | 776 | module_param(agp_try_unsupported, bool, 0); |
775 | MODULE_LICENSE("GPL"); | 777 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 6ecbcafb34b1..f1537eece07f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -418,7 +418,9 @@ static const struct agp_bridge_driver ati_generic_bridge = { | |||
418 | .alloc_by_type = agp_generic_alloc_by_type, | 418 | .alloc_by_type = agp_generic_alloc_by_type, |
419 | .free_by_type = agp_generic_free_by_type, | 419 | .free_by_type = agp_generic_free_by_type, |
420 | .agp_alloc_page = agp_generic_alloc_page, | 420 | .agp_alloc_page = agp_generic_alloc_page, |
421 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
421 | .agp_destroy_page = agp_generic_destroy_page, | 422 | .agp_destroy_page = agp_generic_destroy_page, |
423 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
422 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 424 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
423 | }; | 425 | }; |
424 | 426 | ||
@@ -559,6 +561,6 @@ static void __exit agp_ati_cleanup(void) | |||
559 | module_init(agp_ati_init); | 561 | module_init(agp_ati_init); |
560 | module_exit(agp_ati_cleanup); | 562 | module_exit(agp_ati_cleanup); |
561 | 563 | ||
562 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 564 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
563 | MODULE_LICENSE("GPL and additional rights"); | 565 | MODULE_LICENSE("GPL and additional rights"); |
564 | 566 | ||
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 3a3cc03d401c..8c617ad7497f 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -349,7 +349,7 @@ static __init int agp_setup(char *s) | |||
349 | __setup("agp=", agp_setup); | 349 | __setup("agp=", agp_setup); |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 352 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
353 | MODULE_DESCRIPTION("AGP GART driver"); | 353 | MODULE_DESCRIPTION("AGP GART driver"); |
354 | MODULE_LICENSE("GPL and additional rights"); | 354 | MODULE_LICENSE("GPL and additional rights"); |
355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); | 355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); |
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 8ca6f262ef85..453543a1f293 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
@@ -335,7 +335,9 @@ static const struct agp_bridge_driver efficeon_driver = { | |||
335 | .alloc_by_type = agp_generic_alloc_by_type, | 335 | .alloc_by_type = agp_generic_alloc_by_type, |
336 | .free_by_type = agp_generic_free_by_type, | 336 | .free_by_type = agp_generic_free_by_type, |
337 | .agp_alloc_page = agp_generic_alloc_page, | 337 | .agp_alloc_page = agp_generic_alloc_page, |
338 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
338 | .agp_destroy_page = agp_generic_destroy_page, | 339 | .agp_destroy_page = agp_generic_destroy_page, |
340 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
339 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 341 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
340 | }; | 342 | }; |
341 | 343 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 118dbde25dc7..10d6cbd7c05e 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -201,14 +201,22 @@ void agp_free_memory(struct agp_memory *curr) | |||
201 | return; | 201 | return; |
202 | } | 202 | } |
203 | if (curr->page_count != 0) { | 203 | if (curr->page_count != 0) { |
204 | for (i = 0; i < curr->page_count; i++) { | 204 | if (curr->bridge->driver->agp_destroy_pages) { |
205 | curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]); | 205 | curr->bridge->driver->agp_destroy_pages(curr); |
206 | curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], | 206 | } else { |
207 | AGP_PAGE_DESTROY_UNMAP); | 207 | |
208 | } | 208 | for (i = 0; i < curr->page_count; i++) { |
209 | for (i = 0; i < curr->page_count; i++) { | 209 | curr->memory[i] = (unsigned long)gart_to_virt( |
210 | curr->bridge->driver->agp_destroy_page((void *)curr->memory[i], | 210 | curr->memory[i]); |
211 | AGP_PAGE_DESTROY_FREE); | 211 | curr->bridge->driver->agp_destroy_page( |
212 | (void *)curr->memory[i], | ||
213 | AGP_PAGE_DESTROY_UNMAP); | ||
214 | } | ||
215 | for (i = 0; i < curr->page_count; i++) { | ||
216 | curr->bridge->driver->agp_destroy_page( | ||
217 | (void *)curr->memory[i], | ||
218 | AGP_PAGE_DESTROY_FREE); | ||
219 | } | ||
212 | } | 220 | } |
213 | } | 221 | } |
214 | agp_free_key(curr->key); | 222 | agp_free_key(curr->key); |
@@ -264,6 +272,15 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
264 | if (new == NULL) | 272 | if (new == NULL) |
265 | return NULL; | 273 | return NULL; |
266 | 274 | ||
275 | if (bridge->driver->agp_alloc_pages) { | ||
276 | if (bridge->driver->agp_alloc_pages(bridge, new, page_count)) { | ||
277 | agp_free_memory(new); | ||
278 | return NULL; | ||
279 | } | ||
280 | new->bridge = bridge; | ||
281 | return new; | ||
282 | } | ||
283 | |||
267 | for (i = 0; i < page_count; i++) { | 284 | for (i = 0; i < page_count; i++) { |
268 | void *addr = bridge->driver->agp_alloc_page(bridge); | 285 | void *addr = bridge->driver->agp_alloc_page(bridge); |
269 | 286 | ||
@@ -1203,6 +1220,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user); | |||
1203 | * against a maximum value. | 1220 | * against a maximum value. |
1204 | */ | 1221 | */ |
1205 | 1222 | ||
1223 | int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages) | ||
1224 | { | ||
1225 | struct page * page; | ||
1226 | int i, ret = -ENOMEM; | ||
1227 | |||
1228 | for (i = 0; i < num_pages; i++) { | ||
1229 | page = alloc_page(GFP_KERNEL | GFP_DMA32); | ||
1230 | /* agp_free_memory() needs gart address */ | ||
1231 | if (page == NULL) | ||
1232 | goto out; | ||
1233 | |||
1234 | #ifndef CONFIG_X86 | ||
1235 | map_page_into_agp(page); | ||
1236 | #endif | ||
1237 | get_page(page); | ||
1238 | atomic_inc(&agp_bridge->current_memory_agp); | ||
1239 | |||
1240 | /* set_memory_array_uc() needs virtual address */ | ||
1241 | mem->memory[i] = (unsigned long)page_address(page); | ||
1242 | mem->page_count++; | ||
1243 | } | ||
1244 | |||
1245 | #ifdef CONFIG_X86 | ||
1246 | set_memory_array_uc(mem->memory, num_pages); | ||
1247 | #endif | ||
1248 | ret = 0; | ||
1249 | out: | ||
1250 | for (i = 0; i < mem->page_count; i++) | ||
1251 | mem->memory[i] = virt_to_gart((void *)mem->memory[i]); | ||
1252 | return ret; | ||
1253 | } | ||
1254 | EXPORT_SYMBOL(agp_generic_alloc_pages); | ||
1255 | |||
1206 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1256 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
1207 | { | 1257 | { |
1208 | struct page * page; | 1258 | struct page * page; |
@@ -1219,6 +1269,37 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
1219 | } | 1269 | } |
1220 | EXPORT_SYMBOL(agp_generic_alloc_page); | 1270 | EXPORT_SYMBOL(agp_generic_alloc_page); |
1221 | 1271 | ||
1272 | void agp_generic_destroy_pages(struct agp_memory *mem) | ||
1273 | { | ||
1274 | int i; | ||
1275 | void *addr; | ||
1276 | struct page *page; | ||
1277 | |||
1278 | if (!mem) | ||
1279 | return; | ||
1280 | |||
1281 | for (i = 0; i < mem->page_count; i++) | ||
1282 | mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]); | ||
1283 | |||
1284 | #ifdef CONFIG_X86 | ||
1285 | set_memory_array_wb(mem->memory, mem->page_count); | ||
1286 | #endif | ||
1287 | |||
1288 | for (i = 0; i < mem->page_count; i++) { | ||
1289 | addr = (void *)mem->memory[i]; | ||
1290 | page = virt_to_page(addr); | ||
1291 | |||
1292 | #ifndef CONFIG_X86 | ||
1293 | unmap_page_from_agp(page); | ||
1294 | #endif | ||
1295 | |||
1296 | put_page(page); | ||
1297 | free_page((unsigned long)addr); | ||
1298 | atomic_dec(&agp_bridge->current_memory_agp); | ||
1299 | mem->memory[i] = 0; | ||
1300 | } | ||
1301 | } | ||
1302 | EXPORT_SYMBOL(agp_generic_destroy_pages); | ||
1222 | 1303 | ||
1223 | void agp_generic_destroy_page(void *addr, int flags) | 1304 | void agp_generic_destroy_page(void *addr, int flags) |
1224 | { | 1305 | { |
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 80d7317f85c9..183ac3fe44fb 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
@@ -435,7 +435,9 @@ const struct agp_bridge_driver hp_zx1_driver = { | |||
435 | .alloc_by_type = agp_generic_alloc_by_type, | 435 | .alloc_by_type = agp_generic_alloc_by_type, |
436 | .free_by_type = agp_generic_free_by_type, | 436 | .free_by_type = agp_generic_free_by_type, |
437 | .agp_alloc_page = agp_generic_alloc_page, | 437 | .agp_alloc_page = agp_generic_alloc_page, |
438 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
438 | .agp_destroy_page = agp_generic_destroy_page, | 439 | .agp_destroy_page = agp_generic_destroy_page, |
440 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
439 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 441 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
440 | .cant_use_aperture = true, | 442 | .cant_use_aperture = true, |
441 | }; | 443 | }; |
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index e587eebebc67..10da687d131a 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
@@ -575,7 +575,9 @@ const struct agp_bridge_driver intel_i460_driver = { | |||
575 | .insert_memory = i460_insert_memory_small_io_page, | 575 | .insert_memory = i460_insert_memory_small_io_page, |
576 | .remove_memory = i460_remove_memory_small_io_page, | 576 | .remove_memory = i460_remove_memory_small_io_page, |
577 | .agp_alloc_page = agp_generic_alloc_page, | 577 | .agp_alloc_page = agp_generic_alloc_page, |
578 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
578 | .agp_destroy_page = agp_generic_destroy_page, | 579 | .agp_destroy_page = agp_generic_destroy_page, |
580 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
579 | #endif | 581 | #endif |
580 | .alloc_by_type = agp_generic_alloc_by_type, | 582 | .alloc_by_type = agp_generic_alloc_by_type, |
581 | .free_by_type = agp_generic_free_by_type, | 583 | .free_by_type = agp_generic_free_by_type, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 016fdf0623a4..9cf6e9bb017e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -54,8 +54,7 @@ | |||
54 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ | 54 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ |
55 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ | 55 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ |
56 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ | 56 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ |
57 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ | 57 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) |
58 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) | ||
59 | 58 | ||
60 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | 59 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ |
61 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | 60 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ |
@@ -63,7 +62,8 @@ | |||
63 | 62 | ||
64 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ | 63 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ |
65 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | 64 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ |
66 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB) | 65 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ |
66 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) | ||
67 | 67 | ||
68 | extern int agp_memory_reserved; | 68 | extern int agp_memory_reserved; |
69 | 69 | ||
@@ -214,8 +214,8 @@ static int intel_i810_configure(void) | |||
214 | if (agp_bridge->driver->needs_scratch_page) { | 214 | if (agp_bridge->driver->needs_scratch_page) { |
215 | for (i = 0; i < current_size->num_entries; i++) { | 215 | for (i = 0; i < current_size->num_entries; i++) { |
216 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 216 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); |
217 | readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */ | ||
218 | } | 217 | } |
218 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI posting. */ | ||
219 | } | 219 | } |
220 | global_cache_flush(); | 220 | global_cache_flush(); |
221 | return 0; | 221 | return 0; |
@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(void) | |||
525 | size += 4; | 525 | size += 4; |
526 | } else if (IS_G4X) { | 526 | } else if (IS_G4X) { |
527 | /* On 4 series hardware, GTT stolen is separate from graphics | 527 | /* On 4 series hardware, GTT stolen is separate from graphics |
528 | * stolen, ignore it in stolen gtt entries counting */ | 528 | * stolen, ignore it in stolen gtt entries counting. However, |
529 | size = 0; | 529 | * 4KB of the stolen memory doesn't get mapped to the GTT. |
530 | */ | ||
531 | size = 4; | ||
530 | } else { | 532 | } else { |
531 | /* On previous hardware, the GTT size was just what was | 533 | /* On previous hardware, the GTT size was just what was |
532 | * required to map the aperture. | 534 | * required to map the aperture. |
@@ -773,8 +775,8 @@ static int intel_i830_configure(void) | |||
773 | if (agp_bridge->driver->needs_scratch_page) { | 775 | if (agp_bridge->driver->needs_scratch_page) { |
774 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { | 776 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { |
775 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 777 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); |
776 | readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */ | ||
777 | } | 778 | } |
779 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */ | ||
778 | } | 780 | } |
779 | 781 | ||
780 | global_cache_flush(); | 782 | global_cache_flush(); |
@@ -989,8 +991,8 @@ static int intel_i915_configure(void) | |||
989 | if (agp_bridge->driver->needs_scratch_page) { | 991 | if (agp_bridge->driver->needs_scratch_page) { |
990 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { | 992 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { |
991 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | 993 | writel(agp_bridge->scratch_page, intel_private.gtt+i); |
992 | readl(intel_private.gtt+i); /* PCI Posting. */ | ||
993 | } | 994 | } |
995 | readl(intel_private.gtt+i-1); /* PCI Posting. */ | ||
994 | } | 996 | } |
995 | 997 | ||
996 | global_cache_flush(); | 998 | global_cache_flush(); |
@@ -1711,7 +1713,9 @@ static const struct agp_bridge_driver intel_generic_driver = { | |||
1711 | .alloc_by_type = agp_generic_alloc_by_type, | 1713 | .alloc_by_type = agp_generic_alloc_by_type, |
1712 | .free_by_type = agp_generic_free_by_type, | 1714 | .free_by_type = agp_generic_free_by_type, |
1713 | .agp_alloc_page = agp_generic_alloc_page, | 1715 | .agp_alloc_page = agp_generic_alloc_page, |
1716 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1714 | .agp_destroy_page = agp_generic_destroy_page, | 1717 | .agp_destroy_page = agp_generic_destroy_page, |
1718 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1715 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1719 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1716 | }; | 1720 | }; |
1717 | 1721 | ||
@@ -1736,7 +1740,9 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1736 | .alloc_by_type = intel_i810_alloc_by_type, | 1740 | .alloc_by_type = intel_i810_alloc_by_type, |
1737 | .free_by_type = intel_i810_free_by_type, | 1741 | .free_by_type = intel_i810_free_by_type, |
1738 | .agp_alloc_page = agp_generic_alloc_page, | 1742 | .agp_alloc_page = agp_generic_alloc_page, |
1743 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1739 | .agp_destroy_page = agp_generic_destroy_page, | 1744 | .agp_destroy_page = agp_generic_destroy_page, |
1745 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1740 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1746 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1741 | }; | 1747 | }; |
1742 | 1748 | ||
@@ -1760,7 +1766,9 @@ static const struct agp_bridge_driver intel_815_driver = { | |||
1760 | .alloc_by_type = agp_generic_alloc_by_type, | 1766 | .alloc_by_type = agp_generic_alloc_by_type, |
1761 | .free_by_type = agp_generic_free_by_type, | 1767 | .free_by_type = agp_generic_free_by_type, |
1762 | .agp_alloc_page = agp_generic_alloc_page, | 1768 | .agp_alloc_page = agp_generic_alloc_page, |
1769 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1763 | .agp_destroy_page = agp_generic_destroy_page, | 1770 | .agp_destroy_page = agp_generic_destroy_page, |
1771 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1764 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1772 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1765 | }; | 1773 | }; |
1766 | 1774 | ||
@@ -1785,7 +1793,9 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1785 | .alloc_by_type = intel_i830_alloc_by_type, | 1793 | .alloc_by_type = intel_i830_alloc_by_type, |
1786 | .free_by_type = intel_i810_free_by_type, | 1794 | .free_by_type = intel_i810_free_by_type, |
1787 | .agp_alloc_page = agp_generic_alloc_page, | 1795 | .agp_alloc_page = agp_generic_alloc_page, |
1796 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1788 | .agp_destroy_page = agp_generic_destroy_page, | 1797 | .agp_destroy_page = agp_generic_destroy_page, |
1798 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1789 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1799 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1790 | .chipset_flush = intel_i830_chipset_flush, | 1800 | .chipset_flush = intel_i830_chipset_flush, |
1791 | }; | 1801 | }; |
@@ -1810,7 +1820,9 @@ static const struct agp_bridge_driver intel_820_driver = { | |||
1810 | .alloc_by_type = agp_generic_alloc_by_type, | 1820 | .alloc_by_type = agp_generic_alloc_by_type, |
1811 | .free_by_type = agp_generic_free_by_type, | 1821 | .free_by_type = agp_generic_free_by_type, |
1812 | .agp_alloc_page = agp_generic_alloc_page, | 1822 | .agp_alloc_page = agp_generic_alloc_page, |
1823 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1813 | .agp_destroy_page = agp_generic_destroy_page, | 1824 | .agp_destroy_page = agp_generic_destroy_page, |
1825 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1814 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1826 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1815 | }; | 1827 | }; |
1816 | 1828 | ||
@@ -1834,7 +1846,9 @@ static const struct agp_bridge_driver intel_830mp_driver = { | |||
1834 | .alloc_by_type = agp_generic_alloc_by_type, | 1846 | .alloc_by_type = agp_generic_alloc_by_type, |
1835 | .free_by_type = agp_generic_free_by_type, | 1847 | .free_by_type = agp_generic_free_by_type, |
1836 | .agp_alloc_page = agp_generic_alloc_page, | 1848 | .agp_alloc_page = agp_generic_alloc_page, |
1849 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1837 | .agp_destroy_page = agp_generic_destroy_page, | 1850 | .agp_destroy_page = agp_generic_destroy_page, |
1851 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1838 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1852 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1839 | }; | 1853 | }; |
1840 | 1854 | ||
@@ -1858,7 +1872,9 @@ static const struct agp_bridge_driver intel_840_driver = { | |||
1858 | .alloc_by_type = agp_generic_alloc_by_type, | 1872 | .alloc_by_type = agp_generic_alloc_by_type, |
1859 | .free_by_type = agp_generic_free_by_type, | 1873 | .free_by_type = agp_generic_free_by_type, |
1860 | .agp_alloc_page = agp_generic_alloc_page, | 1874 | .agp_alloc_page = agp_generic_alloc_page, |
1875 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1861 | .agp_destroy_page = agp_generic_destroy_page, | 1876 | .agp_destroy_page = agp_generic_destroy_page, |
1877 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1862 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1878 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1863 | }; | 1879 | }; |
1864 | 1880 | ||
@@ -1882,7 +1898,9 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
1882 | .alloc_by_type = agp_generic_alloc_by_type, | 1898 | .alloc_by_type = agp_generic_alloc_by_type, |
1883 | .free_by_type = agp_generic_free_by_type, | 1899 | .free_by_type = agp_generic_free_by_type, |
1884 | .agp_alloc_page = agp_generic_alloc_page, | 1900 | .agp_alloc_page = agp_generic_alloc_page, |
1901 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1885 | .agp_destroy_page = agp_generic_destroy_page, | 1902 | .agp_destroy_page = agp_generic_destroy_page, |
1903 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1886 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1904 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1887 | .chipset_flush = intel_i830_chipset_flush, | 1905 | .chipset_flush = intel_i830_chipset_flush, |
1888 | }; | 1906 | }; |
@@ -1907,7 +1925,9 @@ static const struct agp_bridge_driver intel_850_driver = { | |||
1907 | .alloc_by_type = agp_generic_alloc_by_type, | 1925 | .alloc_by_type = agp_generic_alloc_by_type, |
1908 | .free_by_type = agp_generic_free_by_type, | 1926 | .free_by_type = agp_generic_free_by_type, |
1909 | .agp_alloc_page = agp_generic_alloc_page, | 1927 | .agp_alloc_page = agp_generic_alloc_page, |
1928 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1910 | .agp_destroy_page = agp_generic_destroy_page, | 1929 | .agp_destroy_page = agp_generic_destroy_page, |
1930 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1911 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1931 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1912 | }; | 1932 | }; |
1913 | 1933 | ||
@@ -1931,7 +1951,9 @@ static const struct agp_bridge_driver intel_860_driver = { | |||
1931 | .alloc_by_type = agp_generic_alloc_by_type, | 1951 | .alloc_by_type = agp_generic_alloc_by_type, |
1932 | .free_by_type = agp_generic_free_by_type, | 1952 | .free_by_type = agp_generic_free_by_type, |
1933 | .agp_alloc_page = agp_generic_alloc_page, | 1953 | .agp_alloc_page = agp_generic_alloc_page, |
1954 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1934 | .agp_destroy_page = agp_generic_destroy_page, | 1955 | .agp_destroy_page = agp_generic_destroy_page, |
1956 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1935 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1957 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1936 | }; | 1958 | }; |
1937 | 1959 | ||
@@ -1956,7 +1978,9 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1956 | .alloc_by_type = intel_i830_alloc_by_type, | 1978 | .alloc_by_type = intel_i830_alloc_by_type, |
1957 | .free_by_type = intel_i810_free_by_type, | 1979 | .free_by_type = intel_i810_free_by_type, |
1958 | .agp_alloc_page = agp_generic_alloc_page, | 1980 | .agp_alloc_page = agp_generic_alloc_page, |
1981 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1959 | .agp_destroy_page = agp_generic_destroy_page, | 1982 | .agp_destroy_page = agp_generic_destroy_page, |
1983 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1960 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1984 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1961 | .chipset_flush = intel_i915_chipset_flush, | 1985 | .chipset_flush = intel_i915_chipset_flush, |
1962 | }; | 1986 | }; |
@@ -1982,7 +2006,9 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1982 | .alloc_by_type = intel_i830_alloc_by_type, | 2006 | .alloc_by_type = intel_i830_alloc_by_type, |
1983 | .free_by_type = intel_i810_free_by_type, | 2007 | .free_by_type = intel_i810_free_by_type, |
1984 | .agp_alloc_page = agp_generic_alloc_page, | 2008 | .agp_alloc_page = agp_generic_alloc_page, |
2009 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1985 | .agp_destroy_page = agp_generic_destroy_page, | 2010 | .agp_destroy_page = agp_generic_destroy_page, |
2011 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1986 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2012 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1987 | .chipset_flush = intel_i915_chipset_flush, | 2013 | .chipset_flush = intel_i915_chipset_flush, |
1988 | }; | 2014 | }; |
@@ -2007,7 +2033,9 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
2007 | .alloc_by_type = agp_generic_alloc_by_type, | 2033 | .alloc_by_type = agp_generic_alloc_by_type, |
2008 | .free_by_type = agp_generic_free_by_type, | 2034 | .free_by_type = agp_generic_free_by_type, |
2009 | .agp_alloc_page = agp_generic_alloc_page, | 2035 | .agp_alloc_page = agp_generic_alloc_page, |
2036 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2010 | .agp_destroy_page = agp_generic_destroy_page, | 2037 | .agp_destroy_page = agp_generic_destroy_page, |
2038 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
2011 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 2039 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
2012 | }; | 2040 | }; |
2013 | 2041 | ||
@@ -2032,7 +2060,9 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
2032 | .alloc_by_type = intel_i830_alloc_by_type, | 2060 | .alloc_by_type = intel_i830_alloc_by_type, |
2033 | .free_by_type = intel_i810_free_by_type, | 2061 | .free_by_type = intel_i810_free_by_type, |
2034 | .agp_alloc_page = agp_generic_alloc_page, | 2062 | .agp_alloc_page = agp_generic_alloc_page, |
2063 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2035 | .agp_destroy_page = agp_generic_destroy_page, | 2064 | .agp_destroy_page = agp_generic_destroy_page, |
2065 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
2036 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2066 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2037 | .chipset_flush = intel_i915_chipset_flush, | 2067 | .chipset_flush = intel_i915_chipset_flush, |
2038 | }; | 2068 | }; |
@@ -2360,5 +2390,5 @@ static void __exit agp_intel_cleanup(void) | |||
2360 | module_init(agp_intel_init); | 2390 | module_init(agp_intel_init); |
2361 | module_exit(agp_intel_cleanup); | 2391 | module_exit(agp_intel_cleanup); |
2362 | 2392 | ||
2363 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 2393 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
2364 | MODULE_LICENSE("GPL and additional rights"); | 2394 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index eaceb61ba2dc..16acee2de117 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Nvidia AGPGART routines. | 2 | * Nvidia AGPGART routines. |
3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up | 3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up |
4 | * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk> | 4 | * to work in 2.5 by Dave Jones <davej@redhat.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
@@ -201,10 +201,15 @@ extern int agp_memory_reserved; | |||
201 | static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | 201 | static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type) |
202 | { | 202 | { |
203 | int i, j; | 203 | int i, j; |
204 | int mask_type; | ||
204 | 205 | ||
205 | if ((type != 0) || (mem->type != 0)) | 206 | mask_type = agp_generic_type_to_mask_type(mem->bridge, type); |
207 | if (mask_type != 0 || type != mem->type) | ||
206 | return -EINVAL; | 208 | return -EINVAL; |
207 | 209 | ||
210 | if (mem->page_count == 0) | ||
211 | return 0; | ||
212 | |||
208 | if ((pg_start + mem->page_count) > | 213 | if ((pg_start + mem->page_count) > |
209 | (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE)) | 214 | (nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE)) |
210 | return -EINVAL; | 215 | return -EINVAL; |
@@ -220,10 +225,13 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type | |||
220 | } | 225 | } |
221 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 226 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
222 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 227 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
223 | mem->memory[i], mem->type), | 228 | mem->memory[i], mask_type), |
224 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); | 229 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); |
225 | readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j); /* PCI Posting. */ | ||
226 | } | 230 | } |
231 | |||
232 | /* PCI Posting. */ | ||
233 | readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j - 1); | ||
234 | |||
227 | agp_bridge->driver->tlb_flush(mem); | 235 | agp_bridge->driver->tlb_flush(mem); |
228 | return 0; | 236 | return 0; |
229 | } | 237 | } |
@@ -233,9 +241,15 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type | |||
233 | { | 241 | { |
234 | int i; | 242 | int i; |
235 | 243 | ||
236 | if ((type != 0) || (mem->type != 0)) | 244 | int mask_type; |
245 | |||
246 | mask_type = agp_generic_type_to_mask_type(mem->bridge, type); | ||
247 | if (mask_type != 0 || type != mem->type) | ||
237 | return -EINVAL; | 248 | return -EINVAL; |
238 | 249 | ||
250 | if (mem->page_count == 0) | ||
251 | return 0; | ||
252 | |||
239 | for (i = pg_start; i < (mem->page_count + pg_start); i++) | 253 | for (i = pg_start; i < (mem->page_count + pg_start); i++) |
240 | writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i); | 254 | writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i); |
241 | 255 | ||
@@ -312,7 +326,9 @@ static const struct agp_bridge_driver nvidia_driver = { | |||
312 | .alloc_by_type = agp_generic_alloc_by_type, | 326 | .alloc_by_type = agp_generic_alloc_by_type, |
313 | .free_by_type = agp_generic_free_by_type, | 327 | .free_by_type = agp_generic_free_by_type, |
314 | .agp_alloc_page = agp_generic_alloc_page, | 328 | .agp_alloc_page = agp_generic_alloc_page, |
329 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
315 | .agp_destroy_page = agp_generic_destroy_page, | 330 | .agp_destroy_page = agp_generic_destroy_page, |
331 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
316 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 332 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
317 | }; | 333 | }; |
318 | 334 | ||
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index f4bbcb273208..db60539bf67a 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -224,7 +224,9 @@ static const struct agp_bridge_driver parisc_agp_driver = { | |||
224 | .alloc_by_type = agp_generic_alloc_by_type, | 224 | .alloc_by_type = agp_generic_alloc_by_type, |
225 | .free_by_type = agp_generic_free_by_type, | 225 | .free_by_type = agp_generic_free_by_type, |
226 | .agp_alloc_page = agp_generic_alloc_page, | 226 | .agp_alloc_page = agp_generic_alloc_page, |
227 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
227 | .agp_destroy_page = agp_generic_destroy_page, | 228 | .agp_destroy_page = agp_generic_destroy_page, |
229 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
228 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 230 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
229 | .cant_use_aperture = true, | 231 | .cant_use_aperture = true, |
230 | }; | 232 | }; |
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 2587ef96a960..6c3837a0184d 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -140,7 +140,9 @@ static struct agp_bridge_driver sis_driver = { | |||
140 | .alloc_by_type = agp_generic_alloc_by_type, | 140 | .alloc_by_type = agp_generic_alloc_by_type, |
141 | .free_by_type = agp_generic_free_by_type, | 141 | .free_by_type = agp_generic_free_by_type, |
142 | .agp_alloc_page = agp_generic_alloc_page, | 142 | .agp_alloc_page = agp_generic_alloc_page, |
143 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
143 | .agp_destroy_page = agp_generic_destroy_page, | 144 | .agp_destroy_page = agp_generic_destroy_page, |
145 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
144 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 146 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
145 | }; | 147 | }; |
146 | 148 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 2fb27fe4c10c..6224df8b7f0a 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -437,7 +437,9 @@ static const struct agp_bridge_driver sworks_driver = { | |||
437 | .alloc_by_type = agp_generic_alloc_by_type, | 437 | .alloc_by_type = agp_generic_alloc_by_type, |
438 | .free_by_type = agp_generic_free_by_type, | 438 | .free_by_type = agp_generic_free_by_type, |
439 | .agp_alloc_page = agp_generic_alloc_page, | 439 | .agp_alloc_page = agp_generic_alloc_page, |
440 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
440 | .agp_destroy_page = agp_generic_destroy_page, | 441 | .agp_destroy_page = agp_generic_destroy_page, |
442 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
441 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 443 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
442 | }; | 444 | }; |
443 | 445 | ||
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index eef72709ec53..0f004b65ec03 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -509,7 +509,9 @@ const struct agp_bridge_driver uninorth_agp_driver = { | |||
509 | .alloc_by_type = agp_generic_alloc_by_type, | 509 | .alloc_by_type = agp_generic_alloc_by_type, |
510 | .free_by_type = agp_generic_free_by_type, | 510 | .free_by_type = agp_generic_free_by_type, |
511 | .agp_alloc_page = agp_generic_alloc_page, | 511 | .agp_alloc_page = agp_generic_alloc_page, |
512 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
512 | .agp_destroy_page = agp_generic_destroy_page, | 513 | .agp_destroy_page = agp_generic_destroy_page, |
514 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
513 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 515 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
514 | .cant_use_aperture = true, | 516 | .cant_use_aperture = true, |
515 | }; | 517 | }; |
@@ -534,7 +536,9 @@ const struct agp_bridge_driver u3_agp_driver = { | |||
534 | .alloc_by_type = agp_generic_alloc_by_type, | 536 | .alloc_by_type = agp_generic_alloc_by_type, |
535 | .free_by_type = agp_generic_free_by_type, | 537 | .free_by_type = agp_generic_free_by_type, |
536 | .agp_alloc_page = agp_generic_alloc_page, | 538 | .agp_alloc_page = agp_generic_alloc_page, |
539 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
537 | .agp_destroy_page = agp_generic_destroy_page, | 540 | .agp_destroy_page = agp_generic_destroy_page, |
541 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
538 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 542 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
539 | .cant_use_aperture = true, | 543 | .cant_use_aperture = true, |
540 | .needs_scratch_page = true, | 544 | .needs_scratch_page = true, |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 7b36476dff41..d3bd243867fc 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -190,7 +190,9 @@ static const struct agp_bridge_driver via_agp3_driver = { | |||
190 | .alloc_by_type = agp_generic_alloc_by_type, | 190 | .alloc_by_type = agp_generic_alloc_by_type, |
191 | .free_by_type = agp_generic_free_by_type, | 191 | .free_by_type = agp_generic_free_by_type, |
192 | .agp_alloc_page = agp_generic_alloc_page, | 192 | .agp_alloc_page = agp_generic_alloc_page, |
193 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
193 | .agp_destroy_page = agp_generic_destroy_page, | 194 | .agp_destroy_page = agp_generic_destroy_page, |
195 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
194 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 196 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
195 | }; | 197 | }; |
196 | 198 | ||
@@ -214,7 +216,9 @@ static const struct agp_bridge_driver via_driver = { | |||
214 | .alloc_by_type = agp_generic_alloc_by_type, | 216 | .alloc_by_type = agp_generic_alloc_by_type, |
215 | .free_by_type = agp_generic_free_by_type, | 217 | .free_by_type = agp_generic_free_by_type, |
216 | .agp_alloc_page = agp_generic_alloc_page, | 218 | .agp_alloc_page = agp_generic_alloc_page, |
219 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
217 | .agp_destroy_page = agp_generic_destroy_page, | 220 | .agp_destroy_page = agp_generic_destroy_page, |
221 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
218 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 222 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
219 | }; | 223 | }; |
220 | 224 | ||
@@ -591,4 +595,4 @@ module_init(agp_via_init); | |||
591 | module_exit(agp_via_cleanup); | 595 | module_exit(agp_via_cleanup); |
592 | 596 | ||
593 | MODULE_LICENSE("GPL"); | 597 | MODULE_LICENSE("GPL"); |
594 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 598 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 6e763e3f5a81..98821f97583c 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -837,9 +837,6 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch) | |||
837 | struct async_struct *info; | 837 | struct async_struct *info; |
838 | unsigned long flags; | 838 | unsigned long flags; |
839 | 839 | ||
840 | if (!tty) | ||
841 | return 0; | ||
842 | |||
843 | info = tty->driver_data; | 840 | info = tty->driver_data; |
844 | 841 | ||
845 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | 842 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) |
@@ -892,9 +889,6 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count | |||
892 | struct async_struct *info; | 889 | struct async_struct *info; |
893 | unsigned long flags; | 890 | unsigned long flags; |
894 | 891 | ||
895 | if (!tty) | ||
896 | return 0; | ||
897 | |||
898 | info = tty->driver_data; | 892 | info = tty->driver_data; |
899 | 893 | ||
900 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 894 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 31d08b641f5b..05674febb0c6 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -478,7 +478,7 @@ static int do_ac_read(int IndexCard, char __user *buf, | |||
478 | struct st_ram_io *st_loc, struct mailbox *mailbox) | 478 | struct st_ram_io *st_loc, struct mailbox *mailbox) |
479 | { | 479 | { |
480 | void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC; | 480 | void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC; |
481 | unsigned char *to = (unsigned char *)&mailbox; | 481 | unsigned char *to = (unsigned char *)mailbox; |
482 | #ifdef DEBUG | 482 | #ifdef DEBUG |
483 | int c; | 483 | int c; |
484 | #endif | 484 | #endif |
@@ -712,8 +712,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un | |||
712 | 712 | ||
713 | IndexCard = adgl->num_card-1; | 713 | IndexCard = adgl->num_card-1; |
714 | 714 | ||
715 | if(cmd != 0 && cmd != 6 && | 715 | if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { |
716 | ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { | ||
717 | static int warncount = 10; | 716 | static int warncount = 10; |
718 | if (warncount) { | 717 | if (warncount) { |
719 | printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); | 718 | printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); |
@@ -832,8 +831,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un | |||
832 | } | 831 | } |
833 | break; | 832 | break; |
834 | default: | 833 | default: |
835 | printk(KERN_INFO "APPLICOM driver ioctl, unknown function code %d\n",cmd) ; | 834 | ret = -ENOTTY; |
836 | ret = -EINVAL; | ||
837 | break; | 835 | break; |
838 | } | 836 | } |
839 | Dummy = readb(apbs[IndexCard].RamIO + VERS); | 837 | Dummy = readb(apbs[IndexCard].RamIO + VERS); |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index b650b4e48e50..456f54db73e2 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -229,9 +229,8 @@ static int bsr_create_devs(struct device_node *bn) | |||
229 | if (result) | 229 | if (result) |
230 | goto out_err; | 230 | goto out_err; |
231 | 231 | ||
232 | cur->bsr_device = device_create_drvdata(bsr_class, NULL, | 232 | cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev, |
233 | cur->bsr_dev, | 233 | cur, cur->bsr_name); |
234 | cur, cur->bsr_name); | ||
235 | if (!cur->bsr_device) { | 234 | if (!cur->bsr_device) { |
236 | printk(KERN_ERR "device_create failed for %s\n", | 235 | printk(KERN_ERR "device_create failed for %s\n", |
237 | cur->bsr_name); | 236 | cur->bsr_name); |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index fe6d774fe2e4..5e5b1dc1a0a7 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -4993,12 +4993,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
4993 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 4993 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4994 | card_name = "Cyclom-Y"; | 4994 | card_name = "Cyclom-Y"; |
4995 | 4995 | ||
4996 | addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); | 4996 | addr0 = ioremap_nocache(pci_resource_start(pdev, 0), |
4997 | CyPCI_Yctl); | ||
4997 | if (addr0 == NULL) { | 4998 | if (addr0 == NULL) { |
4998 | dev_err(&pdev->dev, "can't remap ctl region\n"); | 4999 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4999 | goto err_reg; | 5000 | goto err_reg; |
5000 | } | 5001 | } |
5001 | addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); | 5002 | addr2 = ioremap_nocache(pci_resource_start(pdev, 2), |
5003 | CyPCI_Ywin); | ||
5002 | if (addr2 == NULL) { | 5004 | if (addr2 == NULL) { |
5003 | dev_err(&pdev->dev, "can't remap base region\n"); | 5005 | dev_err(&pdev->dev, "can't remap base region\n"); |
5004 | goto err_unmap; | 5006 | goto err_unmap; |
@@ -5013,7 +5015,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5013 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | 5015 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { |
5014 | struct RUNTIME_9060 __iomem *ctl_addr; | 5016 | struct RUNTIME_9060 __iomem *ctl_addr; |
5015 | 5017 | ||
5016 | ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); | 5018 | ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0), |
5019 | CyPCI_Zctl); | ||
5017 | if (addr0 == NULL) { | 5020 | if (addr0 == NULL) { |
5018 | dev_err(&pdev->dev, "can't remap ctl region\n"); | 5021 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
5019 | goto err_reg; | 5022 | goto err_reg; |
@@ -5026,8 +5029,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5026 | 5029 | ||
5027 | mailbox = (u32)readl(&ctl_addr->mail_box_0); | 5030 | mailbox = (u32)readl(&ctl_addr->mail_box_0); |
5028 | 5031 | ||
5029 | addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? | 5032 | addr2 = ioremap_nocache(pci_resource_start(pdev, 2), |
5030 | CyPCI_Ze_win : CyPCI_Zwin); | 5033 | mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin); |
5031 | if (addr2 == NULL) { | 5034 | if (addr2 == NULL) { |
5032 | dev_err(&pdev->dev, "can't remap base region\n"); | 5035 | dev_err(&pdev->dev, "can't remap base region\n"); |
5033 | goto err_unmap; | 5036 | goto err_unmap; |
@@ -5159,9 +5162,9 @@ err_null: | |||
5159 | cy_card[card_no].base_addr = NULL; | 5162 | cy_card[card_no].base_addr = NULL; |
5160 | free_irq(irq, &cy_card[card_no]); | 5163 | free_irq(irq, &cy_card[card_no]); |
5161 | err_unmap: | 5164 | err_unmap: |
5162 | pci_iounmap(pdev, addr0); | 5165 | iounmap(addr0); |
5163 | if (addr2) | 5166 | if (addr2) |
5164 | pci_iounmap(pdev, addr2); | 5167 | iounmap(addr2); |
5165 | err_reg: | 5168 | err_reg: |
5166 | pci_release_regions(pdev); | 5169 | pci_release_regions(pdev); |
5167 | err_dis: | 5170 | err_dis: |
@@ -5186,9 +5189,9 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev) | |||
5186 | cy_writew(cinfo->ctl_addr + 0x68, | 5189 | cy_writew(cinfo->ctl_addr + 0x68, |
5187 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); | 5190 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); |
5188 | 5191 | ||
5189 | pci_iounmap(pdev, cinfo->base_addr); | 5192 | iounmap(cinfo->base_addr); |
5190 | if (cinfo->ctl_addr) | 5193 | if (cinfo->ctl_addr) |
5191 | pci_iounmap(pdev, cinfo->ctl_addr); | 5194 | iounmap(cinfo->ctl_addr); |
5192 | if (cinfo->irq | 5195 | if (cinfo->irq |
5193 | #ifndef CONFIG_CYZ_INTR | 5196 | #ifndef CONFIG_CYZ_INTR |
5194 | && !IS_CYC_Z(*cinfo) | 5197 | && !IS_CYC_Z(*cinfo) |
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c index fb584938c9c3..0a826d7be10e 100644 --- a/drivers/char/ds1286.c +++ b/drivers/char/ds1286.c | |||
@@ -210,8 +210,8 @@ static int ds1286_ioctl(struct inode *inode, struct file *file, | |||
210 | if (sec != 0) | 210 | if (sec != 0) |
211 | return -EINVAL; | 211 | return -EINVAL; |
212 | 212 | ||
213 | min = BIN2BCD(min); | 213 | min = bin2bcd(min); |
214 | min = BIN2BCD(hrs); | 214 | min = bin2bcd(hrs); |
215 | 215 | ||
216 | spin_lock(&ds1286_lock); | 216 | spin_lock(&ds1286_lock); |
217 | rtc_write(hrs, RTC_HOURS_ALARM); | 217 | rtc_write(hrs, RTC_HOURS_ALARM); |
@@ -353,7 +353,7 @@ static int ds1286_proc_output(char *buf) | |||
353 | 353 | ||
354 | ds1286_get_time(&tm); | 354 | ds1286_get_time(&tm); |
355 | hundredth = rtc_read(RTC_HUNDREDTH_SECOND); | 355 | hundredth = rtc_read(RTC_HUNDREDTH_SECOND); |
356 | BCD_TO_BIN(hundredth); | 356 | hundredth = bcd2bin(hundredth); |
357 | 357 | ||
358 | p += sprintf(p, | 358 | p += sprintf(p, |
359 | "rtc_time\t: %02d:%02d:%02d.%02d\n" | 359 | "rtc_time\t: %02d:%02d:%02d.%02d\n" |
@@ -443,7 +443,6 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) | |||
443 | { | 443 | { |
444 | unsigned char save_control; | 444 | unsigned char save_control; |
445 | unsigned long flags; | 445 | unsigned long flags; |
446 | unsigned long uip_watchdog = jiffies; | ||
447 | 446 | ||
448 | /* | 447 | /* |
449 | * read RTC once any update in progress is done. The update | 448 | * read RTC once any update in progress is done. The update |
@@ -456,8 +455,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) | |||
456 | */ | 455 | */ |
457 | 456 | ||
458 | if (ds1286_is_updating() != 0) | 457 | if (ds1286_is_updating() != 0) |
459 | while (time_before(jiffies, uip_watchdog + 2*HZ/100)) | 458 | msleep(20); |
460 | barrier(); | ||
461 | 459 | ||
462 | /* | 460 | /* |
463 | * Only the values that we read from the RTC are set. We leave | 461 | * Only the values that we read from the RTC are set. We leave |
@@ -479,12 +477,12 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) | |||
479 | rtc_write(save_control, RTC_CMD); | 477 | rtc_write(save_control, RTC_CMD); |
480 | spin_unlock_irqrestore(&ds1286_lock, flags); | 478 | spin_unlock_irqrestore(&ds1286_lock, flags); |
481 | 479 | ||
482 | BCD_TO_BIN(rtc_tm->tm_sec); | 480 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
483 | BCD_TO_BIN(rtc_tm->tm_min); | 481 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
484 | BCD_TO_BIN(rtc_tm->tm_hour); | 482 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
485 | BCD_TO_BIN(rtc_tm->tm_mday); | 483 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
486 | BCD_TO_BIN(rtc_tm->tm_mon); | 484 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
487 | BCD_TO_BIN(rtc_tm->tm_year); | 485 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
488 | 486 | ||
489 | /* | 487 | /* |
490 | * Account for differences between how the RTC uses the values | 488 | * Account for differences between how the RTC uses the values |
@@ -533,12 +531,12 @@ static int ds1286_set_time(struct rtc_time *rtc_tm) | |||
533 | if (yrs >= 100) | 531 | if (yrs >= 100) |
534 | yrs -= 100; | 532 | yrs -= 100; |
535 | 533 | ||
536 | BIN_TO_BCD(sec); | 534 | sec = bin2bcd(sec); |
537 | BIN_TO_BCD(min); | 535 | min = bin2bcd(min); |
538 | BIN_TO_BCD(hrs); | 536 | hrs = bin2bcd(hrs); |
539 | BIN_TO_BCD(day); | 537 | day = bin2bcd(day); |
540 | BIN_TO_BCD(mon); | 538 | mon = bin2bcd(mon); |
541 | BIN_TO_BCD(yrs); | 539 | yrs = bin2bcd(yrs); |
542 | 540 | ||
543 | spin_lock_irqsave(&ds1286_lock, flags); | 541 | spin_lock_irqsave(&ds1286_lock, flags); |
544 | save_control = rtc_read(RTC_CMD); | 542 | save_control = rtc_read(RTC_CMD); |
@@ -574,8 +572,8 @@ static void ds1286_get_alm_time(struct rtc_time *alm_tm) | |||
574 | cmd = rtc_read(RTC_CMD); | 572 | cmd = rtc_read(RTC_CMD); |
575 | spin_unlock_irqrestore(&ds1286_lock, flags); | 573 | spin_unlock_irqrestore(&ds1286_lock, flags); |
576 | 574 | ||
577 | BCD_TO_BIN(alm_tm->tm_min); | 575 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
578 | BCD_TO_BIN(alm_tm->tm_hour); | 576 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
579 | alm_tm->tm_sec = 0; | 577 | alm_tm->tm_sec = 0; |
580 | } | 578 | } |
581 | 579 | ||
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c index c5e67a623951..170693c93c73 100644 --- a/drivers/char/ds1302.c +++ b/drivers/char/ds1302.c | |||
@@ -131,12 +131,12 @@ get_rtc_time(struct rtc_time *rtc_tm) | |||
131 | 131 | ||
132 | local_irq_restore(flags); | 132 | local_irq_restore(flags); |
133 | 133 | ||
134 | BCD_TO_BIN(rtc_tm->tm_sec); | 134 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
135 | BCD_TO_BIN(rtc_tm->tm_min); | 135 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
136 | BCD_TO_BIN(rtc_tm->tm_hour); | 136 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
137 | BCD_TO_BIN(rtc_tm->tm_mday); | 137 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
138 | BCD_TO_BIN(rtc_tm->tm_mon); | 138 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
139 | BCD_TO_BIN(rtc_tm->tm_year); | 139 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * Account for differences between how the RTC uses the values | 142 | * Account for differences between how the RTC uses the values |
@@ -211,12 +211,12 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
211 | else | 211 | else |
212 | yrs -= 1900; /* RTC (70, 71, ... 99) */ | 212 | yrs -= 1900; /* RTC (70, 71, ... 99) */ |
213 | 213 | ||
214 | BIN_TO_BCD(sec); | 214 | sec = bin2bcd(sec); |
215 | BIN_TO_BCD(min); | 215 | min = bin2bcd(min); |
216 | BIN_TO_BCD(hrs); | 216 | hrs = bin2bcd(hrs); |
217 | BIN_TO_BCD(day); | 217 | day = bin2bcd(day); |
218 | BIN_TO_BCD(mon); | 218 | mon = bin2bcd(mon); |
219 | BIN_TO_BCD(yrs); | 219 | yrs = bin2bcd(yrs); |
220 | 220 | ||
221 | lock_kernel(); | 221 | lock_kernel(); |
222 | local_irq_save(flags); | 222 | local_irq_save(flags); |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index ca7c72a486b2..85832ab924e6 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -508,8 +508,8 @@ static int __init dsp56k_init_driver(void) | |||
508 | err = PTR_ERR(dsp56k_class); | 508 | err = PTR_ERR(dsp56k_class); |
509 | goto out_chrdev; | 509 | goto out_chrdev; |
510 | } | 510 | } |
511 | device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), | 511 | device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, |
512 | NULL, "dsp56k"); | 512 | "dsp56k"); |
513 | 513 | ||
514 | printk(banner); | 514 | printk(banner); |
515 | goto out; | 515 | goto out; |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 456e4ede049f..cf2461d34e5f 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1376,6 +1376,7 @@ static void post_fep_init(unsigned int crd) | |||
1376 | unsigned long flags; | 1376 | unsigned long flags; |
1377 | u16 tseg, rseg; | 1377 | u16 tseg, rseg; |
1378 | 1378 | ||
1379 | tty_port_init(&ch->port); | ||
1379 | ch->brdchan = bc; | 1380 | ch->brdchan = bc; |
1380 | ch->mailbox = gd; | 1381 | ch->mailbox = gd; |
1381 | INIT_WORK(&ch->tqueue, do_softint); | 1382 | INIT_WORK(&ch->tqueue, do_softint); |
@@ -1510,10 +1511,6 @@ static void post_fep_init(unsigned int crd) | |||
1510 | ch->fepstopca = 0; | 1511 | ch->fepstopca = 0; |
1511 | 1512 | ||
1512 | ch->close_delay = 50; | 1513 | ch->close_delay = 50; |
1513 | ch->port.count = 0; | ||
1514 | ch->port.blocked_open = 0; | ||
1515 | init_waitqueue_head(&ch->port.open_wait); | ||
1516 | init_waitqueue_head(&ch->port.close_wait); | ||
1517 | 1514 | ||
1518 | spin_unlock_irqrestore(&epca_lock, flags); | 1515 | spin_unlock_irqrestore(&epca_lock, flags); |
1519 | } | 1516 | } |
@@ -2480,7 +2477,11 @@ static int pc_send_break(struct tty_struct *tty, int msec) | |||
2480 | unsigned long flags; | 2477 | unsigned long flags; |
2481 | 2478 | ||
2482 | if (msec == -1) | 2479 | if (msec == -1) |
2483 | return -EOPNOTSUPP; | 2480 | msec = 0xFFFF; |
2481 | else if (msec > 0xFFFE) | ||
2482 | msec = 0xFFFE; | ||
2483 | else if (msec < 1) | ||
2484 | msec = 1; | ||
2484 | 2485 | ||
2485 | spin_lock_irqsave(&epca_lock, flags); | 2486 | spin_lock_irqsave(&epca_lock, flags); |
2486 | globalwinon(ch); | 2487 | globalwinon(ch); |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 19d3afb0e50c..c6090f84a2e4 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -54,8 +54,6 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch) | |||
54 | 54 | ||
55 | func_enter (); | 55 | func_enter (); |
56 | 56 | ||
57 | if (!tty) return 0; | ||
58 | |||
59 | port = tty->driver_data; | 57 | port = tty->driver_data; |
60 | 58 | ||
61 | if (!port) return 0; | 59 | if (!port) return 0; |
@@ -97,8 +95,6 @@ int gs_write(struct tty_struct * tty, | |||
97 | 95 | ||
98 | func_enter (); | 96 | func_enter (); |
99 | 97 | ||
100 | if (!tty) return 0; | ||
101 | |||
102 | port = tty->driver_data; | 98 | port = tty->driver_data; |
103 | 99 | ||
104 | if (!port) return 0; | 100 | if (!port) return 0; |
@@ -185,7 +181,6 @@ static int gs_real_chars_in_buffer(struct tty_struct *tty) | |||
185 | struct gs_port *port; | 181 | struct gs_port *port; |
186 | func_enter (); | 182 | func_enter (); |
187 | 183 | ||
188 | if (!tty) return 0; | ||
189 | port = tty->driver_data; | 184 | port = tty->driver_data; |
190 | 185 | ||
191 | if (!port->rd) return 0; | 186 | if (!port->rd) return 0; |
@@ -274,8 +269,6 @@ void gs_flush_buffer(struct tty_struct *tty) | |||
274 | 269 | ||
275 | func_enter (); | 270 | func_enter (); |
276 | 271 | ||
277 | if (!tty) return; | ||
278 | |||
279 | port = tty->driver_data; | 272 | port = tty->driver_data; |
280 | 273 | ||
281 | if (!port) return; | 274 | if (!port) return; |
@@ -296,8 +289,6 @@ void gs_flush_chars(struct tty_struct * tty) | |||
296 | 289 | ||
297 | func_enter (); | 290 | func_enter (); |
298 | 291 | ||
299 | if (!tty) return; | ||
300 | |||
301 | port = tty->driver_data; | 292 | port = tty->driver_data; |
302 | 293 | ||
303 | if (!port) return; | 294 | if (!port) return; |
@@ -321,8 +312,6 @@ void gs_stop(struct tty_struct * tty) | |||
321 | 312 | ||
322 | func_enter (); | 313 | func_enter (); |
323 | 314 | ||
324 | if (!tty) return; | ||
325 | |||
326 | port = tty->driver_data; | 315 | port = tty->driver_data; |
327 | 316 | ||
328 | if (!port) return; | 317 | if (!port) return; |
@@ -341,8 +330,6 @@ void gs_start(struct tty_struct * tty) | |||
341 | { | 330 | { |
342 | struct gs_port *port; | 331 | struct gs_port *port; |
343 | 332 | ||
344 | if (!tty) return; | ||
345 | |||
346 | port = tty->driver_data; | 333 | port = tty->driver_data; |
347 | 334 | ||
348 | if (!port) return; | 335 | if (!port) return; |
@@ -393,8 +380,6 @@ void gs_hangup(struct tty_struct *tty) | |||
393 | 380 | ||
394 | func_enter (); | 381 | func_enter (); |
395 | 382 | ||
396 | if (!tty) return; | ||
397 | |||
398 | port = tty->driver_data; | 383 | port = tty->driver_data; |
399 | tty = port->port.tty; | 384 | tty = port->port.tty; |
400 | if (!tty) | 385 | if (!tty) |
@@ -426,8 +411,6 @@ int gs_block_til_ready(void *port_, struct file * filp) | |||
426 | 411 | ||
427 | tty = port->port.tty; | 412 | tty = port->port.tty; |
428 | 413 | ||
429 | if (!tty) return 0; | ||
430 | |||
431 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); | 414 | gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); |
432 | /* | 415 | /* |
433 | * If the device is in the middle of being closed, then block | 416 | * If the device is in the middle of being closed, then block |
@@ -523,8 +506,6 @@ void gs_close(struct tty_struct * tty, struct file * filp) | |||
523 | 506 | ||
524 | func_enter (); | 507 | func_enter (); |
525 | 508 | ||
526 | if (!tty) return; | ||
527 | |||
528 | port = (struct gs_port *) tty->driver_data; | 509 | port = (struct gs_port *) tty->driver_data; |
529 | 510 | ||
530 | if (!port) return; | 511 | if (!port) return; |
@@ -621,8 +602,6 @@ void gs_set_termios (struct tty_struct * tty, | |||
621 | 602 | ||
622 | func_enter(); | 603 | func_enter(); |
623 | 604 | ||
624 | if (!tty) return; | ||
625 | |||
626 | port = tty->driver_data; | 605 | port = tty->driver_data; |
627 | 606 | ||
628 | if (!port) return; | 607 | if (!port) return; |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index b3f5dbc6d880..408f5f92cb4e 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -53,6 +53,11 @@ | |||
53 | 53 | ||
54 | #define HPET_RANGE_SIZE 1024 /* from HPET spec */ | 54 | #define HPET_RANGE_SIZE 1024 /* from HPET spec */ |
55 | 55 | ||
56 | |||
57 | /* WARNING -- don't get confused. These macros are never used | ||
58 | * to write the (single) counter, and rarely to read it. | ||
59 | * They're badly named; to fix, someday. | ||
60 | */ | ||
56 | #if BITS_PER_LONG == 64 | 61 | #if BITS_PER_LONG == 64 |
57 | #define write_counter(V, MC) writeq(V, MC) | 62 | #define write_counter(V, MC) writeq(V, MC) |
58 | #define read_counter(MC) readq(MC) | 63 | #define read_counter(MC) readq(MC) |
@@ -77,7 +82,7 @@ static struct clocksource clocksource_hpet = { | |||
77 | .rating = 250, | 82 | .rating = 250, |
78 | .read = read_hpet, | 83 | .read = read_hpet, |
79 | .mask = CLOCKSOURCE_MASK(64), | 84 | .mask = CLOCKSOURCE_MASK(64), |
80 | .mult = 0, /*to be caluclated*/ | 85 | .mult = 0, /* to be calculated */ |
81 | .shift = 10, | 86 | .shift = 10, |
82 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 87 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
83 | }; | 88 | }; |
@@ -86,8 +91,6 @@ static struct clocksource *hpet_clocksource; | |||
86 | 91 | ||
87 | /* A lock for concurrent access by app and isr hpet activity. */ | 92 | /* A lock for concurrent access by app and isr hpet activity. */ |
88 | static DEFINE_SPINLOCK(hpet_lock); | 93 | static DEFINE_SPINLOCK(hpet_lock); |
89 | /* A lock for concurrent intermodule access to hpet and isr hpet activity. */ | ||
90 | static DEFINE_SPINLOCK(hpet_task_lock); | ||
91 | 94 | ||
92 | #define HPET_DEV_NAME (7) | 95 | #define HPET_DEV_NAME (7) |
93 | 96 | ||
@@ -99,7 +102,6 @@ struct hpet_dev { | |||
99 | unsigned long hd_irqdata; | 102 | unsigned long hd_irqdata; |
100 | wait_queue_head_t hd_waitqueue; | 103 | wait_queue_head_t hd_waitqueue; |
101 | struct fasync_struct *hd_async_queue; | 104 | struct fasync_struct *hd_async_queue; |
102 | struct hpet_task *hd_task; | ||
103 | unsigned int hd_flags; | 105 | unsigned int hd_flags; |
104 | unsigned int hd_irq; | 106 | unsigned int hd_irq; |
105 | unsigned int hd_hdwirq; | 107 | unsigned int hd_hdwirq; |
@@ -173,11 +175,6 @@ static irqreturn_t hpet_interrupt(int irq, void *data) | |||
173 | writel(isr, &devp->hd_hpet->hpet_isr); | 175 | writel(isr, &devp->hd_hpet->hpet_isr); |
174 | spin_unlock(&hpet_lock); | 176 | spin_unlock(&hpet_lock); |
175 | 177 | ||
176 | spin_lock(&hpet_task_lock); | ||
177 | if (devp->hd_task) | ||
178 | devp->hd_task->ht_func(devp->hd_task->ht_data); | ||
179 | spin_unlock(&hpet_task_lock); | ||
180 | |||
181 | wake_up_interruptible(&devp->hd_waitqueue); | 178 | wake_up_interruptible(&devp->hd_waitqueue); |
182 | 179 | ||
183 | kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); | 180 | kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); |
@@ -185,6 +182,67 @@ static irqreturn_t hpet_interrupt(int irq, void *data) | |||
185 | return IRQ_HANDLED; | 182 | return IRQ_HANDLED; |
186 | } | 183 | } |
187 | 184 | ||
185 | static void hpet_timer_set_irq(struct hpet_dev *devp) | ||
186 | { | ||
187 | unsigned long v; | ||
188 | int irq, gsi; | ||
189 | struct hpet_timer __iomem *timer; | ||
190 | |||
191 | spin_lock_irq(&hpet_lock); | ||
192 | if (devp->hd_hdwirq) { | ||
193 | spin_unlock_irq(&hpet_lock); | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | timer = devp->hd_timer; | ||
198 | |||
199 | /* we prefer level triggered mode */ | ||
200 | v = readl(&timer->hpet_config); | ||
201 | if (!(v & Tn_INT_TYPE_CNF_MASK)) { | ||
202 | v |= Tn_INT_TYPE_CNF_MASK; | ||
203 | writel(v, &timer->hpet_config); | ||
204 | } | ||
205 | spin_unlock_irq(&hpet_lock); | ||
206 | |||
207 | v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >> | ||
208 | Tn_INT_ROUTE_CAP_SHIFT; | ||
209 | |||
210 | /* | ||
211 | * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by | ||
212 | * legacy device. In IO APIC mode, we skip all the legacy IRQS. | ||
213 | */ | ||
214 | if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) | ||
215 | v &= ~0xf3df; | ||
216 | else | ||
217 | v &= ~0xffff; | ||
218 | |||
219 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; | ||
220 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { | ||
221 | |||
222 | if (irq >= nr_irqs) { | ||
223 | irq = HPET_MAX_IRQ; | ||
224 | break; | ||
225 | } | ||
226 | |||
227 | gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE, | ||
228 | ACPI_ACTIVE_LOW); | ||
229 | if (gsi > 0) | ||
230 | break; | ||
231 | |||
232 | /* FIXME: Setup interrupt source table */ | ||
233 | } | ||
234 | |||
235 | if (irq < HPET_MAX_IRQ) { | ||
236 | spin_lock_irq(&hpet_lock); | ||
237 | v = readl(&timer->hpet_config); | ||
238 | v |= irq << Tn_INT_ROUTE_CNF_SHIFT; | ||
239 | writel(v, &timer->hpet_config); | ||
240 | devp->hd_hdwirq = gsi; | ||
241 | spin_unlock_irq(&hpet_lock); | ||
242 | } | ||
243 | return; | ||
244 | } | ||
245 | |||
188 | static int hpet_open(struct inode *inode, struct file *file) | 246 | static int hpet_open(struct inode *inode, struct file *file) |
189 | { | 247 | { |
190 | struct hpet_dev *devp; | 248 | struct hpet_dev *devp; |
@@ -199,8 +257,7 @@ static int hpet_open(struct inode *inode, struct file *file) | |||
199 | 257 | ||
200 | for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) | 258 | for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) |
201 | for (i = 0; i < hpetp->hp_ntimer; i++) | 259 | for (i = 0; i < hpetp->hp_ntimer; i++) |
202 | if (hpetp->hp_dev[i].hd_flags & HPET_OPEN | 260 | if (hpetp->hp_dev[i].hd_flags & HPET_OPEN) |
203 | || hpetp->hp_dev[i].hd_task) | ||
204 | continue; | 261 | continue; |
205 | else { | 262 | else { |
206 | devp = &hpetp->hp_dev[i]; | 263 | devp = &hpetp->hp_dev[i]; |
@@ -219,6 +276,8 @@ static int hpet_open(struct inode *inode, struct file *file) | |||
219 | spin_unlock_irq(&hpet_lock); | 276 | spin_unlock_irq(&hpet_lock); |
220 | unlock_kernel(); | 277 | unlock_kernel(); |
221 | 278 | ||
279 | hpet_timer_set_irq(devp); | ||
280 | |||
222 | return 0; | 281 | return 0; |
223 | } | 282 | } |
224 | 283 | ||
@@ -441,7 +500,11 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
441 | devp->hd_irq = irq; | 500 | devp->hd_irq = irq; |
442 | t = devp->hd_ireqfreq; | 501 | t = devp->hd_ireqfreq; |
443 | v = readq(&timer->hpet_config); | 502 | v = readq(&timer->hpet_config); |
444 | g = v | Tn_INT_ENB_CNF_MASK; | 503 | |
504 | /* 64-bit comparators are not yet supported through the ioctls, | ||
505 | * so force this into 32-bit mode if it supports both modes | ||
506 | */ | ||
507 | g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK; | ||
445 | 508 | ||
446 | if (devp->hd_flags & HPET_PERIODIC) { | 509 | if (devp->hd_flags & HPET_PERIODIC) { |
447 | write_counter(t, &timer->hpet_compare); | 510 | write_counter(t, &timer->hpet_compare); |
@@ -451,6 +514,12 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
451 | v |= Tn_VAL_SET_CNF_MASK; | 514 | v |= Tn_VAL_SET_CNF_MASK; |
452 | writeq(v, &timer->hpet_config); | 515 | writeq(v, &timer->hpet_config); |
453 | local_irq_save(flags); | 516 | local_irq_save(flags); |
517 | |||
518 | /* NOTE: what we modify here is a hidden accumulator | ||
519 | * register supported by periodic-capable comparators. | ||
520 | * We never want to modify the (single) counter; that | ||
521 | * would affect all the comparators. | ||
522 | */ | ||
454 | m = read_counter(&hpet->hpet_mc); | 523 | m = read_counter(&hpet->hpet_mc); |
455 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); | 524 | write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); |
456 | } else { | 525 | } else { |
@@ -604,57 +673,6 @@ static int hpet_is_known(struct hpet_data *hdp) | |||
604 | return 0; | 673 | return 0; |
605 | } | 674 | } |
606 | 675 | ||
607 | static inline int hpet_tpcheck(struct hpet_task *tp) | ||
608 | { | ||
609 | struct hpet_dev *devp; | ||
610 | struct hpets *hpetp; | ||
611 | |||
612 | devp = tp->ht_opaque; | ||
613 | |||
614 | if (!devp) | ||
615 | return -ENXIO; | ||
616 | |||
617 | for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) | ||
618 | if (devp >= hpetp->hp_dev | ||
619 | && devp < (hpetp->hp_dev + hpetp->hp_ntimer) | ||
620 | && devp->hd_hpet == hpetp->hp_hpet) | ||
621 | return 0; | ||
622 | |||
623 | return -ENXIO; | ||
624 | } | ||
625 | |||
626 | #if 0 | ||
627 | int hpet_unregister(struct hpet_task *tp) | ||
628 | { | ||
629 | struct hpet_dev *devp; | ||
630 | struct hpet_timer __iomem *timer; | ||
631 | int err; | ||
632 | |||
633 | if ((err = hpet_tpcheck(tp))) | ||
634 | return err; | ||
635 | |||
636 | spin_lock_irq(&hpet_task_lock); | ||
637 | spin_lock(&hpet_lock); | ||
638 | |||
639 | devp = tp->ht_opaque; | ||
640 | if (devp->hd_task != tp) { | ||
641 | spin_unlock(&hpet_lock); | ||
642 | spin_unlock_irq(&hpet_task_lock); | ||
643 | return -ENXIO; | ||
644 | } | ||
645 | |||
646 | timer = devp->hd_timer; | ||
647 | writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK), | ||
648 | &timer->hpet_config); | ||
649 | devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC); | ||
650 | devp->hd_task = NULL; | ||
651 | spin_unlock(&hpet_lock); | ||
652 | spin_unlock_irq(&hpet_task_lock); | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | #endif /* 0 */ | ||
657 | |||
658 | static ctl_table hpet_table[] = { | 676 | static ctl_table hpet_table[] = { |
659 | { | 677 | { |
660 | .ctl_name = CTL_UNNUMBERED, | 678 | .ctl_name = CTL_UNNUMBERED, |
@@ -746,6 +764,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
746 | static struct hpets *last = NULL; | 764 | static struct hpets *last = NULL; |
747 | unsigned long period; | 765 | unsigned long period; |
748 | unsigned long long temp; | 766 | unsigned long long temp; |
767 | u32 remainder; | ||
749 | 768 | ||
750 | /* | 769 | /* |
751 | * hpet_alloc can be called by platform dependent code. | 770 | * hpet_alloc can be called by platform dependent code. |
@@ -809,9 +828,13 @@ int hpet_alloc(struct hpet_data *hdp) | |||
809 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); | 828 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); |
810 | printk("\n"); | 829 | printk("\n"); |
811 | 830 | ||
812 | printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", | 831 | temp = hpetp->hp_tick_freq; |
813 | hpetp->hp_which, hpetp->hp_ntimer, | 832 | remainder = do_div(temp, 1000000); |
814 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq); | 833 | printk(KERN_INFO |
834 | "hpet%u: %u comparators, %d-bit %u.%06u MHz counter\n", | ||
835 | hpetp->hp_which, hpetp->hp_ntimer, | ||
836 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, | ||
837 | (unsigned) temp, remainder); | ||
815 | 838 | ||
816 | mcfg = readq(&hpet->hpet_config); | 839 | mcfg = readq(&hpet->hpet_config); |
817 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { | 840 | if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { |
@@ -874,8 +897,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
874 | hdp->hd_address = ioremap(addr.minimum, addr.address_length); | 897 | hdp->hd_address = ioremap(addr.minimum, addr.address_length); |
875 | 898 | ||
876 | if (hpet_is_known(hdp)) { | 899 | if (hpet_is_known(hdp)) { |
877 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | ||
878 | __func__, hdp->hd_phys_address); | ||
879 | iounmap(hdp->hd_address); | 900 | iounmap(hdp->hd_address); |
880 | return AE_ALREADY_EXISTS; | 901 | return AE_ALREADY_EXISTS; |
881 | } | 902 | } |
@@ -891,8 +912,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
891 | HPET_RANGE_SIZE); | 912 | HPET_RANGE_SIZE); |
892 | 913 | ||
893 | if (hpet_is_known(hdp)) { | 914 | if (hpet_is_known(hdp)) { |
894 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | ||
895 | __func__, hdp->hd_phys_address); | ||
896 | iounmap(hdp->hd_address); | 915 | iounmap(hdp->hd_address); |
897 | return AE_ALREADY_EXISTS; | 916 | return AE_ALREADY_EXISTS; |
898 | } | 917 | } |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fd64137b1ab9..bf70450a49cc 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
367 | spin_lock_irqsave(&hp->lock, flags); | 367 | spin_lock_irqsave(&hp->lock, flags); |
368 | 368 | ||
369 | if (--hp->count == 0) { | 369 | if (--hp->count == 0) { |
370 | if (hp->ops->notifier_del) | ||
371 | hp->ops->notifier_del(hp, hp->data); | ||
372 | |||
373 | /* We are done with the tty pointer now. */ | 370 | /* We are done with the tty pointer now. */ |
374 | hp->tty = NULL; | 371 | hp->tty = NULL; |
375 | spin_unlock_irqrestore(&hp->lock, flags); | 372 | spin_unlock_irqrestore(&hp->lock, flags); |
376 | 373 | ||
374 | if (hp->ops->notifier_del) | ||
375 | hp->ops->notifier_del(hp, hp->data); | ||
376 | |||
377 | /* | 377 | /* |
378 | * Chain calls chars_in_buffer() and returns immediately if | 378 | * Chain calls chars_in_buffer() and returns immediately if |
379 | * there is no buffered data otherwise sleeps on a wait queue | 379 | * there is no buffered data otherwise sleeps on a wait queue |
@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct *tty) | |||
416 | hp->n_outbuf = 0; | 416 | hp->n_outbuf = 0; |
417 | hp->tty = NULL; | 417 | hp->tty = NULL; |
418 | 418 | ||
419 | spin_unlock_irqrestore(&hp->lock, flags); | ||
420 | |||
419 | if (hp->ops->notifier_del) | 421 | if (hp->ops->notifier_del) |
420 | hp->ops->notifier_del(hp, hp->data); | 422 | hp->ops->notifier_del(hp, hp->data); |
421 | 423 | ||
422 | spin_unlock_irqrestore(&hp->lock, flags); | ||
423 | |||
424 | while(temp_open_count) { | 424 | while(temp_open_count) { |
425 | --temp_open_count; | 425 | --temp_open_count; |
426 | kref_put(&hp->kref, destroy_hvc_struct); | 426 | kref_put(&hp->kref, destroy_hvc_struct); |
@@ -819,11 +819,11 @@ static int hvc_init(void) | |||
819 | hvc_driver = drv; | 819 | hvc_driver = drv; |
820 | return 0; | 820 | return 0; |
821 | 821 | ||
822 | put_tty: | ||
823 | put_tty_driver(hvc_driver); | ||
824 | stop_thread: | 822 | stop_thread: |
825 | kthread_stop(hvc_task); | 823 | kthread_stop(hvc_task); |
826 | hvc_task = NULL; | 824 | hvc_task = NULL; |
825 | put_tty: | ||
826 | put_tty_driver(drv); | ||
827 | out: | 827 | out: |
828 | return err; | 828 | return err; |
829 | } | 829 | } |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index 6b70aa66a587..538ceea5e7df 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c | |||
@@ -108,8 +108,8 @@ static int __init xen_init(void) | |||
108 | { | 108 | { |
109 | struct hvc_struct *hp; | 109 | struct hvc_struct *hp; |
110 | 110 | ||
111 | if (!is_running_on_xen() || | 111 | if (!xen_pv_domain() || |
112 | is_initial_xendomain() || | 112 | xen_initial_domain() || |
113 | !xen_start_info->console.domU.evtchn) | 113 | !xen_start_info->console.domU.evtchn) |
114 | return -ENODEV; | 114 | return -ENODEV; |
115 | 115 | ||
@@ -142,7 +142,7 @@ static void __exit xen_fini(void) | |||
142 | 142 | ||
143 | static int xen_cons_init(void) | 143 | static int xen_cons_init(void) |
144 | { | 144 | { |
145 | if (!is_running_on_xen()) | 145 | if (!xen_pv_domain()) |
146 | return 0; | 146 | return 0; |
147 | 147 | ||
148 | hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); | 148 | hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); |
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 5220f541df25..8859aeac2d25 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c | |||
@@ -736,7 +736,7 @@ static int __devexit n2rng_remove(struct of_device *op) | |||
736 | return 0; | 736 | return 0; |
737 | } | 737 | } |
738 | 738 | ||
739 | static struct of_device_id n2rng_match[] = { | 739 | static const struct of_device_id n2rng_match[] = { |
740 | { | 740 | { |
741 | .name = "random-number-generator", | 741 | .name = "random-number-generator", |
742 | .compatible = "SUNW,n2-rng", | 742 | .compatible = "SUNW,n2-rng", |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 51738bdd834e..d4e7dca06e4f 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -118,18 +118,21 @@ static int __init omap_rng_probe(struct platform_device *pdev) | |||
118 | 118 | ||
119 | mem = request_mem_region(res->start, res->end - res->start + 1, | 119 | mem = request_mem_region(res->start, res->end - res->start + 1, |
120 | pdev->name); | 120 | pdev->name); |
121 | if (mem == NULL) | 121 | if (mem == NULL) { |
122 | return -EBUSY; | 122 | ret = -EBUSY; |
123 | goto err_region; | ||
124 | } | ||
123 | 125 | ||
124 | dev_set_drvdata(&pdev->dev, mem); | 126 | dev_set_drvdata(&pdev->dev, mem); |
125 | rng_base = (u32 __force __iomem *)io_p2v(res->start); | 127 | rng_base = ioremap(res->start, res->end - res->start + 1); |
128 | if (!rng_base) { | ||
129 | ret = -ENOMEM; | ||
130 | goto err_ioremap; | ||
131 | } | ||
126 | 132 | ||
127 | ret = hwrng_register(&omap_rng_ops); | 133 | ret = hwrng_register(&omap_rng_ops); |
128 | if (ret) { | 134 | if (ret) |
129 | release_resource(mem); | 135 | goto err_register; |
130 | rng_base = NULL; | ||
131 | return ret; | ||
132 | } | ||
133 | 136 | ||
134 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", | 137 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", |
135 | omap_rng_read_reg(RNG_REV_REG)); | 138 | omap_rng_read_reg(RNG_REV_REG)); |
@@ -138,6 +141,18 @@ static int __init omap_rng_probe(struct platform_device *pdev) | |||
138 | rng_dev = pdev; | 141 | rng_dev = pdev; |
139 | 142 | ||
140 | return 0; | 143 | return 0; |
144 | |||
145 | err_register: | ||
146 | iounmap(rng_base); | ||
147 | rng_base = NULL; | ||
148 | err_ioremap: | ||
149 | release_resource(mem); | ||
150 | err_region: | ||
151 | if (cpu_is_omap24xx()) { | ||
152 | clk_disable(rng_ick); | ||
153 | clk_put(rng_ick); | ||
154 | } | ||
155 | return ret; | ||
141 | } | 156 | } |
142 | 157 | ||
143 | static int __exit omap_rng_remove(struct platform_device *pdev) | 158 | static int __exit omap_rng_remove(struct platform_device *pdev) |
@@ -148,6 +163,8 @@ static int __exit omap_rng_remove(struct platform_device *pdev) | |||
148 | 163 | ||
149 | omap_rng_write_reg(RNG_MASK_REG, 0x0); | 164 | omap_rng_write_reg(RNG_MASK_REG, 0x0); |
150 | 165 | ||
166 | iounmap(rng_base); | ||
167 | |||
151 | if (cpu_is_omap24xx()) { | 168 | if (cpu_is_omap24xx()) { |
152 | clk_disable(rng_ick); | 169 | clk_disable(rng_ick); |
153 | clk_put(rng_ick); | 170 | clk_put(rng_ick); |
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index 939618f62fe1..bc397d92b499 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
@@ -4,5 +4,5 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_COMPUTONE) += ip2.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
6 | 6 | ||
7 | ip2-objs := ip2base.o ip2main.o | 7 | ip2-objs := ip2main.o |
8 | 8 | ||
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c index 3601017f58cf..29db44de399f 100644 --- a/drivers/char/ip2/i2ellis.c +++ b/drivers/char/ip2/i2ellis.c | |||
@@ -69,38 +69,6 @@ static DEFINE_RWLOCK(Dl_spinlock); | |||
69 | //======================================================= | 69 | //======================================================= |
70 | 70 | ||
71 | //****************************************************************************** | 71 | //****************************************************************************** |
72 | // Function: iiEllisInit() | ||
73 | // Parameters: None | ||
74 | // | ||
75 | // Returns: Nothing | ||
76 | // | ||
77 | // Description: | ||
78 | // | ||
79 | // This routine performs any required initialization of the iiEllis subsystem. | ||
80 | // | ||
81 | //****************************************************************************** | ||
82 | static void | ||
83 | iiEllisInit(void) | ||
84 | { | ||
85 | } | ||
86 | |||
87 | //****************************************************************************** | ||
88 | // Function: iiEllisCleanup() | ||
89 | // Parameters: None | ||
90 | // | ||
91 | // Returns: Nothing | ||
92 | // | ||
93 | // Description: | ||
94 | // | ||
95 | // This routine performs any required cleanup of the iiEllis subsystem. | ||
96 | // | ||
97 | //****************************************************************************** | ||
98 | static void | ||
99 | iiEllisCleanup(void) | ||
100 | { | ||
101 | } | ||
102 | |||
103 | //****************************************************************************** | ||
104 | // Function: iiSetAddress(pB, address, delay) | 72 | // Function: iiSetAddress(pB, address, delay) |
105 | // Parameters: pB - pointer to the board structure | 73 | // Parameters: pB - pointer to the board structure |
106 | // address - the purported I/O address of the board | 74 | // address - the purported I/O address of the board |
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h index c88a64e527aa..fb6df2456018 100644 --- a/drivers/char/ip2/i2ellis.h +++ b/drivers/char/ip2/i2ellis.h | |||
@@ -511,7 +511,6 @@ typedef void (*delayFunc_t)(unsigned int); | |||
511 | // | 511 | // |
512 | // Initialization of a board & structure is in four (five!) parts: | 512 | // Initialization of a board & structure is in four (five!) parts: |
513 | // | 513 | // |
514 | // 0) iiEllisInit() - Initialize iiEllis subsystem. | ||
515 | // 1) iiSetAddress() - Define the board address & delay function for a board. | 514 | // 1) iiSetAddress() - Define the board address & delay function for a board. |
516 | // 2) iiReset() - Reset the board (provided it exists) | 515 | // 2) iiReset() - Reset the board (provided it exists) |
517 | // -- Note you may do this to several boards -- | 516 | // -- Note you may do this to several boards -- |
@@ -523,7 +522,6 @@ typedef void (*delayFunc_t)(unsigned int); | |||
523 | // loadware. To change loadware, you must begin again with step 2, resetting | 522 | // loadware. To change loadware, you must begin again with step 2, resetting |
524 | // the board again (step 1 not needed). | 523 | // the board again (step 1 not needed). |
525 | 524 | ||
526 | static void iiEllisInit(void); | ||
527 | static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); | 525 | static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); |
528 | static int iiReset(i2eBordStrPtr); | 526 | static int iiReset(i2eBordStrPtr); |
529 | static int iiResetDelay(i2eBordStrPtr); | 527 | static int iiResetDelay(i2eBordStrPtr); |
diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c deleted file mode 100644 index 8155e247c04b..000000000000 --- a/drivers/char/ip2/ip2base.c +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | // ip2.c | ||
2 | // This is a dummy module to make the firmware available when needed | ||
3 | // and allows it to be unloaded when not. Rumor is the __initdata | ||
4 | // macro doesn't always works on all platforms so we use this kludge. | ||
5 | // If not compiled as a module it just makes fip_firm avaliable then | ||
6 | // __initdata should work as advertized | ||
7 | // | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/wait.h> | ||
12 | |||
13 | #ifndef __init | ||
14 | #define __init | ||
15 | #endif | ||
16 | #ifndef __initfunc | ||
17 | #define __initfunc(a) a | ||
18 | #endif | ||
19 | #ifndef __initdata | ||
20 | #define __initdata | ||
21 | #endif | ||
22 | |||
23 | #include "ip2types.h" | ||
24 | |||
25 | int | ||
26 | ip2_loadmain(int *, int *); // ref into ip2main.c | ||
27 | |||
28 | /* Note: Add compiled in defaults to these arrays, not to the structure | ||
29 | in ip2.h any longer. That structure WILL get overridden | ||
30 | by these values, or command line values, or insmod values!!! =mhw= | ||
31 | */ | ||
32 | static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 }; | ||
33 | static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; | ||
34 | |||
35 | static int poll_only = 0; | ||
36 | |||
37 | MODULE_AUTHOR("Doug McNash"); | ||
38 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | ||
39 | module_param_array(irq, int, NULL, 0); | ||
40 | MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards"); | ||
41 | module_param_array(io, int, NULL, 0); | ||
42 | MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards"); | ||
43 | module_param(poll_only, bool, 0); | ||
44 | MODULE_PARM_DESC(poll_only,"Do not use card interrupts"); | ||
45 | |||
46 | |||
47 | static int __init ip2_init(void) | ||
48 | { | ||
49 | if( poll_only ) { | ||
50 | /* Hard lock the interrupts to zero */ | ||
51 | irq[0] = irq[1] = irq[2] = irq[3] = 0; | ||
52 | } | ||
53 | |||
54 | return ip2_loadmain(io, irq); | ||
55 | } | ||
56 | module_init(ip2_init); | ||
57 | |||
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | #ifndef MODULE | ||
61 | /****************************************************************************** | ||
62 | * ip2_setup: | ||
63 | * str: kernel command line string | ||
64 | * | ||
65 | * Can't autoprobe the boards so user must specify configuration on | ||
66 | * kernel command line. Sane people build it modular but the others | ||
67 | * come here. | ||
68 | * | ||
69 | * Alternating pairs of io,irq for up to 4 boards. | ||
70 | * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 | ||
71 | * | ||
72 | * io=0 => No board | ||
73 | * io=1 => PCI | ||
74 | * io=2 => EISA | ||
75 | * else => ISA I/O address | ||
76 | * | ||
77 | * irq=0 or invalid for ISA will revert to polling mode | ||
78 | * | ||
79 | * Any value = -1, do not overwrite compiled in value. | ||
80 | * | ||
81 | ******************************************************************************/ | ||
82 | static int __init ip2_setup(char *str) | ||
83 | { | ||
84 | int ints[10]; /* 4 boards, 2 parameters + 2 */ | ||
85 | int i, j; | ||
86 | |||
87 | str = get_options (str, ARRAY_SIZE(ints), ints); | ||
88 | |||
89 | for( i = 0, j = 1; i < 4; i++ ) { | ||
90 | if( j > ints[0] ) { | ||
91 | break; | ||
92 | } | ||
93 | if( ints[j] >= 0 ) { | ||
94 | io[i] = ints[j]; | ||
95 | } | ||
96 | j++; | ||
97 | if( j > ints[0] ) { | ||
98 | break; | ||
99 | } | ||
100 | if( ints[j] >= 0 ) { | ||
101 | irq[i] = ints[j]; | ||
102 | } | ||
103 | j++; | ||
104 | } | ||
105 | return 1; | ||
106 | } | ||
107 | __setup("ip2=", ip2_setup); | ||
108 | #endif /* !MODULE */ | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 689f9dcd3b86..70e0ebc30bd0 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -150,15 +150,12 @@ static int ip2_read_proc(char *, char **, off_t, int, int *, void * ); | |||
150 | /*************/ | 150 | /*************/ |
151 | 151 | ||
152 | /* String constants to identify ourselves */ | 152 | /* String constants to identify ourselves */ |
153 | static char *pcName = "Computone IntelliPort Plus multiport driver"; | 153 | static const char pcName[] = "Computone IntelliPort Plus multiport driver"; |
154 | static char *pcVersion = "1.2.14"; | 154 | static const char pcVersion[] = "1.2.14"; |
155 | 155 | ||
156 | /* String constants for port names */ | 156 | /* String constants for port names */ |
157 | static char *pcDriver_name = "ip2"; | 157 | static const char pcDriver_name[] = "ip2"; |
158 | static char *pcIpl = "ip2ipl"; | 158 | static const char pcIpl[] = "ip2ipl"; |
159 | |||
160 | // cheezy kludge or genius - you decide? | ||
161 | int ip2_loadmain(int *, int *); | ||
162 | 159 | ||
163 | /***********************/ | 160 | /***********************/ |
164 | /* Function Prototypes */ | 161 | /* Function Prototypes */ |
@@ -240,8 +237,8 @@ static const struct file_operations ip2_ipl = { | |||
240 | .open = ip2_ipl_open, | 237 | .open = ip2_ipl_open, |
241 | }; | 238 | }; |
242 | 239 | ||
243 | static unsigned long irq_counter = 0; | 240 | static unsigned long irq_counter; |
244 | static unsigned long bh_counter = 0; | 241 | static unsigned long bh_counter; |
245 | 242 | ||
246 | // Use immediate queue to service interrupts | 243 | // Use immediate queue to service interrupts |
247 | #define USE_IQI | 244 | #define USE_IQI |
@@ -252,7 +249,6 @@ static unsigned long bh_counter = 0; | |||
252 | */ | 249 | */ |
253 | #define POLL_TIMEOUT (jiffies + 1) | 250 | #define POLL_TIMEOUT (jiffies + 1) |
254 | static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); | 251 | static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); |
255 | static char TimerOn; | ||
256 | 252 | ||
257 | #ifdef IP2DEBUG_TRACE | 253 | #ifdef IP2DEBUG_TRACE |
258 | /* Trace (debug) buffer data */ | 254 | /* Trace (debug) buffer data */ |
@@ -268,8 +264,8 @@ static int tracewrap; | |||
268 | /**********/ | 264 | /**********/ |
269 | 265 | ||
270 | #if defined(MODULE) && defined(IP2DEBUG_OPEN) | 266 | #if defined(MODULE) && defined(IP2DEBUG_OPEN) |
271 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \ | 267 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ |
272 | tty->name,(pCh->flags),ip2_tty_driver->refcount, \ | 268 | tty->name,(pCh->flags), \ |
273 | tty->count,/*GET_USE_COUNT(module)*/0,s) | 269 | tty->count,/*GET_USE_COUNT(module)*/0,s) |
274 | #else | 270 | #else |
275 | #define DBG_CNT(s) | 271 | #define DBG_CNT(s) |
@@ -287,8 +283,9 @@ static int tracewrap; | |||
287 | 283 | ||
288 | MODULE_AUTHOR("Doug McNash"); | 284 | MODULE_AUTHOR("Doug McNash"); |
289 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | 285 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); |
286 | MODULE_LICENSE("GPL"); | ||
290 | 287 | ||
291 | static int poll_only = 0; | 288 | static int poll_only; |
292 | 289 | ||
293 | static int Eisa_irq; | 290 | static int Eisa_irq; |
294 | static int Eisa_slot; | 291 | static int Eisa_slot; |
@@ -297,34 +294,46 @@ static int iindx; | |||
297 | static char rirqs[IP2_MAX_BOARDS]; | 294 | static char rirqs[IP2_MAX_BOARDS]; |
298 | static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; | 295 | static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; |
299 | 296 | ||
297 | /* Note: Add compiled in defaults to these arrays, not to the structure | ||
298 | in ip2.h any longer. That structure WILL get overridden | ||
299 | by these values, or command line values, or insmod values!!! =mhw= | ||
300 | */ | ||
301 | static int io[IP2_MAX_BOARDS]; | ||
302 | static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; | ||
303 | |||
304 | MODULE_AUTHOR("Doug McNash"); | ||
305 | MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); | ||
306 | module_param_array(irq, int, NULL, 0); | ||
307 | MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); | ||
308 | module_param_array(io, int, NULL, 0); | ||
309 | MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); | ||
310 | module_param(poll_only, bool, 0); | ||
311 | MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); | ||
312 | |||
300 | /* for sysfs class support */ | 313 | /* for sysfs class support */ |
301 | static struct class *ip2_class; | 314 | static struct class *ip2_class; |
302 | 315 | ||
303 | // Some functions to keep track of what irq's we have | 316 | /* Some functions to keep track of what irqs we have */ |
304 | 317 | ||
305 | static int | 318 | static int __init is_valid_irq(int irq) |
306 | is_valid_irq(int irq) | ||
307 | { | 319 | { |
308 | int *i = Valid_Irqs; | 320 | int *i = Valid_Irqs; |
309 | 321 | ||
310 | while ((*i != 0) && (*i != irq)) { | 322 | while (*i != 0 && *i != irq) |
311 | i++; | 323 | i++; |
312 | } | 324 | |
313 | return (*i); | 325 | return *i; |
314 | } | 326 | } |
315 | 327 | ||
316 | static void | 328 | static void __init mark_requested_irq(char irq) |
317 | mark_requested_irq( char irq ) | ||
318 | { | 329 | { |
319 | rirqs[iindx++] = irq; | 330 | rirqs[iindx++] = irq; |
320 | } | 331 | } |
321 | 332 | ||
322 | #ifdef MODULE | 333 | static int __exit clear_requested_irq(char irq) |
323 | static int | ||
324 | clear_requested_irq( char irq ) | ||
325 | { | 334 | { |
326 | int i; | 335 | int i; |
327 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 336 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
328 | if (rirqs[i] == irq) { | 337 | if (rirqs[i] == irq) { |
329 | rirqs[i] = 0; | 338 | rirqs[i] = 0; |
330 | return 1; | 339 | return 1; |
@@ -332,17 +341,15 @@ clear_requested_irq( char irq ) | |||
332 | } | 341 | } |
333 | return 0; | 342 | return 0; |
334 | } | 343 | } |
335 | #endif | ||
336 | 344 | ||
337 | static int | 345 | static int have_requested_irq(char irq) |
338 | have_requested_irq( char irq ) | ||
339 | { | 346 | { |
340 | // array init to zeros so 0 irq will not be requested as a side effect | 347 | /* array init to zeros so 0 irq will not be requested as a side |
348 | * effect */ | ||
341 | int i; | 349 | int i; |
342 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 350 | for (i = 0; i < IP2_MAX_BOARDS; ++i) |
343 | if (rirqs[i] == irq) | 351 | if (rirqs[i] == irq) |
344 | return 1; | 352 | return 1; |
345 | } | ||
346 | return 0; | 353 | return 0; |
347 | } | 354 | } |
348 | 355 | ||
@@ -361,53 +368,45 @@ have_requested_irq( char irq ) | |||
361 | /* handle subsequent installations of the driver. All memory allocated by the */ | 368 | /* handle subsequent installations of the driver. All memory allocated by the */ |
362 | /* driver should be returned since it may be unloaded from memory. */ | 369 | /* driver should be returned since it may be unloaded from memory. */ |
363 | /******************************************************************************/ | 370 | /******************************************************************************/ |
364 | #ifdef MODULE | 371 | static void __exit ip2_cleanup_module(void) |
365 | void __exit | ||
366 | ip2_cleanup_module(void) | ||
367 | { | 372 | { |
368 | int err; | 373 | int err; |
369 | int i; | 374 | int i; |
370 | 375 | ||
371 | #ifdef IP2DEBUG_INIT | 376 | del_timer_sync(&PollTimer); |
372 | printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion ); | ||
373 | #endif | ||
374 | /* Stop poll timer if we had one. */ | ||
375 | if ( TimerOn ) { | ||
376 | del_timer ( &PollTimer ); | ||
377 | TimerOn = 0; | ||
378 | } | ||
379 | 377 | ||
380 | /* Reset the boards we have. */ | 378 | /* Reset the boards we have. */ |
381 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 379 | for (i = 0; i < IP2_MAX_BOARDS; i++) |
382 | if ( i2BoardPtrTable[i] ) { | 380 | if (i2BoardPtrTable[i]) |
383 | iiReset( i2BoardPtrTable[i] ); | 381 | iiReset(i2BoardPtrTable[i]); |
384 | } | ||
385 | } | ||
386 | 382 | ||
387 | /* The following is done at most once, if any boards were installed. */ | 383 | /* The following is done at most once, if any boards were installed. */ |
388 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 384 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
389 | if ( i2BoardPtrTable[i] ) { | 385 | if (i2BoardPtrTable[i]) { |
390 | iiResetDelay( i2BoardPtrTable[i] ); | 386 | iiResetDelay(i2BoardPtrTable[i]); |
391 | /* free io addresses and Tibet */ | 387 | /* free io addresses and Tibet */ |
392 | release_region( ip2config.addr[i], 8 ); | 388 | release_region(ip2config.addr[i], 8); |
393 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); | 389 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); |
394 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | 390 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, |
391 | 4 * i + 1)); | ||
395 | } | 392 | } |
396 | /* Disable and remove interrupt handler. */ | 393 | /* Disable and remove interrupt handler. */ |
397 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { | 394 | if (ip2config.irq[i] > 0 && |
398 | free_irq ( ip2config.irq[i], (void *)&pcName); | 395 | have_requested_irq(ip2config.irq[i])) { |
399 | clear_requested_irq( ip2config.irq[i]); | 396 | free_irq(ip2config.irq[i], (void *)&pcName); |
397 | clear_requested_irq(ip2config.irq[i]); | ||
400 | } | 398 | } |
401 | } | 399 | } |
402 | class_destroy(ip2_class); | 400 | class_destroy(ip2_class); |
403 | if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { | 401 | err = tty_unregister_driver(ip2_tty_driver); |
404 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); | 402 | if (err) |
405 | } | 403 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", |
404 | err); | ||
406 | put_tty_driver(ip2_tty_driver); | 405 | put_tty_driver(ip2_tty_driver); |
407 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); | 406 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); |
408 | remove_proc_entry("ip2mem", NULL); | 407 | remove_proc_entry("ip2mem", NULL); |
409 | 408 | ||
410 | // free memory | 409 | /* free memory */ |
411 | for (i = 0; i < IP2_MAX_BOARDS; i++) { | 410 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
412 | void *pB; | 411 | void *pB; |
413 | #ifdef CONFIG_PCI | 412 | #ifdef CONFIG_PCI |
@@ -417,24 +416,18 @@ ip2_cleanup_module(void) | |||
417 | ip2config.pci_dev[i] = NULL; | 416 | ip2config.pci_dev[i] = NULL; |
418 | } | 417 | } |
419 | #endif | 418 | #endif |
420 | if ((pB = i2BoardPtrTable[i]) != 0 ) { | 419 | pB = i2BoardPtrTable[i]; |
421 | kfree ( pB ); | 420 | if (pB != NULL) { |
421 | kfree(pB); | ||
422 | i2BoardPtrTable[i] = NULL; | 422 | i2BoardPtrTable[i] = NULL; |
423 | } | 423 | } |
424 | if ((DevTableMem[i]) != NULL ) { | 424 | if (DevTableMem[i] != NULL) { |
425 | kfree ( DevTableMem[i] ); | 425 | kfree(DevTableMem[i]); |
426 | DevTableMem[i] = NULL; | 426 | DevTableMem[i] = NULL; |
427 | } | 427 | } |
428 | } | 428 | } |
429 | |||
430 | /* Cleanup the iiEllis subsystem. */ | ||
431 | iiEllisCleanup(); | ||
432 | #ifdef IP2DEBUG_INIT | ||
433 | printk (KERN_DEBUG "IP2 Unloaded\n" ); | ||
434 | #endif | ||
435 | } | 429 | } |
436 | module_exit(ip2_cleanup_module); | 430 | module_exit(ip2_cleanup_module); |
437 | #endif /* MODULE */ | ||
438 | 431 | ||
439 | static const struct tty_operations ip2_ops = { | 432 | static const struct tty_operations ip2_ops = { |
440 | .open = ip2_open, | 433 | .open = ip2_open, |
@@ -494,139 +487,168 @@ static const struct firmware *ip2_request_firmware(void) | |||
494 | return fw; | 487 | return fw; |
495 | } | 488 | } |
496 | 489 | ||
497 | int | 490 | #ifndef MODULE |
498 | ip2_loadmain(int *iop, int *irqp) | 491 | /****************************************************************************** |
492 | * ip2_setup: | ||
493 | * str: kernel command line string | ||
494 | * | ||
495 | * Can't autoprobe the boards so user must specify configuration on | ||
496 | * kernel command line. Sane people build it modular but the others | ||
497 | * come here. | ||
498 | * | ||
499 | * Alternating pairs of io,irq for up to 4 boards. | ||
500 | * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 | ||
501 | * | ||
502 | * io=0 => No board | ||
503 | * io=1 => PCI | ||
504 | * io=2 => EISA | ||
505 | * else => ISA I/O address | ||
506 | * | ||
507 | * irq=0 or invalid for ISA will revert to polling mode | ||
508 | * | ||
509 | * Any value = -1, do not overwrite compiled in value. | ||
510 | * | ||
511 | ******************************************************************************/ | ||
512 | static int __init ip2_setup(char *str) | ||
513 | { | ||
514 | int j, ints[10]; /* 4 boards, 2 parameters + 2 */ | ||
515 | unsigned int i; | ||
516 | |||
517 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
518 | |||
519 | for (i = 0, j = 1; i < 4; i++) { | ||
520 | if (j > ints[0]) | ||
521 | break; | ||
522 | if (ints[j] >= 0) | ||
523 | io[i] = ints[j]; | ||
524 | j++; | ||
525 | if (j > ints[0]) | ||
526 | break; | ||
527 | if (ints[j] >= 0) | ||
528 | irq[i] = ints[j]; | ||
529 | j++; | ||
530 | } | ||
531 | return 1; | ||
532 | } | ||
533 | __setup("ip2=", ip2_setup); | ||
534 | #endif /* !MODULE */ | ||
535 | |||
536 | static int __init ip2_loadmain(void) | ||
499 | { | 537 | { |
500 | int i, j, box; | 538 | int i, j, box; |
501 | int err = 0; | 539 | int err = 0; |
502 | static int loaded; | ||
503 | i2eBordStrPtr pB = NULL; | 540 | i2eBordStrPtr pB = NULL; |
504 | int rc = -1; | 541 | int rc = -1; |
505 | static struct pci_dev *pci_dev_i = NULL; | 542 | struct pci_dev *pdev = NULL; |
506 | const struct firmware *fw = NULL; | 543 | const struct firmware *fw = NULL; |
507 | 544 | ||
508 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); | 545 | if (poll_only) { |
546 | /* Hard lock the interrupts to zero */ | ||
547 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; | ||
548 | } | ||
549 | |||
550 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); | ||
509 | 551 | ||
510 | /* process command line arguments to modprobe or | 552 | /* process command line arguments to modprobe or |
511 | insmod i.e. iop & irqp */ | 553 | insmod i.e. iop & irqp */ |
512 | /* irqp and iop should ALWAYS be specified now... But we check | 554 | /* irqp and iop should ALWAYS be specified now... But we check |
513 | them individually just to be sure, anyways... */ | 555 | them individually just to be sure, anyways... */ |
514 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 556 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
515 | if (iop) { | 557 | ip2config.addr[i] = io[i]; |
516 | ip2config.addr[i] = iop[i]; | 558 | if (irq[i] >= 0) |
517 | if (irqp) { | 559 | ip2config.irq[i] = irq[i]; |
518 | if( irqp[i] >= 0 ) { | 560 | else |
519 | ip2config.irq[i] = irqp[i]; | 561 | ip2config.irq[i] = 0; |
520 | } else { | 562 | /* This is a little bit of a hack. If poll_only=1 on command |
521 | ip2config.irq[i] = 0; | 563 | line back in ip2.c OR all IRQs on all specified boards are |
522 | } | 564 | explicitly set to 0, then drop to poll only mode and override |
523 | // This is a little bit of a hack. If poll_only=1 on command | 565 | PCI or EISA interrupts. This superceeds the old hack of |
524 | // line back in ip2.c OR all IRQs on all specified boards are | 566 | triggering if all interrupts were zero (like da default). |
525 | // explicitly set to 0, then drop to poll only mode and override | 567 | Still a hack but less prone to random acts of terrorism. |
526 | // PCI or EISA interrupts. This superceeds the old hack of | 568 | |
527 | // triggering if all interrupts were zero (like da default). | 569 | What we really should do, now that the IRQ default is set |
528 | // Still a hack but less prone to random acts of terrorism. | 570 | to -1, is to use 0 as a hard coded, do not probe. |
529 | // | 571 | |
530 | // What we really should do, now that the IRQ default is set | 572 | /\/\|=mhw=|\/\/ |
531 | // to -1, is to use 0 as a hard coded, do not probe. | 573 | */ |
532 | // | 574 | poll_only |= irq[i]; |
533 | // /\/\|=mhw=|\/\/ | ||
534 | poll_only |= irqp[i]; | ||
535 | } | ||
536 | } | ||
537 | } | 575 | } |
538 | poll_only = !poll_only; | 576 | poll_only = !poll_only; |
539 | 577 | ||
540 | /* Announce our presence */ | 578 | /* Announce our presence */ |
541 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); | 579 | printk(KERN_INFO "%s version %s\n", pcName, pcVersion); |
542 | |||
543 | // ip2 can be unloaded and reloaded for no good reason | ||
544 | // we can't let that happen here or bad things happen | ||
545 | // second load hoses board but not system - fixme later | ||
546 | if (loaded) { | ||
547 | printk( KERN_INFO "Still loaded\n" ); | ||
548 | return 0; | ||
549 | } | ||
550 | loaded++; | ||
551 | 580 | ||
552 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); | 581 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); |
553 | if (!ip2_tty_driver) | 582 | if (!ip2_tty_driver) |
554 | return -ENOMEM; | 583 | return -ENOMEM; |
555 | 584 | ||
556 | /* Initialise the iiEllis subsystem. */ | ||
557 | iiEllisInit(); | ||
558 | |||
559 | /* Initialize arrays. */ | ||
560 | memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable ); | ||
561 | memset( DevTable, 0, sizeof DevTable ); | ||
562 | |||
563 | /* Initialise all the boards we can find (up to the maximum). */ | 585 | /* Initialise all the boards we can find (up to the maximum). */ |
564 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 586 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
565 | switch ( ip2config.addr[i] ) { | 587 | switch (ip2config.addr[i]) { |
566 | case 0: /* skip this slot even if card is present */ | 588 | case 0: /* skip this slot even if card is present */ |
567 | break; | 589 | break; |
568 | default: /* ISA */ | 590 | default: /* ISA */ |
569 | /* ISA address must be specified */ | 591 | /* ISA address must be specified */ |
570 | if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { | 592 | if (ip2config.addr[i] < 0x100 || |
571 | printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", | 593 | ip2config.addr[i] > 0x3f8) { |
572 | i, ip2config.addr[i] ); | 594 | printk(KERN_ERR "IP2: Bad ISA board %d " |
595 | "address %x\n", i, | ||
596 | ip2config.addr[i]); | ||
573 | ip2config.addr[i] = 0; | 597 | ip2config.addr[i] = 0; |
574 | } else { | 598 | break; |
575 | ip2config.type[i] = ISA; | 599 | } |
576 | 600 | ip2config.type[i] = ISA; | |
577 | /* Check for valid irq argument, set for polling if invalid */ | 601 | |
578 | if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { | 602 | /* Check for valid irq argument, set for polling if |
579 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); | 603 | * invalid */ |
580 | ip2config.irq[i] = 0;// 0 is polling and is valid in that sense | 604 | if (ip2config.irq[i] && |
581 | } | 605 | !is_valid_irq(ip2config.irq[i])) { |
606 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", | ||
607 | ip2config.irq[i]); | ||
608 | /* 0 is polling and is valid in that sense */ | ||
609 | ip2config.irq[i] = 0; | ||
582 | } | 610 | } |
583 | break; | 611 | break; |
584 | case PCI: | 612 | case PCI: |
585 | #ifdef CONFIG_PCI | 613 | #ifdef CONFIG_PCI |
586 | { | 614 | { |
587 | int status; | 615 | u32 addr; |
616 | int status; | ||
588 | 617 | ||
589 | pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, | 618 | pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, |
590 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); | 619 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); |
591 | if (pci_dev_i != NULL) { | 620 | if (pdev == NULL) { |
592 | unsigned int addr; | 621 | ip2config.addr[i] = 0; |
593 | 622 | printk(KERN_ERR "IP2: PCI board %d not " | |
594 | if (pci_enable_device(pci_dev_i)) { | 623 | "found\n", i); |
595 | printk( KERN_ERR "IP2: can't enable PCI device at %s\n", | 624 | break; |
596 | pci_name(pci_dev_i)); | 625 | } |
597 | break; | ||
598 | } | ||
599 | ip2config.type[i] = PCI; | ||
600 | ip2config.pci_dev[i] = pci_dev_get(pci_dev_i); | ||
601 | status = | ||
602 | pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); | ||
603 | if ( addr & 1 ) { | ||
604 | ip2config.addr[i]=(USHORT)(addr&0xfffe); | ||
605 | } else { | ||
606 | printk( KERN_ERR "IP2: PCI I/O address error\n"); | ||
607 | } | ||
608 | 626 | ||
609 | // If the PCI BIOS assigned it, lets try and use it. If we | 627 | if (pci_enable_device(pdev)) { |
610 | // can't acquire it or it screws up, deal with it then. | 628 | dev_err(&pdev->dev, "can't enable device\n"); |
611 | 629 | break; | |
612 | // if (!is_valid_irq(pci_irq)) { | ||
613 | // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); | ||
614 | // pci_irq = 0; | ||
615 | // } | ||
616 | ip2config.irq[i] = pci_dev_i->irq; | ||
617 | } else { // ann error | ||
618 | ip2config.addr[i] = 0; | ||
619 | printk(KERN_ERR "IP2: PCI board %d not found\n", i); | ||
620 | } | ||
621 | } | 630 | } |
631 | ip2config.type[i] = PCI; | ||
632 | ip2config.pci_dev[i] = pci_dev_get(pdev); | ||
633 | status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, | ||
634 | &addr); | ||
635 | if (addr & 1) | ||
636 | ip2config.addr[i] = (USHORT)(addr & 0xfffe); | ||
637 | else | ||
638 | dev_err(&pdev->dev, "I/O address error\n"); | ||
639 | |||
640 | ip2config.irq[i] = pdev->irq; | ||
641 | } | ||
622 | #else | 642 | #else |
623 | printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); | 643 | printk(KERN_ERR "IP2: PCI card specified but PCI " |
624 | printk( KERN_ERR "IP2: configured in this kernel.\n"); | 644 | "support not enabled.\n"); |
625 | printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n"); | 645 | printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " |
646 | "defined!\n"); | ||
626 | #endif /* CONFIG_PCI */ | 647 | #endif /* CONFIG_PCI */ |
627 | break; | 648 | break; |
628 | case EISA: | 649 | case EISA: |
629 | if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { | 650 | ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); |
651 | if (ip2config.addr[i] != 0) { | ||
630 | /* Eisa_irq set as side effect, boo */ | 652 | /* Eisa_irq set as side effect, boo */ |
631 | ip2config.type[i] = EISA; | 653 | ip2config.type[i] = EISA; |
632 | } | 654 | } |
@@ -634,31 +656,32 @@ ip2_loadmain(int *iop, int *irqp) | |||
634 | break; | 656 | break; |
635 | } /* switch */ | 657 | } /* switch */ |
636 | } /* for */ | 658 | } /* for */ |
637 | if (pci_dev_i) | 659 | pci_dev_put(pdev); |
638 | pci_dev_put(pci_dev_i); | ||
639 | 660 | ||
640 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 661 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
641 | if ( ip2config.addr[i] ) { | 662 | if (ip2config.addr[i]) { |
642 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); | 663 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); |
643 | if (pB) { | 664 | if (pB) { |
644 | i2BoardPtrTable[i] = pB; | 665 | i2BoardPtrTable[i] = pB; |
645 | iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); | 666 | iiSetAddress(pB, ip2config.addr[i], |
646 | iiReset( pB ); | 667 | ii2DelayTimer); |
647 | } else { | 668 | iiReset(pB); |
648 | printk(KERN_ERR "IP2: board memory allocation error\n"); | 669 | } else |
649 | } | 670 | printk(KERN_ERR "IP2: board memory allocation " |
671 | "error\n"); | ||
650 | } | 672 | } |
651 | } | 673 | } |
652 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 674 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
653 | if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { | 675 | pB = i2BoardPtrTable[i]; |
654 | iiResetDelay( pB ); | 676 | if (pB != NULL) { |
677 | iiResetDelay(pB); | ||
655 | break; | 678 | break; |
656 | } | 679 | } |
657 | } | 680 | } |
658 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 681 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
659 | /* We don't want to request the firmware unless we have at | 682 | /* We don't want to request the firmware unless we have at |
660 | least one board */ | 683 | least one board */ |
661 | if ( i2BoardPtrTable[i] != NULL ) { | 684 | if (i2BoardPtrTable[i] != NULL) { |
662 | if (!fw) | 685 | if (!fw) |
663 | fw = ip2_request_firmware(); | 686 | fw = ip2_request_firmware(); |
664 | if (!fw) | 687 | if (!fw) |
@@ -669,7 +692,7 @@ ip2_loadmain(int *iop, int *irqp) | |||
669 | if (fw) | 692 | if (fw) |
670 | release_firmware(fw); | 693 | release_firmware(fw); |
671 | 694 | ||
672 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); | 695 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); |
673 | 696 | ||
674 | ip2_tty_driver->owner = THIS_MODULE; | 697 | ip2_tty_driver->owner = THIS_MODULE; |
675 | ip2_tty_driver->name = "ttyF"; | 698 | ip2_tty_driver->name = "ttyF"; |
@@ -680,20 +703,23 @@ ip2_loadmain(int *iop, int *irqp) | |||
680 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 703 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
681 | ip2_tty_driver->init_termios = tty_std_termios; | 704 | ip2_tty_driver->init_termios = tty_std_termios; |
682 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | 705 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; |
683 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 706 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | |
707 | TTY_DRIVER_DYNAMIC_DEV; | ||
684 | tty_set_operations(ip2_tty_driver, &ip2_ops); | 708 | tty_set_operations(ip2_tty_driver, &ip2_ops); |
685 | 709 | ||
686 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); | 710 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); |
687 | 711 | ||
688 | /* Register the tty devices. */ | 712 | err = tty_register_driver(ip2_tty_driver); |
689 | if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) { | 713 | if (err) { |
690 | printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err); | 714 | printk(KERN_ERR "IP2: failed to register tty driver\n"); |
691 | put_tty_driver(ip2_tty_driver); | 715 | put_tty_driver(ip2_tty_driver); |
692 | return -EINVAL; | 716 | return err; /* leaking resources */ |
693 | } else | 717 | } |
694 | /* Register the IPL driver. */ | 718 | |
695 | if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { | 719 | err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); |
696 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); | 720 | if (err) { |
721 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", | ||
722 | err); | ||
697 | } else { | 723 | } else { |
698 | /* create the sysfs class */ | 724 | /* create the sysfs class */ |
699 | ip2_class = class_create(THIS_MODULE, "ip2"); | 725 | ip2_class = class_create(THIS_MODULE, "ip2"); |
@@ -705,84 +731,86 @@ ip2_loadmain(int *iop, int *irqp) | |||
705 | /* Register the read_procmem thing */ | 731 | /* Register the read_procmem thing */ |
706 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { | 732 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { |
707 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); | 733 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); |
708 | } else { | 734 | return -EIO; /* leaking resources */ |
735 | } | ||
709 | 736 | ||
710 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 ); | 737 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); |
711 | /* Register the interrupt handler or poll handler, depending upon the | 738 | /* Register the interrupt handler or poll handler, depending upon the |
712 | * specified interrupt. | 739 | * specified interrupt. |
713 | */ | 740 | */ |
714 | 741 | ||
715 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 742 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
716 | if ( 0 == ip2config.addr[i] ) { | 743 | if (ip2config.addr[i] == 0) |
717 | continue; | 744 | continue; |
718 | } | ||
719 | 745 | ||
720 | if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { | 746 | pB = i2BoardPtrTable[i]; |
721 | device_create_drvdata(ip2_class, NULL, | 747 | if (pB != NULL) { |
722 | MKDEV(IP2_IPL_MAJOR, 4 * i), | 748 | device_create(ip2_class, NULL, |
723 | NULL, "ipl%d", i); | 749 | MKDEV(IP2_IPL_MAJOR, 4 * i), |
724 | device_create_drvdata(ip2_class, NULL, | 750 | NULL, "ipl%d", i); |
725 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | 751 | device_create(ip2_class, NULL, |
726 | NULL, "stat%d", i); | 752 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), |
727 | 753 | NULL, "stat%d", i); | |
728 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) | 754 | |
729 | { | 755 | for (box = 0; box < ABS_MAX_BOXES; box++) |
730 | for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) | 756 | for (j = 0; j < ABS_BIGGEST_BOX; j++) |
731 | { | 757 | if (pB->i2eChannelMap[box] & (1 << j)) |
732 | if ( pB->i2eChannelMap[box] & (1 << j) ) | 758 | tty_register_device( |
733 | { | 759 | ip2_tty_driver, |
734 | tty_register_device(ip2_tty_driver, | 760 | j + ABS_BIGGEST_BOX * |
735 | j + ABS_BIGGEST_BOX * | 761 | (box+i*ABS_MAX_BOXES), |
736 | (box+i*ABS_MAX_BOXES), NULL); | 762 | NULL); |
737 | } | 763 | } |
738 | } | ||
739 | } | ||
740 | } | ||
741 | 764 | ||
742 | if (poll_only) { | 765 | if (poll_only) { |
743 | // Poll only forces driver to only use polling and | 766 | /* Poll only forces driver to only use polling and |
744 | // to ignore the probed PCI or EISA interrupts. | 767 | to ignore the probed PCI or EISA interrupts. */ |
745 | ip2config.irq[i] = CIR_POLL; | 768 | ip2config.irq[i] = CIR_POLL; |
746 | } | 769 | } |
747 | if ( ip2config.irq[i] == CIR_POLL ) { | 770 | if (ip2config.irq[i] == CIR_POLL) { |
748 | retry: | 771 | retry: |
749 | if (!TimerOn) { | 772 | if (!timer_pending(&PollTimer)) { |
750 | PollTimer.expires = POLL_TIMEOUT; | 773 | mod_timer(&PollTimer, POLL_TIMEOUT); |
751 | add_timer ( &PollTimer ); | 774 | printk(KERN_INFO "IP2: polling\n"); |
752 | TimerOn = 1; | ||
753 | printk( KERN_INFO "IP2: polling\n"); | ||
754 | } | ||
755 | } else { | ||
756 | if (have_requested_irq(ip2config.irq[i])) | ||
757 | continue; | ||
758 | rc = request_irq( ip2config.irq[i], ip2_interrupt, | ||
759 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
760 | pcName, i2BoardPtrTable[i]); | ||
761 | if (rc) { | ||
762 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); | ||
763 | ip2config.irq[i] = CIR_POLL; | ||
764 | printk( KERN_INFO "IP2: Polling %ld/sec.\n", | ||
765 | (POLL_TIMEOUT - jiffies)); | ||
766 | goto retry; | ||
767 | } | ||
768 | mark_requested_irq(ip2config.irq[i]); | ||
769 | /* Initialise the interrupt handler bottom half (aka slih). */ | ||
770 | } | 775 | } |
771 | } | 776 | } else { |
772 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 777 | if (have_requested_irq(ip2config.irq[i])) |
773 | if ( i2BoardPtrTable[i] ) { | 778 | continue; |
774 | set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ | 779 | rc = request_irq(ip2config.irq[i], ip2_interrupt, |
780 | IP2_SA_FLAGS | | ||
781 | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
782 | pcName, i2BoardPtrTable[i]); | ||
783 | if (rc) { | ||
784 | printk(KERN_ERR "IP2: request_irq failed: " | ||
785 | "error %d\n", rc); | ||
786 | ip2config.irq[i] = CIR_POLL; | ||
787 | printk(KERN_INFO "IP2: Polling %ld/sec.\n", | ||
788 | (POLL_TIMEOUT - jiffies)); | ||
789 | goto retry; | ||
775 | } | 790 | } |
791 | mark_requested_irq(ip2config.irq[i]); | ||
792 | /* Initialise the interrupt handler bottom half | ||
793 | * (aka slih). */ | ||
776 | } | 794 | } |
777 | } | 795 | } |
778 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); | 796 | |
779 | goto out; | 797 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
798 | if (i2BoardPtrTable[i]) { | ||
799 | /* set and enable board interrupt */ | ||
800 | set_irq(i, ip2config.irq[i]); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); | ||
805 | |||
806 | return 0; | ||
780 | 807 | ||
781 | out_chrdev: | 808 | out_chrdev: |
782 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); | 809 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); |
783 | out: | 810 | /* unregister and put tty here */ |
784 | return err; | 811 | return err; |
785 | } | 812 | } |
813 | module_init(ip2_loadmain); | ||
786 | 814 | ||
787 | /******************************************************************************/ | 815 | /******************************************************************************/ |
788 | /* Function: ip2_init_board() */ | 816 | /* Function: ip2_init_board() */ |
@@ -1199,9 +1227,8 @@ ip2_polled_interrupt(void) | |||
1199 | { | 1227 | { |
1200 | int i; | 1228 | int i; |
1201 | i2eBordStrPtr pB; | 1229 | i2eBordStrPtr pB; |
1202 | const int irq = 0; | ||
1203 | 1230 | ||
1204 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); | 1231 | ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); |
1205 | 1232 | ||
1206 | /* Service just the boards on the list using this irq */ | 1233 | /* Service just the boards on the list using this irq */ |
1207 | for( i = 0; i < i2nBoards; ++i ) { | 1234 | for( i = 0; i < i2nBoards; ++i ) { |
@@ -1210,9 +1237,8 @@ ip2_polled_interrupt(void) | |||
1210 | // Only process those boards which match our IRQ. | 1237 | // Only process those boards which match our IRQ. |
1211 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards | 1238 | // IRQ = 0 for polled boards, we won't poll "IRQ" boards |
1212 | 1239 | ||
1213 | if ( pB && (pB->i2eUsingIrq == irq) ) { | 1240 | if (pB && pB->i2eUsingIrq == 0) |
1214 | ip2_irq_work(pB); | 1241 | ip2_irq_work(pB); |
1215 | } | ||
1216 | } | 1242 | } |
1217 | 1243 | ||
1218 | ++irq_counter; | 1244 | ++irq_counter; |
@@ -1250,16 +1276,12 @@ ip2_poll(unsigned long arg) | |||
1250 | { | 1276 | { |
1251 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); | 1277 | ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); |
1252 | 1278 | ||
1253 | TimerOn = 0; // it's the truth but not checked in service | ||
1254 | |||
1255 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. | 1279 | // Just polled boards, IRQ = 0 will hit all non-interrupt boards. |
1256 | // It will NOT poll boards handled by hard interrupts. | 1280 | // It will NOT poll boards handled by hard interrupts. |
1257 | // The issue of queued BH interrupts is handled in ip2_interrupt(). | 1281 | // The issue of queued BH interrupts is handled in ip2_interrupt(). |
1258 | ip2_polled_interrupt(); | 1282 | ip2_polled_interrupt(); |
1259 | 1283 | ||
1260 | PollTimer.expires = POLL_TIMEOUT; | 1284 | mod_timer(&PollTimer, POLL_TIMEOUT); |
1261 | add_timer( &PollTimer ); | ||
1262 | TimerOn = 1; | ||
1263 | 1285 | ||
1264 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | 1286 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1265 | } | 1287 | } |
@@ -2871,7 +2893,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2871 | case 13: | 2893 | case 13: |
2872 | switch ( cmd ) { | 2894 | switch ( cmd ) { |
2873 | case 64: /* Driver - ip2stat */ | 2895 | case 64: /* Driver - ip2stat */ |
2874 | rc = put_user(ip2_tty_driver->refcount, pIndex++ ); | 2896 | rc = put_user(-1, pIndex++ ); |
2875 | rc = put_user(irq_counter, pIndex++ ); | 2897 | rc = put_user(irq_counter, pIndex++ ); |
2876 | rc = put_user(bh_counter, pIndex++ ); | 2898 | rc = put_user(bh_counter, pIndex++ ); |
2877 | break; | 2899 | break; |
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index ec9d0443d92c..2abd881b4cbc 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -130,12 +130,12 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
130 | if (yrs >= 100) | 130 | if (yrs >= 100) |
131 | yrs -= 100; | 131 | yrs -= 100; |
132 | 132 | ||
133 | sec = BIN2BCD(sec); | 133 | sec = bin2bcd(sec); |
134 | min = BIN2BCD(min); | 134 | min = bin2bcd(min); |
135 | hrs = BIN2BCD(hrs); | 135 | hrs = bin2bcd(hrs); |
136 | day = BIN2BCD(day); | 136 | day = bin2bcd(day); |
137 | mon = BIN2BCD(mon); | 137 | mon = bin2bcd(mon); |
138 | yrs = BIN2BCD(yrs); | 138 | yrs = bin2bcd(yrs); |
139 | 139 | ||
140 | spin_lock_irq(&rtc_lock); | 140 | spin_lock_irq(&rtc_lock); |
141 | rtc->control |= M48T35_RTC_SET; | 141 | rtc->control |= M48T35_RTC_SET; |
@@ -311,12 +311,12 @@ static void get_rtc_time(struct rtc_time *rtc_tm) | |||
311 | rtc->control &= ~M48T35_RTC_READ; | 311 | rtc->control &= ~M48T35_RTC_READ; |
312 | spin_unlock_irq(&rtc_lock); | 312 | spin_unlock_irq(&rtc_lock); |
313 | 313 | ||
314 | rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); | 314 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
315 | rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); | 315 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
316 | rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); | 316 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
317 | rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); | 317 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
318 | rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); | 318 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
319 | rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); | 319 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * Account for differences between how the RTC uses the values | 322 | * Account for differences between how the RTC uses the values |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 64e1c169e826..835a33c8d5f5 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device) | |||
871 | entry->dev = dev; | 871 | entry->dev = dev; |
872 | 872 | ||
873 | mutex_lock(®_list_mutex); | 873 | mutex_lock(®_list_mutex); |
874 | device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num); | 874 | device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num); |
875 | list_add(&entry->link, ®_list); | 875 | list_add(&entry->link, ®_list); |
876 | mutex_unlock(®_list_mutex); | 876 | mutex_unlock(®_list_mutex); |
877 | } | 877 | } |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 8e8afb6141f9..3123bf57ad91 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -2695,7 +2695,7 @@ static __devinit void default_find_bmc(void) | |||
2695 | for (i = 0; ; i++) { | 2695 | for (i = 0; ; i++) { |
2696 | if (!ipmi_defaults[i].port) | 2696 | if (!ipmi_defaults[i].port) |
2697 | break; | 2697 | break; |
2698 | #ifdef CONFIG_PPC_MERGE | 2698 | #ifdef CONFIG_PPC |
2699 | if (check_legacy_ioport(ipmi_defaults[i].port)) | 2699 | if (check_legacy_ioport(ipmi_defaults[i].port)) |
2700 | continue; | 2700 | continue; |
2701 | #endif | 2701 | #endif |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 8f7cc190b62d..7d30ee1d3fca 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data) | |||
421 | if (retries >= 100) | 421 | if (retries >= 100) |
422 | goto unlock; | 422 | goto unlock; |
423 | 423 | ||
424 | tty = tty_port_tty_get(&port->port); | ||
425 | if (tty == NULL) | ||
426 | goto put_unlock; | ||
427 | |||
424 | for (; count > 0; count--, port++) { | 428 | for (; count > 0; count--, port++) { |
425 | /* port not active or tx disabled to force flow control */ | 429 | /* port not active or tx disabled to force flow control */ |
426 | if (!(port->port.flags & ASYNC_INITIALIZED) || | 430 | if (!(port->port.flags & ASYNC_INITIALIZED) || |
427 | !(port->status & ISI_TXOK)) | 431 | !(port->status & ISI_TXOK)) |
428 | continue; | 432 | continue; |
429 | 433 | ||
430 | tty = port->port.tty; | ||
431 | |||
432 | if (tty == NULL) | ||
433 | continue; | ||
434 | |||
435 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); | 434 | txcount = min_t(short, TX_SIZE, port->xmit_cnt); |
436 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) | 435 | if (txcount <= 0 || tty->stopped || tty->hw_stopped) |
437 | continue; | 436 | continue; |
@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data) | |||
489 | tty_wakeup(tty); | 488 | tty_wakeup(tty); |
490 | } | 489 | } |
491 | 490 | ||
491 | put_unlock: | ||
492 | tty_kref_put(tty); | ||
492 | unlock: | 493 | unlock: |
493 | spin_unlock_irqrestore(&isi_card[card].card_lock, flags); | 494 | spin_unlock_irqrestore(&isi_card[card].card_lock, flags); |
494 | /* schedule another tx for hopefully in about 10ms */ | 495 | /* schedule another tx for hopefully in about 10ms */ |
@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
547 | return IRQ_HANDLED; | 548 | return IRQ_HANDLED; |
548 | } | 549 | } |
549 | 550 | ||
550 | tty = port->port.tty; | 551 | tty = tty_port_tty_get(&port->port); |
551 | if (tty == NULL) { | 552 | if (tty == NULL) { |
552 | word_count = byte_count >> 1; | 553 | word_count = byte_count >> 1; |
553 | while (byte_count > 1) { | 554 | while (byte_count > 1) { |
@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
588 | } | 589 | } |
589 | 590 | ||
590 | if (port->port.flags & ASYNC_CTS_FLOW) { | 591 | if (port->port.flags & ASYNC_CTS_FLOW) { |
591 | if (port->port.tty->hw_stopped) { | 592 | if (tty->hw_stopped) { |
592 | if (header & ISI_CTS) { | 593 | if (header & ISI_CTS) { |
593 | port->port.tty->hw_stopped = 0; | 594 | port->port.tty->hw_stopped = 0; |
594 | /* start tx ing */ | 595 | /* start tx ing */ |
@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
597 | tty_wakeup(tty); | 598 | tty_wakeup(tty); |
598 | } | 599 | } |
599 | } else if (!(header & ISI_CTS)) { | 600 | } else if (!(header & ISI_CTS)) { |
600 | port->port.tty->hw_stopped = 1; | 601 | tty->hw_stopped = 1; |
601 | /* stop tx ing */ | 602 | /* stop tx ing */ |
602 | port->status &= ~(ISI_TXOK | ISI_CTS); | 603 | port->status &= ~(ISI_TXOK | ISI_CTS); |
603 | } | 604 | } |
@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
660 | } | 661 | } |
661 | outw(0x0000, base+0x04); /* enable interrupts */ | 662 | outw(0x0000, base+0x04); /* enable interrupts */ |
662 | spin_unlock(&card->card_lock); | 663 | spin_unlock(&card->card_lock); |
664 | tty_kref_put(tty); | ||
663 | 665 | ||
664 | return IRQ_HANDLED; | 666 | return IRQ_HANDLED; |
665 | } | 667 | } |
666 | 668 | ||
667 | static void isicom_config_port(struct isi_port *port) | 669 | static void isicom_config_port(struct tty_struct *tty) |
668 | { | 670 | { |
671 | struct isi_port *port = tty->driver_data; | ||
669 | struct isi_board *card = port->card; | 672 | struct isi_board *card = port->card; |
670 | struct tty_struct *tty; | ||
671 | unsigned long baud; | 673 | unsigned long baud; |
672 | unsigned long base = card->base; | 674 | unsigned long base = card->base; |
673 | u16 channel_setup, channel = port->channel, | 675 | u16 channel_setup, channel = port->channel, |
674 | shift_count = card->shift_count; | 676 | shift_count = card->shift_count; |
675 | unsigned char flow_ctrl; | 677 | unsigned char flow_ctrl; |
676 | 678 | ||
677 | tty = port->port.tty; | ||
678 | |||
679 | if (tty == NULL) | ||
680 | return; | ||
681 | /* FIXME: Switch to new tty baud API */ | 679 | /* FIXME: Switch to new tty baud API */ |
682 | baud = C_BAUD(tty); | 680 | baud = C_BAUD(tty); |
683 | if (baud & CBAUDEX) { | 681 | if (baud & CBAUDEX) { |
@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port) | |||
690 | 688 | ||
691 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ | 689 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ |
692 | if (baud < 1 || baud > 4) | 690 | if (baud < 1 || baud > 4) |
693 | port->port.tty->termios->c_cflag &= ~CBAUDEX; | 691 | tty->termios->c_cflag &= ~CBAUDEX; |
694 | else | 692 | else |
695 | baud += 15; | 693 | baud += 15; |
696 | } | 694 | } |
@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp) | |||
797 | spin_unlock_irqrestore(&bp->card_lock, flags); | 795 | spin_unlock_irqrestore(&bp->card_lock, flags); |
798 | } | 796 | } |
799 | 797 | ||
800 | static int isicom_setup_port(struct isi_port *port) | 798 | static int isicom_setup_port(struct tty_struct *tty) |
801 | { | 799 | { |
800 | struct isi_port *port = tty->driver_data; | ||
802 | struct isi_board *card = port->card; | 801 | struct isi_board *card = port->card; |
803 | unsigned long flags; | 802 | unsigned long flags; |
804 | 803 | ||
@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port) | |||
808 | return -ENOMEM; | 807 | return -ENOMEM; |
809 | 808 | ||
810 | spin_lock_irqsave(&card->card_lock, flags); | 809 | spin_lock_irqsave(&card->card_lock, flags); |
811 | if (port->port.tty) | 810 | clear_bit(TTY_IO_ERROR, &tty->flags); |
812 | clear_bit(TTY_IO_ERROR, &port->port.tty->flags); | ||
813 | if (port->port.count == 1) | 811 | if (port->port.count == 1) |
814 | card->count++; | 812 | card->count++; |
815 | 813 | ||
@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port) | |||
823 | InterruptTheCard(card->base); | 821 | InterruptTheCard(card->base); |
824 | } | 822 | } |
825 | 823 | ||
826 | isicom_config_port(port); | 824 | isicom_config_port(tty); |
827 | port->port.flags |= ASYNC_INITIALIZED; | 825 | port->port.flags |= ASYNC_INITIALIZED; |
828 | spin_unlock_irqrestore(&card->card_lock, flags); | 826 | spin_unlock_irqrestore(&card->card_lock, flags); |
829 | 827 | ||
@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
934 | 932 | ||
935 | port->port.count++; | 933 | port->port.count++; |
936 | tty->driver_data = port; | 934 | tty->driver_data = port; |
937 | port->port.tty = tty; | 935 | tty_port_tty_set(&port->port, tty); |
938 | error = isicom_setup_port(port); | 936 | error = isicom_setup_port(tty); |
939 | if (error == 0) | 937 | if (error == 0) |
940 | error = block_til_ready(tty, filp, port); | 938 | error = block_til_ready(tty, filp, port); |
941 | return error; | 939 | return error; |
@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
955 | struct isi_board *card = port->card; | 953 | struct isi_board *card = port->card; |
956 | struct tty_struct *tty; | 954 | struct tty_struct *tty; |
957 | 955 | ||
958 | tty = port->port.tty; | 956 | tty = tty_port_tty_get(&port->port); |
959 | 957 | ||
960 | if (!(port->port.flags & ASYNC_INITIALIZED)) | 958 | if (!(port->port.flags & ASYNC_INITIALIZED)) { |
959 | tty_kref_put(tty); | ||
961 | return; | 960 | return; |
961 | } | ||
962 | 962 | ||
963 | tty_port_free_xmit_buf(&port->port); | 963 | tty_port_free_xmit_buf(&port->port); |
964 | port->port.flags &= ~ASYNC_INITIALIZED; | 964 | port->port.flags &= ~ASYNC_INITIALIZED; |
965 | /* 3rd October 2000 : Vinayak P Risbud */ | 965 | /* 3rd October 2000 : Vinayak P Risbud */ |
966 | port->port.tty = NULL; | 966 | tty_port_tty_set(&port->port, NULL); |
967 | 967 | ||
968 | /*Fix done by Anil .S on 30-04-2001 | 968 | /*Fix done by Anil .S on 30-04-2001 |
969 | remote login through isi port has dtr toggle problem | 969 | remote login through isi port has dtr toggle problem |
@@ -1243,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file, | |||
1243 | return 0; | 1243 | return 0; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | static int isicom_set_serial_info(struct isi_port *port, | 1246 | static int isicom_set_serial_info(struct tty_struct *tty, |
1247 | struct serial_struct __user *info) | 1247 | struct serial_struct __user *info) |
1248 | { | 1248 | { |
1249 | struct isi_port *port = tty->driver_data; | ||
1249 | struct serial_struct newinfo; | 1250 | struct serial_struct newinfo; |
1250 | int reconfig_port; | 1251 | int reconfig_port; |
1251 | 1252 | ||
@@ -1276,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port, | |||
1276 | if (reconfig_port) { | 1277 | if (reconfig_port) { |
1277 | unsigned long flags; | 1278 | unsigned long flags; |
1278 | spin_lock_irqsave(&port->card->card_lock, flags); | 1279 | spin_lock_irqsave(&port->card->card_lock, flags); |
1279 | isicom_config_port(port); | 1280 | isicom_config_port(tty); |
1280 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1281 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1281 | } | 1282 | } |
1282 | unlock_kernel(); | 1283 | unlock_kernel(); |
@@ -1318,7 +1319,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, | |||
1318 | return isicom_get_serial_info(port, argp); | 1319 | return isicom_get_serial_info(port, argp); |
1319 | 1320 | ||
1320 | case TIOCSSERIAL: | 1321 | case TIOCSSERIAL: |
1321 | return isicom_set_serial_info(port, argp); | 1322 | return isicom_set_serial_info(tty, argp); |
1322 | 1323 | ||
1323 | default: | 1324 | default: |
1324 | return -ENOIOCTLCMD; | 1325 | return -ENOIOCTLCMD; |
@@ -1341,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
1341 | return; | 1342 | return; |
1342 | 1343 | ||
1343 | spin_lock_irqsave(&port->card->card_lock, flags); | 1344 | spin_lock_irqsave(&port->card->card_lock, flags); |
1344 | isicom_config_port(port); | 1345 | isicom_config_port(tty); |
1345 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1346 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1346 | 1347 | ||
1347 | if ((old_termios->c_cflag & CRTSCTS) && | 1348 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -1419,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1419 | 1420 | ||
1420 | port->port.count = 0; | 1421 | port->port.count = 0; |
1421 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1422 | port->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1422 | port->port.tty = NULL; | 1423 | tty_port_tty_set(&port->port, NULL); |
1423 | wake_up_interruptible(&port->port.open_wait); | 1424 | wake_up_interruptible(&port->port.open_wait); |
1424 | } | 1425 | } |
1425 | 1426 | ||
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 843a2afaf204..44e5d60f517e 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -623,24 +623,25 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
623 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); | 623 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); |
624 | static void stli_poll(unsigned long arg); | 624 | static void stli_poll(unsigned long arg); |
625 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); | 625 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); |
626 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp); | 626 | static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); |
627 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); | 627 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
628 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); | 628 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
629 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp); | 629 | static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, |
630 | static int stli_setport(struct stliport *portp); | 630 | struct stliport *portp, struct file *filp); |
631 | static int stli_setport(struct tty_struct *tty); | ||
631 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 632 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
632 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 633 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
633 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); | 634 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
634 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); | 635 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); |
635 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); | 636 | static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); |
636 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); | 637 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); |
637 | static long stli_mktiocm(unsigned long sigvalue); | 638 | static long stli_mktiocm(unsigned long sigvalue); |
638 | static void stli_read(struct stlibrd *brdp, struct stliport *portp); | 639 | static void stli_read(struct stlibrd *brdp, struct stliport *portp); |
639 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); | 640 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); |
640 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp); | 641 | static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); |
641 | static int stli_getbrdstats(combrd_t __user *bp); | 642 | static int stli_getbrdstats(combrd_t __user *bp); |
642 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp); | 643 | static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); |
643 | static int stli_portcmdstats(struct stliport *portp); | 644 | static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); |
644 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); | 645 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); |
645 | static int stli_getportstruct(struct stliport __user *arg); | 646 | static int stli_getportstruct(struct stliport __user *arg); |
646 | static int stli_getbrdstruct(struct stlibrd __user *arg); | 647 | static int stli_getbrdstruct(struct stlibrd __user *arg); |
@@ -731,12 +732,16 @@ static void stli_cleanup_ports(struct stlibrd *brdp) | |||
731 | { | 732 | { |
732 | struct stliport *portp; | 733 | struct stliport *portp; |
733 | unsigned int j; | 734 | unsigned int j; |
735 | struct tty_struct *tty; | ||
734 | 736 | ||
735 | for (j = 0; j < STL_MAXPORTS; j++) { | 737 | for (j = 0; j < STL_MAXPORTS; j++) { |
736 | portp = brdp->ports[j]; | 738 | portp = brdp->ports[j]; |
737 | if (portp != NULL) { | 739 | if (portp != NULL) { |
738 | if (portp->port.tty != NULL) | 740 | tty = tty_port_tty_get(&portp->port); |
739 | tty_hangup(portp->port.tty); | 741 | if (tty != NULL) { |
742 | tty_hangup(tty); | ||
743 | tty_kref_put(tty); | ||
744 | } | ||
740 | kfree(portp); | 745 | kfree(portp); |
741 | } | 746 | } |
742 | } | 747 | } |
@@ -824,7 +829,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
824 | * requires several commands to the board we will need to wait for any | 829 | * requires several commands to the board we will need to wait for any |
825 | * other open that is already initializing the port. | 830 | * other open that is already initializing the port. |
826 | */ | 831 | */ |
827 | portp->port.tty = tty; | 832 | tty_port_tty_set(&portp->port, tty); |
828 | tty->driver_data = portp; | 833 | tty->driver_data = portp; |
829 | portp->port.count++; | 834 | portp->port.count++; |
830 | 835 | ||
@@ -835,7 +840,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
835 | 840 | ||
836 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { | 841 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { |
837 | set_bit(ST_INITIALIZING, &portp->state); | 842 | set_bit(ST_INITIALIZING, &portp->state); |
838 | if ((rc = stli_initopen(brdp, portp)) >= 0) { | 843 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) { |
839 | portp->port.flags |= ASYNC_INITIALIZED; | 844 | portp->port.flags |= ASYNC_INITIALIZED; |
840 | clear_bit(TTY_IO_ERROR, &tty->flags); | 845 | clear_bit(TTY_IO_ERROR, &tty->flags); |
841 | } | 846 | } |
@@ -864,7 +869,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
864 | * then also we might have to wait for carrier. | 869 | * then also we might have to wait for carrier. |
865 | */ | 870 | */ |
866 | if (!(filp->f_flags & O_NONBLOCK)) { | 871 | if (!(filp->f_flags & O_NONBLOCK)) { |
867 | if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) | 872 | if ((rc = stli_waitcarrier(tty, brdp, portp, filp)) != 0) |
868 | return rc; | 873 | return rc; |
869 | } | 874 | } |
870 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; | 875 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; |
@@ -930,7 +935,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
930 | stli_flushbuffer(tty); | 935 | stli_flushbuffer(tty); |
931 | 936 | ||
932 | tty->closing = 0; | 937 | tty->closing = 0; |
933 | portp->port.tty = NULL; | 938 | tty_port_tty_set(&portp->port, NULL); |
934 | 939 | ||
935 | if (portp->openwaitcnt) { | 940 | if (portp->openwaitcnt) { |
936 | if (portp->close_delay) | 941 | if (portp->close_delay) |
@@ -952,9 +957,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
952 | * this still all happens pretty quickly. | 957 | * this still all happens pretty quickly. |
953 | */ | 958 | */ |
954 | 959 | ||
955 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) | 960 | static int stli_initopen(struct tty_struct *tty, |
961 | struct stlibrd *brdp, struct stliport *portp) | ||
956 | { | 962 | { |
957 | struct tty_struct *tty; | ||
958 | asynotify_t nt; | 963 | asynotify_t nt; |
959 | asyport_t aport; | 964 | asyport_t aport; |
960 | int rc; | 965 | int rc; |
@@ -969,10 +974,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) | |||
969 | sizeof(asynotify_t), 0)) < 0) | 974 | sizeof(asynotify_t), 0)) < 0) |
970 | return rc; | 975 | return rc; |
971 | 976 | ||
972 | tty = portp->port.tty; | 977 | stli_mkasyport(tty, portp, &aport, tty->termios); |
973 | if (tty == NULL) | ||
974 | return -ENODEV; | ||
975 | stli_mkasyport(portp, &aport, tty->termios); | ||
976 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, | 978 | if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, |
977 | sizeof(asyport_t), 0)) < 0) | 979 | sizeof(asyport_t), 0)) < 0) |
978 | return rc; | 980 | return rc; |
@@ -1161,22 +1163,21 @@ static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned l | |||
1161 | * waiting for the command to complete - so must have user context. | 1163 | * waiting for the command to complete - so must have user context. |
1162 | */ | 1164 | */ |
1163 | 1165 | ||
1164 | static int stli_setport(struct stliport *portp) | 1166 | static int stli_setport(struct tty_struct *tty) |
1165 | { | 1167 | { |
1168 | struct stliport *portp = tty->driver_data; | ||
1166 | struct stlibrd *brdp; | 1169 | struct stlibrd *brdp; |
1167 | asyport_t aport; | 1170 | asyport_t aport; |
1168 | 1171 | ||
1169 | if (portp == NULL) | 1172 | if (portp == NULL) |
1170 | return -ENODEV; | 1173 | return -ENODEV; |
1171 | if (portp->port.tty == NULL) | ||
1172 | return -ENODEV; | ||
1173 | if (portp->brdnr >= stli_nrbrds) | 1174 | if (portp->brdnr >= stli_nrbrds) |
1174 | return -ENODEV; | 1175 | return -ENODEV; |
1175 | brdp = stli_brds[portp->brdnr]; | 1176 | brdp = stli_brds[portp->brdnr]; |
1176 | if (brdp == NULL) | 1177 | if (brdp == NULL) |
1177 | return -ENODEV; | 1178 | return -ENODEV; |
1178 | 1179 | ||
1179 | stli_mkasyport(portp, &aport, portp->port.tty->termios); | 1180 | stli_mkasyport(tty, portp, &aport, tty->termios); |
1180 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); | 1181 | return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); |
1181 | } | 1182 | } |
1182 | 1183 | ||
@@ -1187,7 +1188,8 @@ static int stli_setport(struct stliport *portp) | |||
1187 | * maybe because if we are clocal then we don't need to wait... | 1188 | * maybe because if we are clocal then we don't need to wait... |
1188 | */ | 1189 | */ |
1189 | 1190 | ||
1190 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) | 1191 | static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp, |
1192 | struct stliport *portp, struct file *filp) | ||
1191 | { | 1193 | { |
1192 | unsigned long flags; | 1194 | unsigned long flags; |
1193 | int rc, doclocal; | 1195 | int rc, doclocal; |
@@ -1195,7 +1197,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct | |||
1195 | rc = 0; | 1197 | rc = 0; |
1196 | doclocal = 0; | 1198 | doclocal = 0; |
1197 | 1199 | ||
1198 | if (portp->port.tty->termios->c_cflag & CLOCAL) | 1200 | if (tty->termios->c_cflag & CLOCAL) |
1199 | doclocal++; | 1201 | doclocal++; |
1200 | 1202 | ||
1201 | spin_lock_irqsave(&stli_lock, flags); | 1203 | spin_lock_irqsave(&stli_lock, flags); |
@@ -1373,8 +1375,6 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1373 | stli_txcookrealsize = 0; | 1375 | stli_txcookrealsize = 0; |
1374 | stli_txcooktty = NULL; | 1376 | stli_txcooktty = NULL; |
1375 | 1377 | ||
1376 | if (tty == NULL) | ||
1377 | return; | ||
1378 | if (cooktty == NULL) | 1378 | if (cooktty == NULL) |
1379 | return; | 1379 | return; |
1380 | if (tty != cooktty) | 1380 | if (tty != cooktty) |
@@ -1572,10 +1572,11 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s | |||
1572 | * just quietly ignore any requests to change irq, etc. | 1572 | * just quietly ignore any requests to change irq, etc. |
1573 | */ | 1573 | */ |
1574 | 1574 | ||
1575 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) | 1575 | static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) |
1576 | { | 1576 | { |
1577 | struct serial_struct sio; | 1577 | struct serial_struct sio; |
1578 | int rc; | 1578 | int rc; |
1579 | struct stliport *portp = tty->driver_data; | ||
1579 | 1580 | ||
1580 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | 1581 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) |
1581 | return -EFAULT; | 1582 | return -EFAULT; |
@@ -1594,7 +1595,7 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s | |||
1594 | portp->closing_wait = sio.closing_wait; | 1595 | portp->closing_wait = sio.closing_wait; |
1595 | portp->custom_divisor = sio.custom_divisor; | 1596 | portp->custom_divisor = sio.custom_divisor; |
1596 | 1597 | ||
1597 | if ((rc = stli_setport(portp)) < 0) | 1598 | if ((rc = stli_setport(tty)) < 0) |
1598 | return rc; | 1599 | return rc; |
1599 | return 0; | 1600 | return 0; |
1600 | } | 1601 | } |
@@ -1685,17 +1686,17 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1685 | rc = stli_getserial(portp, argp); | 1686 | rc = stli_getserial(portp, argp); |
1686 | break; | 1687 | break; |
1687 | case TIOCSSERIAL: | 1688 | case TIOCSSERIAL: |
1688 | rc = stli_setserial(portp, argp); | 1689 | rc = stli_setserial(tty, argp); |
1689 | break; | 1690 | break; |
1690 | case STL_GETPFLAG: | 1691 | case STL_GETPFLAG: |
1691 | rc = put_user(portp->pflag, (unsigned __user *)argp); | 1692 | rc = put_user(portp->pflag, (unsigned __user *)argp); |
1692 | break; | 1693 | break; |
1693 | case STL_SETPFLAG: | 1694 | case STL_SETPFLAG: |
1694 | if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) | 1695 | if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) |
1695 | stli_setport(portp); | 1696 | stli_setport(tty); |
1696 | break; | 1697 | break; |
1697 | case COM_GETPORTSTATS: | 1698 | case COM_GETPORTSTATS: |
1698 | rc = stli_getportstats(portp, argp); | 1699 | rc = stli_getportstats(tty, portp, argp); |
1699 | break; | 1700 | break; |
1700 | case COM_CLRPORTSTATS: | 1701 | case COM_CLRPORTSTATS: |
1701 | rc = stli_clrportstats(portp, argp); | 1702 | rc = stli_clrportstats(portp, argp); |
@@ -1729,8 +1730,6 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1729 | struct ktermios *tiosp; | 1730 | struct ktermios *tiosp; |
1730 | asyport_t aport; | 1731 | asyport_t aport; |
1731 | 1732 | ||
1732 | if (tty == NULL) | ||
1733 | return; | ||
1734 | portp = tty->driver_data; | 1733 | portp = tty->driver_data; |
1735 | if (portp == NULL) | 1734 | if (portp == NULL) |
1736 | return; | 1735 | return; |
@@ -1742,7 +1741,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1742 | 1741 | ||
1743 | tiosp = tty->termios; | 1742 | tiosp = tty->termios; |
1744 | 1743 | ||
1745 | stli_mkasyport(portp, &aport, tiosp); | 1744 | stli_mkasyport(tty, portp, &aport, tiosp); |
1746 | stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); | 1745 | stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); |
1747 | stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); | 1746 | stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); |
1748 | stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, | 1747 | stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, |
@@ -1854,7 +1853,7 @@ static void stli_hangup(struct tty_struct *tty) | |||
1854 | clear_bit(ST_TXBUSY, &portp->state); | 1853 | clear_bit(ST_TXBUSY, &portp->state); |
1855 | clear_bit(ST_RXSTOP, &portp->state); | 1854 | clear_bit(ST_RXSTOP, &portp->state); |
1856 | set_bit(TTY_IO_ERROR, &tty->flags); | 1855 | set_bit(TTY_IO_ERROR, &tty->flags); |
1857 | portp->port.tty = NULL; | 1856 | tty_port_tty_set(&portp->port, NULL); |
1858 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1857 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1859 | portp->port.count = 0; | 1858 | portp->port.count = 0; |
1860 | spin_unlock_irqrestore(&stli_lock, flags); | 1859 | spin_unlock_irqrestore(&stli_lock, flags); |
@@ -1935,8 +1934,6 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout) | |||
1935 | struct stliport *portp; | 1934 | struct stliport *portp; |
1936 | unsigned long tend; | 1935 | unsigned long tend; |
1937 | 1936 | ||
1938 | if (tty == NULL) | ||
1939 | return; | ||
1940 | portp = tty->driver_data; | 1937 | portp = tty->driver_data; |
1941 | if (portp == NULL) | 1938 | if (portp == NULL) |
1942 | return; | 1939 | return; |
@@ -1998,7 +1995,7 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn | |||
1998 | char *sp, *uart; | 1995 | char *sp, *uart; |
1999 | int rc, cnt; | 1996 | int rc, cnt; |
2000 | 1997 | ||
2001 | rc = stli_portcmdstats(portp); | 1998 | rc = stli_portcmdstats(NULL, portp); |
2002 | 1999 | ||
2003 | uart = "UNKNOWN"; | 2000 | uart = "UNKNOWN"; |
2004 | if (brdp->state & BST_STARTED) { | 2001 | if (brdp->state & BST_STARTED) { |
@@ -2188,7 +2185,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) | |||
2188 | 2185 | ||
2189 | if (test_bit(ST_RXSTOP, &portp->state)) | 2186 | if (test_bit(ST_RXSTOP, &portp->state)) |
2190 | return; | 2187 | return; |
2191 | tty = portp->port.tty; | 2188 | tty = tty_port_tty_get(&portp->port); |
2192 | if (tty == NULL) | 2189 | if (tty == NULL) |
2193 | return; | 2190 | return; |
2194 | 2191 | ||
@@ -2230,6 +2227,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) | |||
2230 | set_bit(ST_RXING, &portp->state); | 2227 | set_bit(ST_RXING, &portp->state); |
2231 | 2228 | ||
2232 | tty_schedule_flip(tty); | 2229 | tty_schedule_flip(tty); |
2230 | tty_kref_put(tty); | ||
2233 | } | 2231 | } |
2234 | 2232 | ||
2235 | /*****************************************************************************/ | 2233 | /*****************************************************************************/ |
@@ -2362,7 +2360,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) | |||
2362 | if (ap->notify) { | 2360 | if (ap->notify) { |
2363 | nt = ap->changed; | 2361 | nt = ap->changed; |
2364 | ap->notify = 0; | 2362 | ap->notify = 0; |
2365 | tty = portp->port.tty; | 2363 | tty = tty_port_tty_get(&portp->port); |
2366 | 2364 | ||
2367 | if (nt.signal & SG_DCD) { | 2365 | if (nt.signal & SG_DCD) { |
2368 | oldsigs = portp->sigs; | 2366 | oldsigs = portp->sigs; |
@@ -2399,6 +2397,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) | |||
2399 | tty_schedule_flip(tty); | 2397 | tty_schedule_flip(tty); |
2400 | } | 2398 | } |
2401 | } | 2399 | } |
2400 | tty_kref_put(tty); | ||
2402 | 2401 | ||
2403 | if (nt.data & DT_RXBUSY) { | 2402 | if (nt.data & DT_RXBUSY) { |
2404 | donerx++; | 2403 | donerx++; |
@@ -2535,14 +2534,15 @@ static void stli_poll(unsigned long arg) | |||
2535 | * the slave. | 2534 | * the slave. |
2536 | */ | 2535 | */ |
2537 | 2536 | ||
2538 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) | 2537 | static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, |
2538 | asyport_t *pp, struct ktermios *tiosp) | ||
2539 | { | 2539 | { |
2540 | memset(pp, 0, sizeof(asyport_t)); | 2540 | memset(pp, 0, sizeof(asyport_t)); |
2541 | 2541 | ||
2542 | /* | 2542 | /* |
2543 | * Start of by setting the baud, char size, parity and stop bit info. | 2543 | * Start of by setting the baud, char size, parity and stop bit info. |
2544 | */ | 2544 | */ |
2545 | pp->baudout = tty_get_baud_rate(portp->port.tty); | 2545 | pp->baudout = tty_get_baud_rate(tty); |
2546 | if ((tiosp->c_cflag & CBAUD) == B38400) { | 2546 | if ((tiosp->c_cflag & CBAUD) == B38400) { |
2547 | if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 2547 | if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
2548 | pp->baudout = 57600; | 2548 | pp->baudout = 57600; |
@@ -2695,7 +2695,7 @@ static int stli_initports(struct stlibrd *brdp) | |||
2695 | printk("STALLION: failed to allocate port structure\n"); | 2695 | printk("STALLION: failed to allocate port structure\n"); |
2696 | continue; | 2696 | continue; |
2697 | } | 2697 | } |
2698 | 2698 | tty_port_init(&portp->port); | |
2699 | portp->magic = STLI_PORTMAGIC; | 2699 | portp->magic = STLI_PORTMAGIC; |
2700 | portp->portnr = i; | 2700 | portp->portnr = i; |
2701 | portp->brdnr = brdp->brdnr; | 2701 | portp->brdnr = brdp->brdnr; |
@@ -4220,7 +4220,7 @@ static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, | |||
4220 | * what port to get stats for (used through board control device). | 4220 | * what port to get stats for (used through board control device). |
4221 | */ | 4221 | */ |
4222 | 4222 | ||
4223 | static int stli_portcmdstats(struct stliport *portp) | 4223 | static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) |
4224 | { | 4224 | { |
4225 | unsigned long flags; | 4225 | unsigned long flags; |
4226 | struct stlibrd *brdp; | 4226 | struct stlibrd *brdp; |
@@ -4249,15 +4249,15 @@ static int stli_portcmdstats(struct stliport *portp) | |||
4249 | stli_comstats.flags = portp->port.flags; | 4249 | stli_comstats.flags = portp->port.flags; |
4250 | 4250 | ||
4251 | spin_lock_irqsave(&brd_lock, flags); | 4251 | spin_lock_irqsave(&brd_lock, flags); |
4252 | if (portp->port.tty != NULL) { | 4252 | if (tty != NULL) { |
4253 | if (portp->port.tty->driver_data == portp) { | 4253 | if (portp->port.tty == tty) { |
4254 | stli_comstats.ttystate = portp->port.tty->flags; | 4254 | stli_comstats.ttystate = tty->flags; |
4255 | stli_comstats.rxbuffered = -1; | 4255 | stli_comstats.rxbuffered = -1; |
4256 | if (portp->port.tty->termios != NULL) { | 4256 | if (tty->termios != NULL) { |
4257 | stli_comstats.cflags = portp->port.tty->termios->c_cflag; | 4257 | stli_comstats.cflags = tty->termios->c_cflag; |
4258 | stli_comstats.iflags = portp->port.tty->termios->c_iflag; | 4258 | stli_comstats.iflags = tty->termios->c_iflag; |
4259 | stli_comstats.oflags = portp->port.tty->termios->c_oflag; | 4259 | stli_comstats.oflags = tty->termios->c_oflag; |
4260 | stli_comstats.lflags = portp->port.tty->termios->c_lflag; | 4260 | stli_comstats.lflags = tty->termios->c_lflag; |
4261 | } | 4261 | } |
4262 | } | 4262 | } |
4263 | } | 4263 | } |
@@ -4294,7 +4294,8 @@ static int stli_portcmdstats(struct stliport *portp) | |||
4294 | * what port to get stats for (used through board control device). | 4294 | * what port to get stats for (used through board control device). |
4295 | */ | 4295 | */ |
4296 | 4296 | ||
4297 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) | 4297 | static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, |
4298 | comstats_t __user *cp) | ||
4298 | { | 4299 | { |
4299 | struct stlibrd *brdp; | 4300 | struct stlibrd *brdp; |
4300 | int rc; | 4301 | int rc; |
@@ -4312,7 +4313,7 @@ static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) | |||
4312 | if (!brdp) | 4313 | if (!brdp) |
4313 | return -ENODEV; | 4314 | return -ENODEV; |
4314 | 4315 | ||
4315 | if ((rc = stli_portcmdstats(portp)) < 0) | 4316 | if ((rc = stli_portcmdstats(tty, portp)) < 0) |
4316 | return rc; | 4317 | return rc; |
4317 | 4318 | ||
4318 | return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? | 4319 | return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? |
@@ -4427,7 +4428,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4427 | 4428 | ||
4428 | switch (cmd) { | 4429 | switch (cmd) { |
4429 | case COM_GETPORTSTATS: | 4430 | case COM_GETPORTSTATS: |
4430 | rc = stli_getportstats(NULL, argp); | 4431 | rc = stli_getportstats(NULL, NULL, argp); |
4431 | done++; | 4432 | done++; |
4432 | break; | 4433 | break; |
4433 | case COM_CLRPORTSTATS: | 4434 | case COM_CLRPORTSTATS: |
@@ -4599,9 +4600,8 @@ static int __init istallion_module_init(void) | |||
4599 | 4600 | ||
4600 | istallion_class = class_create(THIS_MODULE, "staliomem"); | 4601 | istallion_class = class_create(THIS_MODULE, "staliomem"); |
4601 | for (i = 0; i < 4; i++) | 4602 | for (i = 0; i < 4; i++) |
4602 | device_create_drvdata(istallion_class, NULL, | 4603 | device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), |
4603 | MKDEV(STL_SIOMEMMAJOR, i), | 4604 | NULL, "staliomem%d", i); |
4604 | NULL, "staliomem%d", i); | ||
4605 | 4605 | ||
4606 | return 0; | 4606 | return 0; |
4607 | err_deinit: | 4607 | err_deinit: |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7b3a212c86b1..de26a978fbdd 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1249 | return; | 1249 | return; |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | if (keycode > NR_KEYS) | 1252 | if (keycode >= NR_KEYS) |
1253 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) | 1253 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) |
1254 | keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); | 1254 | keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); |
1255 | else | 1255 | else |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 3f2719b9f77b..e444c2dba160 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -813,8 +813,8 @@ static int lp_register(int nr, struct parport *port) | |||
813 | if (reset) | 813 | if (reset) |
814 | lp_reset(nr); | 814 | lp_reset(nr); |
815 | 815 | ||
816 | device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL, | 816 | device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL, |
817 | "lp%d", nr); | 817 | "lp%d", nr); |
818 | 818 | ||
819 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, | 819 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, |
820 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); | 820 | (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 672b08e694d0..6431f6921a67 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -992,9 +992,9 @@ static int __init chr_dev_init(void) | |||
992 | 992 | ||
993 | mem_class = class_create(THIS_MODULE, "mem"); | 993 | mem_class = class_create(THIS_MODULE, "mem"); |
994 | for (i = 0; i < ARRAY_SIZE(devlist); i++) | 994 | for (i = 0; i < ARRAY_SIZE(devlist); i++) |
995 | device_create_drvdata(mem_class, NULL, | 995 | device_create(mem_class, NULL, |
996 | MKDEV(MEM_MAJOR, devlist[i].minor), | 996 | MKDEV(MEM_MAJOR, devlist[i].minor), NULL, |
997 | NULL, devlist[i].name); | 997 | devlist[i].name); |
998 | 998 | ||
999 | return 0; | 999 | return 0; |
1000 | } | 1000 | } |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 999aa779c08a..a5e0db9d7662 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc) | |||
217 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | 217 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); |
218 | dev = MKDEV(MISC_MAJOR, misc->minor); | 218 | dev = MKDEV(MISC_MAJOR, misc->minor); |
219 | 219 | ||
220 | misc->this_device = device_create_drvdata(misc_class, misc->parent, | 220 | misc->this_device = device_create(misc_class, misc->parent, dev, NULL, |
221 | dev, NULL, "%s", misc->name); | 221 | "%s", misc->name); |
222 | if (IS_ERR(misc->this_device)) { | 222 | if (IS_ERR(misc->this_device)) { |
223 | err = PTR_ERR(misc->this_device); | 223 | err = PTR_ERR(misc->this_device); |
224 | goto out; | 224 | goto out; |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d3d7864e0c1e..12d327a2c9ba 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
205 | static void moxa_poll(unsigned long); | 205 | static void moxa_poll(unsigned long); |
206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | 206 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); |
207 | static void moxa_setup_empty_event(struct tty_struct *); | 207 | static void moxa_setup_empty_event(struct tty_struct *); |
208 | static void moxa_shut_down(struct moxa_port *); | 208 | static void moxa_shut_down(struct tty_struct *); |
209 | /* | 209 | /* |
210 | * moxa board interface functions: | 210 | * moxa board interface functions: |
211 | */ | 211 | */ |
@@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int); | |||
217 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); | 217 | static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); |
218 | static int MoxaPortLineStatus(struct moxa_port *); | 218 | static int MoxaPortLineStatus(struct moxa_port *); |
219 | static void MoxaPortFlushData(struct moxa_port *, int); | 219 | static void MoxaPortFlushData(struct moxa_port *, int); |
220 | static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); | 220 | static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); |
221 | static int MoxaPortReadData(struct moxa_port *); | 221 | static int MoxaPortReadData(struct moxa_port *); |
222 | static int MoxaPortTxQueue(struct moxa_port *); | 222 | static int MoxaPortTxQueue(struct moxa_port *); |
223 | static int MoxaPortRxQueue(struct moxa_port *); | 223 | static int MoxaPortRxQueue(struct moxa_port *); |
@@ -332,6 +332,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
332 | for (i = 0; i < MAX_BOARDS; i++) { | 332 | for (i = 0; i < MAX_BOARDS; i++) { |
333 | p = moxa_boards[i].ports; | 333 | p = moxa_boards[i].ports; |
334 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | 334 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { |
335 | struct tty_struct *ttyp; | ||
335 | memset(&tmp, 0, sizeof(tmp)); | 336 | memset(&tmp, 0, sizeof(tmp)); |
336 | if (!moxa_boards[i].ready) | 337 | if (!moxa_boards[i].ready) |
337 | goto copy; | 338 | goto copy; |
@@ -344,10 +345,12 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
344 | if (status & 4) | 345 | if (status & 4) |
345 | tmp.dcd = 1; | 346 | tmp.dcd = 1; |
346 | 347 | ||
347 | if (!p->port.tty || !p->port.tty->termios) | 348 | ttyp = tty_port_tty_get(&p->port); |
349 | if (!ttyp || !ttyp->termios) | ||
348 | tmp.cflag = p->cflag; | 350 | tmp.cflag = p->cflag; |
349 | else | 351 | else |
350 | tmp.cflag = p->port.tty->termios->c_cflag; | 352 | tmp.cflag = ttyp->termios->c_cflag; |
353 | tty_kref_put(tty); | ||
351 | copy: | 354 | copy: |
352 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | 355 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { |
353 | mutex_unlock(&moxa_openlock); | 356 | mutex_unlock(&moxa_openlock); |
@@ -510,7 +513,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, | |||
510 | size_t len) | 513 | size_t len) |
511 | { | 514 | { |
512 | void __iomem *baseAddr = brd->basemem; | 515 | void __iomem *baseAddr = brd->basemem; |
513 | const u16 *uptr = ptr; | 516 | const __le16 *uptr = ptr; |
514 | size_t wlen, len2, j; | 517 | size_t wlen, len2, j; |
515 | unsigned long key, loadbuf, loadlen, checksum, checksum_ok; | 518 | unsigned long key, loadbuf, loadlen, checksum, checksum_ok; |
516 | unsigned int i, retry; | 519 | unsigned int i, retry; |
@@ -880,8 +883,14 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
880 | 883 | ||
881 | /* pci hot-un-plug support */ | 884 | /* pci hot-un-plug support */ |
882 | for (a = 0; a < brd->numPorts; a++) | 885 | for (a = 0; a < brd->numPorts; a++) |
883 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) | 886 | if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { |
884 | tty_hangup(brd->ports[a].port.tty); | 887 | struct tty_struct *tty = tty_port_tty_get( |
888 | &brd->ports[a].port); | ||
889 | if (tty) { | ||
890 | tty_hangup(tty); | ||
891 | tty_kref_put(tty); | ||
892 | } | ||
893 | } | ||
885 | while (1) { | 894 | while (1) { |
886 | opened = 0; | 895 | opened = 0; |
887 | for (a = 0; a < brd->numPorts; a++) | 896 | for (a = 0; a < brd->numPorts; a++) |
@@ -1096,13 +1105,14 @@ static void __exit moxa_exit(void) | |||
1096 | module_init(moxa_init); | 1105 | module_init(moxa_init); |
1097 | module_exit(moxa_exit); | 1106 | module_exit(moxa_exit); |
1098 | 1107 | ||
1099 | static void moxa_close_port(struct moxa_port *ch) | 1108 | static void moxa_close_port(struct tty_struct *tty) |
1100 | { | 1109 | { |
1101 | moxa_shut_down(ch); | 1110 | struct moxa_port *ch = tty->driver_data; |
1111 | moxa_shut_down(tty); | ||
1102 | MoxaPortFlushData(ch, 2); | 1112 | MoxaPortFlushData(ch, 2); |
1103 | ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1113 | ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1104 | ch->port.tty->driver_data = NULL; | 1114 | tty->driver_data = NULL; |
1105 | ch->port.tty = NULL; | 1115 | tty_port_tty_set(&ch->port, NULL); |
1106 | } | 1116 | } |
1107 | 1117 | ||
1108 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | 1118 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, |
@@ -1161,7 +1171,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1161 | ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; | 1171 | ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; |
1162 | ch->port.count++; | 1172 | ch->port.count++; |
1163 | tty->driver_data = ch; | 1173 | tty->driver_data = ch; |
1164 | ch->port.tty = tty; | 1174 | tty_port_tty_set(&ch->port, tty); |
1165 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1175 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { |
1166 | ch->statusflags = 0; | 1176 | ch->statusflags = 0; |
1167 | moxa_set_tty_param(tty, tty->termios); | 1177 | moxa_set_tty_param(tty, tty->termios); |
@@ -1179,7 +1189,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1179 | if (retval) { | 1189 | if (retval) { |
1180 | if (ch->port.count) /* 0 means already hung up... */ | 1190 | if (ch->port.count) /* 0 means already hung up... */ |
1181 | if (--ch->port.count == 0) | 1191 | if (--ch->port.count == 0) |
1182 | moxa_close_port(ch); | 1192 | moxa_close_port(tty); |
1183 | } else | 1193 | } else |
1184 | ch->port.flags |= ASYNC_NORMAL_ACTIVE; | 1194 | ch->port.flags |= ASYNC_NORMAL_ACTIVE; |
1185 | mutex_unlock(&moxa_openlock); | 1195 | mutex_unlock(&moxa_openlock); |
@@ -1219,7 +1229,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
1219 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | 1229 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ |
1220 | } | 1230 | } |
1221 | 1231 | ||
1222 | moxa_close_port(ch); | 1232 | moxa_close_port(tty); |
1223 | unlock: | 1233 | unlock: |
1224 | mutex_unlock(&moxa_openlock); | 1234 | mutex_unlock(&moxa_openlock); |
1225 | } | 1235 | } |
@@ -1234,7 +1244,7 @@ static int moxa_write(struct tty_struct *tty, | |||
1234 | return 0; | 1244 | return 0; |
1235 | 1245 | ||
1236 | spin_lock_bh(&moxa_lock); | 1246 | spin_lock_bh(&moxa_lock); |
1237 | len = MoxaPortWriteData(ch, buf, count); | 1247 | len = MoxaPortWriteData(tty, buf, count); |
1238 | spin_unlock_bh(&moxa_lock); | 1248 | spin_unlock_bh(&moxa_lock); |
1239 | 1249 | ||
1240 | ch->statusflags |= LOWWAIT; | 1250 | ch->statusflags |= LOWWAIT; |
@@ -1409,7 +1419,7 @@ static void moxa_hangup(struct tty_struct *tty) | |||
1409 | return; | 1419 | return; |
1410 | } | 1420 | } |
1411 | ch->port.count = 0; | 1421 | ch->port.count = 0; |
1412 | moxa_close_port(ch); | 1422 | moxa_close_port(tty); |
1413 | mutex_unlock(&moxa_openlock); | 1423 | mutex_unlock(&moxa_openlock); |
1414 | 1424 | ||
1415 | wake_up_interruptible(&ch->port.open_wait); | 1425 | wake_up_interruptible(&ch->port.open_wait); |
@@ -1417,11 +1427,14 @@ static void moxa_hangup(struct tty_struct *tty) | |||
1417 | 1427 | ||
1418 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | 1428 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) |
1419 | { | 1429 | { |
1430 | struct tty_struct *tty; | ||
1420 | dcd = !!dcd; | 1431 | dcd = !!dcd; |
1421 | 1432 | ||
1422 | if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) { | 1433 | if (dcd != p->DCDState) { |
1423 | if (!dcd) | 1434 | tty = tty_port_tty_get(&p->port); |
1424 | tty_hangup(p->port.tty); | 1435 | if (tty && C_CLOCAL(tty) && !dcd) |
1436 | tty_hangup(tty); | ||
1437 | tty_kref_put(tty); | ||
1425 | } | 1438 | } |
1426 | p->DCDState = dcd; | 1439 | p->DCDState = dcd; |
1427 | } | 1440 | } |
@@ -1429,7 +1442,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | |||
1429 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | 1442 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, |
1430 | u16 __iomem *ip) | 1443 | u16 __iomem *ip) |
1431 | { | 1444 | { |
1432 | struct tty_struct *tty = p->port.tty; | 1445 | struct tty_struct *tty = tty_port_tty_get(&p->port); |
1433 | void __iomem *ofsAddr; | 1446 | void __iomem *ofsAddr; |
1434 | unsigned int inited = p->port.flags & ASYNC_INITIALIZED; | 1447 | unsigned int inited = p->port.flags & ASYNC_INITIALIZED; |
1435 | u16 intr; | 1448 | u16 intr; |
@@ -1476,6 +1489,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1476 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1489 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
1477 | tty_schedule_flip(tty); | 1490 | tty_schedule_flip(tty); |
1478 | } | 1491 | } |
1492 | tty_kref_put(tty); | ||
1479 | 1493 | ||
1480 | if (intr & IntrLine) | 1494 | if (intr & IntrLine) |
1481 | moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); | 1495 | moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); |
@@ -1560,9 +1574,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty) | |||
1560 | spin_unlock_bh(&moxa_lock); | 1574 | spin_unlock_bh(&moxa_lock); |
1561 | } | 1575 | } |
1562 | 1576 | ||
1563 | static void moxa_shut_down(struct moxa_port *ch) | 1577 | static void moxa_shut_down(struct tty_struct *tty) |
1564 | { | 1578 | { |
1565 | struct tty_struct *tp = ch->port.tty; | 1579 | struct moxa_port *ch = tty->driver_data; |
1566 | 1580 | ||
1567 | if (!(ch->port.flags & ASYNC_INITIALIZED)) | 1581 | if (!(ch->port.flags & ASYNC_INITIALIZED)) |
1568 | return; | 1582 | return; |
@@ -1572,7 +1586,7 @@ static void moxa_shut_down(struct moxa_port *ch) | |||
1572 | /* | 1586 | /* |
1573 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. | 1587 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. |
1574 | */ | 1588 | */ |
1575 | if (C_HUPCL(tp)) | 1589 | if (C_HUPCL(tty)) |
1576 | MoxaPortLineCtrl(ch, 0, 0); | 1590 | MoxaPortLineCtrl(ch, 0, 0); |
1577 | 1591 | ||
1578 | spin_lock_bh(&moxa_lock); | 1592 | spin_lock_bh(&moxa_lock); |
@@ -1953,9 +1967,10 @@ static int MoxaPortLineStatus(struct moxa_port *port) | |||
1953 | return val; | 1967 | return val; |
1954 | } | 1968 | } |
1955 | 1969 | ||
1956 | static int MoxaPortWriteData(struct moxa_port *port, | 1970 | static int MoxaPortWriteData(struct tty_struct *tty, |
1957 | const unsigned char *buffer, int len) | 1971 | const unsigned char *buffer, int len) |
1958 | { | 1972 | { |
1973 | struct moxa_port *port = tty->driver_data; | ||
1959 | void __iomem *baseAddr, *ofsAddr, *ofs; | 1974 | void __iomem *baseAddr, *ofsAddr, *ofs; |
1960 | unsigned int c, total; | 1975 | unsigned int c, total; |
1961 | u16 head, tail, tx_mask, spage, epage; | 1976 | u16 head, tail, tx_mask, spage, epage; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index b638403e8e9c..8beef50f95a0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -610,15 +610,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | |||
610 | return 0; | 610 | return 0; |
611 | } | 611 | } |
612 | 612 | ||
613 | static int mxser_set_baud(struct mxser_port *info, long newspd) | 613 | static int mxser_set_baud(struct tty_struct *tty, long newspd) |
614 | { | 614 | { |
615 | struct mxser_port *info = tty->driver_data; | ||
615 | int quot = 0, baud; | 616 | int quot = 0, baud; |
616 | unsigned char cval; | 617 | unsigned char cval; |
617 | 618 | ||
618 | if (!info->port.tty || !info->port.tty->termios) | 619 | if (!info->ioaddr) |
619 | return -1; | ||
620 | |||
621 | if (!(info->ioaddr)) | ||
622 | return -1; | 620 | return -1; |
623 | 621 | ||
624 | if (newspd > info->max_baud) | 622 | if (newspd > info->max_baud) |
@@ -626,13 +624,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
626 | 624 | ||
627 | if (newspd == 134) { | 625 | if (newspd == 134) { |
628 | quot = 2 * info->baud_base / 269; | 626 | quot = 2 * info->baud_base / 269; |
629 | tty_encode_baud_rate(info->port.tty, 134, 134); | 627 | tty_encode_baud_rate(tty, 134, 134); |
630 | } else if (newspd) { | 628 | } else if (newspd) { |
631 | quot = info->baud_base / newspd; | 629 | quot = info->baud_base / newspd; |
632 | if (quot == 0) | 630 | if (quot == 0) |
633 | quot = 1; | 631 | quot = 1; |
634 | baud = info->baud_base/quot; | 632 | baud = info->baud_base/quot; |
635 | tty_encode_baud_rate(info->port.tty, baud, baud); | 633 | tty_encode_baud_rate(tty, baud, baud); |
636 | } else { | 634 | } else { |
637 | quot = 0; | 635 | quot = 0; |
638 | } | 636 | } |
@@ -658,7 +656,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
658 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ | 656 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ |
659 | 657 | ||
660 | #ifdef BOTHER | 658 | #ifdef BOTHER |
661 | if (C_BAUD(info->port.tty) == BOTHER) { | 659 | if (C_BAUD(tty) == BOTHER) { |
662 | quot = info->baud_base % newspd; | 660 | quot = info->baud_base % newspd; |
663 | quot *= 8; | 661 | quot *= 8; |
664 | if (quot % newspd > newspd / 2) { | 662 | if (quot % newspd > newspd / 2) { |
@@ -679,21 +677,20 @@ static int mxser_set_baud(struct mxser_port *info, long newspd) | |||
679 | * This routine is called to set the UART divisor registers to match | 677 | * This routine is called to set the UART divisor registers to match |
680 | * the specified baud rate for a serial port. | 678 | * the specified baud rate for a serial port. |
681 | */ | 679 | */ |
682 | static int mxser_change_speed(struct mxser_port *info, | 680 | static int mxser_change_speed(struct tty_struct *tty, |
683 | struct ktermios *old_termios) | 681 | struct ktermios *old_termios) |
684 | { | 682 | { |
683 | struct mxser_port *info = tty->driver_data; | ||
685 | unsigned cflag, cval, fcr; | 684 | unsigned cflag, cval, fcr; |
686 | int ret = 0; | 685 | int ret = 0; |
687 | unsigned char status; | 686 | unsigned char status; |
688 | 687 | ||
689 | if (!info->port.tty || !info->port.tty->termios) | 688 | cflag = tty->termios->c_cflag; |
690 | return ret; | 689 | if (!info->ioaddr) |
691 | cflag = info->port.tty->termios->c_cflag; | ||
692 | if (!(info->ioaddr)) | ||
693 | return ret; | 690 | return ret; |
694 | 691 | ||
695 | if (mxser_set_baud_method[info->port.tty->index] == 0) | 692 | if (mxser_set_baud_method[tty->index] == 0) |
696 | mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); | 693 | mxser_set_baud(tty, tty_get_baud_rate(tty)); |
697 | 694 | ||
698 | /* byte size and parity */ | 695 | /* byte size and parity */ |
699 | switch (cflag & CSIZE) { | 696 | switch (cflag & CSIZE) { |
@@ -762,9 +759,9 @@ static int mxser_change_speed(struct mxser_port *info, | |||
762 | info->MCR |= UART_MCR_AFE; | 759 | info->MCR |= UART_MCR_AFE; |
763 | } else { | 760 | } else { |
764 | status = inb(info->ioaddr + UART_MSR); | 761 | status = inb(info->ioaddr + UART_MSR); |
765 | if (info->port.tty->hw_stopped) { | 762 | if (tty->hw_stopped) { |
766 | if (status & UART_MSR_CTS) { | 763 | if (status & UART_MSR_CTS) { |
767 | info->port.tty->hw_stopped = 0; | 764 | tty->hw_stopped = 0; |
768 | if (info->type != PORT_16550A && | 765 | if (info->type != PORT_16550A && |
769 | !info->board->chip_flag) { | 766 | !info->board->chip_flag) { |
770 | outb(info->IER & ~UART_IER_THRI, | 767 | outb(info->IER & ~UART_IER_THRI, |
@@ -774,11 +771,11 @@ static int mxser_change_speed(struct mxser_port *info, | |||
774 | outb(info->IER, info->ioaddr + | 771 | outb(info->IER, info->ioaddr + |
775 | UART_IER); | 772 | UART_IER); |
776 | } | 773 | } |
777 | tty_wakeup(info->port.tty); | 774 | tty_wakeup(tty); |
778 | } | 775 | } |
779 | } else { | 776 | } else { |
780 | if (!(status & UART_MSR_CTS)) { | 777 | if (!(status & UART_MSR_CTS)) { |
781 | info->port.tty->hw_stopped = 1; | 778 | tty->hw_stopped = 1; |
782 | if ((info->type != PORT_16550A) && | 779 | if ((info->type != PORT_16550A) && |
783 | (!info->board->chip_flag)) { | 780 | (!info->board->chip_flag)) { |
784 | info->IER &= ~UART_IER_THRI; | 781 | info->IER &= ~UART_IER_THRI; |
@@ -804,21 +801,21 @@ static int mxser_change_speed(struct mxser_port *info, | |||
804 | * Set up parity check flag | 801 | * Set up parity check flag |
805 | */ | 802 | */ |
806 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | 803 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; |
807 | if (I_INPCK(info->port.tty)) | 804 | if (I_INPCK(tty)) |
808 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | 805 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; |
809 | if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) | 806 | if (I_BRKINT(tty) || I_PARMRK(tty)) |
810 | info->read_status_mask |= UART_LSR_BI; | 807 | info->read_status_mask |= UART_LSR_BI; |
811 | 808 | ||
812 | info->ignore_status_mask = 0; | 809 | info->ignore_status_mask = 0; |
813 | 810 | ||
814 | if (I_IGNBRK(info->port.tty)) { | 811 | if (I_IGNBRK(tty)) { |
815 | info->ignore_status_mask |= UART_LSR_BI; | 812 | info->ignore_status_mask |= UART_LSR_BI; |
816 | info->read_status_mask |= UART_LSR_BI; | 813 | info->read_status_mask |= UART_LSR_BI; |
817 | /* | 814 | /* |
818 | * If we're ignore parity and break indicators, ignore | 815 | * If we're ignore parity and break indicators, ignore |
819 | * overruns too. (For real raw support). | 816 | * overruns too. (For real raw support). |
820 | */ | 817 | */ |
821 | if (I_IGNPAR(info->port.tty)) { | 818 | if (I_IGNPAR(tty)) { |
822 | info->ignore_status_mask |= | 819 | info->ignore_status_mask |= |
823 | UART_LSR_OE | | 820 | UART_LSR_OE | |
824 | UART_LSR_PE | | 821 | UART_LSR_PE | |
@@ -830,16 +827,16 @@ static int mxser_change_speed(struct mxser_port *info, | |||
830 | } | 827 | } |
831 | } | 828 | } |
832 | if (info->board->chip_flag) { | 829 | if (info->board->chip_flag) { |
833 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); | 830 | mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); |
834 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); | 831 | mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); |
835 | if (I_IXON(info->port.tty)) { | 832 | if (I_IXON(tty)) { |
836 | mxser_enable_must_rx_software_flow_control( | 833 | mxser_enable_must_rx_software_flow_control( |
837 | info->ioaddr); | 834 | info->ioaddr); |
838 | } else { | 835 | } else { |
839 | mxser_disable_must_rx_software_flow_control( | 836 | mxser_disable_must_rx_software_flow_control( |
840 | info->ioaddr); | 837 | info->ioaddr); |
841 | } | 838 | } |
842 | if (I_IXOFF(info->port.tty)) { | 839 | if (I_IXOFF(tty)) { |
843 | mxser_enable_must_tx_software_flow_control( | 840 | mxser_enable_must_tx_software_flow_control( |
844 | info->ioaddr); | 841 | info->ioaddr); |
845 | } else { | 842 | } else { |
@@ -855,7 +852,8 @@ static int mxser_change_speed(struct mxser_port *info, | |||
855 | return ret; | 852 | return ret; |
856 | } | 853 | } |
857 | 854 | ||
858 | static void mxser_check_modem_status(struct mxser_port *port, int status) | 855 | static void mxser_check_modem_status(struct tty_struct *tty, |
856 | struct mxser_port *port, int status) | ||
859 | { | 857 | { |
860 | /* update input line counters */ | 858 | /* update input line counters */ |
861 | if (status & UART_MSR_TERI) | 859 | if (status & UART_MSR_TERI) |
@@ -874,10 +872,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
874 | wake_up_interruptible(&port->port.open_wait); | 872 | wake_up_interruptible(&port->port.open_wait); |
875 | } | 873 | } |
876 | 874 | ||
875 | tty = tty_port_tty_get(&port->port); | ||
877 | if (port->port.flags & ASYNC_CTS_FLOW) { | 876 | if (port->port.flags & ASYNC_CTS_FLOW) { |
878 | if (port->port.tty->hw_stopped) { | 877 | if (tty->hw_stopped) { |
879 | if (status & UART_MSR_CTS) { | 878 | if (status & UART_MSR_CTS) { |
880 | port->port.tty->hw_stopped = 0; | 879 | tty->hw_stopped = 0; |
881 | 880 | ||
882 | if ((port->type != PORT_16550A) && | 881 | if ((port->type != PORT_16550A) && |
883 | (!port->board->chip_flag)) { | 882 | (!port->board->chip_flag)) { |
@@ -887,11 +886,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
887 | outb(port->IER, port->ioaddr + | 886 | outb(port->IER, port->ioaddr + |
888 | UART_IER); | 887 | UART_IER); |
889 | } | 888 | } |
890 | tty_wakeup(port->port.tty); | 889 | tty_wakeup(tty); |
891 | } | 890 | } |
892 | } else { | 891 | } else { |
893 | if (!(status & UART_MSR_CTS)) { | 892 | if (!(status & UART_MSR_CTS)) { |
894 | port->port.tty->hw_stopped = 1; | 893 | tty->hw_stopped = 1; |
895 | if (port->type != PORT_16550A && | 894 | if (port->type != PORT_16550A && |
896 | !port->board->chip_flag) { | 895 | !port->board->chip_flag) { |
897 | port->IER &= ~UART_IER_THRI; | 896 | port->IER &= ~UART_IER_THRI; |
@@ -903,8 +902,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status) | |||
903 | } | 902 | } |
904 | } | 903 | } |
905 | 904 | ||
906 | static int mxser_startup(struct mxser_port *info) | 905 | static int mxser_startup(struct tty_struct *tty) |
907 | { | 906 | { |
907 | struct mxser_port *info = tty->driver_data; | ||
908 | unsigned long page; | 908 | unsigned long page; |
909 | unsigned long flags; | 909 | unsigned long flags; |
910 | 910 | ||
@@ -921,8 +921,7 @@ static int mxser_startup(struct mxser_port *info) | |||
921 | } | 921 | } |
922 | 922 | ||
923 | if (!info->ioaddr || !info->type) { | 923 | if (!info->ioaddr || !info->type) { |
924 | if (info->port.tty) | 924 | set_bit(TTY_IO_ERROR, &tty->flags); |
925 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
926 | free_page(page); | 925 | free_page(page); |
927 | spin_unlock_irqrestore(&info->slock, flags); | 926 | spin_unlock_irqrestore(&info->slock, flags); |
928 | return 0; | 927 | return 0; |
@@ -952,8 +951,8 @@ static int mxser_startup(struct mxser_port *info) | |||
952 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | 951 | if (inb(info->ioaddr + UART_LSR) == 0xff) { |
953 | spin_unlock_irqrestore(&info->slock, flags); | 952 | spin_unlock_irqrestore(&info->slock, flags); |
954 | if (capable(CAP_SYS_ADMIN)) { | 953 | if (capable(CAP_SYS_ADMIN)) { |
955 | if (info->port.tty) | 954 | if (tty) |
956 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | 955 | set_bit(TTY_IO_ERROR, &tty->flags); |
957 | return 0; | 956 | return 0; |
958 | } else | 957 | } else |
959 | return -ENODEV; | 958 | return -ENODEV; |
@@ -991,14 +990,13 @@ static int mxser_startup(struct mxser_port *info) | |||
991 | (void) inb(info->ioaddr + UART_IIR); | 990 | (void) inb(info->ioaddr + UART_IIR); |
992 | (void) inb(info->ioaddr + UART_MSR); | 991 | (void) inb(info->ioaddr + UART_MSR); |
993 | 992 | ||
994 | if (info->port.tty) | 993 | clear_bit(TTY_IO_ERROR, &tty->flags); |
995 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
996 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 994 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
997 | 995 | ||
998 | /* | 996 | /* |
999 | * and set the speed of the serial port | 997 | * and set the speed of the serial port |
1000 | */ | 998 | */ |
1001 | mxser_change_speed(info, NULL); | 999 | mxser_change_speed(tty, NULL); |
1002 | info->port.flags |= ASYNC_INITIALIZED; | 1000 | info->port.flags |= ASYNC_INITIALIZED; |
1003 | spin_unlock_irqrestore(&info->slock, flags); | 1001 | spin_unlock_irqrestore(&info->slock, flags); |
1004 | 1002 | ||
@@ -1009,8 +1007,9 @@ static int mxser_startup(struct mxser_port *info) | |||
1009 | * This routine will shutdown a serial port; interrupts maybe disabled, and | 1007 | * This routine will shutdown a serial port; interrupts maybe disabled, and |
1010 | * DTR is dropped if the hangup on close termio flag is on. | 1008 | * DTR is dropped if the hangup on close termio flag is on. |
1011 | */ | 1009 | */ |
1012 | static void mxser_shutdown(struct mxser_port *info) | 1010 | static void mxser_shutdown(struct tty_struct *tty) |
1013 | { | 1011 | { |
1012 | struct mxser_port *info = tty->driver_data; | ||
1014 | unsigned long flags; | 1013 | unsigned long flags; |
1015 | 1014 | ||
1016 | if (!(info->port.flags & ASYNC_INITIALIZED)) | 1015 | if (!(info->port.flags & ASYNC_INITIALIZED)) |
@@ -1035,7 +1034,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1035 | info->IER = 0; | 1034 | info->IER = 0; |
1036 | outb(0x00, info->ioaddr + UART_IER); | 1035 | outb(0x00, info->ioaddr + UART_IER); |
1037 | 1036 | ||
1038 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) | 1037 | if (tty->termios->c_cflag & HUPCL) |
1039 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1038 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); |
1040 | outb(info->MCR, info->ioaddr + UART_MCR); | 1039 | outb(info->MCR, info->ioaddr + UART_MCR); |
1041 | 1040 | ||
@@ -1051,8 +1050,7 @@ static void mxser_shutdown(struct mxser_port *info) | |||
1051 | /* read data port to reset things */ | 1050 | /* read data port to reset things */ |
1052 | (void) inb(info->ioaddr + UART_RX); | 1051 | (void) inb(info->ioaddr + UART_RX); |
1053 | 1052 | ||
1054 | if (info->port.tty) | 1053 | set_bit(TTY_IO_ERROR, &tty->flags); |
1055 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
1056 | 1054 | ||
1057 | info->port.flags &= ~ASYNC_INITIALIZED; | 1055 | info->port.flags &= ~ASYNC_INITIALIZED; |
1058 | 1056 | ||
@@ -1084,14 +1082,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1084 | return -ENODEV; | 1082 | return -ENODEV; |
1085 | 1083 | ||
1086 | tty->driver_data = info; | 1084 | tty->driver_data = info; |
1087 | info->port.tty = tty; | 1085 | tty_port_tty_set(&info->port, tty); |
1088 | /* | 1086 | /* |
1089 | * Start up serial port | 1087 | * Start up serial port |
1090 | */ | 1088 | */ |
1091 | spin_lock_irqsave(&info->slock, flags); | 1089 | spin_lock_irqsave(&info->slock, flags); |
1092 | info->port.count++; | 1090 | info->port.count++; |
1093 | spin_unlock_irqrestore(&info->slock, flags); | 1091 | spin_unlock_irqrestore(&info->slock, flags); |
1094 | retval = mxser_startup(info); | 1092 | retval = mxser_startup(tty); |
1095 | if (retval) | 1093 | if (retval) |
1096 | return retval; | 1094 | return retval; |
1097 | 1095 | ||
@@ -1209,13 +1207,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1209 | break; | 1207 | break; |
1210 | } | 1208 | } |
1211 | } | 1209 | } |
1212 | mxser_shutdown(info); | 1210 | mxser_shutdown(tty); |
1213 | 1211 | ||
1214 | mxser_flush_buffer(tty); | 1212 | mxser_flush_buffer(tty); |
1215 | tty_ldisc_flush(tty); | 1213 | tty_ldisc_flush(tty); |
1216 | 1214 | ||
1217 | tty->closing = 0; | 1215 | tty->closing = 0; |
1218 | info->port.tty = NULL; | 1216 | tty_port_tty_set(&info->port, NULL); |
1219 | if (info->port.blocked_open) { | 1217 | if (info->port.blocked_open) { |
1220 | if (info->port.close_delay) | 1218 | if (info->port.close_delay) |
1221 | schedule_timeout_interruptible(info->port.close_delay); | 1219 | schedule_timeout_interruptible(info->port.close_delay); |
@@ -1337,12 +1335,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) | |||
1337 | * friends of mxser_ioctl() | 1335 | * friends of mxser_ioctl() |
1338 | * ------------------------------------------------------------ | 1336 | * ------------------------------------------------------------ |
1339 | */ | 1337 | */ |
1340 | static int mxser_get_serial_info(struct mxser_port *info, | 1338 | static int mxser_get_serial_info(struct tty_struct *tty, |
1341 | struct serial_struct __user *retinfo) | 1339 | struct serial_struct __user *retinfo) |
1342 | { | 1340 | { |
1341 | struct mxser_port *info = tty->driver_data; | ||
1343 | struct serial_struct tmp = { | 1342 | struct serial_struct tmp = { |
1344 | .type = info->type, | 1343 | .type = info->type, |
1345 | .line = info->port.tty->index, | 1344 | .line = tty->index, |
1346 | .port = info->ioaddr, | 1345 | .port = info->ioaddr, |
1347 | .irq = info->board->irq, | 1346 | .irq = info->board->irq, |
1348 | .flags = info->port.flags, | 1347 | .flags = info->port.flags, |
@@ -1357,9 +1356,10 @@ static int mxser_get_serial_info(struct mxser_port *info, | |||
1357 | return 0; | 1356 | return 0; |
1358 | } | 1357 | } |
1359 | 1358 | ||
1360 | static int mxser_set_serial_info(struct mxser_port *info, | 1359 | static int mxser_set_serial_info(struct tty_struct *tty, |
1361 | struct serial_struct __user *new_info) | 1360 | struct serial_struct __user *new_info) |
1362 | { | 1361 | { |
1362 | struct mxser_port *info = tty->driver_data; | ||
1363 | struct serial_struct new_serial; | 1363 | struct serial_struct new_serial; |
1364 | speed_t baud; | 1364 | speed_t baud; |
1365 | unsigned long sl_flags; | 1365 | unsigned long sl_flags; |
@@ -1393,14 +1393,14 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1393 | (new_serial.flags & ASYNC_FLAGS)); | 1393 | (new_serial.flags & ASYNC_FLAGS)); |
1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; | 1394 | info->port.close_delay = new_serial.close_delay * HZ / 100; |
1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; | 1395 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; |
1396 | info->port.tty->low_latency = | 1396 | tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) |
1397 | (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1397 | ? 1 : 0; |
1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | 1398 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1399 | (new_serial.baud_base != info->baud_base || | 1399 | (new_serial.baud_base != info->baud_base || |
1400 | new_serial.custom_divisor != | 1400 | new_serial.custom_divisor != |
1401 | info->custom_divisor)) { | 1401 | info->custom_divisor)) { |
1402 | baud = new_serial.baud_base / new_serial.custom_divisor; | 1402 | baud = new_serial.baud_base / new_serial.custom_divisor; |
1403 | tty_encode_baud_rate(info->port.tty, baud, baud); | 1403 | tty_encode_baud_rate(tty, baud, baud); |
1404 | } | 1404 | } |
1405 | } | 1405 | } |
1406 | 1406 | ||
@@ -1411,11 +1411,11 @@ static int mxser_set_serial_info(struct mxser_port *info, | |||
1411 | if (info->port.flags & ASYNC_INITIALIZED) { | 1411 | if (info->port.flags & ASYNC_INITIALIZED) { |
1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { | 1412 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { |
1413 | spin_lock_irqsave(&info->slock, sl_flags); | 1413 | spin_lock_irqsave(&info->slock, sl_flags); |
1414 | mxser_change_speed(info, NULL); | 1414 | mxser_change_speed(tty, NULL); |
1415 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1415 | spin_unlock_irqrestore(&info->slock, sl_flags); |
1416 | } | 1416 | } |
1417 | } else | 1417 | } else |
1418 | retval = mxser_startup(info); | 1418 | retval = mxser_startup(tty); |
1419 | 1419 | ||
1420 | return retval; | 1420 | return retval; |
1421 | } | 1421 | } |
@@ -1461,7 +1461,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file) | |||
1461 | spin_lock_irqsave(&info->slock, flags); | 1461 | spin_lock_irqsave(&info->slock, flags); |
1462 | status = inb(info->ioaddr + UART_MSR); | 1462 | status = inb(info->ioaddr + UART_MSR); |
1463 | if (status & UART_MSR_ANY_DELTA) | 1463 | if (status & UART_MSR_ANY_DELTA) |
1464 | mxser_check_modem_status(info, status); | 1464 | mxser_check_modem_status(tty, info, status); |
1465 | spin_unlock_irqrestore(&info->slock, flags); | 1465 | spin_unlock_irqrestore(&info->slock, flags); |
1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | | 1466 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | |
1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | | 1467 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | |
@@ -1606,6 +1606,7 @@ static int __init mxser_read_register(int port, unsigned short *regs) | |||
1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | 1606 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) |
1607 | { | 1607 | { |
1608 | struct mxser_port *port; | 1608 | struct mxser_port *port; |
1609 | struct tty_struct *tty; | ||
1609 | int result, status; | 1610 | int result, status; |
1610 | unsigned int i, j; | 1611 | unsigned int i, j; |
1611 | int ret = 0; | 1612 | int ret = 0; |
@@ -1643,12 +1644,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1643 | 1644 | ||
1644 | if (!port->ioaddr) | 1645 | if (!port->ioaddr) |
1645 | goto copy; | 1646 | goto copy; |
1647 | |||
1648 | tty = tty_port_tty_get(&port->port); | ||
1646 | 1649 | ||
1647 | if (!port->port.tty || !port->port.tty->termios) | 1650 | if (!tty || !tty->termios) |
1648 | ms.cflag = port->normal_termios.c_cflag; | 1651 | ms.cflag = port->normal_termios.c_cflag; |
1649 | else | 1652 | else |
1650 | ms.cflag = port->port.tty->termios->c_cflag; | 1653 | ms.cflag = tty->termios->c_cflag; |
1651 | 1654 | tty_kref_put(tty); | |
1652 | status = inb(port->ioaddr + UART_MSR); | 1655 | status = inb(port->ioaddr + UART_MSR); |
1653 | if (status & UART_MSR_DCD) | 1656 | if (status & UART_MSR_DCD) |
1654 | ms.dcd = 1; | 1657 | ms.dcd = 1; |
@@ -1704,15 +1707,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1704 | me->up_txcnt[p] = port->mon_data.up_txcnt; | 1707 | me->up_txcnt[p] = port->mon_data.up_txcnt; |
1705 | me->modem_status[p] = | 1708 | me->modem_status[p] = |
1706 | port->mon_data.modem_status; | 1709 | port->mon_data.modem_status; |
1707 | me->baudrate[p] = tty_get_baud_rate(port->port.tty); | 1710 | tty = tty_port_tty_get(&port->port); |
1708 | 1711 | ||
1709 | if (!port->port.tty || !port->port.tty->termios) { | 1712 | if (!tty || !tty->termios) { |
1710 | cflag = port->normal_termios.c_cflag; | 1713 | cflag = port->normal_termios.c_cflag; |
1711 | iflag = port->normal_termios.c_iflag; | 1714 | iflag = port->normal_termios.c_iflag; |
1715 | me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); | ||
1712 | } else { | 1716 | } else { |
1713 | cflag = port->port.tty->termios->c_cflag; | 1717 | cflag = tty->termios->c_cflag; |
1714 | iflag = port->port.tty->termios->c_iflag; | 1718 | iflag = tty->termios->c_iflag; |
1719 | me->baudrate[p] = tty_get_baud_rate(tty); | ||
1715 | } | 1720 | } |
1721 | tty_kref_put(tty); | ||
1716 | 1722 | ||
1717 | me->databits[p] = cflag & CSIZE; | 1723 | me->databits[p] = cflag & CSIZE; |
1718 | me->stopbits[p] = cflag & CSTOPB; | 1724 | me->stopbits[p] = cflag & CSTOPB; |
@@ -1822,12 +1828,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1822 | switch (cmd) { | 1828 | switch (cmd) { |
1823 | case TIOCGSERIAL: | 1829 | case TIOCGSERIAL: |
1824 | lock_kernel(); | 1830 | lock_kernel(); |
1825 | retval = mxser_get_serial_info(info, argp); | 1831 | retval = mxser_get_serial_info(tty, argp); |
1826 | unlock_kernel(); | 1832 | unlock_kernel(); |
1827 | return retval; | 1833 | return retval; |
1828 | case TIOCSSERIAL: | 1834 | case TIOCSSERIAL: |
1829 | lock_kernel(); | 1835 | lock_kernel(); |
1830 | retval = mxser_set_serial_info(info, argp); | 1836 | retval = mxser_set_serial_info(tty, argp); |
1831 | unlock_kernel(); | 1837 | unlock_kernel(); |
1832 | return retval; | 1838 | return retval; |
1833 | case TIOCSERGETLSR: /* Get line status register */ | 1839 | case TIOCSERGETLSR: /* Get line status register */ |
@@ -1896,7 +1902,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1896 | 1902 | ||
1897 | lock_kernel(); | 1903 | lock_kernel(); |
1898 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1904 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1899 | mxser_check_modem_status(info, status); | 1905 | mxser_check_modem_status(tty, info, status); |
1900 | 1906 | ||
1901 | mcr = inb(info->ioaddr + UART_MCR); | 1907 | mcr = inb(info->ioaddr + UART_MCR); |
1902 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1908 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
@@ -1909,7 +1915,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1909 | else | 1915 | else |
1910 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | 1916 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; |
1911 | 1917 | ||
1912 | if (info->port.tty->hw_stopped) | 1918 | if (tty->hw_stopped) |
1913 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1919 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1914 | else | 1920 | else |
1915 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1921 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
@@ -1958,7 +1964,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1958 | } | 1964 | } |
1959 | } | 1965 | } |
1960 | 1966 | ||
1961 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 1967 | if (tty->termios->c_cflag & CRTSCTS) { |
1962 | info->MCR &= ~UART_MCR_RTS; | 1968 | info->MCR &= ~UART_MCR_RTS; |
1963 | outb(info->MCR, info->ioaddr + UART_MCR); | 1969 | outb(info->MCR, info->ioaddr + UART_MCR); |
1964 | } | 1970 | } |
@@ -1995,7 +2001,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1995 | } | 2001 | } |
1996 | } | 2002 | } |
1997 | 2003 | ||
1998 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 2004 | if (tty->termios->c_cflag & CRTSCTS) { |
1999 | info->MCR |= UART_MCR_RTS; | 2005 | info->MCR |= UART_MCR_RTS; |
2000 | outb(info->MCR, info->ioaddr + UART_MCR); | 2006 | outb(info->MCR, info->ioaddr + UART_MCR); |
2001 | } | 2007 | } |
@@ -2040,7 +2046,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
2040 | unsigned long flags; | 2046 | unsigned long flags; |
2041 | 2047 | ||
2042 | spin_lock_irqsave(&info->slock, flags); | 2048 | spin_lock_irqsave(&info->slock, flags); |
2043 | mxser_change_speed(info, old_termios); | 2049 | mxser_change_speed(tty, old_termios); |
2044 | spin_unlock_irqrestore(&info->slock, flags); | 2050 | spin_unlock_irqrestore(&info->slock, flags); |
2045 | 2051 | ||
2046 | if ((old_termios->c_cflag & CRTSCTS) && | 2052 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -2138,10 +2144,10 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2138 | struct mxser_port *info = tty->driver_data; | 2144 | struct mxser_port *info = tty->driver_data; |
2139 | 2145 | ||
2140 | mxser_flush_buffer(tty); | 2146 | mxser_flush_buffer(tty); |
2141 | mxser_shutdown(info); | 2147 | mxser_shutdown(tty); |
2142 | info->port.count = 0; | 2148 | info->port.count = 0; |
2143 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 2149 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
2144 | info->port.tty = NULL; | 2150 | tty_port_tty_set(&info->port, NULL); |
2145 | wake_up_interruptible(&info->port.open_wait); | 2151 | wake_up_interruptible(&info->port.open_wait); |
2146 | } | 2152 | } |
2147 | 2153 | ||
@@ -2164,9 +2170,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2164 | return 0; | 2170 | return 0; |
2165 | } | 2171 | } |
2166 | 2172 | ||
2167 | static void mxser_receive_chars(struct mxser_port *port, int *status) | 2173 | static void mxser_receive_chars(struct tty_struct *tty, |
2174 | struct mxser_port *port, int *status) | ||
2168 | { | 2175 | { |
2169 | struct tty_struct *tty = port->port.tty; | ||
2170 | unsigned char ch, gdl; | 2176 | unsigned char ch, gdl; |
2171 | int ignored = 0; | 2177 | int ignored = 0; |
2172 | int cnt = 0; | 2178 | int cnt = 0; |
@@ -2174,9 +2180,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) | |||
2174 | int max = 256; | 2180 | int max = 256; |
2175 | 2181 | ||
2176 | recv_room = tty->receive_room; | 2182 | recv_room = tty->receive_room; |
2177 | if ((recv_room == 0) && (!port->ldisc_stop_rx)) | 2183 | if (recv_room == 0 && !port->ldisc_stop_rx) |
2178 | mxser_stoprx(tty); | 2184 | mxser_stoprx(tty); |
2179 | |||
2180 | if (port->board->chip_flag != MOXA_OTHER_UART) { | 2185 | if (port->board->chip_flag != MOXA_OTHER_UART) { |
2181 | 2186 | ||
2182 | if (*status & UART_LSR_SPECIAL) | 2187 | if (*status & UART_LSR_SPECIAL) |
@@ -2253,7 +2258,7 @@ intr_old: | |||
2253 | } while (*status & UART_LSR_DR); | 2258 | } while (*status & UART_LSR_DR); |
2254 | 2259 | ||
2255 | end_intr: | 2260 | end_intr: |
2256 | mxvar_log.rxcnt[port->port.tty->index] += cnt; | 2261 | mxvar_log.rxcnt[tty->index] += cnt; |
2257 | port->mon_data.rxcnt += cnt; | 2262 | port->mon_data.rxcnt += cnt; |
2258 | port->mon_data.up_rxcnt += cnt; | 2263 | port->mon_data.up_rxcnt += cnt; |
2259 | 2264 | ||
@@ -2267,14 +2272,14 @@ end_intr: | |||
2267 | spin_lock(&port->slock); | 2272 | spin_lock(&port->slock); |
2268 | } | 2273 | } |
2269 | 2274 | ||
2270 | static void mxser_transmit_chars(struct mxser_port *port) | 2275 | static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) |
2271 | { | 2276 | { |
2272 | int count, cnt; | 2277 | int count, cnt; |
2273 | 2278 | ||
2274 | if (port->x_char) { | 2279 | if (port->x_char) { |
2275 | outb(port->x_char, port->ioaddr + UART_TX); | 2280 | outb(port->x_char, port->ioaddr + UART_TX); |
2276 | port->x_char = 0; | 2281 | port->x_char = 0; |
2277 | mxvar_log.txcnt[port->port.tty->index]++; | 2282 | mxvar_log.txcnt[tty->index]++; |
2278 | port->mon_data.txcnt++; | 2283 | port->mon_data.txcnt++; |
2279 | port->mon_data.up_txcnt++; | 2284 | port->mon_data.up_txcnt++; |
2280 | port->icount.tx++; | 2285 | port->icount.tx++; |
@@ -2284,8 +2289,8 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2284 | if (port->port.xmit_buf == NULL) | 2289 | if (port->port.xmit_buf == NULL) |
2285 | return; | 2290 | return; |
2286 | 2291 | ||
2287 | if ((port->xmit_cnt <= 0) || port->port.tty->stopped || | 2292 | if (port->xmit_cnt <= 0 || tty->stopped || |
2288 | (port->port.tty->hw_stopped && | 2293 | (tty->hw_stopped && |
2289 | (port->type != PORT_16550A) && | 2294 | (port->type != PORT_16550A) && |
2290 | (!port->board->chip_flag))) { | 2295 | (!port->board->chip_flag))) { |
2291 | port->IER &= ~UART_IER_THRI; | 2296 | port->IER &= ~UART_IER_THRI; |
@@ -2302,14 +2307,14 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2302 | if (--port->xmit_cnt <= 0) | 2307 | if (--port->xmit_cnt <= 0) |
2303 | break; | 2308 | break; |
2304 | } while (--count > 0); | 2309 | } while (--count > 0); |
2305 | mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); | 2310 | mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); |
2306 | 2311 | ||
2307 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | 2312 | port->mon_data.txcnt += (cnt - port->xmit_cnt); |
2308 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2313 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2309 | port->icount.tx += (cnt - port->xmit_cnt); | 2314 | port->icount.tx += (cnt - port->xmit_cnt); |
2310 | 2315 | ||
2311 | if (port->xmit_cnt < WAKEUP_CHARS) | 2316 | if (port->xmit_cnt < WAKEUP_CHARS && tty) |
2312 | tty_wakeup(port->port.tty); | 2317 | tty_wakeup(tty); |
2313 | 2318 | ||
2314 | if (port->xmit_cnt <= 0) { | 2319 | if (port->xmit_cnt <= 0) { |
2315 | port->IER &= ~UART_IER_THRI; | 2320 | port->IER &= ~UART_IER_THRI; |
@@ -2328,6 +2333,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2328 | int max, irqbits, bits, msr; | 2333 | int max, irqbits, bits, msr; |
2329 | unsigned int int_cnt, pass_counter = 0; | 2334 | unsigned int int_cnt, pass_counter = 0; |
2330 | int handled = IRQ_NONE; | 2335 | int handled = IRQ_NONE; |
2336 | struct tty_struct *tty; | ||
2331 | 2337 | ||
2332 | for (i = 0; i < MXSER_BOARDS; i++) | 2338 | for (i = 0; i < MXSER_BOARDS; i++) |
2333 | if (dev_id == &mxser_boards[i]) { | 2339 | if (dev_id == &mxser_boards[i]) { |
@@ -2360,13 +2366,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2360 | if (iir & UART_IIR_NO_INT) | 2366 | if (iir & UART_IIR_NO_INT) |
2361 | break; | 2367 | break; |
2362 | iir &= MOXA_MUST_IIR_MASK; | 2368 | iir &= MOXA_MUST_IIR_MASK; |
2363 | if (!port->port.tty || | 2369 | tty = tty_port_tty_get(&port->port); |
2370 | if (!tty || | ||
2364 | (port->port.flags & ASYNC_CLOSING) || | 2371 | (port->port.flags & ASYNC_CLOSING) || |
2365 | !(port->port.flags & | 2372 | !(port->port.flags & |
2366 | ASYNC_INITIALIZED)) { | 2373 | ASYNC_INITIALIZED)) { |
2367 | status = inb(port->ioaddr + UART_LSR); | 2374 | status = inb(port->ioaddr + UART_LSR); |
2368 | outb(0x27, port->ioaddr + UART_FCR); | 2375 | outb(0x27, port->ioaddr + UART_FCR); |
2369 | inb(port->ioaddr + UART_MSR); | 2376 | inb(port->ioaddr + UART_MSR); |
2377 | tty_kref_put(tty); | ||
2370 | break; | 2378 | break; |
2371 | } | 2379 | } |
2372 | 2380 | ||
@@ -2387,27 +2395,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2387 | iir == MOXA_MUST_IIR_RDA || | 2395 | iir == MOXA_MUST_IIR_RDA || |
2388 | iir == MOXA_MUST_IIR_RTO || | 2396 | iir == MOXA_MUST_IIR_RTO || |
2389 | iir == MOXA_MUST_IIR_LSR) | 2397 | iir == MOXA_MUST_IIR_LSR) |
2390 | mxser_receive_chars(port, | 2398 | mxser_receive_chars(tty, port, |
2391 | &status); | 2399 | &status); |
2392 | 2400 | ||
2393 | } else { | 2401 | } else { |
2394 | status &= port->read_status_mask; | 2402 | status &= port->read_status_mask; |
2395 | if (status & UART_LSR_DR) | 2403 | if (status & UART_LSR_DR) |
2396 | mxser_receive_chars(port, | 2404 | mxser_receive_chars(tty, port, |
2397 | &status); | 2405 | &status); |
2398 | } | 2406 | } |
2399 | msr = inb(port->ioaddr + UART_MSR); | 2407 | msr = inb(port->ioaddr + UART_MSR); |
2400 | if (msr & UART_MSR_ANY_DELTA) | 2408 | if (msr & UART_MSR_ANY_DELTA) |
2401 | mxser_check_modem_status(port, msr); | 2409 | mxser_check_modem_status(tty, port, msr); |
2402 | 2410 | ||
2403 | if (port->board->chip_flag) { | 2411 | if (port->board->chip_flag) { |
2404 | if (iir == 0x02 && (status & | 2412 | if (iir == 0x02 && (status & |
2405 | UART_LSR_THRE)) | 2413 | UART_LSR_THRE)) |
2406 | mxser_transmit_chars(port); | 2414 | mxser_transmit_chars(tty, port); |
2407 | } else { | 2415 | } else { |
2408 | if (status & UART_LSR_THRE) | 2416 | if (status & UART_LSR_THRE) |
2409 | mxser_transmit_chars(port); | 2417 | mxser_transmit_chars(tty, port); |
2410 | } | 2418 | } |
2419 | tty_kref_put(tty); | ||
2411 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | 2420 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); |
2412 | spin_unlock(&port->slock); | 2421 | spin_unlock(&port->slock); |
2413 | } | 2422 | } |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 69ec6399c714..bacb3e2872ae 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -764,7 +764,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
764 | break; | 764 | break; |
765 | 765 | ||
766 | default: | 766 | default: |
767 | error = n_tty_ioctl (tty, file, cmd, arg); | 767 | error = n_tty_ioctl_helper(tty, file, cmd, arg); |
768 | break; | 768 | break; |
769 | } | 769 | } |
770 | return error; | 770 | return error; |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index ae377aa473ba..4a8215a89ad3 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -372,14 +372,8 @@ static void remove_from_rx_queue(struct r3964_info *pInfo, | |||
372 | static void put_char(struct r3964_info *pInfo, unsigned char ch) | 372 | static void put_char(struct r3964_info *pInfo, unsigned char ch) |
373 | { | 373 | { |
374 | struct tty_struct *tty = pInfo->tty; | 374 | struct tty_struct *tty = pInfo->tty; |
375 | |||
376 | if (tty == NULL) | ||
377 | return; | ||
378 | |||
379 | /* FIXME: put_char should not be called from an IRQ */ | 375 | /* FIXME: put_char should not be called from an IRQ */ |
380 | if (tty->ops->put_char) { | 376 | tty_put_char(tty, ch); |
381 | tty->ops->put_char(tty, ch); | ||
382 | } | ||
383 | pInfo->bcc ^= ch; | 377 | pInfo->bcc ^= ch; |
384 | } | 378 | } |
385 | 379 | ||
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 708c2b1dbe51..efbfe9612658 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * | 26 | * |
27 | * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to | 27 | * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to |
28 | * waiting writing processes-Sapan Bhatia <sapan@corewars.org>. | 28 | * waiting writing processes-Sapan Bhatia <sapan@corewars.org>. |
29 | * Also fixed a bug in BLOCKING mode where write_chan returns | 29 | * Also fixed a bug in BLOCKING mode where n_tty_write returns |
30 | * EAGAIN | 30 | * EAGAIN |
31 | */ | 31 | */ |
32 | 32 | ||
@@ -99,6 +99,7 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
99 | 99 | ||
100 | static void n_tty_set_room(struct tty_struct *tty) | 100 | static void n_tty_set_room(struct tty_struct *tty) |
101 | { | 101 | { |
102 | /* tty->read_cnt is not read locked ? */ | ||
102 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | 103 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; |
103 | 104 | ||
104 | /* | 105 | /* |
@@ -121,6 +122,16 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | |||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
125 | /** | ||
126 | * put_tty_queue - add character to tty | ||
127 | * @c: character | ||
128 | * @tty: tty device | ||
129 | * | ||
130 | * Add a character to the tty read_buf queue. This is done under the | ||
131 | * read_lock to serialize character addition and also to protect us | ||
132 | * against parallel reads or flushes | ||
133 | */ | ||
134 | |||
124 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) | 135 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) |
125 | { | 136 | { |
126 | unsigned long flags; | 137 | unsigned long flags; |
@@ -137,14 +148,11 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty) | |||
137 | * check_unthrottle - allow new receive data | 148 | * check_unthrottle - allow new receive data |
138 | * @tty; tty device | 149 | * @tty; tty device |
139 | * | 150 | * |
140 | * Check whether to call the driver.unthrottle function. | 151 | * Check whether to call the driver unthrottle functions |
141 | * We test the TTY_THROTTLED bit first so that it always | 152 | * |
142 | * indicates the current state. The decision about whether | ||
143 | * it is worth allowing more input has been taken by the caller. | ||
144 | * Can sleep, may be called under the atomic_read_lock mutex but | 153 | * Can sleep, may be called under the atomic_read_lock mutex but |
145 | * this is not guaranteed. | 154 | * this is not guaranteed. |
146 | */ | 155 | */ |
147 | |||
148 | static void check_unthrottle(struct tty_struct *tty) | 156 | static void check_unthrottle(struct tty_struct *tty) |
149 | { | 157 | { |
150 | if (tty->count) | 158 | if (tty->count) |
@@ -158,6 +166,8 @@ static void check_unthrottle(struct tty_struct *tty) | |||
158 | * Reset the read buffer counters, clear the flags, | 166 | * Reset the read buffer counters, clear the flags, |
159 | * and make sure the driver is unthrottled. Called | 167 | * and make sure the driver is unthrottled. Called |
160 | * from n_tty_open() and n_tty_flush_buffer(). | 168 | * from n_tty_open() and n_tty_flush_buffer(). |
169 | * | ||
170 | * Locking: tty_read_lock for read fields. | ||
161 | */ | 171 | */ |
162 | static void reset_buffer_flags(struct tty_struct *tty) | 172 | static void reset_buffer_flags(struct tty_struct *tty) |
163 | { | 173 | { |
@@ -181,7 +191,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
181 | * at hangup) or when the N_TTY line discipline internally has to | 191 | * at hangup) or when the N_TTY line discipline internally has to |
182 | * clean the pending queue (for example some signals). | 192 | * clean the pending queue (for example some signals). |
183 | * | 193 | * |
184 | * Locking: ctrl_lock | 194 | * Locking: ctrl_lock, read_lock. |
185 | */ | 195 | */ |
186 | 196 | ||
187 | static void n_tty_flush_buffer(struct tty_struct *tty) | 197 | static void n_tty_flush_buffer(struct tty_struct *tty) |
@@ -207,6 +217,8 @@ static void n_tty_flush_buffer(struct tty_struct *tty) | |||
207 | * | 217 | * |
208 | * Report the number of characters buffered to be delivered to user | 218 | * Report the number of characters buffered to be delivered to user |
209 | * at this instant in time. | 219 | * at this instant in time. |
220 | * | ||
221 | * Locking: read_lock | ||
210 | */ | 222 | */ |
211 | 223 | ||
212 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | 224 | static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) |
@@ -346,7 +358,7 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
346 | * the simple cases normally found and helps to generate blocks of | 358 | * the simple cases normally found and helps to generate blocks of |
347 | * symbols for the console driver and thus improve performance. | 359 | * symbols for the console driver and thus improve performance. |
348 | * | 360 | * |
349 | * Called from write_chan under the tty layer write lock. Relies | 361 | * Called from n_tty_write under the tty layer write lock. Relies |
350 | * on lock_kernel for the tty->column state. | 362 | * on lock_kernel for the tty->column state. |
351 | */ | 363 | */ |
352 | 364 | ||
@@ -410,6 +422,8 @@ break_out: | |||
410 | * | 422 | * |
411 | * Echo user input back onto the screen. This must be called only when | 423 | * Echo user input back onto the screen. This must be called only when |
412 | * L_ECHO(tty) is true. Called from the driver receive_buf path. | 424 | * L_ECHO(tty) is true. Called from the driver receive_buf path. |
425 | * | ||
426 | * Relies on BKL for tty column locking | ||
413 | */ | 427 | */ |
414 | 428 | ||
415 | static void echo_char(unsigned char c, struct tty_struct *tty) | 429 | static void echo_char(unsigned char c, struct tty_struct *tty) |
@@ -422,6 +436,12 @@ static void echo_char(unsigned char c, struct tty_struct *tty) | |||
422 | opost(c, tty); | 436 | opost(c, tty); |
423 | } | 437 | } |
424 | 438 | ||
439 | /** | ||
440 | * finsh_erasing - complete erase | ||
441 | * @tty: tty doing the erase | ||
442 | * | ||
443 | * Relies on BKL for tty column locking | ||
444 | */ | ||
425 | static inline void finish_erasing(struct tty_struct *tty) | 445 | static inline void finish_erasing(struct tty_struct *tty) |
426 | { | 446 | { |
427 | if (tty->erasing) { | 447 | if (tty->erasing) { |
@@ -439,6 +459,8 @@ static inline void finish_erasing(struct tty_struct *tty) | |||
439 | * Perform erase and necessary output when an erase character is | 459 | * Perform erase and necessary output when an erase character is |
440 | * present in the stream from the driver layer. Handles the complexities | 460 | * present in the stream from the driver layer. Handles the complexities |
441 | * of UTF-8 multibyte symbols. | 461 | * of UTF-8 multibyte symbols. |
462 | * | ||
463 | * Locking: read_lock for tty buffers, BKL for column/erasing state | ||
442 | */ | 464 | */ |
443 | 465 | ||
444 | static void eraser(unsigned char c, struct tty_struct *tty) | 466 | static void eraser(unsigned char c, struct tty_struct *tty) |
@@ -447,6 +469,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
447 | int head, seen_alnums, cnt; | 469 | int head, seen_alnums, cnt; |
448 | unsigned long flags; | 470 | unsigned long flags; |
449 | 471 | ||
472 | /* FIXME: locking needed ? */ | ||
450 | if (tty->read_head == tty->canon_head) { | 473 | if (tty->read_head == tty->canon_head) { |
451 | /* opost('\a', tty); */ /* what do you think? */ | 474 | /* opost('\a', tty); */ /* what do you think? */ |
452 | return; | 475 | return; |
@@ -481,6 +504,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
481 | } | 504 | } |
482 | 505 | ||
483 | seen_alnums = 0; | 506 | seen_alnums = 0; |
507 | /* FIXME: Locking ?? */ | ||
484 | while (tty->read_head != tty->canon_head) { | 508 | while (tty->read_head != tty->canon_head) { |
485 | head = tty->read_head; | 509 | head = tty->read_head; |
486 | 510 | ||
@@ -583,6 +607,8 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
583 | * may caus terminal flushing to take place according to the termios | 607 | * may caus terminal flushing to take place according to the termios |
584 | * settings and character used. Called from the driver receive_buf | 608 | * settings and character used. Called from the driver receive_buf |
585 | * path so serialized. | 609 | * path so serialized. |
610 | * | ||
611 | * Locking: ctrl_lock, read_lock (both via flush buffer) | ||
586 | */ | 612 | */ |
587 | 613 | ||
588 | static inline void isig(int sig, struct tty_struct *tty, int flush) | 614 | static inline void isig(int sig, struct tty_struct *tty, int flush) |
@@ -1007,12 +1033,26 @@ int is_ignored(int sig) | |||
1007 | * and is protected from re-entry by the tty layer. The user is | 1033 | * and is protected from re-entry by the tty layer. The user is |
1008 | * guaranteed that this function will not be re-entered or in progress | 1034 | * guaranteed that this function will not be re-entered or in progress |
1009 | * when the ldisc is closed. | 1035 | * when the ldisc is closed. |
1036 | * | ||
1037 | * Locking: Caller holds tty->termios_mutex | ||
1010 | */ | 1038 | */ |
1011 | 1039 | ||
1012 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | 1040 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
1013 | { | 1041 | { |
1014 | if (!tty) | 1042 | int canon_change = 1; |
1015 | return; | 1043 | BUG_ON(!tty); |
1044 | |||
1045 | if (old) | ||
1046 | canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON; | ||
1047 | if (canon_change) { | ||
1048 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | ||
1049 | tty->canon_head = tty->read_tail; | ||
1050 | tty->canon_data = 0; | ||
1051 | tty->erasing = 0; | ||
1052 | } | ||
1053 | |||
1054 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | ||
1055 | wake_up_interruptible(&tty->read_wait); | ||
1016 | 1056 | ||
1017 | tty->icanon = (L_ICANON(tty) != 0); | 1057 | tty->icanon = (L_ICANON(tty) != 0); |
1018 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1058 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
@@ -1143,7 +1183,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1143 | * @b: user data | 1183 | * @b: user data |
1144 | * @nr: size of data | 1184 | * @nr: size of data |
1145 | * | 1185 | * |
1146 | * Helper function to speed up read_chan. It is only called when | 1186 | * Helper function to speed up n_tty_read. It is only called when |
1147 | * ICANON is off; it copies characters straight from the tty queue to | 1187 | * ICANON is off; it copies characters straight from the tty queue to |
1148 | * user space directly. It can be profitably called twice; once to | 1188 | * user space directly. It can be profitably called twice; once to |
1149 | * drain the space from the tail pointer to the (physical) end of the | 1189 | * drain the space from the tail pointer to the (physical) end of the |
@@ -1210,7 +1250,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1210 | if (file->f_op->write != redirected_tty_write && | 1250 | if (file->f_op->write != redirected_tty_write && |
1211 | current->signal->tty == tty) { | 1251 | current->signal->tty == tty) { |
1212 | if (!tty->pgrp) | 1252 | if (!tty->pgrp) |
1213 | printk(KERN_ERR "read_chan: no tty->pgrp!\n"); | 1253 | printk(KERN_ERR "n_tty_read: no tty->pgrp!\n"); |
1214 | else if (task_pgrp(current) != tty->pgrp) { | 1254 | else if (task_pgrp(current) != tty->pgrp) { |
1215 | if (is_ignored(SIGTTIN) || | 1255 | if (is_ignored(SIGTTIN) || |
1216 | is_current_pgrp_orphaned()) | 1256 | is_current_pgrp_orphaned()) |
@@ -1225,7 +1265,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1225 | 1265 | ||
1226 | 1266 | ||
1227 | /** | 1267 | /** |
1228 | * read_chan - read function for tty | 1268 | * n_tty_read - read function for tty |
1229 | * @tty: tty device | 1269 | * @tty: tty device |
1230 | * @file: file object | 1270 | * @file: file object |
1231 | * @buf: userspace buffer pointer | 1271 | * @buf: userspace buffer pointer |
@@ -1239,7 +1279,7 @@ static int job_control(struct tty_struct *tty, struct file *file) | |||
1239 | * This code must be sure never to sleep through a hangup. | 1279 | * This code must be sure never to sleep through a hangup. |
1240 | */ | 1280 | */ |
1241 | 1281 | ||
1242 | static ssize_t read_chan(struct tty_struct *tty, struct file *file, | 1282 | static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, |
1243 | unsigned char __user *buf, size_t nr) | 1283 | unsigned char __user *buf, size_t nr) |
1244 | { | 1284 | { |
1245 | unsigned char __user *b = buf; | 1285 | unsigned char __user *b = buf; |
@@ -1254,10 +1294,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, | |||
1254 | 1294 | ||
1255 | do_it_again: | 1295 | do_it_again: |
1256 | 1296 | ||
1257 | if (!tty->read_buf) { | 1297 | BUG_ON(!tty->read_buf); |
1258 | printk(KERN_ERR "n_tty_read_chan: read_buf == NULL?!?\n"); | ||
1259 | return -EIO; | ||
1260 | } | ||
1261 | 1298 | ||
1262 | c = job_control(tty, file); | 1299 | c = job_control(tty, file); |
1263 | if (c < 0) | 1300 | if (c < 0) |
@@ -1444,7 +1481,7 @@ do_it_again: | |||
1444 | } | 1481 | } |
1445 | 1482 | ||
1446 | /** | 1483 | /** |
1447 | * write_chan - write function for tty | 1484 | * n_tty_write - write function for tty |
1448 | * @tty: tty device | 1485 | * @tty: tty device |
1449 | * @file: file object | 1486 | * @file: file object |
1450 | * @buf: userspace buffer pointer | 1487 | * @buf: userspace buffer pointer |
@@ -1458,7 +1495,7 @@ do_it_again: | |||
1458 | * This code must be sure never to sleep through a hangup. | 1495 | * This code must be sure never to sleep through a hangup. |
1459 | */ | 1496 | */ |
1460 | 1497 | ||
1461 | static ssize_t write_chan(struct tty_struct *tty, struct file *file, | 1498 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, |
1462 | const unsigned char *buf, size_t nr) | 1499 | const unsigned char *buf, size_t nr) |
1463 | { | 1500 | { |
1464 | const unsigned char *b = buf; | 1501 | const unsigned char *b = buf; |
@@ -1532,7 +1569,7 @@ break_out: | |||
1532 | } | 1569 | } |
1533 | 1570 | ||
1534 | /** | 1571 | /** |
1535 | * normal_poll - poll method for N_TTY | 1572 | * n_tty_poll - poll method for N_TTY |
1536 | * @tty: terminal device | 1573 | * @tty: terminal device |
1537 | * @file: file accessing it | 1574 | * @file: file accessing it |
1538 | * @wait: poll table | 1575 | * @wait: poll table |
@@ -1545,7 +1582,7 @@ break_out: | |||
1545 | * Called without the kernel lock held - fine | 1582 | * Called without the kernel lock held - fine |
1546 | */ | 1583 | */ |
1547 | 1584 | ||
1548 | static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | 1585 | static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, |
1549 | poll_table *wait) | 1586 | poll_table *wait) |
1550 | { | 1587 | { |
1551 | unsigned int mask = 0; | 1588 | unsigned int mask = 0; |
@@ -1573,6 +1610,44 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file, | |||
1573 | return mask; | 1610 | return mask; |
1574 | } | 1611 | } |
1575 | 1612 | ||
1613 | static unsigned long inq_canon(struct tty_struct *tty) | ||
1614 | { | ||
1615 | int nr, head, tail; | ||
1616 | |||
1617 | if (!tty->canon_data) | ||
1618 | return 0; | ||
1619 | head = tty->canon_head; | ||
1620 | tail = tty->read_tail; | ||
1621 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | ||
1622 | /* Skip EOF-chars.. */ | ||
1623 | while (head != tail) { | ||
1624 | if (test_bit(tail, tty->read_flags) && | ||
1625 | tty->read_buf[tail] == __DISABLED_CHAR) | ||
1626 | nr--; | ||
1627 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | ||
1628 | } | ||
1629 | return nr; | ||
1630 | } | ||
1631 | |||
1632 | static int n_tty_ioctl(struct tty_struct *tty, struct file *file, | ||
1633 | unsigned int cmd, unsigned long arg) | ||
1634 | { | ||
1635 | int retval; | ||
1636 | |||
1637 | switch (cmd) { | ||
1638 | case TIOCOUTQ: | ||
1639 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1640 | case TIOCINQ: | ||
1641 | /* FIXME: Locking */ | ||
1642 | retval = tty->read_cnt; | ||
1643 | if (L_ICANON(tty)) | ||
1644 | retval = inq_canon(tty); | ||
1645 | return put_user(retval, (unsigned int __user *) arg); | ||
1646 | default: | ||
1647 | return n_tty_ioctl_helper(tty, file, cmd, arg); | ||
1648 | } | ||
1649 | } | ||
1650 | |||
1576 | struct tty_ldisc_ops tty_ldisc_N_TTY = { | 1651 | struct tty_ldisc_ops tty_ldisc_N_TTY = { |
1577 | .magic = TTY_LDISC_MAGIC, | 1652 | .magic = TTY_LDISC_MAGIC, |
1578 | .name = "n_tty", | 1653 | .name = "n_tty", |
@@ -1580,11 +1655,11 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
1580 | .close = n_tty_close, | 1655 | .close = n_tty_close, |
1581 | .flush_buffer = n_tty_flush_buffer, | 1656 | .flush_buffer = n_tty_flush_buffer, |
1582 | .chars_in_buffer = n_tty_chars_in_buffer, | 1657 | .chars_in_buffer = n_tty_chars_in_buffer, |
1583 | .read = read_chan, | 1658 | .read = n_tty_read, |
1584 | .write = write_chan, | 1659 | .write = n_tty_write, |
1585 | .ioctl = n_tty_ioctl, | 1660 | .ioctl = n_tty_ioctl, |
1586 | .set_termios = n_tty_set_termios, | 1661 | .set_termios = n_tty_set_termios, |
1587 | .poll = normal_poll, | 1662 | .poll = n_tty_poll, |
1588 | .receive_buf = n_tty_receive_buf, | 1663 | .receive_buf = n_tty_receive_buf, |
1589 | .write_wakeup = n_tty_write_wakeup | 1664 | .write_wakeup = n_tty_write_wakeup |
1590 | }; | 1665 | }; |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 66a0f931c66c..9a34a1935283 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1599,7 +1599,10 @@ static int ntty_open(struct tty_struct *tty, struct file *file) | |||
1599 | return 0; | 1599 | return 0; |
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | /* Called when the userspace process close the tty, /dev/noz*. */ | 1602 | /* Called when the userspace process close the tty, /dev/noz*. Also |
1603 | called immediately if ntty_open fails in which case tty->driver_data | ||
1604 | will be NULL an we exit by the first return */ | ||
1605 | |||
1603 | static void ntty_close(struct tty_struct *tty, struct file *file) | 1606 | static void ntty_close(struct tty_struct *tty, struct file *file) |
1604 | { | 1607 | { |
1605 | struct nozomi *dc = get_dc_by_tty(tty); | 1608 | struct nozomi *dc = get_dc_by_tty(tty); |
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index b930de50407a..3f7da8cf3a80 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -41,7 +41,8 @@ static u8 pc8736x_gpio_shadow[4]; | |||
41 | #define SIO_BASE2 0x4E /* alt command-reg to check */ | 41 | #define SIO_BASE2 0x4E /* alt command-reg to check */ |
42 | 42 | ||
43 | #define SIO_SID 0x20 /* SuperI/O ID Register */ | 43 | #define SIO_SID 0x20 /* SuperI/O ID Register */ |
44 | #define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */ | 44 | #define SIO_SID_PC87365 0xe5 /* Expected value in ID Register for PC87365 */ |
45 | #define SIO_SID_PC87366 0xe9 /* Expected value in ID Register for PC87366 */ | ||
45 | 46 | ||
46 | #define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ | 47 | #define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ |
47 | 48 | ||
@@ -91,13 +92,17 @@ static inline int superio_inb(int addr) | |||
91 | 92 | ||
92 | static int pc8736x_superio_present(void) | 93 | static int pc8736x_superio_present(void) |
93 | { | 94 | { |
95 | int id; | ||
96 | |||
94 | /* try the 2 possible values, read a hardware reg to verify */ | 97 | /* try the 2 possible values, read a hardware reg to verify */ |
95 | superio_cmd = SIO_BASE1; | 98 | superio_cmd = SIO_BASE1; |
96 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | 99 | id = superio_inb(SIO_SID); |
100 | if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366) | ||
97 | return superio_cmd; | 101 | return superio_cmd; |
98 | 102 | ||
99 | superio_cmd = SIO_BASE2; | 103 | superio_cmd = SIO_BASE2; |
100 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | 104 | id = superio_inb(SIO_SID); |
105 | if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366) | ||
101 | return superio_cmd; | 106 | return superio_cmd; |
102 | 107 | ||
103 | return 0; | 108 | return 0; |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index f070ae7bd91a..dbb912574569 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1759,65 +1759,40 @@ static void cmm_cm4000_release(struct pcmcia_device * link) | |||
1759 | 1759 | ||
1760 | /*==== Interface to PCMCIA Layer =======================================*/ | 1760 | /*==== Interface to PCMCIA Layer =======================================*/ |
1761 | 1761 | ||
1762 | static int cm4000_config_check(struct pcmcia_device *p_dev, | ||
1763 | cistpl_cftable_entry_t *cfg, | ||
1764 | cistpl_cftable_entry_t *dflt, | ||
1765 | unsigned int vcc, | ||
1766 | void *priv_data) | ||
1767 | { | ||
1768 | if (!cfg->io.nwin) | ||
1769 | return -ENODEV; | ||
1770 | |||
1771 | /* Get the IOaddr */ | ||
1772 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
1773 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
1774 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
1775 | if (!(cfg->io.flags & CISTPL_IO_8BIT)) | ||
1776 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
1777 | if (!(cfg->io.flags & CISTPL_IO_16BIT)) | ||
1778 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
1779 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
1780 | |||
1781 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
1782 | } | ||
1783 | |||
1762 | static int cm4000_config(struct pcmcia_device * link, int devno) | 1784 | static int cm4000_config(struct pcmcia_device * link, int devno) |
1763 | { | 1785 | { |
1764 | struct cm4000_dev *dev; | 1786 | struct cm4000_dev *dev; |
1765 | tuple_t tuple; | ||
1766 | cisparse_t parse; | ||
1767 | u_char buf[64]; | ||
1768 | int fail_fn, fail_rc; | ||
1769 | int rc; | ||
1770 | 1787 | ||
1771 | /* read the config-tuples */ | 1788 | /* read the config-tuples */ |
1772 | tuple.Attributes = 0; | 1789 | if (pcmcia_loop_config(link, cm4000_config_check, NULL)) |
1773 | tuple.TupleData = buf; | ||
1774 | tuple.TupleDataMax = sizeof(buf); | ||
1775 | tuple.TupleOffset = 0; | ||
1776 | |||
1777 | link->io.BasePort2 = 0; | ||
1778 | link->io.NumPorts2 = 0; | ||
1779 | link->io.Attributes2 = 0; | ||
1780 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
1781 | for (rc = pcmcia_get_first_tuple(link, &tuple); | ||
1782 | rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) { | ||
1783 | |||
1784 | rc = pcmcia_get_tuple_data(link, &tuple); | ||
1785 | if (rc != CS_SUCCESS) | ||
1786 | continue; | ||
1787 | rc = pcmcia_parse_tuple(link, &tuple, &parse); | ||
1788 | if (rc != CS_SUCCESS) | ||
1789 | continue; | ||
1790 | |||
1791 | link->conf.ConfigIndex = parse.cftable_entry.index; | ||
1792 | |||
1793 | if (!parse.cftable_entry.io.nwin) | ||
1794 | continue; | ||
1795 | |||
1796 | /* Get the IOaddr */ | ||
1797 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
1798 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
1799 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
1800 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) | ||
1801 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
1802 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) | ||
1803 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
1804 | link->io.IOAddrLines = parse.cftable_entry.io.flags | ||
1805 | & CISTPL_IO_LINES_MASK; | ||
1806 | |||
1807 | rc = pcmcia_request_io(link, &link->io); | ||
1808 | if (rc == CS_SUCCESS) | ||
1809 | break; /* we are done */ | ||
1810 | } | ||
1811 | if (rc != CS_SUCCESS) | ||
1812 | goto cs_release; | 1790 | goto cs_release; |
1813 | 1791 | ||
1814 | link->conf.IntType = 00000002; | 1792 | link->conf.IntType = 00000002; |
1815 | 1793 | ||
1816 | if ((fail_rc = | 1794 | if (pcmcia_request_configuration(link, &link->conf)) |
1817 | pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) { | ||
1818 | fail_fn = RequestConfiguration; | ||
1819 | goto cs_release; | 1795 | goto cs_release; |
1820 | } | ||
1821 | 1796 | ||
1822 | dev = link->priv; | 1797 | dev = link->priv; |
1823 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | 1798 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); |
@@ -1896,7 +1871,7 @@ static int cm4000_probe(struct pcmcia_device *link) | |||
1896 | return ret; | 1871 | return ret; |
1897 | } | 1872 | } |
1898 | 1873 | ||
1899 | device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i); | 1874 | device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i); |
1900 | 1875 | ||
1901 | return 0; | 1876 | return 0; |
1902 | } | 1877 | } |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 0b5934bef7a4..4f0723b07974 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -526,65 +526,49 @@ static void cm4040_reader_release(struct pcmcia_device *link) | |||
526 | return; | 526 | return; |
527 | } | 527 | } |
528 | 528 | ||
529 | static int reader_config(struct pcmcia_device *link, int devno) | 529 | static int cm4040_config_check(struct pcmcia_device *p_dev, |
530 | cistpl_cftable_entry_t *cfg, | ||
531 | cistpl_cftable_entry_t *dflt, | ||
532 | unsigned int vcc, | ||
533 | void *priv_data) | ||
530 | { | 534 | { |
531 | struct reader_dev *dev; | ||
532 | tuple_t tuple; | ||
533 | cisparse_t parse; | ||
534 | u_char buf[64]; | ||
535 | int fail_fn, fail_rc; | ||
536 | int rc; | 535 | int rc; |
536 | if (!cfg->io.nwin) | ||
537 | return -ENODEV; | ||
538 | |||
539 | /* Get the IOaddr */ | ||
540 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
541 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
542 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
543 | if (!(cfg->io.flags & CISTPL_IO_8BIT)) | ||
544 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
545 | if (!(cfg->io.flags & CISTPL_IO_16BIT)) | ||
546 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
547 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
548 | |||
549 | rc = pcmcia_request_io(p_dev, &p_dev->io); | ||
550 | dev_printk(KERN_INFO, &handle_to_dev(p_dev), | ||
551 | "pcmcia_request_io returned 0x%x\n", rc); | ||
552 | return rc; | ||
553 | } | ||
554 | |||
537 | 555 | ||
538 | tuple.Attributes = 0; | 556 | static int reader_config(struct pcmcia_device *link, int devno) |
539 | tuple.TupleData = buf; | 557 | { |
540 | tuple.TupleDataMax = sizeof(buf); | 558 | struct reader_dev *dev; |
541 | tuple.TupleOffset = 0; | 559 | int fail_rc; |
542 | 560 | ||
543 | link->io.BasePort2 = 0; | 561 | link->io.BasePort2 = 0; |
544 | link->io.NumPorts2 = 0; | 562 | link->io.NumPorts2 = 0; |
545 | link->io.Attributes2 = 0; | 563 | link->io.Attributes2 = 0; |
546 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 564 | |
547 | for (rc = pcmcia_get_first_tuple(link, &tuple); | 565 | if (pcmcia_loop_config(link, cm4040_config_check, NULL)) |
548 | rc == CS_SUCCESS; | ||
549 | rc = pcmcia_get_next_tuple(link, &tuple)) { | ||
550 | rc = pcmcia_get_tuple_data(link, &tuple); | ||
551 | if (rc != CS_SUCCESS) | ||
552 | continue; | ||
553 | rc = pcmcia_parse_tuple(link, &tuple, &parse); | ||
554 | if (rc != CS_SUCCESS) | ||
555 | continue; | ||
556 | |||
557 | link->conf.ConfigIndex = parse.cftable_entry.index; | ||
558 | |||
559 | if (!parse.cftable_entry.io.nwin) | ||
560 | continue; | ||
561 | |||
562 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
563 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
564 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
565 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) | ||
566 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
567 | if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) | ||
568 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
569 | link->io.IOAddrLines = parse.cftable_entry.io.flags | ||
570 | & CISTPL_IO_LINES_MASK; | ||
571 | rc = pcmcia_request_io(link, &link->io); | ||
572 | |||
573 | dev_printk(KERN_INFO, &handle_to_dev(link), "foo"); | ||
574 | if (rc == CS_SUCCESS) | ||
575 | break; | ||
576 | else | ||
577 | dev_printk(KERN_INFO, &handle_to_dev(link), | ||
578 | "pcmcia_request_io failed 0x%x\n", rc); | ||
579 | } | ||
580 | if (rc != CS_SUCCESS) | ||
581 | goto cs_release; | 566 | goto cs_release; |
582 | 567 | ||
583 | link->conf.IntType = 00000002; | 568 | link->conf.IntType = 00000002; |
584 | 569 | ||
585 | if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) | 570 | fail_rc = pcmcia_request_configuration(link, &link->conf); |
586 | !=CS_SUCCESS) { | 571 | if (fail_rc != 0) { |
587 | fail_fn = RequestConfiguration; | ||
588 | dev_printk(KERN_INFO, &handle_to_dev(link), | 572 | dev_printk(KERN_INFO, &handle_to_dev(link), |
589 | "pcmcia_request_configuration failed 0x%x\n", | 573 | "pcmcia_request_configuration failed 0x%x\n", |
590 | fail_rc); | 574 | fail_rc); |
@@ -653,8 +637,7 @@ static int reader_probe(struct pcmcia_device *link) | |||
653 | return ret; | 637 | return ret; |
654 | } | 638 | } |
655 | 639 | ||
656 | device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL, | 640 | device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i); |
657 | "cmx%d", i); | ||
658 | 641 | ||
659 | return 0; | 642 | return 0; |
660 | } | 643 | } |
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 5eca7a99afe6..5216fce0c62d 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -65,9 +65,9 @@ static void signalled_reboot_work(struct work_struct *work_reboot) | |||
65 | struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, | 65 | struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, |
66 | work_reboot); | 66 | work_reboot); |
67 | struct pcmcia_device *link = ipw->link; | 67 | struct pcmcia_device *link = ipw->link; |
68 | int ret = pccard_reset_card(link->socket); | 68 | int ret = pcmcia_reset_card(link->socket); |
69 | 69 | ||
70 | if (ret != CS_SUCCESS) | 70 | if (ret != 0) |
71 | cs_error(link, ResetCard, ret); | 71 | cs_error(link, ResetCard, ret); |
72 | } | 72 | } |
73 | 73 | ||
@@ -83,7 +83,6 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
83 | { | 83 | { |
84 | struct pcmcia_device *link = ipw->link; | 84 | struct pcmcia_device *link = ipw->link; |
85 | int ret; | 85 | int ret; |
86 | config_info_t conf; | ||
87 | tuple_t tuple; | 86 | tuple_t tuple; |
88 | unsigned short buf[64]; | 87 | unsigned short buf[64]; |
89 | cisparse_t parse; | 88 | cisparse_t parse; |
@@ -105,7 +104,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
105 | while (ret == 0) { | 104 | while (ret == 0) { |
106 | ret = pcmcia_get_tuple_data(link, &tuple); | 105 | ret = pcmcia_get_tuple_data(link, &tuple); |
107 | 106 | ||
108 | if (ret != CS_SUCCESS) { | 107 | if (ret != 0) { |
109 | cs_error(link, GetTupleData, ret); | 108 | cs_error(link, GetTupleData, ret); |
110 | goto exit0; | 109 | goto exit0; |
111 | } | 110 | } |
@@ -116,21 +115,21 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
116 | 115 | ||
117 | ret = pcmcia_get_first_tuple(link, &tuple); | 116 | ret = pcmcia_get_first_tuple(link, &tuple); |
118 | 117 | ||
119 | if (ret != CS_SUCCESS) { | 118 | if (ret != 0) { |
120 | cs_error(link, GetFirstTuple, ret); | 119 | cs_error(link, GetFirstTuple, ret); |
121 | goto exit0; | 120 | goto exit0; |
122 | } | 121 | } |
123 | 122 | ||
124 | ret = pcmcia_get_tuple_data(link, &tuple); | 123 | ret = pcmcia_get_tuple_data(link, &tuple); |
125 | 124 | ||
126 | if (ret != CS_SUCCESS) { | 125 | if (ret != 0) { |
127 | cs_error(link, GetTupleData, ret); | 126 | cs_error(link, GetTupleData, ret); |
128 | goto exit0; | 127 | goto exit0; |
129 | } | 128 | } |
130 | 129 | ||
131 | ret = pcmcia_parse_tuple(link, &tuple, &parse); | 130 | ret = pcmcia_parse_tuple(&tuple, &parse); |
132 | 131 | ||
133 | if (ret != CS_SUCCESS) { | 132 | if (ret != 0) { |
134 | cs_error(link, ParseTuple, ret); | 133 | cs_error(link, ParseTuple, ret); |
135 | goto exit0; | 134 | goto exit0; |
136 | } | 135 | } |
@@ -152,21 +151,21 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
152 | 151 | ||
153 | ret = pcmcia_get_first_tuple(link, &tuple); | 152 | ret = pcmcia_get_first_tuple(link, &tuple); |
154 | 153 | ||
155 | if (ret != CS_SUCCESS) { | 154 | if (ret != 0) { |
156 | cs_error(link, GetFirstTuple, ret); | 155 | cs_error(link, GetFirstTuple, ret); |
157 | goto exit0; | 156 | goto exit0; |
158 | } | 157 | } |
159 | 158 | ||
160 | ret = pcmcia_get_tuple_data(link, &tuple); | 159 | ret = pcmcia_get_tuple_data(link, &tuple); |
161 | 160 | ||
162 | if (ret != CS_SUCCESS) { | 161 | if (ret != 0) { |
163 | cs_error(link, GetTupleData, ret); | 162 | cs_error(link, GetTupleData, ret); |
164 | goto exit0; | 163 | goto exit0; |
165 | } | 164 | } |
166 | 165 | ||
167 | ret = pcmcia_parse_tuple(link, &tuple, &parse); | 166 | ret = pcmcia_parse_tuple(&tuple, &parse); |
168 | 167 | ||
169 | if (ret != CS_SUCCESS) { | 168 | if (ret != 0) { |
170 | cs_error(link, GetTupleData, ret); | 169 | cs_error(link, GetTupleData, ret); |
171 | goto exit0; | 170 | goto exit0; |
172 | } | 171 | } |
@@ -181,7 +180,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
181 | 180 | ||
182 | ret = pcmcia_request_io(link, &link->io); | 181 | ret = pcmcia_request_io(link, &link->io); |
183 | 182 | ||
184 | if (ret != CS_SUCCESS) { | 183 | if (ret != 0) { |
185 | cs_error(link, RequestIO, ret); | 184 | cs_error(link, RequestIO, ret); |
186 | goto exit0; | 185 | goto exit0; |
187 | } | 186 | } |
@@ -195,21 +194,21 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
195 | 194 | ||
196 | ret = pcmcia_get_first_tuple(link, &tuple); | 195 | ret = pcmcia_get_first_tuple(link, &tuple); |
197 | 196 | ||
198 | if (ret != CS_SUCCESS) { | 197 | if (ret != 0) { |
199 | cs_error(link, GetFirstTuple, ret); | 198 | cs_error(link, GetFirstTuple, ret); |
200 | goto exit1; | 199 | goto exit1; |
201 | } | 200 | } |
202 | 201 | ||
203 | ret = pcmcia_get_tuple_data(link, &tuple); | 202 | ret = pcmcia_get_tuple_data(link, &tuple); |
204 | 203 | ||
205 | if (ret != CS_SUCCESS) { | 204 | if (ret != 0) { |
206 | cs_error(link, GetTupleData, ret); | 205 | cs_error(link, GetTupleData, ret); |
207 | goto exit1; | 206 | goto exit1; |
208 | } | 207 | } |
209 | 208 | ||
210 | ret = pcmcia_parse_tuple(link, &tuple, &parse); | 209 | ret = pcmcia_parse_tuple(&tuple, &parse); |
211 | 210 | ||
212 | if (ret != CS_SUCCESS) { | 211 | if (ret != 0) { |
213 | cs_error(link, ParseTuple, ret); | 212 | cs_error(link, ParseTuple, ret); |
214 | goto exit1; | 213 | goto exit1; |
215 | } | 214 | } |
@@ -227,7 +226,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
227 | ret = pcmcia_request_window(&link, &ipw->request_common_memory, | 226 | ret = pcmcia_request_window(&link, &ipw->request_common_memory, |
228 | &ipw->handle_common_memory); | 227 | &ipw->handle_common_memory); |
229 | 228 | ||
230 | if (ret != CS_SUCCESS) { | 229 | if (ret != 0) { |
231 | cs_error(link, RequestWindow, ret); | 230 | cs_error(link, RequestWindow, ret); |
232 | goto exit1; | 231 | goto exit1; |
233 | } | 232 | } |
@@ -239,7 +238,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
239 | ret = pcmcia_map_mem_page(ipw->handle_common_memory, | 238 | ret = pcmcia_map_mem_page(ipw->handle_common_memory, |
240 | &memreq_common_memory); | 239 | &memreq_common_memory); |
241 | 240 | ||
242 | if (ret != CS_SUCCESS) { | 241 | if (ret != 0) { |
243 | cs_error(link, MapMemPage, ret); | 242 | cs_error(link, MapMemPage, ret); |
244 | goto exit1; | 243 | goto exit1; |
245 | } | 244 | } |
@@ -261,7 +260,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
261 | ret = pcmcia_request_window(&link, &ipw->request_attr_memory, | 260 | ret = pcmcia_request_window(&link, &ipw->request_attr_memory, |
262 | &ipw->handle_attr_memory); | 261 | &ipw->handle_attr_memory); |
263 | 262 | ||
264 | if (ret != CS_SUCCESS) { | 263 | if (ret != 0) { |
265 | cs_error(link, RequestWindow, ret); | 264 | cs_error(link, RequestWindow, ret); |
266 | goto exit2; | 265 | goto exit2; |
267 | } | 266 | } |
@@ -272,7 +271,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
272 | ret = pcmcia_map_mem_page(ipw->handle_attr_memory, | 271 | ret = pcmcia_map_mem_page(ipw->handle_attr_memory, |
273 | &memreq_attr_memory); | 272 | &memreq_attr_memory); |
274 | 273 | ||
275 | if (ret != CS_SUCCESS) { | 274 | if (ret != 0) { |
276 | cs_error(link, MapMemPage, ret); | 275 | cs_error(link, MapMemPage, ret); |
277 | goto exit2; | 276 | goto exit2; |
278 | } | 277 | } |
@@ -292,20 +291,11 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
292 | 291 | ||
293 | ret = pcmcia_request_irq(link, &link->irq); | 292 | ret = pcmcia_request_irq(link, &link->irq); |
294 | 293 | ||
295 | if (ret != CS_SUCCESS) { | 294 | if (ret != 0) { |
296 | cs_error(link, RequestIRQ, ret); | 295 | cs_error(link, RequestIRQ, ret); |
297 | goto exit3; | 296 | goto exit3; |
298 | } | 297 | } |
299 | 298 | ||
300 | /* Look up current Vcc */ | ||
301 | |||
302 | ret = pcmcia_get_configuration_info(link, &conf); | ||
303 | |||
304 | if (ret != CS_SUCCESS) { | ||
305 | cs_error(link, GetConfigurationInfo, ret); | ||
306 | goto exit4; | ||
307 | } | ||
308 | |||
309 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", | 299 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", |
310 | ipw->is_v2_card ? "V2/V3" : "V1"); | 300 | ipw->is_v2_card ? "V2/V3" : "V1"); |
311 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 301 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
@@ -341,7 +331,7 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
341 | */ | 331 | */ |
342 | ret = pcmcia_request_configuration(link, &link->conf); | 332 | ret = pcmcia_request_configuration(link, &link->conf); |
343 | 333 | ||
344 | if (ret != CS_SUCCESS) { | 334 | if (ret != 0) { |
345 | cs_error(link, RequestConfiguration, ret); | 335 | cs_error(link, RequestConfiguration, ret); |
346 | goto exit4; | 336 | goto exit4; |
347 | } | 337 | } |
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 3a23e7694d55..569f2f7743a7 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -276,6 +276,7 @@ static int ipw_write_room(struct tty_struct *linux_tty) | |||
276 | struct ipw_tty *tty = linux_tty->driver_data; | 276 | struct ipw_tty *tty = linux_tty->driver_data; |
277 | int room; | 277 | int room; |
278 | 278 | ||
279 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
279 | if (!tty) | 280 | if (!tty) |
280 | return -ENODEV; | 281 | return -ENODEV; |
281 | 282 | ||
@@ -397,6 +398,7 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set, | |||
397 | static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) | 398 | static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) |
398 | { | 399 | { |
399 | struct ipw_tty *tty = linux_tty->driver_data; | 400 | struct ipw_tty *tty = linux_tty->driver_data; |
401 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
400 | 402 | ||
401 | if (!tty) | 403 | if (!tty) |
402 | return -ENODEV; | 404 | return -ENODEV; |
@@ -412,6 +414,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, struct file *file, | |||
412 | unsigned int set, unsigned int clear) | 414 | unsigned int set, unsigned int clear) |
413 | { | 415 | { |
414 | struct ipw_tty *tty = linux_tty->driver_data; | 416 | struct ipw_tty *tty = linux_tty->driver_data; |
417 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
415 | 418 | ||
416 | if (!tty) | 419 | if (!tty) |
417 | return -ENODEV; | 420 | return -ENODEV; |
@@ -433,6 +436,8 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
433 | if (!tty->open_count) | 436 | if (!tty->open_count) |
434 | return -EINVAL; | 437 | return -EINVAL; |
435 | 438 | ||
439 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
440 | |||
436 | switch (cmd) { | 441 | switch (cmd) { |
437 | case TIOCGSERIAL: | 442 | case TIOCGSERIAL: |
438 | return ipwireless_get_serial_info(tty, (void __user *) arg); | 443 | return ipwireless_get_serial_info(tty, (void __user *) arg); |
@@ -467,13 +472,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
467 | } | 472 | } |
468 | return 0; | 473 | return 0; |
469 | 474 | ||
470 | case TCGETS: | ||
471 | case TCGETA: | ||
472 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
473 | |||
474 | case TCFLSH: | ||
475 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
476 | |||
477 | case FIONREAD: | 475 | case FIONREAD: |
478 | { | 476 | { |
479 | int val = 0; | 477 | int val = 0; |
@@ -482,10 +480,11 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
482 | return -EFAULT; | 480 | return -EFAULT; |
483 | } | 481 | } |
484 | return 0; | 482 | return 0; |
483 | case TCFLSH: | ||
484 | return tty_perform_flush(linux_tty, arg); | ||
485 | } | 485 | } |
486 | } | 486 | } |
487 | 487 | return tty_mode_ioctl(linux_tty, file, cmd , arg); | |
488 | return -ENOIOCTLCMD; | ||
489 | } | 488 | } |
490 | 489 | ||
491 | static int add_tty(dev_node_t *nodesp, int j, | 490 | static int add_tty(dev_node_t *nodesp, int j, |
@@ -588,6 +587,8 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
588 | tty_hangup(ttyj->linux_tty); | 587 | tty_hangup(ttyj->linux_tty); |
589 | /* Wait till the tty_hangup has completed */ | 588 | /* Wait till the tty_hangup has completed */ |
590 | flush_scheduled_work(); | 589 | flush_scheduled_work(); |
590 | /* FIXME: Exactly how is the tty object locked here | ||
591 | against a parallel ioctl etc */ | ||
591 | mutex_lock(&ttyj->ipw_tty_mutex); | 592 | mutex_lock(&ttyj->ipw_tty_mutex); |
592 | } | 593 | } |
593 | while (ttyj->open_count) | 594 | while (ttyj->open_count) |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c240562c218b..9a626e50b793 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -601,7 +601,7 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
601 | 601 | ||
602 | cfg = &(parse.cftable_entry); | 602 | cfg = &(parse.cftable_entry); |
603 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | 603 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
604 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | 604 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); |
605 | 605 | ||
606 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | 606 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; |
607 | if (cfg->index == 0) | 607 | if (cfg->index == 0) |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index bee39fdfba73..c84c34fb1231 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -760,9 +760,8 @@ static const struct file_operations pp_fops = { | |||
760 | 760 | ||
761 | static void pp_attach(struct parport *port) | 761 | static void pp_attach(struct parport *port) |
762 | { | 762 | { |
763 | device_create_drvdata(ppdev_class, port->dev, | 763 | device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), |
764 | MKDEV(PP_MAJOR, port->number), | 764 | NULL, "parport%d", port->number); |
765 | NULL, "parport%d", port->number); | ||
766 | } | 765 | } |
767 | 766 | ||
768 | static void pp_detach(struct parport *port) | 767 | static void pp_detach(struct parport *port) |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 76b27932d229..6d4582712b1f 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -8,10 +8,12 @@ | |||
8 | * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to | 8 | * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to |
9 | * waiting writers -- Sapan Bhatia <sapan@corewars.org> | 9 | * waiting writers -- Sapan Bhatia <sapan@corewars.org> |
10 | * | 10 | * |
11 | * | 11 | * When reading this code see also fs/devpts. In particular note that the |
12 | * driver_data field is used by the devpts side as a binding to the devpts | ||
13 | * inode. | ||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #include <linux/module.h> /* For EXPORT_SYMBOL */ | 16 | #include <linux/module.h> |
15 | 17 | ||
16 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
@@ -23,26 +25,25 @@ | |||
23 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
24 | #include <linux/init.h> | 26 | #include <linux/init.h> |
25 | #include <linux/sysctl.h> | 27 | #include <linux/sysctl.h> |
26 | 28 | #include <linux/device.h> | |
27 | #include <asm/uaccess.h> | 29 | #include <linux/uaccess.h> |
28 | #include <asm/system.h> | ||
29 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
30 | #include <linux/devpts_fs.h> | 31 | #include <linux/devpts_fs.h> |
31 | 32 | ||
33 | #include <asm/system.h> | ||
34 | |||
32 | /* These are global because they are accessed in tty_io.c */ | 35 | /* These are global because they are accessed in tty_io.c */ |
33 | #ifdef CONFIG_UNIX98_PTYS | 36 | #ifdef CONFIG_UNIX98_PTYS |
34 | struct tty_driver *ptm_driver; | 37 | struct tty_driver *ptm_driver; |
35 | static struct tty_driver *pts_driver; | 38 | static struct tty_driver *pts_driver; |
36 | #endif | 39 | #endif |
37 | 40 | ||
38 | static void pty_close(struct tty_struct * tty, struct file * filp) | 41 | static void pty_close(struct tty_struct *tty, struct file *filp) |
39 | { | 42 | { |
40 | if (!tty) | 43 | BUG_ON(!tty); |
41 | return; | 44 | if (tty->driver->subtype == PTY_TYPE_MASTER) |
42 | if (tty->driver->subtype == PTY_TYPE_MASTER) { | 45 | WARN_ON(tty->count > 1); |
43 | if (tty->count > 1) | 46 | else { |
44 | printk("master pty_close: count = %d!!\n", tty->count); | ||
45 | } else { | ||
46 | if (tty->count > 2) | 47 | if (tty->count > 2) |
47 | return; | 48 | return; |
48 | } | 49 | } |
@@ -59,7 +60,7 @@ static void pty_close(struct tty_struct * tty, struct file * filp) | |||
59 | set_bit(TTY_OTHER_CLOSED, &tty->flags); | 60 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
60 | #ifdef CONFIG_UNIX98_PTYS | 61 | #ifdef CONFIG_UNIX98_PTYS |
61 | if (tty->driver == ptm_driver) | 62 | if (tty->driver == ptm_driver) |
62 | devpts_pty_kill(tty->index); | 63 | devpts_pty_kill(tty->link); |
63 | #endif | 64 | #endif |
64 | tty_vhangup(tty->link); | 65 | tty_vhangup(tty->link); |
65 | } | 66 | } |
@@ -69,13 +70,13 @@ static void pty_close(struct tty_struct * tty, struct file * filp) | |||
69 | * The unthrottle routine is called by the line discipline to signal | 70 | * The unthrottle routine is called by the line discipline to signal |
70 | * that it can receive more characters. For PTY's, the TTY_THROTTLED | 71 | * that it can receive more characters. For PTY's, the TTY_THROTTLED |
71 | * flag is always set, to force the line discipline to always call the | 72 | * flag is always set, to force the line discipline to always call the |
72 | * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE | 73 | * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE |
73 | * characters in the queue. This is necessary since each time this | 74 | * characters in the queue. This is necessary since each time this |
74 | * happens, we need to wake up any sleeping processes that could be | 75 | * happens, we need to wake up any sleeping processes that could be |
75 | * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() | 76 | * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() |
76 | * for the pty buffer to be drained. | 77 | * for the pty buffer to be drained. |
77 | */ | 78 | */ |
78 | static void pty_unthrottle(struct tty_struct * tty) | 79 | static void pty_unthrottle(struct tty_struct *tty) |
79 | { | 80 | { |
80 | struct tty_struct *o_tty = tty->link; | 81 | struct tty_struct *o_tty = tty->link; |
81 | 82 | ||
@@ -87,7 +88,7 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
87 | } | 88 | } |
88 | 89 | ||
89 | /* | 90 | /* |
90 | * WSH 05/24/97: modified to | 91 | * WSH 05/24/97: modified to |
91 | * (1) use space in tty->flip instead of a shared temp buffer | 92 | * (1) use space in tty->flip instead of a shared temp buffer |
92 | * The flip buffers aren't being used for a pty, so there's lots | 93 | * The flip buffers aren't being used for a pty, so there's lots |
93 | * of space available. The buffer is protected by a per-pty | 94 | * of space available. The buffer is protected by a per-pty |
@@ -100,7 +101,8 @@ static void pty_unthrottle(struct tty_struct * tty) | |||
100 | * not our partners. We can't just take the other one blindly without | 101 | * not our partners. We can't just take the other one blindly without |
101 | * risking deadlocks. | 102 | * risking deadlocks. |
102 | */ | 103 | */ |
103 | static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) | 104 | static int pty_write(struct tty_struct *tty, const unsigned char *buf, |
105 | int count) | ||
104 | { | 106 | { |
105 | struct tty_struct *to = tty->link; | 107 | struct tty_struct *to = tty->link; |
106 | int c; | 108 | int c; |
@@ -112,7 +114,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun | |||
112 | if (c > count) | 114 | if (c > count) |
113 | c = count; | 115 | c = count; |
114 | to->ldisc.ops->receive_buf(to, buf, NULL, c); | 116 | to->ldisc.ops->receive_buf(to, buf, NULL, c); |
115 | 117 | ||
116 | return c; | 118 | return c; |
117 | } | 119 | } |
118 | 120 | ||
@@ -128,17 +130,17 @@ static int pty_write_room(struct tty_struct *tty) | |||
128 | 130 | ||
129 | /* | 131 | /* |
130 | * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior | 132 | * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior |
131 | * The chars_in_buffer() value is used by the ldisc select() function | 133 | * The chars_in_buffer() value is used by the ldisc select() function |
132 | * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). | 134 | * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). |
133 | * The pty driver chars_in_buffer() Master/Slave must behave differently: | 135 | * The pty driver chars_in_buffer() Master/Slave must behave differently: |
134 | * | 136 | * |
135 | * The Master side needs to allow typed-ahead commands to accumulate | 137 | * The Master side needs to allow typed-ahead commands to accumulate |
136 | * while being canonicalized, so we report "our buffer" as empty until | 138 | * while being canonicalized, so we report "our buffer" as empty until |
137 | * some threshold is reached, and then report the count. (Any count > | 139 | * some threshold is reached, and then report the count. (Any count > |
138 | * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock | 140 | * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock |
139 | * the count returned must be 0 if no canonical data is available to be | 141 | * the count returned must be 0 if no canonical data is available to be |
140 | * read. (The N_TTY ldisc.chars_in_buffer now knows this.) | 142 | * read. (The N_TTY ldisc.chars_in_buffer now knows this.) |
141 | * | 143 | * |
142 | * The Slave side passes all characters in raw mode to the Master side's | 144 | * The Slave side passes all characters in raw mode to the Master side's |
143 | * buffer where they can be read immediately, so in this case we can | 145 | * buffer where they can be read immediately, so in this case we can |
144 | * return the true count in the buffer. | 146 | * return the true count in the buffer. |
@@ -155,21 +157,22 @@ static int pty_chars_in_buffer(struct tty_struct *tty) | |||
155 | /* The ldisc must report 0 if no characters available to be read */ | 157 | /* The ldisc must report 0 if no characters available to be read */ |
156 | count = to->ldisc.ops->chars_in_buffer(to); | 158 | count = to->ldisc.ops->chars_in_buffer(to); |
157 | 159 | ||
158 | if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; | 160 | if (tty->driver->subtype == PTY_TYPE_SLAVE) |
161 | return count; | ||
159 | 162 | ||
160 | /* Master side driver ... if the other side's read buffer is less than | 163 | /* Master side driver ... if the other side's read buffer is less than |
161 | * half full, return 0 to allow writers to proceed; otherwise return | 164 | * half full, return 0 to allow writers to proceed; otherwise return |
162 | * the count. This leaves a comfortable margin to avoid overflow, | 165 | * the count. This leaves a comfortable margin to avoid overflow, |
163 | * and still allows half a buffer's worth of typed-ahead commands. | 166 | * and still allows half a buffer's worth of typed-ahead commands. |
164 | */ | 167 | */ |
165 | return ((count < N_TTY_BUF_SIZE/2) ? 0 : count); | 168 | return (count < N_TTY_BUF_SIZE/2) ? 0 : count; |
166 | } | 169 | } |
167 | 170 | ||
168 | /* Set the lock flag on a pty */ | 171 | /* Set the lock flag on a pty */ |
169 | static int pty_set_lock(struct tty_struct *tty, int __user * arg) | 172 | static int pty_set_lock(struct tty_struct *tty, int __user *arg) |
170 | { | 173 | { |
171 | int val; | 174 | int val; |
172 | if (get_user(val,arg)) | 175 | if (get_user(val, arg)) |
173 | return -EFAULT; | 176 | return -EFAULT; |
174 | if (val) | 177 | if (val) |
175 | set_bit(TTY_PTY_LOCK, &tty->flags); | 178 | set_bit(TTY_PTY_LOCK, &tty->flags); |
@@ -182,13 +185,13 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
182 | { | 185 | { |
183 | struct tty_struct *to = tty->link; | 186 | struct tty_struct *to = tty->link; |
184 | unsigned long flags; | 187 | unsigned long flags; |
185 | 188 | ||
186 | if (!to) | 189 | if (!to) |
187 | return; | 190 | return; |
188 | 191 | ||
189 | if (to->ldisc.ops->flush_buffer) | 192 | if (to->ldisc.ops->flush_buffer) |
190 | to->ldisc.ops->flush_buffer(to); | 193 | to->ldisc.ops->flush_buffer(to); |
191 | 194 | ||
192 | if (to->packet) { | 195 | if (to->packet) { |
193 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 196 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
194 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 197 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
@@ -197,7 +200,7 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
197 | } | 200 | } |
198 | } | 201 | } |
199 | 202 | ||
200 | static int pty_open(struct tty_struct *tty, struct file * filp) | 203 | static int pty_open(struct tty_struct *tty, struct file *filp) |
201 | { | 204 | { |
202 | int retval = -ENODEV; | 205 | int retval = -ENODEV; |
203 | 206 | ||
@@ -220,13 +223,65 @@ out: | |||
220 | return retval; | 223 | return retval; |
221 | } | 224 | } |
222 | 225 | ||
223 | static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 226 | static void pty_set_termios(struct tty_struct *tty, |
227 | struct ktermios *old_termios) | ||
228 | { | ||
229 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | ||
230 | tty->termios->c_cflag |= (CS8 | CREAD); | ||
231 | } | ||
232 | |||
233 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
224 | { | 234 | { |
225 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | 235 | struct tty_struct *o_tty; |
226 | tty->termios->c_cflag |= (CS8 | CREAD); | 236 | int idx = tty->index; |
237 | int retval; | ||
238 | |||
239 | o_tty = alloc_tty_struct(); | ||
240 | if (!o_tty) | ||
241 | return -ENOMEM; | ||
242 | if (!try_module_get(driver->other->owner)) { | ||
243 | /* This cannot in fact currently happen */ | ||
244 | free_tty_struct(o_tty); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | initialize_tty_struct(o_tty, driver->other, idx); | ||
248 | |||
249 | /* We always use new tty termios data so we can do this | ||
250 | the easy way .. */ | ||
251 | retval = tty_init_termios(tty); | ||
252 | if (retval) | ||
253 | goto free_mem_out; | ||
254 | |||
255 | retval = tty_init_termios(o_tty); | ||
256 | if (retval) { | ||
257 | tty_free_termios(tty); | ||
258 | goto free_mem_out; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Everything allocated ... set up the o_tty structure. | ||
263 | */ | ||
264 | driver->other->ttys[idx] = o_tty; | ||
265 | tty_driver_kref_get(driver->other); | ||
266 | if (driver->subtype == PTY_TYPE_MASTER) | ||
267 | o_tty->count++; | ||
268 | /* Establish the links in both directions */ | ||
269 | tty->link = o_tty; | ||
270 | o_tty->link = tty; | ||
271 | |||
272 | tty_driver_kref_get(driver); | ||
273 | tty->count++; | ||
274 | driver->ttys[idx] = tty; | ||
275 | return 0; | ||
276 | free_mem_out: | ||
277 | module_put(o_tty->driver->owner); | ||
278 | free_tty_struct(o_tty); | ||
279 | return -ENOMEM; | ||
227 | } | 280 | } |
228 | 281 | ||
282 | |||
229 | static const struct tty_operations pty_ops = { | 283 | static const struct tty_operations pty_ops = { |
284 | .install = pty_install, | ||
230 | .open = pty_open, | 285 | .open = pty_open, |
231 | .close = pty_close, | 286 | .close = pty_close, |
232 | .write = pty_write, | 287 | .write = pty_write, |
@@ -329,8 +384,11 @@ static inline void legacy_pty_init(void) { } | |||
329 | * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. | 384 | * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. |
330 | */ | 385 | */ |
331 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | 386 | int pty_limit = NR_UNIX98_PTY_DEFAULT; |
332 | static int pty_limit_min = 0; | 387 | static int pty_limit_min; |
333 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 388 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
389 | static int pty_count; | ||
390 | |||
391 | static struct cdev ptmx_cdev; | ||
334 | 392 | ||
335 | static struct ctl_table pty_table[] = { | 393 | static struct ctl_table pty_table[] = { |
336 | { | 394 | { |
@@ -348,6 +406,7 @@ static struct ctl_table pty_table[] = { | |||
348 | .procname = "nr", | 406 | .procname = "nr", |
349 | .maxlen = sizeof(int), | 407 | .maxlen = sizeof(int), |
350 | .mode = 0444, | 408 | .mode = 0444, |
409 | .data = &pty_count, | ||
351 | .proc_handler = &proc_dointvec, | 410 | .proc_handler = &proc_dointvec, |
352 | }, { | 411 | }, { |
353 | .ctl_name = 0 | 412 | .ctl_name = 0 |
@@ -388,7 +447,127 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | |||
388 | return -ENOIOCTLCMD; | 447 | return -ENOIOCTLCMD; |
389 | } | 448 | } |
390 | 449 | ||
450 | /** | ||
451 | * ptm_unix98_lookup - find a pty master | ||
452 | * @driver: ptm driver | ||
453 | * @idx: tty index | ||
454 | * | ||
455 | * Look up a pty master device. Called under the tty_mutex for now. | ||
456 | * This provides our locking. | ||
457 | */ | ||
458 | |||
459 | static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, | ||
460 | struct inode *ptm_inode, int idx) | ||
461 | { | ||
462 | struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); | ||
463 | if (tty) | ||
464 | tty = tty->link; | ||
465 | return tty; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * pts_unix98_lookup - find a pty slave | ||
470 | * @driver: pts driver | ||
471 | * @idx: tty index | ||
472 | * | ||
473 | * Look up a pty master device. Called under the tty_mutex for now. | ||
474 | * This provides our locking. | ||
475 | */ | ||
476 | |||
477 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | ||
478 | struct inode *pts_inode, int idx) | ||
479 | { | ||
480 | struct tty_struct *tty = devpts_get_tty(pts_inode, idx); | ||
481 | /* Master must be open before slave */ | ||
482 | if (!tty) | ||
483 | return ERR_PTR(-EIO); | ||
484 | return tty; | ||
485 | } | ||
486 | |||
487 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
488 | { | ||
489 | /* We have our own method as we don't use the tty index */ | ||
490 | kfree(tty->termios); | ||
491 | } | ||
492 | |||
493 | /* We have no need to install and remove our tty objects as devpts does all | ||
494 | the work for us */ | ||
495 | |||
496 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | ||
497 | { | ||
498 | struct tty_struct *o_tty; | ||
499 | int idx = tty->index; | ||
500 | |||
501 | o_tty = alloc_tty_struct(); | ||
502 | if (!o_tty) | ||
503 | return -ENOMEM; | ||
504 | if (!try_module_get(driver->other->owner)) { | ||
505 | /* This cannot in fact currently happen */ | ||
506 | free_tty_struct(o_tty); | ||
507 | return -ENOMEM; | ||
508 | } | ||
509 | initialize_tty_struct(o_tty, driver->other, idx); | ||
510 | |||
511 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
512 | if (tty->termios == NULL) | ||
513 | goto free_mem_out; | ||
514 | *tty->termios = driver->init_termios; | ||
515 | tty->termios_locked = tty->termios + 1; | ||
516 | |||
517 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
518 | if (o_tty->termios == NULL) | ||
519 | goto free_mem_out; | ||
520 | *o_tty->termios = driver->other->init_termios; | ||
521 | o_tty->termios_locked = o_tty->termios + 1; | ||
522 | |||
523 | tty_driver_kref_get(driver->other); | ||
524 | if (driver->subtype == PTY_TYPE_MASTER) | ||
525 | o_tty->count++; | ||
526 | /* Establish the links in both directions */ | ||
527 | tty->link = o_tty; | ||
528 | o_tty->link = tty; | ||
529 | /* | ||
530 | * All structures have been allocated, so now we install them. | ||
531 | * Failures after this point use release_tty to clean up, so | ||
532 | * there's no need to null out the local pointers. | ||
533 | */ | ||
534 | tty_driver_kref_get(driver); | ||
535 | tty->count++; | ||
536 | pty_count++; | ||
537 | return 0; | ||
538 | free_mem_out: | ||
539 | kfree(o_tty->termios); | ||
540 | module_put(o_tty->driver->owner); | ||
541 | free_tty_struct(o_tty); | ||
542 | kfree(tty->termios); | ||
543 | return -ENOMEM; | ||
544 | } | ||
545 | |||
546 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
547 | { | ||
548 | pty_count--; | ||
549 | } | ||
550 | |||
551 | static const struct tty_operations ptm_unix98_ops = { | ||
552 | .lookup = ptm_unix98_lookup, | ||
553 | .install = pty_unix98_install, | ||
554 | .remove = pty_unix98_remove, | ||
555 | .open = pty_open, | ||
556 | .close = pty_close, | ||
557 | .write = pty_write, | ||
558 | .write_room = pty_write_room, | ||
559 | .flush_buffer = pty_flush_buffer, | ||
560 | .chars_in_buffer = pty_chars_in_buffer, | ||
561 | .unthrottle = pty_unthrottle, | ||
562 | .set_termios = pty_set_termios, | ||
563 | .ioctl = pty_unix98_ioctl, | ||
564 | .shutdown = pty_unix98_shutdown | ||
565 | }; | ||
566 | |||
391 | static const struct tty_operations pty_unix98_ops = { | 567 | static const struct tty_operations pty_unix98_ops = { |
568 | .lookup = pts_unix98_lookup, | ||
569 | .install = pty_unix98_install, | ||
570 | .remove = pty_unix98_remove, | ||
392 | .open = pty_open, | 571 | .open = pty_open, |
393 | .close = pty_close, | 572 | .close = pty_close, |
394 | .write = pty_write, | 573 | .write = pty_write, |
@@ -397,9 +576,73 @@ static const struct tty_operations pty_unix98_ops = { | |||
397 | .chars_in_buffer = pty_chars_in_buffer, | 576 | .chars_in_buffer = pty_chars_in_buffer, |
398 | .unthrottle = pty_unthrottle, | 577 | .unthrottle = pty_unthrottle, |
399 | .set_termios = pty_set_termios, | 578 | .set_termios = pty_set_termios, |
400 | .ioctl = pty_unix98_ioctl | 579 | .shutdown = pty_unix98_shutdown |
401 | }; | 580 | }; |
402 | 581 | ||
582 | /** | ||
583 | * ptmx_open - open a unix 98 pty master | ||
584 | * @inode: inode of device file | ||
585 | * @filp: file pointer to tty | ||
586 | * | ||
587 | * Allocate a unix98 pty master device from the ptmx driver. | ||
588 | * | ||
589 | * Locking: tty_mutex protects the init_dev work. tty->count should | ||
590 | * protect the rest. | ||
591 | * allocated_ptys_lock handles the list of free pty numbers | ||
592 | */ | ||
593 | |||
594 | static int __ptmx_open(struct inode *inode, struct file *filp) | ||
595 | { | ||
596 | struct tty_struct *tty; | ||
597 | int retval; | ||
598 | int index; | ||
599 | |||
600 | nonseekable_open(inode, filp); | ||
601 | |||
602 | /* find a device that is not in use. */ | ||
603 | index = devpts_new_index(inode); | ||
604 | if (index < 0) | ||
605 | return index; | ||
606 | |||
607 | mutex_lock(&tty_mutex); | ||
608 | tty = tty_init_dev(ptm_driver, index, 1); | ||
609 | mutex_unlock(&tty_mutex); | ||
610 | |||
611 | if (IS_ERR(tty)) { | ||
612 | retval = PTR_ERR(tty); | ||
613 | goto out; | ||
614 | } | ||
615 | |||
616 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | ||
617 | filp->private_data = tty; | ||
618 | file_move(filp, &tty->tty_files); | ||
619 | |||
620 | retval = devpts_pty_new(inode, tty->link); | ||
621 | if (retval) | ||
622 | goto out1; | ||
623 | |||
624 | retval = ptm_driver->ops->open(tty, filp); | ||
625 | if (!retval) | ||
626 | return 0; | ||
627 | out1: | ||
628 | tty_release_dev(filp); | ||
629 | return retval; | ||
630 | out: | ||
631 | devpts_kill_index(inode, index); | ||
632 | return retval; | ||
633 | } | ||
634 | |||
635 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
636 | { | ||
637 | int ret; | ||
638 | |||
639 | lock_kernel(); | ||
640 | ret = __ptmx_open(inode, filp); | ||
641 | unlock_kernel(); | ||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | static struct file_operations ptmx_fops; | ||
403 | 646 | ||
404 | static void __init unix98_pty_init(void) | 647 | static void __init unix98_pty_init(void) |
405 | { | 648 | { |
@@ -427,7 +670,7 @@ static void __init unix98_pty_init(void) | |||
427 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 670 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
428 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 671 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
429 | ptm_driver->other = pts_driver; | 672 | ptm_driver->other = pts_driver; |
430 | tty_set_operations(ptm_driver, &pty_unix98_ops); | 673 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
431 | 674 | ||
432 | pts_driver->owner = THIS_MODULE; | 675 | pts_driver->owner = THIS_MODULE; |
433 | pts_driver->driver_name = "pty_slave"; | 676 | pts_driver->driver_name = "pty_slave"; |
@@ -443,16 +686,26 @@ static void __init unix98_pty_init(void) | |||
443 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 686 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
444 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 687 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
445 | pts_driver->other = ptm_driver; | 688 | pts_driver->other = ptm_driver; |
446 | tty_set_operations(pts_driver, &pty_ops); | 689 | tty_set_operations(pts_driver, &pty_unix98_ops); |
447 | 690 | ||
448 | if (tty_register_driver(ptm_driver)) | 691 | if (tty_register_driver(ptm_driver)) |
449 | panic("Couldn't register Unix98 ptm driver"); | 692 | panic("Couldn't register Unix98 ptm driver"); |
450 | if (tty_register_driver(pts_driver)) | 693 | if (tty_register_driver(pts_driver)) |
451 | panic("Couldn't register Unix98 pts driver"); | 694 | panic("Couldn't register Unix98 pts driver"); |
452 | 695 | ||
453 | pty_table[1].data = &ptm_driver->refcount; | ||
454 | register_sysctl_table(pty_root_table); | 696 | register_sysctl_table(pty_root_table); |
697 | |||
698 | /* Now create the /dev/ptmx special device */ | ||
699 | tty_default_fops(&ptmx_fops); | ||
700 | ptmx_fops.open = ptmx_open; | ||
701 | |||
702 | cdev_init(&ptmx_cdev, &ptmx_fops); | ||
703 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | ||
704 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | ||
705 | panic("Couldn't register /dev/ptmx driver\n"); | ||
706 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | ||
455 | } | 707 | } |
708 | |||
456 | #else | 709 | #else |
457 | static inline void unix98_pty_init(void) { } | 710 | static inline void unix98_pty_init(void) { } |
458 | #endif | 711 | #endif |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 7ce1ac4baa6d..705a839f1796 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -558,9 +558,26 @@ struct timer_rand_state { | |||
558 | unsigned dont_count_entropy:1; | 558 | unsigned dont_count_entropy:1; |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static struct timer_rand_state input_timer_state; | ||
562 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; | 561 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; |
563 | 562 | ||
563 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
564 | { | ||
565 | if (irq >= nr_irqs) | ||
566 | return NULL; | ||
567 | |||
568 | return irq_timer_state[irq]; | ||
569 | } | ||
570 | |||
571 | static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) | ||
572 | { | ||
573 | if (irq >= nr_irqs) | ||
574 | return; | ||
575 | |||
576 | irq_timer_state[irq] = state; | ||
577 | } | ||
578 | |||
579 | static struct timer_rand_state input_timer_state; | ||
580 | |||
564 | /* | 581 | /* |
565 | * This function adds entropy to the entropy "pool" by using timing | 582 | * This function adds entropy to the entropy "pool" by using timing |
566 | * delays. It uses the timer_rand_state structure to make an estimate | 583 | * delays. It uses the timer_rand_state structure to make an estimate |
@@ -648,11 +665,15 @@ EXPORT_SYMBOL_GPL(add_input_randomness); | |||
648 | 665 | ||
649 | void add_interrupt_randomness(int irq) | 666 | void add_interrupt_randomness(int irq) |
650 | { | 667 | { |
651 | if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) | 668 | struct timer_rand_state *state; |
669 | |||
670 | state = get_timer_rand_state(irq); | ||
671 | |||
672 | if (state == NULL) | ||
652 | return; | 673 | return; |
653 | 674 | ||
654 | DEBUG_ENT("irq event %d\n", irq); | 675 | DEBUG_ENT("irq event %d\n", irq); |
655 | add_timer_randomness(irq_timer_state[irq], 0x100 + irq); | 676 | add_timer_randomness(state, 0x100 + irq); |
656 | } | 677 | } |
657 | 678 | ||
658 | #ifdef CONFIG_BLOCK | 679 | #ifdef CONFIG_BLOCK |
@@ -661,10 +682,10 @@ void add_disk_randomness(struct gendisk *disk) | |||
661 | if (!disk || !disk->random) | 682 | if (!disk || !disk->random) |
662 | return; | 683 | return; |
663 | /* first major is 1, so we get >= 0x200 here */ | 684 | /* first major is 1, so we get >= 0x200 here */ |
664 | DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor); | 685 | DEBUG_ENT("disk event %d:%d\n", |
686 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
665 | 687 | ||
666 | add_timer_randomness(disk->random, | 688 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
667 | 0x100 + MKDEV(disk->major, disk->first_minor)); | ||
668 | } | 689 | } |
669 | #endif | 690 | #endif |
670 | 691 | ||
@@ -912,7 +933,12 @@ void rand_initialize_irq(int irq) | |||
912 | { | 933 | { |
913 | struct timer_rand_state *state; | 934 | struct timer_rand_state *state; |
914 | 935 | ||
915 | if (irq >= NR_IRQS || irq_timer_state[irq]) | 936 | if (irq >= nr_irqs) |
937 | return; | ||
938 | |||
939 | state = get_timer_rand_state(irq); | ||
940 | |||
941 | if (state) | ||
916 | return; | 942 | return; |
917 | 943 | ||
918 | /* | 944 | /* |
@@ -921,7 +947,7 @@ void rand_initialize_irq(int irq) | |||
921 | */ | 947 | */ |
922 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | 948 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); |
923 | if (state) | 949 | if (state) |
924 | irq_timer_state[irq] = state; | 950 | set_timer_rand_state(irq, state); |
925 | } | 951 | } |
926 | 952 | ||
927 | #ifdef CONFIG_BLOCK | 953 | #ifdef CONFIG_BLOCK |
@@ -1205,7 +1231,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp, | |||
1205 | return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos); | 1231 | return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos); |
1206 | } | 1232 | } |
1207 | 1233 | ||
1208 | static int uuid_strategy(ctl_table *table, int __user *name, int nlen, | 1234 | static int uuid_strategy(ctl_table *table, |
1209 | void __user *oldval, size_t __user *oldlenp, | 1235 | void __user *oldval, size_t __user *oldlenp, |
1210 | void __user *newval, size_t newlen) | 1236 | void __user *newval, size_t newlen) |
1211 | { | 1237 | { |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 47b8cf281d4a..e139372d0e69 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp, | |||
131 | static void bind_device(struct raw_config_request *rq) | 131 | static void bind_device(struct raw_config_request *rq) |
132 | { | 132 | { |
133 | device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); | 133 | device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); |
134 | device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), | 134 | device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL, |
135 | NULL, "raw%d", rq->raw_minor); | 135 | "raw%d", rq->raw_minor); |
136 | } | 136 | } |
137 | 137 | ||
138 | /* | 138 | /* |
@@ -283,8 +283,7 @@ static int __init raw_init(void) | |||
283 | ret = PTR_ERR(raw_class); | 283 | ret = PTR_ERR(raw_class); |
284 | goto error_region; | 284 | goto error_region; |
285 | } | 285 | } |
286 | device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, | 286 | device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); |
287 | "rawctl"); | ||
288 | 287 | ||
289 | return 0; | 288 | return 0; |
290 | 289 | ||
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index f53d4d00faf0..32dc89720d58 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -88,15 +88,15 @@ | |||
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | #ifdef CONFIG_SPARC32 | 90 | #ifdef CONFIG_SPARC32 |
91 | #include <linux/pci.h> | 91 | #include <linux/of.h> |
92 | #include <linux/jiffies.h> | 92 | #include <linux/of_device.h> |
93 | #include <asm/ebus.h> | 93 | #include <asm/io.h> |
94 | 94 | ||
95 | static unsigned long rtc_port; | 95 | static unsigned long rtc_port; |
96 | static int rtc_irq = PCI_IRQ_NONE; | 96 | static int rtc_irq; |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #ifdef CONFIG_HPET_RTC_IRQ | 99 | #ifdef CONFIG_HPET_EMULATE_RTC |
100 | #undef RTC_IRQ | 100 | #undef RTC_IRQ |
101 | #endif | 101 | #endif |
102 | 102 | ||
@@ -518,17 +518,17 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
518 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || | 518 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || |
519 | RTC_ALWAYS_BCD) { | 519 | RTC_ALWAYS_BCD) { |
520 | if (sec < 60) | 520 | if (sec < 60) |
521 | BIN_TO_BCD(sec); | 521 | sec = bin2bcd(sec); |
522 | else | 522 | else |
523 | sec = 0xff; | 523 | sec = 0xff; |
524 | 524 | ||
525 | if (min < 60) | 525 | if (min < 60) |
526 | BIN_TO_BCD(min); | 526 | min = bin2bcd(min); |
527 | else | 527 | else |
528 | min = 0xff; | 528 | min = 0xff; |
529 | 529 | ||
530 | if (hrs < 24) | 530 | if (hrs < 24) |
531 | BIN_TO_BCD(hrs); | 531 | hrs = bin2bcd(hrs); |
532 | else | 532 | else |
533 | hrs = 0xff; | 533 | hrs = 0xff; |
534 | } | 534 | } |
@@ -614,12 +614,12 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
614 | 614 | ||
615 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) | 615 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) |
616 | || RTC_ALWAYS_BCD) { | 616 | || RTC_ALWAYS_BCD) { |
617 | BIN_TO_BCD(sec); | 617 | sec = bin2bcd(sec); |
618 | BIN_TO_BCD(min); | 618 | min = bin2bcd(min); |
619 | BIN_TO_BCD(hrs); | 619 | hrs = bin2bcd(hrs); |
620 | BIN_TO_BCD(day); | 620 | day = bin2bcd(day); |
621 | BIN_TO_BCD(mon); | 621 | mon = bin2bcd(mon); |
622 | BIN_TO_BCD(yrs); | 622 | yrs = bin2bcd(yrs); |
623 | } | 623 | } |
624 | 624 | ||
625 | save_control = CMOS_READ(RTC_CONTROL); | 625 | save_control = CMOS_READ(RTC_CONTROL); |
@@ -973,8 +973,8 @@ static int __init rtc_init(void) | |||
973 | char *guess = NULL; | 973 | char *guess = NULL; |
974 | #endif | 974 | #endif |
975 | #ifdef CONFIG_SPARC32 | 975 | #ifdef CONFIG_SPARC32 |
976 | struct linux_ebus *ebus; | 976 | struct device_node *ebus_dp; |
977 | struct linux_ebus_device *edev; | 977 | struct of_device *op; |
978 | #else | 978 | #else |
979 | void *r; | 979 | void *r; |
980 | #ifdef RTC_IRQ | 980 | #ifdef RTC_IRQ |
@@ -983,12 +983,16 @@ static int __init rtc_init(void) | |||
983 | #endif | 983 | #endif |
984 | 984 | ||
985 | #ifdef CONFIG_SPARC32 | 985 | #ifdef CONFIG_SPARC32 |
986 | for_each_ebus(ebus) { | 986 | for_each_node_by_name(ebus_dp, "ebus") { |
987 | for_each_ebusdev(edev, ebus) { | 987 | struct device_node *dp; |
988 | if (strcmp(edev->prom_node->name, "rtc") == 0) { | 988 | for (dp = ebus_dp; dp; dp = dp->sibling) { |
989 | rtc_port = edev->resource[0].start; | 989 | if (!strcmp(dp->name, "rtc")) { |
990 | rtc_irq = edev->irqs[0]; | 990 | op = of_find_device_by_node(dp); |
991 | goto found; | 991 | if (op) { |
992 | rtc_port = op->resource[0].start; | ||
993 | rtc_irq = op->irqs[0]; | ||
994 | goto found; | ||
995 | } | ||
992 | } | 996 | } |
993 | } | 997 | } |
994 | } | 998 | } |
@@ -997,7 +1001,7 @@ static int __init rtc_init(void) | |||
997 | return -EIO; | 1001 | return -EIO; |
998 | 1002 | ||
999 | found: | 1003 | found: |
1000 | if (rtc_irq == PCI_IRQ_NONE) { | 1004 | if (!rtc_irq) { |
1001 | rtc_has_irq = 0; | 1005 | rtc_has_irq = 0; |
1002 | goto no_irq; | 1006 | goto no_irq; |
1003 | } | 1007 | } |
@@ -1095,7 +1099,7 @@ no_irq: | |||
1095 | spin_unlock_irq(&rtc_lock); | 1099 | spin_unlock_irq(&rtc_lock); |
1096 | 1100 | ||
1097 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1101 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
1098 | BCD_TO_BIN(year); /* This should never happen... */ | 1102 | year = bcd2bin(year); /* This should never happen... */ |
1099 | 1103 | ||
1100 | if (year < 20) { | 1104 | if (year < 20) { |
1101 | epoch = 2000; | 1105 | epoch = 2000; |
@@ -1348,13 +1352,13 @@ static void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1348 | spin_unlock_irqrestore(&rtc_lock, flags); | 1352 | spin_unlock_irqrestore(&rtc_lock, flags); |
1349 | 1353 | ||
1350 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 1354 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1351 | BCD_TO_BIN(rtc_tm->tm_sec); | 1355 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
1352 | BCD_TO_BIN(rtc_tm->tm_min); | 1356 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
1353 | BCD_TO_BIN(rtc_tm->tm_hour); | 1357 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
1354 | BCD_TO_BIN(rtc_tm->tm_mday); | 1358 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
1355 | BCD_TO_BIN(rtc_tm->tm_mon); | 1359 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
1356 | BCD_TO_BIN(rtc_tm->tm_year); | 1360 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
1357 | BCD_TO_BIN(rtc_tm->tm_wday); | 1361 | rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday); |
1358 | } | 1362 | } |
1359 | 1363 | ||
1360 | #ifdef CONFIG_MACH_DECSTATION | 1364 | #ifdef CONFIG_MACH_DECSTATION |
@@ -1388,9 +1392,9 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) | |||
1388 | spin_unlock_irq(&rtc_lock); | 1392 | spin_unlock_irq(&rtc_lock); |
1389 | 1393 | ||
1390 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 1394 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1391 | BCD_TO_BIN(alm_tm->tm_sec); | 1395 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
1392 | BCD_TO_BIN(alm_tm->tm_min); | 1396 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
1393 | BCD_TO_BIN(alm_tm->tm_hour); | 1397 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
1394 | } | 1398 | } |
1395 | } | 1399 | } |
1396 | 1400 | ||
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 3ce60df14c0a..32b74de18f5f 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -444,8 +444,8 @@ scdrv_init(void) | |||
444 | continue; | 444 | continue; |
445 | } | 445 | } |
446 | 446 | ||
447 | device_create_drvdata(snsc_class, NULL, dev, NULL, | 447 | device_create(snsc_class, NULL, dev, NULL, |
448 | "%s", devname); | 448 | "%s", devname); |
449 | 449 | ||
450 | ia64_sn_irtr_intr_enable(scd->scd_nasid, | 450 | ia64_sn_irtr_intr_enable(scd->scd_nasid, |
451 | 0 /*ignored */ , | 451 | 0 /*ignored */ , |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 19db1eb87c26..963b03fb29e5 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -405,9 +405,9 @@ static unsigned int stl_baudrates[] = { | |||
405 | 405 | ||
406 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 406 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); |
407 | static int stl_brdinit(struct stlbrd *brdp); | 407 | static int stl_brdinit(struct stlbrd *brdp); |
408 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); | 408 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); |
409 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | 409 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); |
410 | static int stl_waitcarrier(struct stlport *portp, struct file *filp); | 410 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp); |
411 | 411 | ||
412 | /* | 412 | /* |
413 | * CD1400 uart specific handling functions. | 413 | * CD1400 uart specific handling functions. |
@@ -612,8 +612,9 @@ static struct class *stallion_class; | |||
612 | static void stl_cd_change(struct stlport *portp) | 612 | static void stl_cd_change(struct stlport *portp) |
613 | { | 613 | { |
614 | unsigned int oldsigs = portp->sigs; | 614 | unsigned int oldsigs = portp->sigs; |
615 | struct tty_struct *tty = tty_port_tty_get(&portp->port); | ||
615 | 616 | ||
616 | if (!portp->port.tty) | 617 | if (!tty) |
617 | return; | 618 | return; |
618 | 619 | ||
619 | portp->sigs = stl_getsignals(portp); | 620 | portp->sigs = stl_getsignals(portp); |
@@ -623,7 +624,8 @@ static void stl_cd_change(struct stlport *portp) | |||
623 | 624 | ||
624 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) | 625 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) |
625 | if (portp->port.flags & ASYNC_CHECK_CD) | 626 | if (portp->port.flags & ASYNC_CHECK_CD) |
626 | tty_hangup(portp->port.tty); | 627 | tty_hangup(tty); |
628 | tty_kref_put(tty); | ||
627 | } | 629 | } |
628 | 630 | ||
629 | /* | 631 | /* |
@@ -734,7 +736,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
734 | * On the first open of the device setup the port hardware, and | 736 | * On the first open of the device setup the port hardware, and |
735 | * initialize the per port data structure. | 737 | * initialize the per port data structure. |
736 | */ | 738 | */ |
737 | portp->port.tty = tty; | 739 | tty_port_tty_set(&portp->port, tty); |
738 | tty->driver_data = portp; | 740 | tty->driver_data = portp; |
739 | portp->port.count++; | 741 | portp->port.count++; |
740 | 742 | ||
@@ -774,7 +776,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
774 | * then also we might have to wait for carrier. | 776 | * then also we might have to wait for carrier. |
775 | */ | 777 | */ |
776 | if (!(filp->f_flags & O_NONBLOCK)) | 778 | if (!(filp->f_flags & O_NONBLOCK)) |
777 | if ((rc = stl_waitcarrier(portp, filp)) != 0) | 779 | if ((rc = stl_waitcarrier(tty, portp, filp)) != 0) |
778 | return rc; | 780 | return rc; |
779 | 781 | ||
780 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; | 782 | portp->port.flags |= ASYNC_NORMAL_ACTIVE; |
@@ -789,7 +791,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
789 | * maybe because if we are clocal then we don't need to wait... | 791 | * maybe because if we are clocal then we don't need to wait... |
790 | */ | 792 | */ |
791 | 793 | ||
792 | static int stl_waitcarrier(struct stlport *portp, struct file *filp) | 794 | static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, |
795 | struct file *filp) | ||
793 | { | 796 | { |
794 | unsigned long flags; | 797 | unsigned long flags; |
795 | int rc, doclocal; | 798 | int rc, doclocal; |
@@ -801,7 +804,7 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp) | |||
801 | 804 | ||
802 | spin_lock_irqsave(&stallion_lock, flags); | 805 | spin_lock_irqsave(&stallion_lock, flags); |
803 | 806 | ||
804 | if (portp->port.tty->termios->c_cflag & CLOCAL) | 807 | if (tty->termios->c_cflag & CLOCAL) |
805 | doclocal++; | 808 | doclocal++; |
806 | 809 | ||
807 | portp->openwaitcnt++; | 810 | portp->openwaitcnt++; |
@@ -846,8 +849,6 @@ static void stl_flushbuffer(struct tty_struct *tty) | |||
846 | 849 | ||
847 | pr_debug("stl_flushbuffer(tty=%p)\n", tty); | 850 | pr_debug("stl_flushbuffer(tty=%p)\n", tty); |
848 | 851 | ||
849 | if (tty == NULL) | ||
850 | return; | ||
851 | portp = tty->driver_data; | 852 | portp = tty->driver_data; |
852 | if (portp == NULL) | 853 | if (portp == NULL) |
853 | return; | 854 | return; |
@@ -865,8 +866,6 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
865 | 866 | ||
866 | pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); | 867 | pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); |
867 | 868 | ||
868 | if (tty == NULL) | ||
869 | return; | ||
870 | portp = tty->driver_data; | 869 | portp = tty->driver_data; |
871 | if (portp == NULL) | 870 | if (portp == NULL) |
872 | return; | 871 | return; |
@@ -949,7 +948,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
949 | tty_ldisc_flush(tty); | 948 | tty_ldisc_flush(tty); |
950 | 949 | ||
951 | tty->closing = 0; | 950 | tty->closing = 0; |
952 | portp->port.tty = NULL; | 951 | tty_port_tty_set(&portp->port, NULL); |
953 | 952 | ||
954 | if (portp->openwaitcnt) { | 953 | if (portp->openwaitcnt) { |
955 | if (portp->close_delay) | 954 | if (portp->close_delay) |
@@ -1033,8 +1032,6 @@ static int stl_putchar(struct tty_struct *tty, unsigned char ch) | |||
1033 | 1032 | ||
1034 | pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); | 1033 | pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); |
1035 | 1034 | ||
1036 | if (tty == NULL) | ||
1037 | return -EINVAL; | ||
1038 | portp = tty->driver_data; | 1035 | portp = tty->driver_data; |
1039 | if (portp == NULL) | 1036 | if (portp == NULL) |
1040 | return -EINVAL; | 1037 | return -EINVAL; |
@@ -1070,8 +1067,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1070 | 1067 | ||
1071 | pr_debug("stl_flushchars(tty=%p)\n", tty); | 1068 | pr_debug("stl_flushchars(tty=%p)\n", tty); |
1072 | 1069 | ||
1073 | if (tty == NULL) | ||
1074 | return; | ||
1075 | portp = tty->driver_data; | 1070 | portp = tty->driver_data; |
1076 | if (portp == NULL) | 1071 | if (portp == NULL) |
1077 | return; | 1072 | return; |
@@ -1090,8 +1085,6 @@ static int stl_writeroom(struct tty_struct *tty) | |||
1090 | 1085 | ||
1091 | pr_debug("stl_writeroom(tty=%p)\n", tty); | 1086 | pr_debug("stl_writeroom(tty=%p)\n", tty); |
1092 | 1087 | ||
1093 | if (tty == NULL) | ||
1094 | return 0; | ||
1095 | portp = tty->driver_data; | 1088 | portp = tty->driver_data; |
1096 | if (portp == NULL) | 1089 | if (portp == NULL) |
1097 | return 0; | 1090 | return 0; |
@@ -1122,8 +1115,6 @@ static int stl_charsinbuffer(struct tty_struct *tty) | |||
1122 | 1115 | ||
1123 | pr_debug("stl_charsinbuffer(tty=%p)\n", tty); | 1116 | pr_debug("stl_charsinbuffer(tty=%p)\n", tty); |
1124 | 1117 | ||
1125 | if (tty == NULL) | ||
1126 | return 0; | ||
1127 | portp = tty->driver_data; | 1118 | portp = tty->driver_data; |
1128 | if (portp == NULL) | 1119 | if (portp == NULL) |
1129 | return 0; | 1120 | return 0; |
@@ -1183,8 +1174,9 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1183 | * just quietly ignore any requests to change irq, etc. | 1174 | * just quietly ignore any requests to change irq, etc. |
1184 | */ | 1175 | */ |
1185 | 1176 | ||
1186 | static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) | 1177 | static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) |
1187 | { | 1178 | { |
1179 | struct stlport * portp = tty->driver_data; | ||
1188 | struct serial_struct sio; | 1180 | struct serial_struct sio; |
1189 | 1181 | ||
1190 | pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); | 1182 | pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); |
@@ -1205,7 +1197,7 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) | |||
1205 | portp->close_delay = sio.close_delay; | 1197 | portp->close_delay = sio.close_delay; |
1206 | portp->closing_wait = sio.closing_wait; | 1198 | portp->closing_wait = sio.closing_wait; |
1207 | portp->custom_divisor = sio.custom_divisor; | 1199 | portp->custom_divisor = sio.custom_divisor; |
1208 | stl_setport(portp, portp->port.tty->termios); | 1200 | stl_setport(portp, tty->termios); |
1209 | return 0; | 1201 | return 0; |
1210 | } | 1202 | } |
1211 | 1203 | ||
@@ -1215,8 +1207,6 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file) | |||
1215 | { | 1207 | { |
1216 | struct stlport *portp; | 1208 | struct stlport *portp; |
1217 | 1209 | ||
1218 | if (tty == NULL) | ||
1219 | return -ENODEV; | ||
1220 | portp = tty->driver_data; | 1210 | portp = tty->driver_data; |
1221 | if (portp == NULL) | 1211 | if (portp == NULL) |
1222 | return -ENODEV; | 1212 | return -ENODEV; |
@@ -1232,8 +1222,6 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file, | |||
1232 | struct stlport *portp; | 1222 | struct stlport *portp; |
1233 | int rts = -1, dtr = -1; | 1223 | int rts = -1, dtr = -1; |
1234 | 1224 | ||
1235 | if (tty == NULL) | ||
1236 | return -ENODEV; | ||
1237 | portp = tty->driver_data; | 1225 | portp = tty->driver_data; |
1238 | if (portp == NULL) | 1226 | if (portp == NULL) |
1239 | return -ENODEV; | 1227 | return -ENODEV; |
@@ -1262,8 +1250,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1262 | pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, | 1250 | pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, |
1263 | arg); | 1251 | arg); |
1264 | 1252 | ||
1265 | if (tty == NULL) | ||
1266 | return -ENODEV; | ||
1267 | portp = tty->driver_data; | 1253 | portp = tty->driver_data; |
1268 | if (portp == NULL) | 1254 | if (portp == NULL) |
1269 | return -ENODEV; | 1255 | return -ENODEV; |
@@ -1282,10 +1268,10 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1282 | rc = stl_getserial(portp, argp); | 1268 | rc = stl_getserial(portp, argp); |
1283 | break; | 1269 | break; |
1284 | case TIOCSSERIAL: | 1270 | case TIOCSSERIAL: |
1285 | rc = stl_setserial(portp, argp); | 1271 | rc = stl_setserial(tty, argp); |
1286 | break; | 1272 | break; |
1287 | case COM_GETPORTSTATS: | 1273 | case COM_GETPORTSTATS: |
1288 | rc = stl_getportstats(portp, argp); | 1274 | rc = stl_getportstats(tty, portp, argp); |
1289 | break; | 1275 | break; |
1290 | case COM_CLRPORTSTATS: | 1276 | case COM_CLRPORTSTATS: |
1291 | rc = stl_clrportstats(portp, argp); | 1277 | rc = stl_clrportstats(portp, argp); |
@@ -1317,8 +1303,6 @@ static void stl_start(struct tty_struct *tty) | |||
1317 | 1303 | ||
1318 | pr_debug("stl_start(tty=%p)\n", tty); | 1304 | pr_debug("stl_start(tty=%p)\n", tty); |
1319 | 1305 | ||
1320 | if (tty == NULL) | ||
1321 | return; | ||
1322 | portp = tty->driver_data; | 1306 | portp = tty->driver_data; |
1323 | if (portp == NULL) | 1307 | if (portp == NULL) |
1324 | return; | 1308 | return; |
@@ -1334,8 +1318,6 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old) | |||
1334 | 1318 | ||
1335 | pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); | 1319 | pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); |
1336 | 1320 | ||
1337 | if (tty == NULL) | ||
1338 | return; | ||
1339 | portp = tty->driver_data; | 1321 | portp = tty->driver_data; |
1340 | if (portp == NULL) | 1322 | if (portp == NULL) |
1341 | return; | 1323 | return; |
@@ -1369,8 +1351,6 @@ static void stl_throttle(struct tty_struct *tty) | |||
1369 | 1351 | ||
1370 | pr_debug("stl_throttle(tty=%p)\n", tty); | 1352 | pr_debug("stl_throttle(tty=%p)\n", tty); |
1371 | 1353 | ||
1372 | if (tty == NULL) | ||
1373 | return; | ||
1374 | portp = tty->driver_data; | 1354 | portp = tty->driver_data; |
1375 | if (portp == NULL) | 1355 | if (portp == NULL) |
1376 | return; | 1356 | return; |
@@ -1389,8 +1369,6 @@ static void stl_unthrottle(struct tty_struct *tty) | |||
1389 | 1369 | ||
1390 | pr_debug("stl_unthrottle(tty=%p)\n", tty); | 1370 | pr_debug("stl_unthrottle(tty=%p)\n", tty); |
1391 | 1371 | ||
1392 | if (tty == NULL) | ||
1393 | return; | ||
1394 | portp = tty->driver_data; | 1372 | portp = tty->driver_data; |
1395 | if (portp == NULL) | 1373 | if (portp == NULL) |
1396 | return; | 1374 | return; |
@@ -1410,8 +1388,6 @@ static void stl_stop(struct tty_struct *tty) | |||
1410 | 1388 | ||
1411 | pr_debug("stl_stop(tty=%p)\n", tty); | 1389 | pr_debug("stl_stop(tty=%p)\n", tty); |
1412 | 1390 | ||
1413 | if (tty == NULL) | ||
1414 | return; | ||
1415 | portp = tty->driver_data; | 1391 | portp = tty->driver_data; |
1416 | if (portp == NULL) | 1392 | if (portp == NULL) |
1417 | return; | 1393 | return; |
@@ -1432,8 +1408,6 @@ static void stl_hangup(struct tty_struct *tty) | |||
1432 | 1408 | ||
1433 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1409 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1434 | 1410 | ||
1435 | if (tty == NULL) | ||
1436 | return; | ||
1437 | portp = tty->driver_data; | 1411 | portp = tty->driver_data; |
1438 | if (portp == NULL) | 1412 | if (portp == NULL) |
1439 | return; | 1413 | return; |
@@ -1452,7 +1426,7 @@ static void stl_hangup(struct tty_struct *tty) | |||
1452 | portp->tx.head = NULL; | 1426 | portp->tx.head = NULL; |
1453 | portp->tx.tail = NULL; | 1427 | portp->tx.tail = NULL; |
1454 | } | 1428 | } |
1455 | portp->port.tty = NULL; | 1429 | tty_port_tty_set(&portp->port, NULL); |
1456 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1430 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1457 | portp->port.count = 0; | 1431 | portp->port.count = 0; |
1458 | wake_up_interruptible(&portp->port.open_wait); | 1432 | wake_up_interruptible(&portp->port.open_wait); |
@@ -1466,8 +1440,6 @@ static int stl_breakctl(struct tty_struct *tty, int state) | |||
1466 | 1440 | ||
1467 | pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); | 1441 | pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); |
1468 | 1442 | ||
1469 | if (tty == NULL) | ||
1470 | return -EINVAL; | ||
1471 | portp = tty->driver_data; | 1443 | portp = tty->driver_data; |
1472 | if (portp == NULL) | 1444 | if (portp == NULL) |
1473 | return -EINVAL; | 1445 | return -EINVAL; |
@@ -1484,8 +1456,6 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) | |||
1484 | 1456 | ||
1485 | pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); | 1457 | pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); |
1486 | 1458 | ||
1487 | if (tty == NULL) | ||
1488 | return; | ||
1489 | portp = tty->driver_data; | 1459 | portp = tty->driver_data; |
1490 | if (portp == NULL) | 1460 | if (portp == NULL) |
1491 | return; | 1461 | return; |
@@ -1805,7 +1775,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) | |||
1805 | "(size=%Zd)\n", sizeof(struct stlport)); | 1775 | "(size=%Zd)\n", sizeof(struct stlport)); |
1806 | break; | 1776 | break; |
1807 | } | 1777 | } |
1808 | 1778 | tty_port_init(&portp->port); | |
1809 | portp->magic = STL_PORTMAGIC; | 1779 | portp->magic = STL_PORTMAGIC; |
1810 | portp->portnr = i; | 1780 | portp->portnr = i; |
1811 | portp->brdnr = panelp->brdnr; | 1781 | portp->brdnr = panelp->brdnr; |
@@ -1832,6 +1802,7 @@ static void stl_cleanup_panels(struct stlbrd *brdp) | |||
1832 | struct stlpanel *panelp; | 1802 | struct stlpanel *panelp; |
1833 | struct stlport *portp; | 1803 | struct stlport *portp; |
1834 | unsigned int j, k; | 1804 | unsigned int j, k; |
1805 | struct tty_struct *tty; | ||
1835 | 1806 | ||
1836 | for (j = 0; j < STL_MAXPANELS; j++) { | 1807 | for (j = 0; j < STL_MAXPANELS; j++) { |
1837 | panelp = brdp->panels[j]; | 1808 | panelp = brdp->panels[j]; |
@@ -1841,8 +1812,11 @@ static void stl_cleanup_panels(struct stlbrd *brdp) | |||
1841 | portp = panelp->ports[k]; | 1812 | portp = panelp->ports[k]; |
1842 | if (portp == NULL) | 1813 | if (portp == NULL) |
1843 | continue; | 1814 | continue; |
1844 | if (portp->port.tty != NULL) | 1815 | tty = tty_port_tty_get(&portp->port); |
1845 | stl_hangup(portp->port.tty); | 1816 | if (tty != NULL) { |
1817 | stl_hangup(tty); | ||
1818 | tty_kref_put(tty); | ||
1819 | } | ||
1846 | kfree(portp->tx.buf); | 1820 | kfree(portp->tx.buf); |
1847 | kfree(portp); | 1821 | kfree(portp); |
1848 | } | 1822 | } |
@@ -2498,7 +2472,7 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) | |||
2498 | * what port to get stats for (used through board control device). | 2472 | * what port to get stats for (used through board control device). |
2499 | */ | 2473 | */ |
2500 | 2474 | ||
2501 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) | 2475 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) |
2502 | { | 2476 | { |
2503 | comstats_t stl_comstats; | 2477 | comstats_t stl_comstats; |
2504 | unsigned char *head, *tail; | 2478 | unsigned char *head, *tail; |
@@ -2525,18 +2499,17 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) | |||
2525 | portp->stats.rxbuffered = 0; | 2499 | portp->stats.rxbuffered = 0; |
2526 | 2500 | ||
2527 | spin_lock_irqsave(&stallion_lock, flags); | 2501 | spin_lock_irqsave(&stallion_lock, flags); |
2528 | if (portp->port.tty != NULL) | 2502 | if (tty != NULL && portp->port.tty == tty) { |
2529 | if (portp->port.tty->driver_data == portp) { | 2503 | portp->stats.ttystate = tty->flags; |
2530 | portp->stats.ttystate = portp->port.tty->flags; | 2504 | /* No longer available as a statistic */ |
2531 | /* No longer available as a statistic */ | 2505 | portp->stats.rxbuffered = 1; /*tty->flip.count; */ |
2532 | portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */ | 2506 | if (tty->termios != NULL) { |
2533 | if (portp->port.tty->termios != NULL) { | 2507 | portp->stats.cflags = tty->termios->c_cflag; |
2534 | portp->stats.cflags = portp->port.tty->termios->c_cflag; | 2508 | portp->stats.iflags = tty->termios->c_iflag; |
2535 | portp->stats.iflags = portp->port.tty->termios->c_iflag; | 2509 | portp->stats.oflags = tty->termios->c_oflag; |
2536 | portp->stats.oflags = portp->port.tty->termios->c_oflag; | 2510 | portp->stats.lflags = tty->termios->c_lflag; |
2537 | portp->stats.lflags = portp->port.tty->termios->c_lflag; | ||
2538 | } | ||
2539 | } | 2511 | } |
2512 | } | ||
2540 | spin_unlock_irqrestore(&stallion_lock, flags); | 2513 | spin_unlock_irqrestore(&stallion_lock, flags); |
2541 | 2514 | ||
2542 | head = portp->tx.head; | 2515 | head = portp->tx.head; |
@@ -2640,7 +2613,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2640 | 2613 | ||
2641 | switch (cmd) { | 2614 | switch (cmd) { |
2642 | case COM_GETPORTSTATS: | 2615 | case COM_GETPORTSTATS: |
2643 | rc = stl_getportstats(NULL, argp); | 2616 | rc = stl_getportstats(NULL, NULL, argp); |
2644 | break; | 2617 | break; |
2645 | case COM_CLRPORTSTATS: | 2618 | case COM_CLRPORTSTATS: |
2646 | rc = stl_clrportstats(NULL, argp); | 2619 | rc = stl_clrportstats(NULL, argp); |
@@ -3243,7 +3216,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) | |||
3243 | 3216 | ||
3244 | if (portp == NULL) | 3217 | if (portp == NULL) |
3245 | return; | 3218 | return; |
3246 | tty = portp->port.tty; | 3219 | tty = tty_port_tty_get(&portp->port); |
3247 | if (tty == NULL) | 3220 | if (tty == NULL) |
3248 | return; | 3221 | return; |
3249 | 3222 | ||
@@ -3288,6 +3261,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) | |||
3288 | 3261 | ||
3289 | BRDDISABLE(portp->brdnr); | 3262 | BRDDISABLE(portp->brdnr); |
3290 | spin_unlock_irqrestore(&brd_lock, flags); | 3263 | spin_unlock_irqrestore(&brd_lock, flags); |
3264 | tty_kref_put(tty); | ||
3291 | } | 3265 | } |
3292 | 3266 | ||
3293 | /*****************************************************************************/ | 3267 | /*****************************************************************************/ |
@@ -3305,7 +3279,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) | |||
3305 | 3279 | ||
3306 | if (portp == NULL) | 3280 | if (portp == NULL) |
3307 | return; | 3281 | return; |
3308 | tty = portp->port.tty; | 3282 | tty = tty_port_tty_get(&portp->port); |
3309 | if (tty == NULL) | 3283 | if (tty == NULL) |
3310 | return; | 3284 | return; |
3311 | 3285 | ||
@@ -3325,6 +3299,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) | |||
3325 | } | 3299 | } |
3326 | BRDDISABLE(portp->brdnr); | 3300 | BRDDISABLE(portp->brdnr); |
3327 | spin_unlock_irqrestore(&brd_lock, flags); | 3301 | spin_unlock_irqrestore(&brd_lock, flags); |
3302 | tty_kref_put(tty); | ||
3328 | } | 3303 | } |
3329 | 3304 | ||
3330 | /*****************************************************************************/ | 3305 | /*****************************************************************************/ |
@@ -3478,6 +3453,7 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) | |||
3478 | int len, stlen; | 3453 | int len, stlen; |
3479 | char *head, *tail; | 3454 | char *head, *tail; |
3480 | unsigned char ioack, srer; | 3455 | unsigned char ioack, srer; |
3456 | struct tty_struct *tty; | ||
3481 | 3457 | ||
3482 | pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); | 3458 | pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); |
3483 | 3459 | ||
@@ -3504,8 +3480,11 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) | |||
3504 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 3480 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
3505 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 3481 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
3506 | set_bit(ASYI_TXLOW, &portp->istate); | 3482 | set_bit(ASYI_TXLOW, &portp->istate); |
3507 | if (portp->port.tty) | 3483 | tty = tty_port_tty_get(&portp->port); |
3508 | tty_wakeup(portp->port.tty); | 3484 | if (tty) { |
3485 | tty_wakeup(tty); | ||
3486 | tty_kref_put(tty); | ||
3487 | } | ||
3509 | } | 3488 | } |
3510 | 3489 | ||
3511 | if (len == 0) { | 3490 | if (len == 0) { |
@@ -3569,7 +3548,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) | |||
3569 | return; | 3548 | return; |
3570 | } | 3549 | } |
3571 | portp = panelp->ports[(ioack >> 3)]; | 3550 | portp = panelp->ports[(ioack >> 3)]; |
3572 | tty = portp->port.tty; | 3551 | tty = tty_port_tty_get(&portp->port); |
3573 | 3552 | ||
3574 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { | 3553 | if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { |
3575 | outb((RDCR + portp->uartaddr), ioaddr); | 3554 | outb((RDCR + portp->uartaddr), ioaddr); |
@@ -3633,10 +3612,12 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) | |||
3633 | } | 3612 | } |
3634 | } else { | 3613 | } else { |
3635 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); | 3614 | printk("STALLION: bad RX interrupt ack value=%x\n", ioack); |
3615 | tty_kref_put(tty); | ||
3636 | return; | 3616 | return; |
3637 | } | 3617 | } |
3638 | 3618 | ||
3639 | stl_rxalldone: | 3619 | stl_rxalldone: |
3620 | tty_kref_put(tty); | ||
3640 | outb((EOSRR + portp->uartaddr), ioaddr); | 3621 | outb((EOSRR + portp->uartaddr), ioaddr); |
3641 | outb(0, (ioaddr + EREG_DATA)); | 3622 | outb(0, (ioaddr + EREG_DATA)); |
3642 | } | 3623 | } |
@@ -4175,7 +4156,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) | |||
4175 | 4156 | ||
4176 | if (portp == NULL) | 4157 | if (portp == NULL) |
4177 | return; | 4158 | return; |
4178 | tty = portp->port.tty; | 4159 | tty = tty_port_tty_get(&portp->port); |
4179 | if (tty == NULL) | 4160 | if (tty == NULL) |
4180 | return; | 4161 | return; |
4181 | 4162 | ||
@@ -4226,6 +4207,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) | |||
4226 | 4207 | ||
4227 | BRDDISABLE(portp->brdnr); | 4208 | BRDDISABLE(portp->brdnr); |
4228 | spin_unlock_irqrestore(&brd_lock, flags); | 4209 | spin_unlock_irqrestore(&brd_lock, flags); |
4210 | tty_kref_put(tty); | ||
4229 | } | 4211 | } |
4230 | 4212 | ||
4231 | /*****************************************************************************/ | 4213 | /*****************************************************************************/ |
@@ -4244,7 +4226,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) | |||
4244 | 4226 | ||
4245 | if (portp == NULL) | 4227 | if (portp == NULL) |
4246 | return; | 4228 | return; |
4247 | tty = portp->port.tty; | 4229 | tty = tty_port_tty_get(&portp->port); |
4248 | if (tty == NULL) | 4230 | if (tty == NULL) |
4249 | return; | 4231 | return; |
4250 | 4232 | ||
@@ -4269,6 +4251,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) | |||
4269 | } | 4251 | } |
4270 | BRDDISABLE(portp->brdnr); | 4252 | BRDDISABLE(portp->brdnr); |
4271 | spin_unlock_irqrestore(&brd_lock, flags); | 4253 | spin_unlock_irqrestore(&brd_lock, flags); |
4254 | tty_kref_put(tty); | ||
4272 | } | 4255 | } |
4273 | 4256 | ||
4274 | /*****************************************************************************/ | 4257 | /*****************************************************************************/ |
@@ -4408,6 +4391,7 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) | |||
4408 | 4391 | ||
4409 | static void stl_sc26198txisr(struct stlport *portp) | 4392 | static void stl_sc26198txisr(struct stlport *portp) |
4410 | { | 4393 | { |
4394 | struct tty_struct *tty; | ||
4411 | unsigned int ioaddr; | 4395 | unsigned int ioaddr; |
4412 | unsigned char mr0; | 4396 | unsigned char mr0; |
4413 | int len, stlen; | 4397 | int len, stlen; |
@@ -4422,8 +4406,11 @@ static void stl_sc26198txisr(struct stlport *portp) | |||
4422 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 4406 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
4423 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 4407 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
4424 | set_bit(ASYI_TXLOW, &portp->istate); | 4408 | set_bit(ASYI_TXLOW, &portp->istate); |
4425 | if (portp->port.tty) | 4409 | tty = tty_port_tty_get(&portp->port); |
4426 | tty_wakeup(portp->port.tty); | 4410 | if (tty) { |
4411 | tty_wakeup(tty); | ||
4412 | tty_kref_put(tty); | ||
4413 | } | ||
4427 | } | 4414 | } |
4428 | 4415 | ||
4429 | if (len == 0) { | 4416 | if (len == 0) { |
@@ -4476,7 +4463,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) | |||
4476 | 4463 | ||
4477 | pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); | 4464 | pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); |
4478 | 4465 | ||
4479 | tty = portp->port.tty; | 4466 | tty = tty_port_tty_get(&portp->port); |
4480 | ioaddr = portp->ioaddr; | 4467 | ioaddr = portp->ioaddr; |
4481 | outb(GIBCR, (ioaddr + XP_ADDR)); | 4468 | outb(GIBCR, (ioaddr + XP_ADDR)); |
4482 | len = inb(ioaddr + XP_DATA) + 1; | 4469 | len = inb(ioaddr + XP_DATA) + 1; |
@@ -4515,6 +4502,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) | |||
4515 | stl_sc26198txunflow(portp, tty); | 4502 | stl_sc26198txunflow(portp, tty); |
4516 | } | 4503 | } |
4517 | } | 4504 | } |
4505 | tty_kref_put(tty); | ||
4518 | } | 4506 | } |
4519 | 4507 | ||
4520 | /*****************************************************************************/ | 4508 | /*****************************************************************************/ |
@@ -4528,7 +4516,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char | |||
4528 | struct tty_struct *tty; | 4516 | struct tty_struct *tty; |
4529 | unsigned int ioaddr; | 4517 | unsigned int ioaddr; |
4530 | 4518 | ||
4531 | tty = portp->port.tty; | 4519 | tty = tty_port_tty_get(&portp->port); |
4532 | ioaddr = portp->ioaddr; | 4520 | ioaddr = portp->ioaddr; |
4533 | 4521 | ||
4534 | if (status & SR_RXPARITY) | 4522 | if (status & SR_RXPARITY) |
@@ -4566,6 +4554,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char | |||
4566 | if (status == 0) | 4554 | if (status == 0) |
4567 | portp->stats.rxtotal++; | 4555 | portp->stats.rxtotal++; |
4568 | } | 4556 | } |
4557 | tty_kref_put(tty); | ||
4569 | } | 4558 | } |
4570 | 4559 | ||
4571 | /*****************************************************************************/ | 4560 | /*****************************************************************************/ |
@@ -4754,8 +4743,8 @@ static int __init stallion_module_init(void) | |||
4754 | if (IS_ERR(stallion_class)) | 4743 | if (IS_ERR(stallion_class)) |
4755 | printk("STALLION: failed to create class\n"); | 4744 | printk("STALLION: failed to create class\n"); |
4756 | for (i = 0; i < 4; i++) | 4745 | for (i = 0; i < 4; i++) |
4757 | device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), | 4746 | device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), |
4758 | NULL, "staliomem%d", i); | 4747 | NULL, "staliomem%d", i); |
4759 | 4748 | ||
4760 | return 0; | 4749 | return 0; |
4761 | err_unrtty: | 4750 | err_unrtty: |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index c385206f9db5..ba4e86281fbf 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board, | |||
2504 | del_timer(&board->timer); | 2504 | del_timer(&board->timer); |
2505 | if (pdev) { | 2505 | if (pdev) { |
2506 | #ifdef CONFIG_PCI | 2506 | #ifdef CONFIG_PCI |
2507 | pci_iounmap(pdev, board->base); | 2507 | iounmap(board->base2); |
2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); | 2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); |
2509 | #endif | 2509 | #endif |
2510 | } else { | 2510 | } else { |
@@ -2677,7 +2677,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, | |||
2677 | } | 2677 | } |
2678 | board->hw_base = pci_resource_start(pdev, reg); | 2678 | board->hw_base = pci_resource_start(pdev, reg); |
2679 | board->base2 = | 2679 | board->base2 = |
2680 | board->base = pci_iomap(pdev, reg, WINDOW_LEN(board)); | 2680 | board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); |
2681 | if (!board->base) { | 2681 | if (!board->base) { |
2682 | dev_err(&pdev->dev, "ioremap failed\n"); | 2682 | dev_err(&pdev->dev, "ioremap failed\n"); |
2683 | goto err_reg; | 2683 | goto err_reg; |
@@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, | |||
2703 | 2703 | ||
2704 | return 0; | 2704 | return 0; |
2705 | err_unmap: | 2705 | err_unmap: |
2706 | pci_iounmap(pdev, board->base); | 2706 | iounmap(board->base2); |
2707 | err_reg: | 2707 | err_reg: |
2708 | pci_release_region(pdev, reg); | 2708 | pci_release_region(pdev, reg); |
2709 | err_flag: | 2709 | err_flag: |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 8fdfe9c871e3..ce0d9da52a8a 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/reboot.h> | 23 | #include <linux/reboot.h> |
24 | #include <linux/sysrq.h> | 24 | #include <linux/sysrq.h> |
25 | #include <linux/kbd_kern.h> | 25 | #include <linux/kbd_kern.h> |
26 | #include <linux/proc_fs.h> | ||
26 | #include <linux/quotaops.h> | 27 | #include <linux/quotaops.h> |
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -167,7 +168,7 @@ static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | |||
167 | static struct sysrq_key_op sysrq_show_timers_op = { | 168 | static struct sysrq_key_op sysrq_show_timers_op = { |
168 | .handler = sysrq_handle_show_timers, | 169 | .handler = sysrq_handle_show_timers, |
169 | .help_msg = "show-all-timers(Q)", | 170 | .help_msg = "show-all-timers(Q)", |
170 | .action_msg = "Show Pending Timers", | 171 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
171 | }; | 172 | }; |
172 | 173 | ||
173 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 174 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) |
@@ -326,6 +327,7 @@ static struct sysrq_key_op sysrq_moom_op = { | |||
326 | .handler = sysrq_handle_moom, | 327 | .handler = sysrq_handle_moom, |
327 | .help_msg = "Full", | 328 | .help_msg = "Full", |
328 | .action_msg = "Manual OOM execution", | 329 | .action_msg = "Manual OOM execution", |
330 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | ||
329 | }; | 331 | }; |
330 | 332 | ||
331 | static void sysrq_handle_kill(int key, struct tty_struct *tty) | 333 | static void sysrq_handle_kill(int key, struct tty_struct *tty) |
@@ -533,3 +535,32 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) | |||
533 | return __sysrq_swap_key_ops(key, NULL, op_p); | 535 | return __sysrq_swap_key_ops(key, NULL, op_p); |
534 | } | 536 | } |
535 | EXPORT_SYMBOL(unregister_sysrq_key); | 537 | EXPORT_SYMBOL(unregister_sysrq_key); |
538 | |||
539 | #ifdef CONFIG_PROC_FS | ||
540 | /* | ||
541 | * writing 'C' to /proc/sysrq-trigger is like sysrq-C | ||
542 | */ | ||
543 | static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, | ||
544 | size_t count, loff_t *ppos) | ||
545 | { | ||
546 | if (count) { | ||
547 | char c; | ||
548 | |||
549 | if (get_user(c, buf)) | ||
550 | return -EFAULT; | ||
551 | __handle_sysrq(c, NULL, 0); | ||
552 | } | ||
553 | return count; | ||
554 | } | ||
555 | |||
556 | static const struct file_operations proc_sysrq_trigger_operations = { | ||
557 | .write = write_sysrq_trigger, | ||
558 | }; | ||
559 | |||
560 | static int __init sysrq_init(void) | ||
561 | { | ||
562 | proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations); | ||
563 | return 0; | ||
564 | } | ||
565 | module_init(sysrq_init); | ||
566 | #endif | ||
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 3738cfa209ff..f5fc64f89c5c 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -6,6 +6,7 @@ menuconfig TCG_TPM | |||
6 | tristate "TPM Hardware Support" | 6 | tristate "TPM Hardware Support" |
7 | depends on HAS_IOMEM | 7 | depends on HAS_IOMEM |
8 | depends on EXPERIMENTAL | 8 | depends on EXPERIMENTAL |
9 | select SECURITYFS | ||
9 | ---help--- | 10 | ---help--- |
10 | If you have a TPM security chip in your system, which | 11 | If you have a TPM security chip in your system, which |
11 | implements the Trusted Computing Group's specification, | 12 | implements the Trusted Computing Group's specification, |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ae766d868454..9c47dc48c9fd 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip) | |||
525 | timeout = | 525 | timeout = |
526 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))); | 526 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))); |
527 | if (timeout) | 527 | if (timeout) |
528 | chip->vendor.timeout_a = msecs_to_jiffies(timeout); | 528 | chip->vendor.timeout_a = usecs_to_jiffies(timeout); |
529 | timeout = | 529 | timeout = |
530 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX))); | 530 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX))); |
531 | if (timeout) | 531 | if (timeout) |
532 | chip->vendor.timeout_b = msecs_to_jiffies(timeout); | 532 | chip->vendor.timeout_b = usecs_to_jiffies(timeout); |
533 | timeout = | 533 | timeout = |
534 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX))); | 534 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX))); |
535 | if (timeout) | 535 | if (timeout) |
536 | chip->vendor.timeout_c = msecs_to_jiffies(timeout); | 536 | chip->vendor.timeout_c = usecs_to_jiffies(timeout); |
537 | timeout = | 537 | timeout = |
538 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX))); | 538 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX))); |
539 | if (timeout) | 539 | if (timeout) |
540 | chip->vendor.timeout_d = msecs_to_jiffies(timeout); | 540 | chip->vendor.timeout_d = usecs_to_jiffies(timeout); |
541 | 541 | ||
542 | duration: | 542 | duration: |
543 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | 543 | memcpy(data, tpm_cap, sizeof(tpm_cap)); |
@@ -554,15 +554,22 @@ duration: | |||
554 | return; | 554 | return; |
555 | 555 | ||
556 | chip->vendor.duration[TPM_SHORT] = | 556 | chip->vendor.duration[TPM_SHORT] = |
557 | msecs_to_jiffies(be32_to_cpu | 557 | usecs_to_jiffies(be32_to_cpu |
558 | (*((__be32 *) (data + | 558 | (*((__be32 *) (data + |
559 | TPM_GET_CAP_RET_UINT32_1_IDX)))); | 559 | TPM_GET_CAP_RET_UINT32_1_IDX)))); |
560 | /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above | ||
561 | * value wrong and apparently reports msecs rather than usecs. So we | ||
562 | * fix up the resulting too-small TPM_SHORT value to make things work. | ||
563 | */ | ||
564 | if (chip->vendor.duration[TPM_SHORT] < (HZ/100)) | ||
565 | chip->vendor.duration[TPM_SHORT] = HZ; | ||
566 | |||
560 | chip->vendor.duration[TPM_MEDIUM] = | 567 | chip->vendor.duration[TPM_MEDIUM] = |
561 | msecs_to_jiffies(be32_to_cpu | 568 | usecs_to_jiffies(be32_to_cpu |
562 | (*((__be32 *) (data + | 569 | (*((__be32 *) (data + |
563 | TPM_GET_CAP_RET_UINT32_2_IDX)))); | 570 | TPM_GET_CAP_RET_UINT32_2_IDX)))); |
564 | chip->vendor.duration[TPM_LONG] = | 571 | chip->vendor.duration[TPM_LONG] = |
565 | msecs_to_jiffies(be32_to_cpu | 572 | usecs_to_jiffies(be32_to_cpu |
566 | (*((__be32 *) (data + | 573 | (*((__be32 *) (data + |
567 | TPM_GET_CAP_RET_UINT32_3_IDX)))); | 574 | TPM_GET_CAP_RET_UINT32_3_IDX)))); |
568 | } | 575 | } |
@@ -954,72 +961,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel); | |||
954 | 961 | ||
955 | /* | 962 | /* |
956 | * Device file system interface to the TPM | 963 | * Device file system interface to the TPM |
964 | * | ||
965 | * It's assured that the chip will be opened just once, | ||
966 | * by the check of is_open variable, which is protected | ||
967 | * by driver_lock. | ||
957 | */ | 968 | */ |
958 | int tpm_open(struct inode *inode, struct file *file) | 969 | int tpm_open(struct inode *inode, struct file *file) |
959 | { | 970 | { |
960 | int rc = 0, minor = iminor(inode); | 971 | int minor = iminor(inode); |
961 | struct tpm_chip *chip = NULL, *pos; | 972 | struct tpm_chip *chip = NULL, *pos; |
962 | 973 | ||
963 | lock_kernel(); | 974 | rcu_read_lock(); |
964 | spin_lock(&driver_lock); | 975 | list_for_each_entry_rcu(pos, &tpm_chip_list, list) { |
965 | |||
966 | list_for_each_entry(pos, &tpm_chip_list, list) { | ||
967 | if (pos->vendor.miscdev.minor == minor) { | 976 | if (pos->vendor.miscdev.minor == minor) { |
968 | chip = pos; | 977 | chip = pos; |
978 | get_device(chip->dev); | ||
969 | break; | 979 | break; |
970 | } | 980 | } |
971 | } | 981 | } |
982 | rcu_read_unlock(); | ||
972 | 983 | ||
973 | if (chip == NULL) { | 984 | if (!chip) |
974 | rc = -ENODEV; | 985 | return -ENODEV; |
975 | goto err_out; | ||
976 | } | ||
977 | 986 | ||
978 | if (chip->num_opens) { | 987 | if (test_and_set_bit(0, &chip->is_open)) { |
979 | dev_dbg(chip->dev, "Another process owns this TPM\n"); | 988 | dev_dbg(chip->dev, "Another process owns this TPM\n"); |
980 | rc = -EBUSY; | 989 | put_device(chip->dev); |
981 | goto err_out; | 990 | return -EBUSY; |
982 | } | 991 | } |
983 | 992 | ||
984 | chip->num_opens++; | ||
985 | get_device(chip->dev); | ||
986 | |||
987 | spin_unlock(&driver_lock); | ||
988 | |||
989 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); | 993 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); |
990 | if (chip->data_buffer == NULL) { | 994 | if (chip->data_buffer == NULL) { |
991 | chip->num_opens--; | 995 | clear_bit(0, &chip->is_open); |
992 | put_device(chip->dev); | 996 | put_device(chip->dev); |
993 | unlock_kernel(); | ||
994 | return -ENOMEM; | 997 | return -ENOMEM; |
995 | } | 998 | } |
996 | 999 | ||
997 | atomic_set(&chip->data_pending, 0); | 1000 | atomic_set(&chip->data_pending, 0); |
998 | 1001 | ||
999 | file->private_data = chip; | 1002 | file->private_data = chip; |
1000 | unlock_kernel(); | ||
1001 | return 0; | 1003 | return 0; |
1002 | |||
1003 | err_out: | ||
1004 | spin_unlock(&driver_lock); | ||
1005 | unlock_kernel(); | ||
1006 | return rc; | ||
1007 | } | 1004 | } |
1008 | EXPORT_SYMBOL_GPL(tpm_open); | 1005 | EXPORT_SYMBOL_GPL(tpm_open); |
1009 | 1006 | ||
1007 | /* | ||
1008 | * Called on file close | ||
1009 | */ | ||
1010 | int tpm_release(struct inode *inode, struct file *file) | 1010 | int tpm_release(struct inode *inode, struct file *file) |
1011 | { | 1011 | { |
1012 | struct tpm_chip *chip = file->private_data; | 1012 | struct tpm_chip *chip = file->private_data; |
1013 | 1013 | ||
1014 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1014 | flush_scheduled_work(); | 1015 | flush_scheduled_work(); |
1015 | spin_lock(&driver_lock); | ||
1016 | file->private_data = NULL; | 1016 | file->private_data = NULL; |
1017 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1018 | atomic_set(&chip->data_pending, 0); | 1017 | atomic_set(&chip->data_pending, 0); |
1019 | chip->num_opens--; | ||
1020 | put_device(chip->dev); | ||
1021 | kfree(chip->data_buffer); | 1018 | kfree(chip->data_buffer); |
1022 | spin_unlock(&driver_lock); | 1019 | clear_bit(0, &chip->is_open); |
1020 | put_device(chip->dev); | ||
1023 | return 0; | 1021 | return 0; |
1024 | } | 1022 | } |
1025 | EXPORT_SYMBOL_GPL(tpm_release); | 1023 | EXPORT_SYMBOL_GPL(tpm_release); |
@@ -1093,13 +1091,11 @@ void tpm_remove_hardware(struct device *dev) | |||
1093 | } | 1091 | } |
1094 | 1092 | ||
1095 | spin_lock(&driver_lock); | 1093 | spin_lock(&driver_lock); |
1096 | 1094 | list_del_rcu(&chip->list); | |
1097 | list_del(&chip->list); | ||
1098 | |||
1099 | spin_unlock(&driver_lock); | 1095 | spin_unlock(&driver_lock); |
1096 | synchronize_rcu(); | ||
1100 | 1097 | ||
1101 | misc_deregister(&chip->vendor.miscdev); | 1098 | misc_deregister(&chip->vendor.miscdev); |
1102 | |||
1103 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); | 1099 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); |
1104 | tpm_bios_log_teardown(chip->bios_dir); | 1100 | tpm_bios_log_teardown(chip->bios_dir); |
1105 | 1101 | ||
@@ -1144,25 +1140,33 @@ int tpm_pm_resume(struct device *dev) | |||
1144 | } | 1140 | } |
1145 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 1141 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
1146 | 1142 | ||
1143 | /* In case vendor provided release function, call it too.*/ | ||
1144 | |||
1145 | void tpm_dev_vendor_release(struct tpm_chip *chip) | ||
1146 | { | ||
1147 | if (chip->vendor.release) | ||
1148 | chip->vendor.release(chip->dev); | ||
1149 | |||
1150 | clear_bit(chip->dev_num, dev_mask); | ||
1151 | kfree(chip->vendor.miscdev.name); | ||
1152 | } | ||
1153 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | ||
1154 | |||
1155 | |||
1147 | /* | 1156 | /* |
1148 | * Once all references to platform device are down to 0, | 1157 | * Once all references to platform device are down to 0, |
1149 | * release all allocated structures. | 1158 | * release all allocated structures. |
1150 | * In case vendor provided release function, | ||
1151 | * call it too. | ||
1152 | */ | 1159 | */ |
1153 | static void tpm_dev_release(struct device *dev) | 1160 | void tpm_dev_release(struct device *dev) |
1154 | { | 1161 | { |
1155 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1162 | struct tpm_chip *chip = dev_get_drvdata(dev); |
1156 | 1163 | ||
1157 | if (chip->vendor.release) | 1164 | tpm_dev_vendor_release(chip); |
1158 | chip->vendor.release(dev); | ||
1159 | 1165 | ||
1160 | chip->release(dev); | 1166 | chip->release(dev); |
1161 | |||
1162 | clear_bit(chip->dev_num, dev_mask); | ||
1163 | kfree(chip->vendor.miscdev.name); | ||
1164 | kfree(chip); | 1167 | kfree(chip); |
1165 | } | 1168 | } |
1169 | EXPORT_SYMBOL_GPL(tpm_dev_release); | ||
1166 | 1170 | ||
1167 | /* | 1171 | /* |
1168 | * Called from tpm_<specific>.c probe function only for devices | 1172 | * Called from tpm_<specific>.c probe function only for devices |
@@ -1171,8 +1175,8 @@ static void tpm_dev_release(struct device *dev) | |||
1171 | * upon errant exit from this function specific probe function should call | 1175 | * upon errant exit from this function specific probe function should call |
1172 | * pci_disable_device | 1176 | * pci_disable_device |
1173 | */ | 1177 | */ |
1174 | struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific | 1178 | struct tpm_chip *tpm_register_hardware(struct device *dev, |
1175 | *entry) | 1179 | const struct tpm_vendor_specific *entry) |
1176 | { | 1180 | { |
1177 | #define DEVNAME_SIZE 7 | 1181 | #define DEVNAME_SIZE 7 |
1178 | 1182 | ||
@@ -1183,11 +1187,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1183 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1187 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1184 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); | 1188 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); |
1185 | 1189 | ||
1186 | if (chip == NULL || devname == NULL) { | 1190 | if (chip == NULL || devname == NULL) |
1187 | kfree(chip); | 1191 | goto out_free; |
1188 | kfree(devname); | ||
1189 | return NULL; | ||
1190 | } | ||
1191 | 1192 | ||
1192 | mutex_init(&chip->buffer_mutex); | 1193 | mutex_init(&chip->buffer_mutex); |
1193 | mutex_init(&chip->tpm_mutex); | 1194 | mutex_init(&chip->tpm_mutex); |
@@ -1204,8 +1205,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1204 | 1205 | ||
1205 | if (chip->dev_num >= TPM_NUM_DEVICES) { | 1206 | if (chip->dev_num >= TPM_NUM_DEVICES) { |
1206 | dev_err(dev, "No available tpm device numbers\n"); | 1207 | dev_err(dev, "No available tpm device numbers\n"); |
1207 | kfree(chip); | 1208 | goto out_free; |
1208 | return NULL; | ||
1209 | } else if (chip->dev_num == 0) | 1209 | } else if (chip->dev_num == 0) |
1210 | chip->vendor.miscdev.minor = TPM_MINOR; | 1210 | chip->vendor.miscdev.minor = TPM_MINOR; |
1211 | else | 1211 | else |
@@ -1231,22 +1231,26 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1231 | return NULL; | 1231 | return NULL; |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | spin_lock(&driver_lock); | ||
1235 | |||
1236 | list_add(&chip->list, &tpm_chip_list); | ||
1237 | |||
1238 | spin_unlock(&driver_lock); | ||
1239 | |||
1240 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { | 1234 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { |
1241 | list_del(&chip->list); | ||
1242 | misc_deregister(&chip->vendor.miscdev); | 1235 | misc_deregister(&chip->vendor.miscdev); |
1243 | put_device(chip->dev); | 1236 | put_device(chip->dev); |
1237 | |||
1244 | return NULL; | 1238 | return NULL; |
1245 | } | 1239 | } |
1246 | 1240 | ||
1247 | chip->bios_dir = tpm_bios_log_setup(devname); | 1241 | chip->bios_dir = tpm_bios_log_setup(devname); |
1248 | 1242 | ||
1243 | /* Make chip available */ | ||
1244 | spin_lock(&driver_lock); | ||
1245 | list_add_rcu(&chip->list, &tpm_chip_list); | ||
1246 | spin_unlock(&driver_lock); | ||
1247 | |||
1249 | return chip; | 1248 | return chip; |
1249 | |||
1250 | out_free: | ||
1251 | kfree(chip); | ||
1252 | kfree(devname); | ||
1253 | return NULL; | ||
1250 | } | 1254 | } |
1251 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 1255 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
1252 | 1256 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index e885148b4cfb..8e30df4a4388 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -90,7 +90,7 @@ struct tpm_chip { | |||
90 | struct device *dev; /* Device stuff */ | 90 | struct device *dev; /* Device stuff */ |
91 | 91 | ||
92 | int dev_num; /* /dev/tpm# */ | 92 | int dev_num; /* /dev/tpm# */ |
93 | int num_opens; /* only one allowed */ | 93 | unsigned long is_open; /* only one allowed */ |
94 | int time_expired; | 94 | int time_expired; |
95 | 95 | ||
96 | /* Data passed to and from the tpm via the read/write calls */ | 96 | /* Data passed to and from the tpm via the read/write calls */ |
@@ -132,6 +132,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *, | |||
132 | const struct tpm_vendor_specific *); | 132 | const struct tpm_vendor_specific *); |
133 | extern int tpm_open(struct inode *, struct file *); | 133 | extern int tpm_open(struct inode *, struct file *); |
134 | extern int tpm_release(struct inode *, struct file *); | 134 | extern int tpm_release(struct inode *, struct file *); |
135 | extern void tpm_dev_vendor_release(struct tpm_chip *); | ||
135 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 136 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, |
136 | loff_t *); | 137 | loff_t *); |
137 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | 138 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index ed1879c0dd8d..717af7ad1bdf 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { | |||
630 | {"", 0} /* Terminator */ | 630 | {"", 0} /* Terminator */ |
631 | }; | 631 | }; |
632 | 632 | ||
633 | static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) | ||
634 | { | ||
635 | struct tpm_chip *chip = pnp_get_drvdata(dev); | ||
636 | |||
637 | tpm_dev_vendor_release(chip); | ||
638 | |||
639 | kfree(chip); | ||
640 | } | ||
641 | |||
642 | |||
633 | static struct pnp_driver tis_pnp_driver = { | 643 | static struct pnp_driver tis_pnp_driver = { |
634 | .name = "tpm_tis", | 644 | .name = "tpm_tis", |
635 | .id_table = tpm_pnp_tbl, | 645 | .id_table = tpm_pnp_tbl, |
636 | .probe = tpm_tis_pnp_init, | 646 | .probe = tpm_tis_pnp_init, |
637 | .suspend = tpm_tis_pnp_suspend, | 647 | .suspend = tpm_tis_pnp_suspend, |
638 | .resume = tpm_tis_pnp_resume, | 648 | .resume = tpm_tis_pnp_resume, |
649 | .remove = tpm_tis_pnp_remove, | ||
639 | }; | 650 | }; |
640 | 651 | ||
641 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 | 652 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 |
@@ -683,6 +694,7 @@ static void __exit cleanup_tis(void) | |||
683 | spin_lock(&tis_lock); | 694 | spin_lock(&tis_lock); |
684 | list_for_each_entry_safe(i, j, &tis_chips, list) { | 695 | list_for_each_entry_safe(i, j, &tis_chips, list) { |
685 | chip = to_tpm_chip(i); | 696 | chip = to_tpm_chip(i); |
697 | tpm_remove_hardware(chip->dev); | ||
686 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | 698 | iowrite32(~TPM_GLOBAL_INT_ENABLE & |
687 | ioread32(chip->vendor.iobase + | 699 | ioread32(chip->vendor.iobase + |
688 | TPM_INT_ENABLE(chip->vendor. | 700 | TPM_INT_ENABLE(chip->vendor. |
@@ -694,9 +706,9 @@ static void __exit cleanup_tis(void) | |||
694 | free_irq(chip->vendor.irq, chip); | 706 | free_irq(chip->vendor.irq, chip); |
695 | iounmap(i->iobase); | 707 | iounmap(i->iobase); |
696 | list_del(&i->list); | 708 | list_del(&i->list); |
697 | tpm_remove_hardware(chip->dev); | ||
698 | } | 709 | } |
699 | spin_unlock(&tis_lock); | 710 | spin_unlock(&tis_lock); |
711 | |||
700 | if (force) { | 712 | if (force) { |
701 | platform_device_unregister(pdev); | 713 | platform_device_unregister(pdev); |
702 | driver_unregister(&tis_drv); | 714 | driver_unregister(&tis_drv); |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 3582f43345a8..5787249934c8 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
@@ -93,7 +93,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
93 | get_task_comm(name, tsk); | 93 | get_task_comm(name, tsk); |
94 | audit_log_untrustedstring(ab, name); | 94 | audit_log_untrustedstring(ab, name); |
95 | audit_log_format(ab, " data="); | 95 | audit_log_format(ab, " data="); |
96 | audit_log_n_untrustedstring(ab, buf->data, buf->valid); | 96 | audit_log_n_hex(ab, buf->data, buf->valid); |
97 | audit_log_end(ab); | 97 | audit_log_end(ab); |
98 | } | 98 | } |
99 | buf->valid = 0; | 99 | buf->valid = 0; |
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c new file mode 100644 index 000000000000..810ee25d66a4 --- /dev/null +++ b/drivers/char/tty_buffer.c | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | * Tty buffer allocation management | ||
3 | */ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/tty.h> | ||
8 | #include <linux/tty_driver.h> | ||
9 | #include <linux/tty_flip.h> | ||
10 | #include <linux/timer.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | /** | ||
21 | * tty_buffer_free_all - free buffers used by a tty | ||
22 | * @tty: tty to free from | ||
23 | * | ||
24 | * Remove all the buffers pending on a tty whether queued with data | ||
25 | * or in the free ring. Must be called when the tty is no longer in use | ||
26 | * | ||
27 | * Locking: none | ||
28 | */ | ||
29 | |||
30 | void tty_buffer_free_all(struct tty_struct *tty) | ||
31 | { | ||
32 | struct tty_buffer *thead; | ||
33 | while ((thead = tty->buf.head) != NULL) { | ||
34 | tty->buf.head = thead->next; | ||
35 | kfree(thead); | ||
36 | } | ||
37 | while ((thead = tty->buf.free) != NULL) { | ||
38 | tty->buf.free = thead->next; | ||
39 | kfree(thead); | ||
40 | } | ||
41 | tty->buf.tail = NULL; | ||
42 | tty->buf.memory_used = 0; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * tty_buffer_alloc - allocate a tty buffer | ||
47 | * @tty: tty device | ||
48 | * @size: desired size (characters) | ||
49 | * | ||
50 | * Allocate a new tty buffer to hold the desired number of characters. | ||
51 | * Return NULL if out of memory or the allocation would exceed the | ||
52 | * per device queue | ||
53 | * | ||
54 | * Locking: Caller must hold tty->buf.lock | ||
55 | */ | ||
56 | |||
57 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | ||
58 | { | ||
59 | struct tty_buffer *p; | ||
60 | |||
61 | if (tty->buf.memory_used + size > 65536) | ||
62 | return NULL; | ||
63 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
64 | if (p == NULL) | ||
65 | return NULL; | ||
66 | p->used = 0; | ||
67 | p->size = size; | ||
68 | p->next = NULL; | ||
69 | p->commit = 0; | ||
70 | p->read = 0; | ||
71 | p->char_buf_ptr = (char *)(p->data); | ||
72 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
73 | tty->buf.memory_used += size; | ||
74 | return p; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * tty_buffer_free - free a tty buffer | ||
79 | * @tty: tty owning the buffer | ||
80 | * @b: the buffer to free | ||
81 | * | ||
82 | * Free a tty buffer, or add it to the free list according to our | ||
83 | * internal strategy | ||
84 | * | ||
85 | * Locking: Caller must hold tty->buf.lock | ||
86 | */ | ||
87 | |||
88 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
89 | { | ||
90 | /* Dumb strategy for now - should keep some stats */ | ||
91 | tty->buf.memory_used -= b->size; | ||
92 | WARN_ON(tty->buf.memory_used < 0); | ||
93 | |||
94 | if (b->size >= 512) | ||
95 | kfree(b); | ||
96 | else { | ||
97 | b->next = tty->buf.free; | ||
98 | tty->buf.free = b; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * __tty_buffer_flush - flush full tty buffers | ||
104 | * @tty: tty to flush | ||
105 | * | ||
106 | * flush all the buffers containing receive data. Caller must | ||
107 | * hold the buffer lock and must have ensured no parallel flush to | ||
108 | * ldisc is running. | ||
109 | * | ||
110 | * Locking: Caller must hold tty->buf.lock | ||
111 | */ | ||
112 | |||
113 | static void __tty_buffer_flush(struct tty_struct *tty) | ||
114 | { | ||
115 | struct tty_buffer *thead; | ||
116 | |||
117 | while ((thead = tty->buf.head) != NULL) { | ||
118 | tty->buf.head = thead->next; | ||
119 | tty_buffer_free(tty, thead); | ||
120 | } | ||
121 | tty->buf.tail = NULL; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * tty_buffer_flush - flush full tty buffers | ||
126 | * @tty: tty to flush | ||
127 | * | ||
128 | * flush all the buffers containing receive data. If the buffer is | ||
129 | * being processed by flush_to_ldisc then we defer the processing | ||
130 | * to that function | ||
131 | * | ||
132 | * Locking: none | ||
133 | */ | ||
134 | |||
135 | void tty_buffer_flush(struct tty_struct *tty) | ||
136 | { | ||
137 | unsigned long flags; | ||
138 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
139 | |||
140 | /* If the data is being pushed to the tty layer then we can't | ||
141 | process it here. Instead set a flag and the flush_to_ldisc | ||
142 | path will process the flush request before it exits */ | ||
143 | if (test_bit(TTY_FLUSHING, &tty->flags)) { | ||
144 | set_bit(TTY_FLUSHPENDING, &tty->flags); | ||
145 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
146 | wait_event(tty->read_wait, | ||
147 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); | ||
148 | return; | ||
149 | } else | ||
150 | __tty_buffer_flush(tty); | ||
151 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * tty_buffer_find - find a free tty buffer | ||
156 | * @tty: tty owning the buffer | ||
157 | * @size: characters wanted | ||
158 | * | ||
159 | * Locate an existing suitable tty buffer or if we are lacking one then | ||
160 | * allocate a new one. We round our buffers off in 256 character chunks | ||
161 | * to get better allocation behaviour. | ||
162 | * | ||
163 | * Locking: Caller must hold tty->buf.lock | ||
164 | */ | ||
165 | |||
166 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
167 | { | ||
168 | struct tty_buffer **tbh = &tty->buf.free; | ||
169 | while ((*tbh) != NULL) { | ||
170 | struct tty_buffer *t = *tbh; | ||
171 | if (t->size >= size) { | ||
172 | *tbh = t->next; | ||
173 | t->next = NULL; | ||
174 | t->used = 0; | ||
175 | t->commit = 0; | ||
176 | t->read = 0; | ||
177 | tty->buf.memory_used += t->size; | ||
178 | return t; | ||
179 | } | ||
180 | tbh = &((*tbh)->next); | ||
181 | } | ||
182 | /* Round the buffer size out */ | ||
183 | size = (size + 0xFF) & ~0xFF; | ||
184 | return tty_buffer_alloc(tty, size); | ||
185 | /* Should possibly check if this fails for the largest buffer we | ||
186 | have queued and recycle that ? */ | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * tty_buffer_request_room - grow tty buffer if needed | ||
191 | * @tty: tty structure | ||
192 | * @size: size desired | ||
193 | * | ||
194 | * Make at least size bytes of linear space available for the tty | ||
195 | * buffer. If we fail return the size we managed to find. | ||
196 | * | ||
197 | * Locking: Takes tty->buf.lock | ||
198 | */ | ||
199 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
200 | { | ||
201 | struct tty_buffer *b, *n; | ||
202 | int left; | ||
203 | unsigned long flags; | ||
204 | |||
205 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
206 | |||
207 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
208 | remove this conditional if its worth it. This would be invisible | ||
209 | to the callers */ | ||
210 | if ((b = tty->buf.tail) != NULL) | ||
211 | left = b->size - b->used; | ||
212 | else | ||
213 | left = 0; | ||
214 | |||
215 | if (left < size) { | ||
216 | /* This is the slow path - looking for new buffers to use */ | ||
217 | if ((n = tty_buffer_find(tty, size)) != NULL) { | ||
218 | if (b != NULL) { | ||
219 | b->next = n; | ||
220 | b->commit = b->used; | ||
221 | } else | ||
222 | tty->buf.head = n; | ||
223 | tty->buf.tail = n; | ||
224 | } else | ||
225 | size = left; | ||
226 | } | ||
227 | |||
228 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
229 | return size; | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
232 | |||
233 | /** | ||
234 | * tty_insert_flip_string - Add characters to the tty buffer | ||
235 | * @tty: tty structure | ||
236 | * @chars: characters | ||
237 | * @size: size | ||
238 | * | ||
239 | * Queue a series of bytes to the tty buffering. All the characters | ||
240 | * passed are marked as without error. Returns the number added. | ||
241 | * | ||
242 | * Locking: Called functions may take tty->buf.lock | ||
243 | */ | ||
244 | |||
245 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | ||
246 | size_t size) | ||
247 | { | ||
248 | int copied = 0; | ||
249 | do { | ||
250 | int space = tty_buffer_request_room(tty, size - copied); | ||
251 | struct tty_buffer *tb = tty->buf.tail; | ||
252 | /* If there is no space then tb may be NULL */ | ||
253 | if (unlikely(space == 0)) | ||
254 | break; | ||
255 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
256 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
257 | tb->used += space; | ||
258 | copied += space; | ||
259 | chars += space; | ||
260 | /* There is a small chance that we need to split the data over | ||
261 | several buffers. If this is the case we must loop */ | ||
262 | } while (unlikely(size > copied)); | ||
263 | return copied; | ||
264 | } | ||
265 | EXPORT_SYMBOL(tty_insert_flip_string); | ||
266 | |||
267 | /** | ||
268 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
269 | * @tty: tty structure | ||
270 | * @chars: characters | ||
271 | * @flags: flag bytes | ||
272 | * @size: size | ||
273 | * | ||
274 | * Queue a series of bytes to the tty buffering. For each character | ||
275 | * the flags array indicates the status of the character. Returns the | ||
276 | * number added. | ||
277 | * | ||
278 | * Locking: Called functions may take tty->buf.lock | ||
279 | */ | ||
280 | |||
281 | int tty_insert_flip_string_flags(struct tty_struct *tty, | ||
282 | const unsigned char *chars, const char *flags, size_t size) | ||
283 | { | ||
284 | int copied = 0; | ||
285 | do { | ||
286 | int space = tty_buffer_request_room(tty, size - copied); | ||
287 | struct tty_buffer *tb = tty->buf.tail; | ||
288 | /* If there is no space then tb may be NULL */ | ||
289 | if (unlikely(space == 0)) | ||
290 | break; | ||
291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
292 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
293 | tb->used += space; | ||
294 | copied += space; | ||
295 | chars += space; | ||
296 | flags += space; | ||
297 | /* There is a small chance that we need to split the data over | ||
298 | several buffers. If this is the case we must loop */ | ||
299 | } while (unlikely(size > copied)); | ||
300 | return copied; | ||
301 | } | ||
302 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | ||
303 | |||
304 | /** | ||
305 | * tty_schedule_flip - push characters to ldisc | ||
306 | * @tty: tty to push from | ||
307 | * | ||
308 | * Takes any pending buffers and transfers their ownership to the | ||
309 | * ldisc side of the queue. It then schedules those characters for | ||
310 | * processing by the line discipline. | ||
311 | * | ||
312 | * Locking: Takes tty->buf.lock | ||
313 | */ | ||
314 | |||
315 | void tty_schedule_flip(struct tty_struct *tty) | ||
316 | { | ||
317 | unsigned long flags; | ||
318 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
319 | if (tty->buf.tail != NULL) | ||
320 | tty->buf.tail->commit = tty->buf.tail->used; | ||
321 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
322 | schedule_delayed_work(&tty->buf.work, 1); | ||
323 | } | ||
324 | EXPORT_SYMBOL(tty_schedule_flip); | ||
325 | |||
326 | /** | ||
327 | * tty_prepare_flip_string - make room for characters | ||
328 | * @tty: tty | ||
329 | * @chars: return pointer for character write area | ||
330 | * @size: desired size | ||
331 | * | ||
332 | * Prepare a block of space in the buffer for data. Returns the length | ||
333 | * available and buffer pointer to the space which is now allocated and | ||
334 | * accounted for as ready for normal characters. This is used for drivers | ||
335 | * that need their own block copy routines into the buffer. There is no | ||
336 | * guarantee the buffer is a DMA target! | ||
337 | * | ||
338 | * Locking: May call functions taking tty->buf.lock | ||
339 | */ | ||
340 | |||
341 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | ||
342 | size_t size) | ||
343 | { | ||
344 | int space = tty_buffer_request_room(tty, size); | ||
345 | if (likely(space)) { | ||
346 | struct tty_buffer *tb = tty->buf.tail; | ||
347 | *chars = tb->char_buf_ptr + tb->used; | ||
348 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
349 | tb->used += space; | ||
350 | } | ||
351 | return space; | ||
352 | } | ||
353 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
354 | |||
355 | /** | ||
356 | * tty_prepare_flip_string_flags - make room for characters | ||
357 | * @tty: tty | ||
358 | * @chars: return pointer for character write area | ||
359 | * @flags: return pointer for status flag write area | ||
360 | * @size: desired size | ||
361 | * | ||
362 | * Prepare a block of space in the buffer for data. Returns the length | ||
363 | * available and buffer pointer to the space which is now allocated and | ||
364 | * accounted for as ready for characters. This is used for drivers | ||
365 | * that need their own block copy routines into the buffer. There is no | ||
366 | * guarantee the buffer is a DMA target! | ||
367 | * | ||
368 | * Locking: May call functions taking tty->buf.lock | ||
369 | */ | ||
370 | |||
371 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | ||
372 | unsigned char **chars, char **flags, size_t size) | ||
373 | { | ||
374 | int space = tty_buffer_request_room(tty, size); | ||
375 | if (likely(space)) { | ||
376 | struct tty_buffer *tb = tty->buf.tail; | ||
377 | *chars = tb->char_buf_ptr + tb->used; | ||
378 | *flags = tb->flag_buf_ptr + tb->used; | ||
379 | tb->used += space; | ||
380 | } | ||
381 | return space; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
384 | |||
385 | |||
386 | |||
387 | /** | ||
388 | * flush_to_ldisc | ||
389 | * @work: tty structure passed from work queue. | ||
390 | * | ||
391 | * This routine is called out of the software interrupt to flush data | ||
392 | * from the buffer chain to the line discipline. | ||
393 | * | ||
394 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
395 | * while invoking the line discipline receive_buf method. The | ||
396 | * receive_buf method is single threaded for each tty instance. | ||
397 | */ | ||
398 | |||
399 | static void flush_to_ldisc(struct work_struct *work) | ||
400 | { | ||
401 | struct tty_struct *tty = | ||
402 | container_of(work, struct tty_struct, buf.work.work); | ||
403 | unsigned long flags; | ||
404 | struct tty_ldisc *disc; | ||
405 | struct tty_buffer *tbuf, *head; | ||
406 | char *char_buf; | ||
407 | unsigned char *flag_buf; | ||
408 | |||
409 | disc = tty_ldisc_ref(tty); | ||
410 | if (disc == NULL) /* !TTY_LDISC */ | ||
411 | return; | ||
412 | |||
413 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
414 | /* So we know a flush is running */ | ||
415 | set_bit(TTY_FLUSHING, &tty->flags); | ||
416 | head = tty->buf.head; | ||
417 | if (head != NULL) { | ||
418 | tty->buf.head = NULL; | ||
419 | for (;;) { | ||
420 | int count = head->commit - head->read; | ||
421 | if (!count) { | ||
422 | if (head->next == NULL) | ||
423 | break; | ||
424 | tbuf = head; | ||
425 | head = head->next; | ||
426 | tty_buffer_free(tty, tbuf); | ||
427 | continue; | ||
428 | } | ||
429 | /* Ldisc or user is trying to flush the buffers | ||
430 | we are feeding to the ldisc, stop feeding the | ||
431 | line discipline as we want to empty the queue */ | ||
432 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | ||
433 | break; | ||
434 | if (!tty->receive_room) { | ||
435 | schedule_delayed_work(&tty->buf.work, 1); | ||
436 | break; | ||
437 | } | ||
438 | if (count > tty->receive_room) | ||
439 | count = tty->receive_room; | ||
440 | char_buf = head->char_buf_ptr + head->read; | ||
441 | flag_buf = head->flag_buf_ptr + head->read; | ||
442 | head->read += count; | ||
443 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
444 | disc->ops->receive_buf(tty, char_buf, | ||
445 | flag_buf, count); | ||
446 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
447 | } | ||
448 | /* Restore the queue head */ | ||
449 | tty->buf.head = head; | ||
450 | } | ||
451 | /* We may have a deferred request to flush the input buffer, | ||
452 | if so pull the chain under the lock and empty the queue */ | ||
453 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | ||
454 | __tty_buffer_flush(tty); | ||
455 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | ||
456 | wake_up(&tty->read_wait); | ||
457 | } | ||
458 | clear_bit(TTY_FLUSHING, &tty->flags); | ||
459 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
460 | |||
461 | tty_ldisc_deref(disc); | ||
462 | } | ||
463 | |||
464 | /** | ||
465 | * tty_flip_buffer_push - terminal | ||
466 | * @tty: tty to push | ||
467 | * | ||
468 | * Queue a push of the terminal flip buffers to the line discipline. This | ||
469 | * function must not be called from IRQ context if tty->low_latency is set. | ||
470 | * | ||
471 | * In the event of the queue being busy for flipping the work will be | ||
472 | * held off and retried later. | ||
473 | * | ||
474 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
475 | */ | ||
476 | |||
477 | void tty_flip_buffer_push(struct tty_struct *tty) | ||
478 | { | ||
479 | unsigned long flags; | ||
480 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
481 | if (tty->buf.tail != NULL) | ||
482 | tty->buf.tail->commit = tty->buf.tail->used; | ||
483 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
484 | |||
485 | if (tty->low_latency) | ||
486 | flush_to_ldisc(&tty->buf.work.work); | ||
487 | else | ||
488 | schedule_delayed_work(&tty->buf.work, 1); | ||
489 | } | ||
490 | EXPORT_SYMBOL(tty_flip_buffer_push); | ||
491 | |||
492 | /** | ||
493 | * tty_buffer_init - prepare a tty buffer structure | ||
494 | * @tty: tty to initialise | ||
495 | * | ||
496 | * Set up the initial state of the buffer management for a tty device. | ||
497 | * Must be called before the other tty buffer functions are used. | ||
498 | * | ||
499 | * Locking: none | ||
500 | */ | ||
501 | |||
502 | void tty_buffer_init(struct tty_struct *tty) | ||
503 | { | ||
504 | spin_lock_init(&tty->buf.lock); | ||
505 | tty->buf.head = NULL; | ||
506 | tty->buf.tail = NULL; | ||
507 | tty->buf.free = NULL; | ||
508 | tty->buf.memory_used = 0; | ||
509 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | ||
510 | } | ||
511 | |||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e4dce8709541..59f472143f08 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -49,7 +49,7 @@ | |||
49 | * implement CONFIG_VT and generalize console device interface. | 49 | * implement CONFIG_VT and generalize console device interface. |
50 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 | 50 | * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 |
51 | * | 51 | * |
52 | * Rewrote init_dev and release_dev to eliminate races. | 52 | * Rewrote tty_init_dev and tty_release_dev to eliminate races. |
53 | * -- Bill Hawes <whawes@star.net>, June 97 | 53 | * -- Bill Hawes <whawes@star.net>, June 97 |
54 | * | 54 | * |
55 | * Added devfs support. | 55 | * Added devfs support. |
@@ -136,13 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | #ifdef CONFIG_UNIX98_PTYS | ||
140 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ | ||
141 | static int ptmx_open(struct inode *, struct file *); | ||
142 | #endif | ||
143 | |||
144 | static void initialize_tty_struct(struct tty_struct *tty); | ||
145 | |||
146 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
147 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
148 | ssize_t redirected_tty_write(struct file *, const char __user *, | 141 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -171,13 +164,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | |||
171 | * Locking: none | 164 | * Locking: none |
172 | */ | 165 | */ |
173 | 166 | ||
174 | static struct tty_struct *alloc_tty_struct(void) | 167 | struct tty_struct *alloc_tty_struct(void) |
175 | { | 168 | { |
176 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); | 169 | return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); |
177 | } | 170 | } |
178 | 171 | ||
179 | static void tty_buffer_free_all(struct tty_struct *); | ||
180 | |||
181 | /** | 172 | /** |
182 | * free_tty_struct - free a disused tty | 173 | * free_tty_struct - free a disused tty |
183 | * @tty: tty struct to free | 174 | * @tty: tty struct to free |
@@ -187,7 +178,7 @@ static void tty_buffer_free_all(struct tty_struct *); | |||
187 | * Locking: none. Must be called after tty is definitely unused | 178 | * Locking: none. Must be called after tty is definitely unused |
188 | */ | 179 | */ |
189 | 180 | ||
190 | static inline void free_tty_struct(struct tty_struct *tty) | 181 | void free_tty_struct(struct tty_struct *tty) |
191 | { | 182 | { |
192 | kfree(tty->write_buf); | 183 | kfree(tty->write_buf); |
193 | tty_buffer_free_all(tty); | 184 | tty_buffer_free_all(tty); |
@@ -263,398 +254,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
263 | return 0; | 254 | return 0; |
264 | } | 255 | } |
265 | 256 | ||
266 | /* | ||
267 | * Tty buffer allocation management | ||
268 | */ | ||
269 | |||
270 | /** | ||
271 | * tty_buffer_free_all - free buffers used by a tty | ||
272 | * @tty: tty to free from | ||
273 | * | ||
274 | * Remove all the buffers pending on a tty whether queued with data | ||
275 | * or in the free ring. Must be called when the tty is no longer in use | ||
276 | * | ||
277 | * Locking: none | ||
278 | */ | ||
279 | |||
280 | static void tty_buffer_free_all(struct tty_struct *tty) | ||
281 | { | ||
282 | struct tty_buffer *thead; | ||
283 | while ((thead = tty->buf.head) != NULL) { | ||
284 | tty->buf.head = thead->next; | ||
285 | kfree(thead); | ||
286 | } | ||
287 | while ((thead = tty->buf.free) != NULL) { | ||
288 | tty->buf.free = thead->next; | ||
289 | kfree(thead); | ||
290 | } | ||
291 | tty->buf.tail = NULL; | ||
292 | tty->buf.memory_used = 0; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * tty_buffer_init - prepare a tty buffer structure | ||
297 | * @tty: tty to initialise | ||
298 | * | ||
299 | * Set up the initial state of the buffer management for a tty device. | ||
300 | * Must be called before the other tty buffer functions are used. | ||
301 | * | ||
302 | * Locking: none | ||
303 | */ | ||
304 | |||
305 | static void tty_buffer_init(struct tty_struct *tty) | ||
306 | { | ||
307 | spin_lock_init(&tty->buf.lock); | ||
308 | tty->buf.head = NULL; | ||
309 | tty->buf.tail = NULL; | ||
310 | tty->buf.free = NULL; | ||
311 | tty->buf.memory_used = 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * tty_buffer_alloc - allocate a tty buffer | ||
316 | * @tty: tty device | ||
317 | * @size: desired size (characters) | ||
318 | * | ||
319 | * Allocate a new tty buffer to hold the desired number of characters. | ||
320 | * Return NULL if out of memory or the allocation would exceed the | ||
321 | * per device queue | ||
322 | * | ||
323 | * Locking: Caller must hold tty->buf.lock | ||
324 | */ | ||
325 | |||
326 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | ||
327 | { | ||
328 | struct tty_buffer *p; | ||
329 | |||
330 | if (tty->buf.memory_used + size > 65536) | ||
331 | return NULL; | ||
332 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
333 | if (p == NULL) | ||
334 | return NULL; | ||
335 | p->used = 0; | ||
336 | p->size = size; | ||
337 | p->next = NULL; | ||
338 | p->commit = 0; | ||
339 | p->read = 0; | ||
340 | p->char_buf_ptr = (char *)(p->data); | ||
341 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | ||
342 | tty->buf.memory_used += size; | ||
343 | return p; | ||
344 | } | ||
345 | |||
346 | /** | ||
347 | * tty_buffer_free - free a tty buffer | ||
348 | * @tty: tty owning the buffer | ||
349 | * @b: the buffer to free | ||
350 | * | ||
351 | * Free a tty buffer, or add it to the free list according to our | ||
352 | * internal strategy | ||
353 | * | ||
354 | * Locking: Caller must hold tty->buf.lock | ||
355 | */ | ||
356 | |||
357 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | ||
358 | { | ||
359 | /* Dumb strategy for now - should keep some stats */ | ||
360 | tty->buf.memory_used -= b->size; | ||
361 | WARN_ON(tty->buf.memory_used < 0); | ||
362 | |||
363 | if (b->size >= 512) | ||
364 | kfree(b); | ||
365 | else { | ||
366 | b->next = tty->buf.free; | ||
367 | tty->buf.free = b; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * __tty_buffer_flush - flush full tty buffers | ||
373 | * @tty: tty to flush | ||
374 | * | ||
375 | * flush all the buffers containing receive data. Caller must | ||
376 | * hold the buffer lock and must have ensured no parallel flush to | ||
377 | * ldisc is running. | ||
378 | * | ||
379 | * Locking: Caller must hold tty->buf.lock | ||
380 | */ | ||
381 | |||
382 | static void __tty_buffer_flush(struct tty_struct *tty) | ||
383 | { | ||
384 | struct tty_buffer *thead; | ||
385 | |||
386 | while ((thead = tty->buf.head) != NULL) { | ||
387 | tty->buf.head = thead->next; | ||
388 | tty_buffer_free(tty, thead); | ||
389 | } | ||
390 | tty->buf.tail = NULL; | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * tty_buffer_flush - flush full tty buffers | ||
395 | * @tty: tty to flush | ||
396 | * | ||
397 | * flush all the buffers containing receive data. If the buffer is | ||
398 | * being processed by flush_to_ldisc then we defer the processing | ||
399 | * to that function | ||
400 | * | ||
401 | * Locking: none | ||
402 | */ | ||
403 | |||
404 | static void tty_buffer_flush(struct tty_struct *tty) | ||
405 | { | ||
406 | unsigned long flags; | ||
407 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
408 | |||
409 | /* If the data is being pushed to the tty layer then we can't | ||
410 | process it here. Instead set a flag and the flush_to_ldisc | ||
411 | path will process the flush request before it exits */ | ||
412 | if (test_bit(TTY_FLUSHING, &tty->flags)) { | ||
413 | set_bit(TTY_FLUSHPENDING, &tty->flags); | ||
414 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
415 | wait_event(tty->read_wait, | ||
416 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); | ||
417 | return; | ||
418 | } else | ||
419 | __tty_buffer_flush(tty); | ||
420 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * tty_buffer_find - find a free tty buffer | ||
425 | * @tty: tty owning the buffer | ||
426 | * @size: characters wanted | ||
427 | * | ||
428 | * Locate an existing suitable tty buffer or if we are lacking one then | ||
429 | * allocate a new one. We round our buffers off in 256 character chunks | ||
430 | * to get better allocation behaviour. | ||
431 | * | ||
432 | * Locking: Caller must hold tty->buf.lock | ||
433 | */ | ||
434 | |||
435 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | ||
436 | { | ||
437 | struct tty_buffer **tbh = &tty->buf.free; | ||
438 | while ((*tbh) != NULL) { | ||
439 | struct tty_buffer *t = *tbh; | ||
440 | if (t->size >= size) { | ||
441 | *tbh = t->next; | ||
442 | t->next = NULL; | ||
443 | t->used = 0; | ||
444 | t->commit = 0; | ||
445 | t->read = 0; | ||
446 | tty->buf.memory_used += t->size; | ||
447 | return t; | ||
448 | } | ||
449 | tbh = &((*tbh)->next); | ||
450 | } | ||
451 | /* Round the buffer size out */ | ||
452 | size = (size + 0xFF) & ~0xFF; | ||
453 | return tty_buffer_alloc(tty, size); | ||
454 | /* Should possibly check if this fails for the largest buffer we | ||
455 | have queued and recycle that ? */ | ||
456 | } | ||
457 | |||
458 | /** | ||
459 | * tty_buffer_request_room - grow tty buffer if needed | ||
460 | * @tty: tty structure | ||
461 | * @size: size desired | ||
462 | * | ||
463 | * Make at least size bytes of linear space available for the tty | ||
464 | * buffer. If we fail return the size we managed to find. | ||
465 | * | ||
466 | * Locking: Takes tty->buf.lock | ||
467 | */ | ||
468 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
469 | { | ||
470 | struct tty_buffer *b, *n; | ||
471 | int left; | ||
472 | unsigned long flags; | ||
473 | |||
474 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
475 | |||
476 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | ||
477 | remove this conditional if its worth it. This would be invisible | ||
478 | to the callers */ | ||
479 | if ((b = tty->buf.tail) != NULL) | ||
480 | left = b->size - b->used; | ||
481 | else | ||
482 | left = 0; | ||
483 | |||
484 | if (left < size) { | ||
485 | /* This is the slow path - looking for new buffers to use */ | ||
486 | if ((n = tty_buffer_find(tty, size)) != NULL) { | ||
487 | if (b != NULL) { | ||
488 | b->next = n; | ||
489 | b->commit = b->used; | ||
490 | } else | ||
491 | tty->buf.head = n; | ||
492 | tty->buf.tail = n; | ||
493 | } else | ||
494 | size = left; | ||
495 | } | ||
496 | |||
497 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
498 | return size; | ||
499 | } | ||
500 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | ||
501 | |||
502 | /** | ||
503 | * tty_insert_flip_string - Add characters to the tty buffer | ||
504 | * @tty: tty structure | ||
505 | * @chars: characters | ||
506 | * @size: size | ||
507 | * | ||
508 | * Queue a series of bytes to the tty buffering. All the characters | ||
509 | * passed are marked as without error. Returns the number added. | ||
510 | * | ||
511 | * Locking: Called functions may take tty->buf.lock | ||
512 | */ | ||
513 | |||
514 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | ||
515 | size_t size) | ||
516 | { | ||
517 | int copied = 0; | ||
518 | do { | ||
519 | int space = tty_buffer_request_room(tty, size - copied); | ||
520 | struct tty_buffer *tb = tty->buf.tail; | ||
521 | /* If there is no space then tb may be NULL */ | ||
522 | if (unlikely(space == 0)) | ||
523 | break; | ||
524 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
525 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
526 | tb->used += space; | ||
527 | copied += space; | ||
528 | chars += space; | ||
529 | /* There is a small chance that we need to split the data over | ||
530 | several buffers. If this is the case we must loop */ | ||
531 | } while (unlikely(size > copied)); | ||
532 | return copied; | ||
533 | } | ||
534 | EXPORT_SYMBOL(tty_insert_flip_string); | ||
535 | |||
536 | /** | ||
537 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
538 | * @tty: tty structure | ||
539 | * @chars: characters | ||
540 | * @flags: flag bytes | ||
541 | * @size: size | ||
542 | * | ||
543 | * Queue a series of bytes to the tty buffering. For each character | ||
544 | * the flags array indicates the status of the character. Returns the | ||
545 | * number added. | ||
546 | * | ||
547 | * Locking: Called functions may take tty->buf.lock | ||
548 | */ | ||
549 | |||
550 | int tty_insert_flip_string_flags(struct tty_struct *tty, | ||
551 | const unsigned char *chars, const char *flags, size_t size) | ||
552 | { | ||
553 | int copied = 0; | ||
554 | do { | ||
555 | int space = tty_buffer_request_room(tty, size - copied); | ||
556 | struct tty_buffer *tb = tty->buf.tail; | ||
557 | /* If there is no space then tb may be NULL */ | ||
558 | if (unlikely(space == 0)) | ||
559 | break; | ||
560 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | ||
561 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | ||
562 | tb->used += space; | ||
563 | copied += space; | ||
564 | chars += space; | ||
565 | flags += space; | ||
566 | /* There is a small chance that we need to split the data over | ||
567 | several buffers. If this is the case we must loop */ | ||
568 | } while (unlikely(size > copied)); | ||
569 | return copied; | ||
570 | } | ||
571 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | ||
572 | |||
573 | /** | ||
574 | * tty_schedule_flip - push characters to ldisc | ||
575 | * @tty: tty to push from | ||
576 | * | ||
577 | * Takes any pending buffers and transfers their ownership to the | ||
578 | * ldisc side of the queue. It then schedules those characters for | ||
579 | * processing by the line discipline. | ||
580 | * | ||
581 | * Locking: Takes tty->buf.lock | ||
582 | */ | ||
583 | |||
584 | void tty_schedule_flip(struct tty_struct *tty) | ||
585 | { | ||
586 | unsigned long flags; | ||
587 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
588 | if (tty->buf.tail != NULL) | ||
589 | tty->buf.tail->commit = tty->buf.tail->used; | ||
590 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
591 | schedule_delayed_work(&tty->buf.work, 1); | ||
592 | } | ||
593 | EXPORT_SYMBOL(tty_schedule_flip); | ||
594 | |||
595 | /** | ||
596 | * tty_prepare_flip_string - make room for characters | ||
597 | * @tty: tty | ||
598 | * @chars: return pointer for character write area | ||
599 | * @size: desired size | ||
600 | * | ||
601 | * Prepare a block of space in the buffer for data. Returns the length | ||
602 | * available and buffer pointer to the space which is now allocated and | ||
603 | * accounted for as ready for normal characters. This is used for drivers | ||
604 | * that need their own block copy routines into the buffer. There is no | ||
605 | * guarantee the buffer is a DMA target! | ||
606 | * | ||
607 | * Locking: May call functions taking tty->buf.lock | ||
608 | */ | ||
609 | |||
610 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | ||
611 | size_t size) | ||
612 | { | ||
613 | int space = tty_buffer_request_room(tty, size); | ||
614 | if (likely(space)) { | ||
615 | struct tty_buffer *tb = tty->buf.tail; | ||
616 | *chars = tb->char_buf_ptr + tb->used; | ||
617 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | ||
618 | tb->used += space; | ||
619 | } | ||
620 | return space; | ||
621 | } | ||
622 | |||
623 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | ||
624 | |||
625 | /** | ||
626 | * tty_prepare_flip_string_flags - make room for characters | ||
627 | * @tty: tty | ||
628 | * @chars: return pointer for character write area | ||
629 | * @flags: return pointer for status flag write area | ||
630 | * @size: desired size | ||
631 | * | ||
632 | * Prepare a block of space in the buffer for data. Returns the length | ||
633 | * available and buffer pointer to the space which is now allocated and | ||
634 | * accounted for as ready for characters. This is used for drivers | ||
635 | * that need their own block copy routines into the buffer. There is no | ||
636 | * guarantee the buffer is a DMA target! | ||
637 | * | ||
638 | * Locking: May call functions taking tty->buf.lock | ||
639 | */ | ||
640 | |||
641 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | ||
642 | unsigned char **chars, char **flags, size_t size) | ||
643 | { | ||
644 | int space = tty_buffer_request_room(tty, size); | ||
645 | if (likely(space)) { | ||
646 | struct tty_buffer *tb = tty->buf.tail; | ||
647 | *chars = tb->char_buf_ptr + tb->used; | ||
648 | *flags = tb->flag_buf_ptr + tb->used; | ||
649 | tb->used += space; | ||
650 | } | ||
651 | return space; | ||
652 | } | ||
653 | |||
654 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | ||
655 | |||
656 | |||
657 | |||
658 | /** | 257 | /** |
659 | * get_tty_driver - find device of a tty | 258 | * get_tty_driver - find device of a tty |
660 | * @dev_t: device identifier | 259 | * @dev_t: device identifier |
@@ -675,7 +274,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) | |||
675 | if (device < base || device >= base + p->num) | 274 | if (device < base || device >= base + p->num) |
676 | continue; | 275 | continue; |
677 | *index = device - base; | 276 | *index = device - base; |
678 | return p; | 277 | return tty_driver_kref_get(p); |
679 | } | 278 | } |
680 | return NULL; | 279 | return NULL; |
681 | } | 280 | } |
@@ -719,7 +318,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
719 | 318 | ||
720 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 319 | if (tty_line >= 0 && tty_line <= p->num && p->ops && |
721 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { | 320 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { |
722 | res = p; | 321 | res = tty_driver_kref_get(p); |
723 | *line = tty_line; | 322 | *line = tty_line; |
724 | break; | 323 | break; |
725 | } | 324 | } |
@@ -819,20 +418,6 @@ static const struct file_operations tty_fops = { | |||
819 | .fasync = tty_fasync, | 418 | .fasync = tty_fasync, |
820 | }; | 419 | }; |
821 | 420 | ||
822 | #ifdef CONFIG_UNIX98_PTYS | ||
823 | static const struct file_operations ptmx_fops = { | ||
824 | .llseek = no_llseek, | ||
825 | .read = tty_read, | ||
826 | .write = tty_write, | ||
827 | .poll = tty_poll, | ||
828 | .unlocked_ioctl = tty_ioctl, | ||
829 | .compat_ioctl = tty_compat_ioctl, | ||
830 | .open = ptmx_open, | ||
831 | .release = tty_release, | ||
832 | .fasync = tty_fasync, | ||
833 | }; | ||
834 | #endif | ||
835 | |||
836 | static const struct file_operations console_fops = { | 421 | static const struct file_operations console_fops = { |
837 | .llseek = no_llseek, | 422 | .llseek = no_llseek, |
838 | .read = tty_read, | 423 | .read = tty_read, |
@@ -953,6 +538,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
953 | struct tty_ldisc *ld; | 538 | struct tty_ldisc *ld; |
954 | int closecount = 0, n; | 539 | int closecount = 0, n; |
955 | unsigned long flags; | 540 | unsigned long flags; |
541 | int refs = 0; | ||
956 | 542 | ||
957 | if (!tty) | 543 | if (!tty) |
958 | return; | 544 | return; |
@@ -1019,8 +605,12 @@ static void do_tty_hangup(struct work_struct *work) | |||
1019 | if (tty->session) { | 605 | if (tty->session) { |
1020 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | 606 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
1021 | spin_lock_irq(&p->sighand->siglock); | 607 | spin_lock_irq(&p->sighand->siglock); |
1022 | if (p->signal->tty == tty) | 608 | if (p->signal->tty == tty) { |
1023 | p->signal->tty = NULL; | 609 | p->signal->tty = NULL; |
610 | /* We defer the dereferences outside fo | ||
611 | the tasklist lock */ | ||
612 | refs++; | ||
613 | } | ||
1024 | if (!p->signal->leader) { | 614 | if (!p->signal->leader) { |
1025 | spin_unlock_irq(&p->sighand->siglock); | 615 | spin_unlock_irq(&p->sighand->siglock); |
1026 | continue; | 616 | continue; |
@@ -1046,6 +636,10 @@ static void do_tty_hangup(struct work_struct *work) | |||
1046 | tty->ctrl_status = 0; | 636 | tty->ctrl_status = 0; |
1047 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 637 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1048 | 638 | ||
639 | /* Account for the p->signal references we killed */ | ||
640 | while (refs--) | ||
641 | tty_kref_put(tty); | ||
642 | |||
1049 | /* | 643 | /* |
1050 | * If one of the devices matches a console pointer, we | 644 | * If one of the devices matches a console pointer, we |
1051 | * cannot just call hangup() because that will cause | 645 | * cannot just call hangup() because that will cause |
@@ -1115,6 +709,23 @@ void tty_vhangup(struct tty_struct *tty) | |||
1115 | EXPORT_SYMBOL(tty_vhangup); | 709 | EXPORT_SYMBOL(tty_vhangup); |
1116 | 710 | ||
1117 | /** | 711 | /** |
712 | * tty_vhangup_self - process vhangup for own ctty | ||
713 | * | ||
714 | * Perform a vhangup on the current controlling tty | ||
715 | */ | ||
716 | |||
717 | void tty_vhangup_self(void) | ||
718 | { | ||
719 | struct tty_struct *tty; | ||
720 | |||
721 | tty = get_current_tty(); | ||
722 | if (tty) { | ||
723 | tty_vhangup(tty); | ||
724 | tty_kref_put(tty); | ||
725 | } | ||
726 | } | ||
727 | |||
728 | /** | ||
1118 | * tty_hung_up_p - was tty hung up | 729 | * tty_hung_up_p - was tty hung up |
1119 | * @filp: file pointer of tty | 730 | * @filp: file pointer of tty |
1120 | * | 731 | * |
@@ -1167,16 +778,14 @@ void disassociate_ctty(int on_exit) | |||
1167 | struct pid *tty_pgrp = NULL; | 778 | struct pid *tty_pgrp = NULL; |
1168 | 779 | ||
1169 | 780 | ||
1170 | mutex_lock(&tty_mutex); | ||
1171 | tty = get_current_tty(); | 781 | tty = get_current_tty(); |
1172 | if (tty) { | 782 | if (tty) { |
1173 | tty_pgrp = get_pid(tty->pgrp); | 783 | tty_pgrp = get_pid(tty->pgrp); |
1174 | lock_kernel(); | 784 | lock_kernel(); |
1175 | mutex_unlock(&tty_mutex); | ||
1176 | /* XXX: here we race, there is nothing protecting tty */ | ||
1177 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 785 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1178 | tty_vhangup(tty); | 786 | tty_vhangup(tty); |
1179 | unlock_kernel(); | 787 | unlock_kernel(); |
788 | tty_kref_put(tty); | ||
1180 | } else if (on_exit) { | 789 | } else if (on_exit) { |
1181 | struct pid *old_pgrp; | 790 | struct pid *old_pgrp; |
1182 | spin_lock_irq(¤t->sighand->siglock); | 791 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1188,7 +797,6 @@ void disassociate_ctty(int on_exit) | |||
1188 | kill_pgrp(old_pgrp, SIGCONT, on_exit); | 797 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
1189 | put_pid(old_pgrp); | 798 | put_pid(old_pgrp); |
1190 | } | 799 | } |
1191 | mutex_unlock(&tty_mutex); | ||
1192 | return; | 800 | return; |
1193 | } | 801 | } |
1194 | if (tty_pgrp) { | 802 | if (tty_pgrp) { |
@@ -1203,8 +811,6 @@ void disassociate_ctty(int on_exit) | |||
1203 | current->signal->tty_old_pgrp = NULL; | 811 | current->signal->tty_old_pgrp = NULL; |
1204 | spin_unlock_irq(¤t->sighand->siglock); | 812 | spin_unlock_irq(¤t->sighand->siglock); |
1205 | 813 | ||
1206 | mutex_lock(&tty_mutex); | ||
1207 | /* It is possible that do_tty_hangup has free'd this tty */ | ||
1208 | tty = get_current_tty(); | 814 | tty = get_current_tty(); |
1209 | if (tty) { | 815 | if (tty) { |
1210 | unsigned long flags; | 816 | unsigned long flags; |
@@ -1214,13 +820,13 @@ void disassociate_ctty(int on_exit) | |||
1214 | tty->session = NULL; | 820 | tty->session = NULL; |
1215 | tty->pgrp = NULL; | 821 | tty->pgrp = NULL; |
1216 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 822 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
823 | tty_kref_put(tty); | ||
1217 | } else { | 824 | } else { |
1218 | #ifdef TTY_DEBUG_HANGUP | 825 | #ifdef TTY_DEBUG_HANGUP |
1219 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 826 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
1220 | " = NULL", tty); | 827 | " = NULL", tty); |
1221 | #endif | 828 | #endif |
1222 | } | 829 | } |
1223 | mutex_unlock(&tty_mutex); | ||
1224 | 830 | ||
1225 | /* Now clear signal->tty under the lock */ | 831 | /* Now clear signal->tty under the lock */ |
1226 | read_lock(&tasklist_lock); | 832 | read_lock(&tasklist_lock); |
@@ -1420,19 +1026,19 @@ static inline ssize_t do_tty_write( | |||
1420 | 1026 | ||
1421 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ | 1027 | /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ |
1422 | if (tty->write_cnt < chunk) { | 1028 | if (tty->write_cnt < chunk) { |
1423 | unsigned char *buf; | 1029 | unsigned char *buf_chunk; |
1424 | 1030 | ||
1425 | if (chunk < 1024) | 1031 | if (chunk < 1024) |
1426 | chunk = 1024; | 1032 | chunk = 1024; |
1427 | 1033 | ||
1428 | buf = kmalloc(chunk, GFP_KERNEL); | 1034 | buf_chunk = kmalloc(chunk, GFP_KERNEL); |
1429 | if (!buf) { | 1035 | if (!buf_chunk) { |
1430 | ret = -ENOMEM; | 1036 | ret = -ENOMEM; |
1431 | goto out; | 1037 | goto out; |
1432 | } | 1038 | } |
1433 | kfree(tty->write_buf); | 1039 | kfree(tty->write_buf); |
1434 | tty->write_cnt = chunk; | 1040 | tty->write_cnt = chunk; |
1435 | tty->write_buf = buf; | 1041 | tty->write_buf = buf_chunk; |
1436 | } | 1042 | } |
1437 | 1043 | ||
1438 | /* Do the write .. */ | 1044 | /* Do the write .. */ |
@@ -1466,6 +1072,31 @@ out: | |||
1466 | return ret; | 1072 | return ret; |
1467 | } | 1073 | } |
1468 | 1074 | ||
1075 | /** | ||
1076 | * tty_write_message - write a message to a certain tty, not just the console. | ||
1077 | * @tty: the destination tty_struct | ||
1078 | * @msg: the message to write | ||
1079 | * | ||
1080 | * This is used for messages that need to be redirected to a specific tty. | ||
1081 | * We don't put it into the syslog queue right now maybe in the future if | ||
1082 | * really needed. | ||
1083 | * | ||
1084 | * We must still hold the BKL and test the CLOSING flag for the moment. | ||
1085 | */ | ||
1086 | |||
1087 | void tty_write_message(struct tty_struct *tty, char *msg) | ||
1088 | { | ||
1089 | lock_kernel(); | ||
1090 | if (tty) { | ||
1091 | mutex_lock(&tty->atomic_write_lock); | ||
1092 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) | ||
1093 | tty->ops->write(tty, msg, strlen(msg)); | ||
1094 | tty_write_unlock(tty); | ||
1095 | } | ||
1096 | unlock_kernel(); | ||
1097 | return; | ||
1098 | } | ||
1099 | |||
1469 | 1100 | ||
1470 | /** | 1101 | /** |
1471 | * tty_write - write method for tty device file | 1102 | * tty_write - write method for tty device file |
@@ -1533,42 +1164,6 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
1533 | return tty_write(file, buf, count, ppos); | 1164 | return tty_write(file, buf, count, ppos); |
1534 | } | 1165 | } |
1535 | 1166 | ||
1536 | void tty_port_init(struct tty_port *port) | ||
1537 | { | ||
1538 | memset(port, 0, sizeof(*port)); | ||
1539 | init_waitqueue_head(&port->open_wait); | ||
1540 | init_waitqueue_head(&port->close_wait); | ||
1541 | mutex_init(&port->mutex); | ||
1542 | port->close_delay = (50 * HZ) / 100; | ||
1543 | port->closing_wait = (3000 * HZ) / 100; | ||
1544 | } | ||
1545 | EXPORT_SYMBOL(tty_port_init); | ||
1546 | |||
1547 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
1548 | { | ||
1549 | /* We may sleep in get_zeroed_page() */ | ||
1550 | mutex_lock(&port->mutex); | ||
1551 | if (port->xmit_buf == NULL) | ||
1552 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
1553 | mutex_unlock(&port->mutex); | ||
1554 | if (port->xmit_buf == NULL) | ||
1555 | return -ENOMEM; | ||
1556 | return 0; | ||
1557 | } | ||
1558 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
1559 | |||
1560 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
1561 | { | ||
1562 | mutex_lock(&port->mutex); | ||
1563 | if (port->xmit_buf != NULL) { | ||
1564 | free_page((unsigned long)port->xmit_buf); | ||
1565 | port->xmit_buf = NULL; | ||
1566 | } | ||
1567 | mutex_unlock(&port->mutex); | ||
1568 | } | ||
1569 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
1570 | |||
1571 | |||
1572 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1167 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1573 | 1168 | ||
1574 | /** | 1169 | /** |
@@ -1592,7 +1187,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1592 | } | 1187 | } |
1593 | 1188 | ||
1594 | /** | 1189 | /** |
1595 | * pty_line_name - generate name for a tty | 1190 | * tty_line_name - generate name for a tty |
1596 | * @driver: the tty driver in use | 1191 | * @driver: the tty driver in use |
1597 | * @index: the minor number | 1192 | * @index: the minor number |
1598 | * @p: output buffer of at least 7 bytes | 1193 | * @p: output buffer of at least 7 bytes |
@@ -1608,10 +1203,148 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1608 | } | 1203 | } |
1609 | 1204 | ||
1610 | /** | 1205 | /** |
1611 | * init_dev - initialise a tty device | 1206 | * tty_driver_lookup_tty() - find an existing tty, if any |
1207 | * @driver: the driver for the tty | ||
1208 | * @idx: the minor number | ||
1209 | * | ||
1210 | * Return the tty, if found or ERR_PTR() otherwise. | ||
1211 | * | ||
1212 | * Locking: tty_mutex must be held. If tty is found, the mutex must | ||
1213 | * be held until the 'fast-open' is also done. Will change once we | ||
1214 | * have refcounting in the driver and per driver locking | ||
1215 | */ | ||
1216 | struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, | ||
1217 | struct inode *inode, int idx) | ||
1218 | { | ||
1219 | struct tty_struct *tty; | ||
1220 | |||
1221 | if (driver->ops->lookup) | ||
1222 | return driver->ops->lookup(driver, inode, idx); | ||
1223 | |||
1224 | tty = driver->ttys[idx]; | ||
1225 | return tty; | ||
1226 | } | ||
1227 | |||
1228 | /** | ||
1229 | * tty_init_termios - helper for termios setup | ||
1230 | * @tty: the tty to set up | ||
1231 | * | ||
1232 | * Initialise the termios structures for this tty. Thus runs under | ||
1233 | * the tty_mutex currently so we can be relaxed about ordering. | ||
1234 | */ | ||
1235 | |||
1236 | int tty_init_termios(struct tty_struct *tty) | ||
1237 | { | ||
1238 | struct ktermios *tp; | ||
1239 | int idx = tty->index; | ||
1240 | |||
1241 | tp = tty->driver->termios[idx]; | ||
1242 | if (tp == NULL) { | ||
1243 | tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
1244 | if (tp == NULL) | ||
1245 | return -ENOMEM; | ||
1246 | memcpy(tp, &tty->driver->init_termios, | ||
1247 | sizeof(struct ktermios)); | ||
1248 | tty->driver->termios[idx] = tp; | ||
1249 | } | ||
1250 | tty->termios = tp; | ||
1251 | tty->termios_locked = tp + 1; | ||
1252 | |||
1253 | /* Compatibility until drivers always set this */ | ||
1254 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1255 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1256 | return 0; | ||
1257 | } | ||
1258 | |||
1259 | /** | ||
1260 | * tty_driver_install_tty() - install a tty entry in the driver | ||
1261 | * @driver: the driver for the tty | ||
1262 | * @tty: the tty | ||
1263 | * | ||
1264 | * Install a tty object into the driver tables. The tty->index field | ||
1265 | * will be set by the time this is called. This method is responsible | ||
1266 | * for ensuring any need additional structures are allocated and | ||
1267 | * configured. | ||
1268 | * | ||
1269 | * Locking: tty_mutex for now | ||
1270 | */ | ||
1271 | static int tty_driver_install_tty(struct tty_driver *driver, | ||
1272 | struct tty_struct *tty) | ||
1273 | { | ||
1274 | int idx = tty->index; | ||
1275 | |||
1276 | if (driver->ops->install) | ||
1277 | return driver->ops->install(driver, tty); | ||
1278 | |||
1279 | if (tty_init_termios(tty) == 0) { | ||
1280 | tty_driver_kref_get(driver); | ||
1281 | tty->count++; | ||
1282 | driver->ttys[idx] = tty; | ||
1283 | return 0; | ||
1284 | } | ||
1285 | return -ENOMEM; | ||
1286 | } | ||
1287 | |||
1288 | /** | ||
1289 | * tty_driver_remove_tty() - remove a tty from the driver tables | ||
1290 | * @driver: the driver for the tty | ||
1291 | * @idx: the minor number | ||
1292 | * | ||
1293 | * Remvoe a tty object from the driver tables. The tty->index field | ||
1294 | * will be set by the time this is called. | ||
1295 | * | ||
1296 | * Locking: tty_mutex for now | ||
1297 | */ | ||
1298 | static void tty_driver_remove_tty(struct tty_driver *driver, | ||
1299 | struct tty_struct *tty) | ||
1300 | { | ||
1301 | if (driver->ops->remove) | ||
1302 | driver->ops->remove(driver, tty); | ||
1303 | else | ||
1304 | driver->ttys[tty->index] = NULL; | ||
1305 | } | ||
1306 | |||
1307 | /* | ||
1308 | * tty_reopen() - fast re-open of an open tty | ||
1309 | * @tty - the tty to open | ||
1310 | * | ||
1311 | * Return 0 on success, -errno on error. | ||
1312 | * | ||
1313 | * Locking: tty_mutex must be held from the time the tty was found | ||
1314 | * till this open completes. | ||
1315 | */ | ||
1316 | static int tty_reopen(struct tty_struct *tty) | ||
1317 | { | ||
1318 | struct tty_driver *driver = tty->driver; | ||
1319 | |||
1320 | if (test_bit(TTY_CLOSING, &tty->flags)) | ||
1321 | return -EIO; | ||
1322 | |||
1323 | if (driver->type == TTY_DRIVER_TYPE_PTY && | ||
1324 | driver->subtype == PTY_TYPE_MASTER) { | ||
1325 | /* | ||
1326 | * special case for PTY masters: only one open permitted, | ||
1327 | * and the slave side open count is incremented as well. | ||
1328 | */ | ||
1329 | if (tty->count) | ||
1330 | return -EIO; | ||
1331 | |||
1332 | tty->link->count++; | ||
1333 | } | ||
1334 | tty->count++; | ||
1335 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
1336 | |||
1337 | WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | /** | ||
1343 | * tty_init_dev - initialise a tty device | ||
1612 | * @driver: tty driver we are opening a device on | 1344 | * @driver: tty driver we are opening a device on |
1613 | * @idx: device index | 1345 | * @idx: device index |
1614 | * @tty: returned tty structure | 1346 | * @ret_tty: returned tty structure |
1347 | * @first_ok: ok to open a new device (used by ptmx) | ||
1615 | * | 1348 | * |
1616 | * Prepare a tty device. This may not be a "new" clean device but | 1349 | * Prepare a tty device. This may not be a "new" clean device but |
1617 | * could also be an active device. The pty drivers require special | 1350 | * could also be an active device. The pty drivers require special |
@@ -1631,37 +1364,16 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1631 | * relaxed for the (most common) case of reopening a tty. | 1364 | * relaxed for the (most common) case of reopening a tty. |
1632 | */ | 1365 | */ |
1633 | 1366 | ||
1634 | static int init_dev(struct tty_driver *driver, int idx, | 1367 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, |
1635 | struct tty_struct **ret_tty) | 1368 | int first_ok) |
1636 | { | 1369 | { |
1637 | struct tty_struct *tty, *o_tty; | 1370 | struct tty_struct *tty; |
1638 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1371 | int retval; |
1639 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | ||
1640 | int retval = 0; | ||
1641 | 1372 | ||
1642 | /* check whether we're reopening an existing tty */ | 1373 | /* Check if pty master is being opened multiple times */ |
1643 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1374 | if (driver->subtype == PTY_TYPE_MASTER && |
1644 | tty = devpts_get_tty(idx); | 1375 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) |
1645 | /* | 1376 | return ERR_PTR(-EIO); |
1646 | * If we don't have a tty here on a slave open, it's because | ||
1647 | * the master already started the close process and there's | ||
1648 | * no relation between devpts file and tty anymore. | ||
1649 | */ | ||
1650 | if (!tty && driver->subtype == PTY_TYPE_SLAVE) { | ||
1651 | retval = -EIO; | ||
1652 | goto end_init; | ||
1653 | } | ||
1654 | /* | ||
1655 | * It's safe from now on because init_dev() is called with | ||
1656 | * tty_mutex held and release_dev() won't change tty->count | ||
1657 | * or tty->flags without having to grab tty_mutex | ||
1658 | */ | ||
1659 | if (tty && driver->subtype == PTY_TYPE_MASTER) | ||
1660 | tty = tty->link; | ||
1661 | } else { | ||
1662 | tty = driver->ttys[idx]; | ||
1663 | } | ||
1664 | if (tty) goto fast_track; | ||
1665 | 1377 | ||
1666 | /* | 1378 | /* |
1667 | * First time open is complex, especially for PTY devices. | 1379 | * First time open is complex, especially for PTY devices. |
@@ -1671,189 +1383,69 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1671 | * and locked termios may be retained.) | 1383 | * and locked termios may be retained.) |
1672 | */ | 1384 | */ |
1673 | 1385 | ||
1674 | if (!try_module_get(driver->owner)) { | 1386 | if (!try_module_get(driver->owner)) |
1675 | retval = -ENODEV; | 1387 | return ERR_PTR(-ENODEV); |
1676 | goto end_init; | ||
1677 | } | ||
1678 | |||
1679 | o_tty = NULL; | ||
1680 | tp = o_tp = NULL; | ||
1681 | ltp = o_ltp = NULL; | ||
1682 | 1388 | ||
1683 | tty = alloc_tty_struct(); | 1389 | tty = alloc_tty_struct(); |
1684 | if (!tty) | 1390 | if (!tty) |
1685 | goto fail_no_mem; | 1391 | goto fail_no_mem; |
1686 | initialize_tty_struct(tty); | 1392 | initialize_tty_struct(tty, driver, idx); |
1687 | tty->driver = driver; | ||
1688 | tty->ops = driver->ops; | ||
1689 | tty->index = idx; | ||
1690 | tty_line_name(driver, idx, tty->name); | ||
1691 | |||
1692 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1693 | tp_loc = &tty->termios; | ||
1694 | ltp_loc = &tty->termios_locked; | ||
1695 | } else { | ||
1696 | tp_loc = &driver->termios[idx]; | ||
1697 | ltp_loc = &driver->termios_locked[idx]; | ||
1698 | } | ||
1699 | |||
1700 | if (!*tp_loc) { | ||
1701 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1702 | if (!tp) | ||
1703 | goto free_mem_out; | ||
1704 | *tp = driver->init_termios; | ||
1705 | } | ||
1706 | |||
1707 | if (!*ltp_loc) { | ||
1708 | ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1709 | if (!ltp) | ||
1710 | goto free_mem_out; | ||
1711 | } | ||
1712 | |||
1713 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | ||
1714 | o_tty = alloc_tty_struct(); | ||
1715 | if (!o_tty) | ||
1716 | goto free_mem_out; | ||
1717 | initialize_tty_struct(o_tty); | ||
1718 | o_tty->driver = driver->other; | ||
1719 | o_tty->ops = driver->ops; | ||
1720 | o_tty->index = idx; | ||
1721 | tty_line_name(driver->other, idx, o_tty->name); | ||
1722 | |||
1723 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1724 | o_tp_loc = &o_tty->termios; | ||
1725 | o_ltp_loc = &o_tty->termios_locked; | ||
1726 | } else { | ||
1727 | o_tp_loc = &driver->other->termios[idx]; | ||
1728 | o_ltp_loc = &driver->other->termios_locked[idx]; | ||
1729 | } | ||
1730 | 1393 | ||
1731 | if (!*o_tp_loc) { | 1394 | retval = tty_driver_install_tty(driver, tty); |
1732 | o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | 1395 | if (retval < 0) { |
1733 | if (!o_tp) | 1396 | free_tty_struct(tty); |
1734 | goto free_mem_out; | 1397 | module_put(driver->owner); |
1735 | *o_tp = driver->other->init_termios; | 1398 | return ERR_PTR(retval); |
1736 | } | ||
1737 | |||
1738 | if (!*o_ltp_loc) { | ||
1739 | o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1740 | if (!o_ltp) | ||
1741 | goto free_mem_out; | ||
1742 | } | ||
1743 | |||
1744 | /* | ||
1745 | * Everything allocated ... set up the o_tty structure. | ||
1746 | */ | ||
1747 | if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1748 | driver->other->ttys[idx] = o_tty; | ||
1749 | if (!*o_tp_loc) | ||
1750 | *o_tp_loc = o_tp; | ||
1751 | if (!*o_ltp_loc) | ||
1752 | *o_ltp_loc = o_ltp; | ||
1753 | o_tty->termios = *o_tp_loc; | ||
1754 | o_tty->termios_locked = *o_ltp_loc; | ||
1755 | driver->other->refcount++; | ||
1756 | if (driver->subtype == PTY_TYPE_MASTER) | ||
1757 | o_tty->count++; | ||
1758 | |||
1759 | /* Establish the links in both directions */ | ||
1760 | tty->link = o_tty; | ||
1761 | o_tty->link = tty; | ||
1762 | } | 1399 | } |
1763 | 1400 | ||
1764 | /* | 1401 | /* |
1765 | * All structures have been allocated, so now we install them. | ||
1766 | * Failures after this point use release_tty to clean up, so | ||
1767 | * there's no need to null out the local pointers. | ||
1768 | */ | ||
1769 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1770 | driver->ttys[idx] = tty; | ||
1771 | |||
1772 | if (!*tp_loc) | ||
1773 | *tp_loc = tp; | ||
1774 | if (!*ltp_loc) | ||
1775 | *ltp_loc = ltp; | ||
1776 | tty->termios = *tp_loc; | ||
1777 | tty->termios_locked = *ltp_loc; | ||
1778 | /* Compatibility until drivers always set this */ | ||
1779 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1780 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1781 | driver->refcount++; | ||
1782 | tty->count++; | ||
1783 | |||
1784 | /* | ||
1785 | * Structures all installed ... call the ldisc open routines. | 1402 | * Structures all installed ... call the ldisc open routines. |
1786 | * If we fail here just call release_tty to clean up. No need | 1403 | * If we fail here just call release_tty to clean up. No need |
1787 | * to decrement the use counts, as release_tty doesn't care. | 1404 | * to decrement the use counts, as release_tty doesn't care. |
1788 | */ | 1405 | */ |
1789 | 1406 | ||
1790 | retval = tty_ldisc_setup(tty, o_tty); | 1407 | retval = tty_ldisc_setup(tty, tty->link); |
1791 | |||
1792 | if (retval) | 1408 | if (retval) |
1793 | goto release_mem_out; | 1409 | goto release_mem_out; |
1794 | goto success; | 1410 | return tty; |
1795 | |||
1796 | /* | ||
1797 | * This fast open can be used if the tty is already open. | ||
1798 | * No memory is allocated, and the only failures are from | ||
1799 | * attempting to open a closing tty or attempting multiple | ||
1800 | * opens on a pty master. | ||
1801 | */ | ||
1802 | fast_track: | ||
1803 | if (test_bit(TTY_CLOSING, &tty->flags)) { | ||
1804 | retval = -EIO; | ||
1805 | goto end_init; | ||
1806 | } | ||
1807 | if (driver->type == TTY_DRIVER_TYPE_PTY && | ||
1808 | driver->subtype == PTY_TYPE_MASTER) { | ||
1809 | /* | ||
1810 | * special case for PTY masters: only one open permitted, | ||
1811 | * and the slave side open count is incremented as well. | ||
1812 | */ | ||
1813 | if (tty->count) { | ||
1814 | retval = -EIO; | ||
1815 | goto end_init; | ||
1816 | } | ||
1817 | tty->link->count++; | ||
1818 | } | ||
1819 | tty->count++; | ||
1820 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
1821 | |||
1822 | /* FIXME */ | ||
1823 | if (!test_bit(TTY_LDISC, &tty->flags)) | ||
1824 | printk(KERN_ERR "init_dev but no ldisc\n"); | ||
1825 | success: | ||
1826 | *ret_tty = tty; | ||
1827 | |||
1828 | /* All paths come through here to release the mutex */ | ||
1829 | end_init: | ||
1830 | return retval; | ||
1831 | |||
1832 | /* Release locally allocated memory ... nothing placed in slots */ | ||
1833 | free_mem_out: | ||
1834 | kfree(o_tp); | ||
1835 | if (o_tty) | ||
1836 | free_tty_struct(o_tty); | ||
1837 | kfree(ltp); | ||
1838 | kfree(tp); | ||
1839 | free_tty_struct(tty); | ||
1840 | 1411 | ||
1841 | fail_no_mem: | 1412 | fail_no_mem: |
1842 | module_put(driver->owner); | 1413 | module_put(driver->owner); |
1843 | retval = -ENOMEM; | 1414 | return ERR_PTR(-ENOMEM); |
1844 | goto end_init; | ||
1845 | 1415 | ||
1846 | /* call the tty release_tty routine to clean out this slot */ | 1416 | /* call the tty release_tty routine to clean out this slot */ |
1847 | release_mem_out: | 1417 | release_mem_out: |
1848 | if (printk_ratelimit()) | 1418 | if (printk_ratelimit()) |
1849 | printk(KERN_INFO "init_dev: ldisc open failed, " | 1419 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1850 | "clearing slot %d\n", idx); | 1420 | "clearing slot %d\n", idx); |
1851 | release_tty(tty, idx); | 1421 | release_tty(tty, idx); |
1852 | goto end_init; | 1422 | return ERR_PTR(retval); |
1853 | } | 1423 | } |
1854 | 1424 | ||
1425 | void tty_free_termios(struct tty_struct *tty) | ||
1426 | { | ||
1427 | struct ktermios *tp; | ||
1428 | int idx = tty->index; | ||
1429 | /* Kill this flag and push into drivers for locking etc */ | ||
1430 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1431 | /* FIXME: Locking on ->termios array */ | ||
1432 | tp = tty->termios; | ||
1433 | tty->driver->termios[idx] = NULL; | ||
1434 | kfree(tp); | ||
1435 | } | ||
1436 | } | ||
1437 | EXPORT_SYMBOL(tty_free_termios); | ||
1438 | |||
1439 | void tty_shutdown(struct tty_struct *tty) | ||
1440 | { | ||
1441 | tty_driver_remove_tty(tty->driver, tty); | ||
1442 | tty_free_termios(tty); | ||
1443 | } | ||
1444 | EXPORT_SYMBOL(tty_shutdown); | ||
1445 | |||
1855 | /** | 1446 | /** |
1856 | * release_one_tty - release tty structure memory | 1447 | * release_one_tty - release tty structure memory |
1448 | * @kref: kref of tty we are obliterating | ||
1857 | * | 1449 | * |
1858 | * Releases memory associated with a tty structure, and clears out the | 1450 | * Releases memory associated with a tty structure, and clears out the |
1859 | * driver table slots. This function is called when a device is no longer | 1451 | * driver table slots. This function is called when a device is no longer |
@@ -1863,31 +1455,19 @@ release_mem_out: | |||
1863 | * tty_mutex - sometimes only | 1455 | * tty_mutex - sometimes only |
1864 | * takes the file list lock internally when working on the list | 1456 | * takes the file list lock internally when working on the list |
1865 | * of ttys that the driver keeps. | 1457 | * of ttys that the driver keeps. |
1866 | * FIXME: should we require tty_mutex is held here ?? | ||
1867 | */ | 1458 | */ |
1868 | static void release_one_tty(struct tty_struct *tty, int idx) | 1459 | static void release_one_tty(struct kref *kref) |
1869 | { | 1460 | { |
1870 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 1461 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1871 | struct ktermios *tp; | 1462 | struct tty_driver *driver = tty->driver; |
1872 | |||
1873 | if (!devpts) | ||
1874 | tty->driver->ttys[idx] = NULL; | ||
1875 | |||
1876 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1877 | tp = tty->termios; | ||
1878 | if (!devpts) | ||
1879 | tty->driver->termios[idx] = NULL; | ||
1880 | kfree(tp); | ||
1881 | |||
1882 | tp = tty->termios_locked; | ||
1883 | if (!devpts) | ||
1884 | tty->driver->termios_locked[idx] = NULL; | ||
1885 | kfree(tp); | ||
1886 | } | ||
1887 | |||
1888 | 1463 | ||
1464 | if (tty->ops->shutdown) | ||
1465 | tty->ops->shutdown(tty); | ||
1466 | else | ||
1467 | tty_shutdown(tty); | ||
1889 | tty->magic = 0; | 1468 | tty->magic = 0; |
1890 | tty->driver->refcount--; | 1469 | tty_driver_kref_put(driver); |
1470 | module_put(driver->owner); | ||
1891 | 1471 | ||
1892 | file_list_lock(); | 1472 | file_list_lock(); |
1893 | list_del_init(&tty->tty_files); | 1473 | list_del_init(&tty->tty_files); |
@@ -1897,6 +1477,21 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1897 | } | 1477 | } |
1898 | 1478 | ||
1899 | /** | 1479 | /** |
1480 | * tty_kref_put - release a tty kref | ||
1481 | * @tty: tty device | ||
1482 | * | ||
1483 | * Release a reference to a tty device and if need be let the kref | ||
1484 | * layer destruct the object for us | ||
1485 | */ | ||
1486 | |||
1487 | void tty_kref_put(struct tty_struct *tty) | ||
1488 | { | ||
1489 | if (tty) | ||
1490 | kref_put(&tty->kref, release_one_tty); | ||
1491 | } | ||
1492 | EXPORT_SYMBOL(tty_kref_put); | ||
1493 | |||
1494 | /** | ||
1900 | * release_tty - release tty structure memory | 1495 | * release_tty - release tty structure memory |
1901 | * | 1496 | * |
1902 | * Release both @tty and a possible linked partner (think pty pair), | 1497 | * Release both @tty and a possible linked partner (think pty pair), |
@@ -1907,15 +1502,16 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1907 | * takes the file list lock internally when working on the list | 1502 | * takes the file list lock internally when working on the list |
1908 | * of ttys that the driver keeps. | 1503 | * of ttys that the driver keeps. |
1909 | * FIXME: should we require tty_mutex is held here ?? | 1504 | * FIXME: should we require tty_mutex is held here ?? |
1505 | * | ||
1910 | */ | 1506 | */ |
1911 | static void release_tty(struct tty_struct *tty, int idx) | 1507 | static void release_tty(struct tty_struct *tty, int idx) |
1912 | { | 1508 | { |
1913 | struct tty_driver *driver = tty->driver; | 1509 | /* This should always be true but check for the moment */ |
1510 | WARN_ON(tty->index != idx); | ||
1914 | 1511 | ||
1915 | if (tty->link) | 1512 | if (tty->link) |
1916 | release_one_tty(tty->link, idx); | 1513 | tty_kref_put(tty->link); |
1917 | release_one_tty(tty, idx); | 1514 | tty_kref_put(tty); |
1918 | module_put(driver->owner); | ||
1919 | } | 1515 | } |
1920 | 1516 | ||
1921 | /* | 1517 | /* |
@@ -1926,20 +1522,21 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1926 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could | 1522 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could |
1927 | * lead to double frees or releasing memory still in use. | 1523 | * lead to double frees or releasing memory still in use. |
1928 | */ | 1524 | */ |
1929 | static void release_dev(struct file *filp) | 1525 | void tty_release_dev(struct file *filp) |
1930 | { | 1526 | { |
1931 | struct tty_struct *tty, *o_tty; | 1527 | struct tty_struct *tty, *o_tty; |
1932 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1528 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1933 | int devpts; | 1529 | int devpts; |
1934 | int idx; | 1530 | int idx; |
1935 | char buf[64]; | 1531 | char buf[64]; |
1532 | struct inode *inode; | ||
1936 | 1533 | ||
1534 | inode = filp->f_path.dentry->d_inode; | ||
1937 | tty = (struct tty_struct *)filp->private_data; | 1535 | tty = (struct tty_struct *)filp->private_data; |
1938 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, | 1536 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1939 | "release_dev")) | ||
1940 | return; | 1537 | return; |
1941 | 1538 | ||
1942 | check_tty_count(tty, "release_dev"); | 1539 | check_tty_count(tty, "tty_release_dev"); |
1943 | 1540 | ||
1944 | tty_fasync(-1, filp, 0); | 1541 | tty_fasync(-1, filp, 0); |
1945 | 1542 | ||
@@ -1951,33 +1548,27 @@ static void release_dev(struct file *filp) | |||
1951 | 1548 | ||
1952 | #ifdef TTY_PARANOIA_CHECK | 1549 | #ifdef TTY_PARANOIA_CHECK |
1953 | if (idx < 0 || idx >= tty->driver->num) { | 1550 | if (idx < 0 || idx >= tty->driver->num) { |
1954 | printk(KERN_DEBUG "release_dev: bad idx when trying to " | 1551 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1955 | "free (%s)\n", tty->name); | 1552 | "free (%s)\n", tty->name); |
1956 | return; | 1553 | return; |
1957 | } | 1554 | } |
1958 | if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1555 | if (!devpts) { |
1959 | if (tty != tty->driver->ttys[idx]) { | 1556 | if (tty != tty->driver->ttys[idx]) { |
1960 | printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " | 1557 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1961 | "for (%s)\n", idx, tty->name); | 1558 | "for (%s)\n", idx, tty->name); |
1962 | return; | 1559 | return; |
1963 | } | 1560 | } |
1964 | if (tty->termios != tty->driver->termios[idx]) { | 1561 | if (tty->termios != tty->driver->termios[idx]) { |
1965 | printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " | 1562 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1966 | "for (%s)\n", | 1563 | "for (%s)\n", |
1967 | idx, tty->name); | 1564 | idx, tty->name); |
1968 | return; | 1565 | return; |
1969 | } | 1566 | } |
1970 | if (tty->termios_locked != tty->driver->termios_locked[idx]) { | ||
1971 | printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not " | ||
1972 | "termios_locked for (%s)\n", | ||
1973 | idx, tty->name); | ||
1974 | return; | ||
1975 | } | ||
1976 | } | 1567 | } |
1977 | #endif | 1568 | #endif |
1978 | 1569 | ||
1979 | #ifdef TTY_DEBUG_HANGUP | 1570 | #ifdef TTY_DEBUG_HANGUP |
1980 | printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", | 1571 | printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", |
1981 | tty_name(tty, buf), tty->count); | 1572 | tty_name(tty, buf), tty->count); |
1982 | #endif | 1573 | #endif |
1983 | 1574 | ||
@@ -1985,26 +1576,19 @@ static void release_dev(struct file *filp) | |||
1985 | if (tty->driver->other && | 1576 | if (tty->driver->other && |
1986 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1577 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1987 | if (o_tty != tty->driver->other->ttys[idx]) { | 1578 | if (o_tty != tty->driver->other->ttys[idx]) { |
1988 | printk(KERN_DEBUG "release_dev: other->table[%d] " | 1579 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1989 | "not o_tty for (%s)\n", | 1580 | "not o_tty for (%s)\n", |
1990 | idx, tty->name); | 1581 | idx, tty->name); |
1991 | return; | 1582 | return; |
1992 | } | 1583 | } |
1993 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1584 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1994 | printk(KERN_DEBUG "release_dev: other->termios[%d] " | 1585 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1995 | "not o_termios for (%s)\n", | 1586 | "not o_termios for (%s)\n", |
1996 | idx, tty->name); | 1587 | idx, tty->name); |
1997 | return; | 1588 | return; |
1998 | } | 1589 | } |
1999 | if (o_tty->termios_locked != | ||
2000 | tty->driver->other->termios_locked[idx]) { | ||
2001 | printk(KERN_DEBUG "release_dev: other->termios_locked[" | ||
2002 | "%d] not o_termios_locked for (%s)\n", | ||
2003 | idx, tty->name); | ||
2004 | return; | ||
2005 | } | ||
2006 | if (o_tty->link != tty) { | 1590 | if (o_tty->link != tty) { |
2007 | printk(KERN_DEBUG "release_dev: bad pty pointers\n"); | 1591 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
2008 | return; | 1592 | return; |
2009 | } | 1593 | } |
2010 | } | 1594 | } |
@@ -2062,7 +1646,7 @@ static void release_dev(struct file *filp) | |||
2062 | if (!do_sleep) | 1646 | if (!do_sleep) |
2063 | break; | 1647 | break; |
2064 | 1648 | ||
2065 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " | 1649 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
2066 | "active!\n", tty_name(tty, buf)); | 1650 | "active!\n", tty_name(tty, buf)); |
2067 | mutex_unlock(&tty_mutex); | 1651 | mutex_unlock(&tty_mutex); |
2068 | schedule(); | 1652 | schedule(); |
@@ -2075,14 +1659,14 @@ static void release_dev(struct file *filp) | |||
2075 | */ | 1659 | */ |
2076 | if (pty_master) { | 1660 | if (pty_master) { |
2077 | if (--o_tty->count < 0) { | 1661 | if (--o_tty->count < 0) { |
2078 | printk(KERN_WARNING "release_dev: bad pty slave count " | 1662 | printk(KERN_WARNING "tty_release_dev: bad pty slave count " |
2079 | "(%d) for %s\n", | 1663 | "(%d) for %s\n", |
2080 | o_tty->count, tty_name(o_tty, buf)); | 1664 | o_tty->count, tty_name(o_tty, buf)); |
2081 | o_tty->count = 0; | 1665 | o_tty->count = 0; |
2082 | } | 1666 | } |
2083 | } | 1667 | } |
2084 | if (--tty->count < 0) { | 1668 | if (--tty->count < 0) { |
2085 | printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n", | 1669 | printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n", |
2086 | tty->count, tty_name(tty, buf)); | 1670 | tty->count, tty_name(tty, buf)); |
2087 | tty->count = 0; | 1671 | tty->count = 0; |
2088 | } | 1672 | } |
@@ -2145,11 +1729,11 @@ static void release_dev(struct file *filp) | |||
2145 | 1729 | ||
2146 | /* Make this pty number available for reallocation */ | 1730 | /* Make this pty number available for reallocation */ |
2147 | if (devpts) | 1731 | if (devpts) |
2148 | devpts_kill_index(idx); | 1732 | devpts_kill_index(inode, idx); |
2149 | } | 1733 | } |
2150 | 1734 | ||
2151 | /** | 1735 | /** |
2152 | * tty_open - open a tty device | 1736 | * __tty_open - open a tty device |
2153 | * @inode: inode of device file | 1737 | * @inode: inode of device file |
2154 | * @filp: file pointer to tty | 1738 | * @filp: file pointer to tty |
2155 | * | 1739 | * |
@@ -2164,14 +1748,14 @@ static void release_dev(struct file *filp) | |||
2164 | * The termios state of a pty is reset on first open so that | 1748 | * The termios state of a pty is reset on first open so that |
2165 | * settings don't persist across reuse. | 1749 | * settings don't persist across reuse. |
2166 | * | 1750 | * |
2167 | * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. | 1751 | * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. |
2168 | * tty->count should protect the rest. | 1752 | * tty->count should protect the rest. |
2169 | * ->siglock protects ->signal/->sighand | 1753 | * ->siglock protects ->signal/->sighand |
2170 | */ | 1754 | */ |
2171 | 1755 | ||
2172 | static int __tty_open(struct inode *inode, struct file *filp) | 1756 | static int __tty_open(struct inode *inode, struct file *filp) |
2173 | { | 1757 | { |
2174 | struct tty_struct *tty; | 1758 | struct tty_struct *tty = NULL; |
2175 | int noctty, retval; | 1759 | int noctty, retval; |
2176 | struct tty_driver *driver; | 1760 | struct tty_driver *driver; |
2177 | int index; | 1761 | int index; |
@@ -2193,23 +1777,25 @@ retry_open: | |||
2193 | mutex_unlock(&tty_mutex); | 1777 | mutex_unlock(&tty_mutex); |
2194 | return -ENXIO; | 1778 | return -ENXIO; |
2195 | } | 1779 | } |
2196 | driver = tty->driver; | 1780 | driver = tty_driver_kref_get(tty->driver); |
2197 | index = tty->index; | 1781 | index = tty->index; |
2198 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 1782 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
2199 | /* noctty = 1; */ | 1783 | /* noctty = 1; */ |
1784 | /* FIXME: Should we take a driver reference ? */ | ||
1785 | tty_kref_put(tty); | ||
2200 | goto got_driver; | 1786 | goto got_driver; |
2201 | } | 1787 | } |
2202 | #ifdef CONFIG_VT | 1788 | #ifdef CONFIG_VT |
2203 | if (device == MKDEV(TTY_MAJOR, 0)) { | 1789 | if (device == MKDEV(TTY_MAJOR, 0)) { |
2204 | extern struct tty_driver *console_driver; | 1790 | extern struct tty_driver *console_driver; |
2205 | driver = console_driver; | 1791 | driver = tty_driver_kref_get(console_driver); |
2206 | index = fg_console; | 1792 | index = fg_console; |
2207 | noctty = 1; | 1793 | noctty = 1; |
2208 | goto got_driver; | 1794 | goto got_driver; |
2209 | } | 1795 | } |
2210 | #endif | 1796 | #endif |
2211 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | 1797 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { |
2212 | driver = console_device(&index); | 1798 | driver = tty_driver_kref_get(console_device(&index)); |
2213 | if (driver) { | 1799 | if (driver) { |
2214 | /* Don't let /dev/console block */ | 1800 | /* Don't let /dev/console block */ |
2215 | filp->f_flags |= O_NONBLOCK; | 1801 | filp->f_flags |= O_NONBLOCK; |
@@ -2226,10 +1812,25 @@ retry_open: | |||
2226 | return -ENODEV; | 1812 | return -ENODEV; |
2227 | } | 1813 | } |
2228 | got_driver: | 1814 | got_driver: |
2229 | retval = init_dev(driver, index, &tty); | 1815 | if (!tty) { |
1816 | /* check whether we're reopening an existing tty */ | ||
1817 | tty = tty_driver_lookup_tty(driver, inode, index); | ||
1818 | |||
1819 | if (IS_ERR(tty)) | ||
1820 | return PTR_ERR(tty); | ||
1821 | } | ||
1822 | |||
1823 | if (tty) { | ||
1824 | retval = tty_reopen(tty); | ||
1825 | if (retval) | ||
1826 | tty = ERR_PTR(retval); | ||
1827 | } else | ||
1828 | tty = tty_init_dev(driver, index, 0); | ||
1829 | |||
2230 | mutex_unlock(&tty_mutex); | 1830 | mutex_unlock(&tty_mutex); |
2231 | if (retval) | 1831 | tty_driver_kref_put(driver); |
2232 | return retval; | 1832 | if (IS_ERR(tty)) |
1833 | return PTR_ERR(tty); | ||
2233 | 1834 | ||
2234 | filp->private_data = tty; | 1835 | filp->private_data = tty; |
2235 | file_move(filp, &tty->tty_files); | 1836 | file_move(filp, &tty->tty_files); |
@@ -2257,7 +1858,7 @@ got_driver: | |||
2257 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1858 | printk(KERN_DEBUG "error %d in opening %s...", retval, |
2258 | tty->name); | 1859 | tty->name); |
2259 | #endif | 1860 | #endif |
2260 | release_dev(filp); | 1861 | tty_release_dev(filp); |
2261 | if (retval != -ERESTARTSYS) | 1862 | if (retval != -ERESTARTSYS) |
2262 | return retval; | 1863 | return retval; |
2263 | if (signal_pending(current)) | 1864 | if (signal_pending(current)) |
@@ -2296,69 +1897,6 @@ static int tty_open(struct inode *inode, struct file *filp) | |||
2296 | 1897 | ||
2297 | 1898 | ||
2298 | 1899 | ||
2299 | #ifdef CONFIG_UNIX98_PTYS | ||
2300 | /** | ||
2301 | * ptmx_open - open a unix 98 pty master | ||
2302 | * @inode: inode of device file | ||
2303 | * @filp: file pointer to tty | ||
2304 | * | ||
2305 | * Allocate a unix98 pty master device from the ptmx driver. | ||
2306 | * | ||
2307 | * Locking: tty_mutex protects theinit_dev work. tty->count should | ||
2308 | * protect the rest. | ||
2309 | * allocated_ptys_lock handles the list of free pty numbers | ||
2310 | */ | ||
2311 | |||
2312 | static int __ptmx_open(struct inode *inode, struct file *filp) | ||
2313 | { | ||
2314 | struct tty_struct *tty; | ||
2315 | int retval; | ||
2316 | int index; | ||
2317 | |||
2318 | nonseekable_open(inode, filp); | ||
2319 | |||
2320 | /* find a device that is not in use. */ | ||
2321 | index = devpts_new_index(); | ||
2322 | if (index < 0) | ||
2323 | return index; | ||
2324 | |||
2325 | mutex_lock(&tty_mutex); | ||
2326 | retval = init_dev(ptm_driver, index, &tty); | ||
2327 | mutex_unlock(&tty_mutex); | ||
2328 | |||
2329 | if (retval) | ||
2330 | goto out; | ||
2331 | |||
2332 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | ||
2333 | filp->private_data = tty; | ||
2334 | file_move(filp, &tty->tty_files); | ||
2335 | |||
2336 | retval = devpts_pty_new(tty->link); | ||
2337 | if (retval) | ||
2338 | goto out1; | ||
2339 | |||
2340 | check_tty_count(tty, "ptmx_open"); | ||
2341 | retval = ptm_driver->ops->open(tty, filp); | ||
2342 | if (!retval) | ||
2343 | return 0; | ||
2344 | out1: | ||
2345 | release_dev(filp); | ||
2346 | return retval; | ||
2347 | out: | ||
2348 | devpts_kill_index(index); | ||
2349 | return retval; | ||
2350 | } | ||
2351 | |||
2352 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
2353 | { | ||
2354 | int ret; | ||
2355 | |||
2356 | lock_kernel(); | ||
2357 | ret = __ptmx_open(inode, filp); | ||
2358 | unlock_kernel(); | ||
2359 | return ret; | ||
2360 | } | ||
2361 | #endif | ||
2362 | 1900 | ||
2363 | /** | 1901 | /** |
2364 | * tty_release - vfs callback for close | 1902 | * tty_release - vfs callback for close |
@@ -2369,13 +1907,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2369 | * this tty. There may however be several such references. | 1907 | * this tty. There may however be several such references. |
2370 | * | 1908 | * |
2371 | * Locking: | 1909 | * Locking: |
2372 | * Takes bkl. See release_dev | 1910 | * Takes bkl. See tty_release_dev |
2373 | */ | 1911 | */ |
2374 | 1912 | ||
2375 | static int tty_release(struct inode *inode, struct file *filp) | 1913 | static int tty_release(struct inode *inode, struct file *filp) |
2376 | { | 1914 | { |
2377 | lock_kernel(); | 1915 | lock_kernel(); |
2378 | release_dev(filp); | 1916 | tty_release_dev(filp); |
2379 | unlock_kernel(); | 1917 | unlock_kernel(); |
2380 | return 0; | 1918 | return 0; |
2381 | } | 1919 | } |
@@ -2524,7 +2062,7 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2524 | 2062 | ||
2525 | /* For a PTY we need to lock the tty side */ | 2063 | /* For a PTY we need to lock the tty side */ |
2526 | mutex_lock(&real_tty->termios_mutex); | 2064 | mutex_lock(&real_tty->termios_mutex); |
2527 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) | 2065 | if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) |
2528 | goto done; | 2066 | goto done; |
2529 | /* Get the PID values and reference them so we can | 2067 | /* Get the PID values and reference them so we can |
2530 | avoid holding the tty ctrl lock while sending signals */ | 2068 | avoid holding the tty ctrl lock while sending signals */ |
@@ -2996,7 +2534,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2996 | case TIOCSTI: | 2534 | case TIOCSTI: |
2997 | return tiocsti(tty, p); | 2535 | return tiocsti(tty, p); |
2998 | case TIOCGWINSZ: | 2536 | case TIOCGWINSZ: |
2999 | return tiocgwinsz(tty, p); | 2537 | return tiocgwinsz(real_tty, p); |
3000 | case TIOCSWINSZ: | 2538 | case TIOCSWINSZ: |
3001 | return tiocswinsz(tty, real_tty, p); | 2539 | return tiocswinsz(tty, real_tty, p); |
3002 | case TIOCCONS: | 2540 | case TIOCCONS: |
@@ -3026,10 +2564,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3026 | return put_user(tty->ldisc.ops->num, (int __user *)p); | 2564 | return put_user(tty->ldisc.ops->num, (int __user *)p); |
3027 | case TIOCSETD: | 2565 | case TIOCSETD: |
3028 | return tiocsetd(tty, p); | 2566 | return tiocsetd(tty, p); |
3029 | #ifdef CONFIG_VT | ||
3030 | case TIOCLINUX: | ||
3031 | return tioclinux(tty, arg); | ||
3032 | #endif | ||
3033 | /* | 2567 | /* |
3034 | * Break handling | 2568 | * Break handling |
3035 | */ | 2569 | */ |
@@ -3220,113 +2754,6 @@ void do_SAK(struct tty_struct *tty) | |||
3220 | EXPORT_SYMBOL(do_SAK); | 2754 | EXPORT_SYMBOL(do_SAK); |
3221 | 2755 | ||
3222 | /** | 2756 | /** |
3223 | * flush_to_ldisc | ||
3224 | * @work: tty structure passed from work queue. | ||
3225 | * | ||
3226 | * This routine is called out of the software interrupt to flush data | ||
3227 | * from the buffer chain to the line discipline. | ||
3228 | * | ||
3229 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
3230 | * while invoking the line discipline receive_buf method. The | ||
3231 | * receive_buf method is single threaded for each tty instance. | ||
3232 | */ | ||
3233 | |||
3234 | static void flush_to_ldisc(struct work_struct *work) | ||
3235 | { | ||
3236 | struct tty_struct *tty = | ||
3237 | container_of(work, struct tty_struct, buf.work.work); | ||
3238 | unsigned long flags; | ||
3239 | struct tty_ldisc *disc; | ||
3240 | struct tty_buffer *tbuf, *head; | ||
3241 | char *char_buf; | ||
3242 | unsigned char *flag_buf; | ||
3243 | |||
3244 | disc = tty_ldisc_ref(tty); | ||
3245 | if (disc == NULL) /* !TTY_LDISC */ | ||
3246 | return; | ||
3247 | |||
3248 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3249 | /* So we know a flush is running */ | ||
3250 | set_bit(TTY_FLUSHING, &tty->flags); | ||
3251 | head = tty->buf.head; | ||
3252 | if (head != NULL) { | ||
3253 | tty->buf.head = NULL; | ||
3254 | for (;;) { | ||
3255 | int count = head->commit - head->read; | ||
3256 | if (!count) { | ||
3257 | if (head->next == NULL) | ||
3258 | break; | ||
3259 | tbuf = head; | ||
3260 | head = head->next; | ||
3261 | tty_buffer_free(tty, tbuf); | ||
3262 | continue; | ||
3263 | } | ||
3264 | /* Ldisc or user is trying to flush the buffers | ||
3265 | we are feeding to the ldisc, stop feeding the | ||
3266 | line discipline as we want to empty the queue */ | ||
3267 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | ||
3268 | break; | ||
3269 | if (!tty->receive_room) { | ||
3270 | schedule_delayed_work(&tty->buf.work, 1); | ||
3271 | break; | ||
3272 | } | ||
3273 | if (count > tty->receive_room) | ||
3274 | count = tty->receive_room; | ||
3275 | char_buf = head->char_buf_ptr + head->read; | ||
3276 | flag_buf = head->flag_buf_ptr + head->read; | ||
3277 | head->read += count; | ||
3278 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3279 | disc->ops->receive_buf(tty, char_buf, | ||
3280 | flag_buf, count); | ||
3281 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3282 | } | ||
3283 | /* Restore the queue head */ | ||
3284 | tty->buf.head = head; | ||
3285 | } | ||
3286 | /* We may have a deferred request to flush the input buffer, | ||
3287 | if so pull the chain under the lock and empty the queue */ | ||
3288 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | ||
3289 | __tty_buffer_flush(tty); | ||
3290 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | ||
3291 | wake_up(&tty->read_wait); | ||
3292 | } | ||
3293 | clear_bit(TTY_FLUSHING, &tty->flags); | ||
3294 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3295 | |||
3296 | tty_ldisc_deref(disc); | ||
3297 | } | ||
3298 | |||
3299 | /** | ||
3300 | * tty_flip_buffer_push - terminal | ||
3301 | * @tty: tty to push | ||
3302 | * | ||
3303 | * Queue a push of the terminal flip buffers to the line discipline. This | ||
3304 | * function must not be called from IRQ context if tty->low_latency is set. | ||
3305 | * | ||
3306 | * In the event of the queue being busy for flipping the work will be | ||
3307 | * held off and retried later. | ||
3308 | * | ||
3309 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
3310 | */ | ||
3311 | |||
3312 | void tty_flip_buffer_push(struct tty_struct *tty) | ||
3313 | { | ||
3314 | unsigned long flags; | ||
3315 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3316 | if (tty->buf.tail != NULL) | ||
3317 | tty->buf.tail->commit = tty->buf.tail->used; | ||
3318 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3319 | |||
3320 | if (tty->low_latency) | ||
3321 | flush_to_ldisc(&tty->buf.work.work); | ||
3322 | else | ||
3323 | schedule_delayed_work(&tty->buf.work, 1); | ||
3324 | } | ||
3325 | |||
3326 | EXPORT_SYMBOL(tty_flip_buffer_push); | ||
3327 | |||
3328 | |||
3329 | /** | ||
3330 | * initialize_tty_struct | 2757 | * initialize_tty_struct |
3331 | * @tty: tty to initialize | 2758 | * @tty: tty to initialize |
3332 | * | 2759 | * |
@@ -3336,9 +2763,11 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
3336 | * Locking: none - tty in question must not be exposed at this point | 2763 | * Locking: none - tty in question must not be exposed at this point |
3337 | */ | 2764 | */ |
3338 | 2765 | ||
3339 | static void initialize_tty_struct(struct tty_struct *tty) | 2766 | void initialize_tty_struct(struct tty_struct *tty, |
2767 | struct tty_driver *driver, int idx) | ||
3340 | { | 2768 | { |
3341 | memset(tty, 0, sizeof(struct tty_struct)); | 2769 | memset(tty, 0, sizeof(struct tty_struct)); |
2770 | kref_init(&tty->kref); | ||
3342 | tty->magic = TTY_MAGIC; | 2771 | tty->magic = TTY_MAGIC; |
3343 | tty_ldisc_init(tty); | 2772 | tty_ldisc_init(tty); |
3344 | tty->session = NULL; | 2773 | tty->session = NULL; |
@@ -3346,7 +2775,6 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3346 | tty->overrun_time = jiffies; | 2775 | tty->overrun_time = jiffies; |
3347 | tty->buf.head = tty->buf.tail = NULL; | 2776 | tty->buf.head = tty->buf.tail = NULL; |
3348 | tty_buffer_init(tty); | 2777 | tty_buffer_init(tty); |
3349 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | ||
3350 | mutex_init(&tty->termios_mutex); | 2778 | mutex_init(&tty->termios_mutex); |
3351 | init_waitqueue_head(&tty->write_wait); | 2779 | init_waitqueue_head(&tty->write_wait); |
3352 | init_waitqueue_head(&tty->read_wait); | 2780 | init_waitqueue_head(&tty->read_wait); |
@@ -3357,6 +2785,11 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3357 | spin_lock_init(&tty->ctrl_lock); | 2785 | spin_lock_init(&tty->ctrl_lock); |
3358 | INIT_LIST_HEAD(&tty->tty_files); | 2786 | INIT_LIST_HEAD(&tty->tty_files); |
3359 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 2787 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
2788 | |||
2789 | tty->driver = driver; | ||
2790 | tty->ops = driver->ops; | ||
2791 | tty->index = idx; | ||
2792 | tty_line_name(driver, idx, tty->name); | ||
3360 | } | 2793 | } |
3361 | 2794 | ||
3362 | /** | 2795 | /** |
@@ -3377,10 +2810,9 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch) | |||
3377 | return tty->ops->put_char(tty, ch); | 2810 | return tty->ops->put_char(tty, ch); |
3378 | return tty->ops->write(tty, &ch, 1); | 2811 | return tty->ops->write(tty, &ch, 1); |
3379 | } | 2812 | } |
3380 | |||
3381 | EXPORT_SYMBOL_GPL(tty_put_char); | 2813 | EXPORT_SYMBOL_GPL(tty_put_char); |
3382 | 2814 | ||
3383 | static struct class *tty_class; | 2815 | struct class *tty_class; |
3384 | 2816 | ||
3385 | /** | 2817 | /** |
3386 | * tty_register_device - register a tty device | 2818 | * tty_register_device - register a tty device |
@@ -3418,8 +2850,9 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3418 | else | 2850 | else |
3419 | tty_line_name(driver, index, name); | 2851 | tty_line_name(driver, index, name); |
3420 | 2852 | ||
3421 | return device_create_drvdata(tty_class, device, dev, NULL, name); | 2853 | return device_create(tty_class, device, dev, NULL, name); |
3422 | } | 2854 | } |
2855 | EXPORT_SYMBOL(tty_register_device); | ||
3423 | 2856 | ||
3424 | /** | 2857 | /** |
3425 | * tty_unregister_device - unregister a tty device | 2858 | * tty_unregister_device - unregister a tty device |
@@ -3437,8 +2870,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3437 | device_destroy(tty_class, | 2870 | device_destroy(tty_class, |
3438 | MKDEV(driver->major, driver->minor_start) + index); | 2871 | MKDEV(driver->major, driver->minor_start) + index); |
3439 | } | 2872 | } |
3440 | |||
3441 | EXPORT_SYMBOL(tty_register_device); | ||
3442 | EXPORT_SYMBOL(tty_unregister_device); | 2873 | EXPORT_SYMBOL(tty_unregister_device); |
3443 | 2874 | ||
3444 | struct tty_driver *alloc_tty_driver(int lines) | 2875 | struct tty_driver *alloc_tty_driver(int lines) |
@@ -3447,27 +2878,65 @@ struct tty_driver *alloc_tty_driver(int lines) | |||
3447 | 2878 | ||
3448 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 2879 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3449 | if (driver) { | 2880 | if (driver) { |
2881 | kref_init(&driver->kref); | ||
3450 | driver->magic = TTY_DRIVER_MAGIC; | 2882 | driver->magic = TTY_DRIVER_MAGIC; |
3451 | driver->num = lines; | 2883 | driver->num = lines; |
3452 | /* later we'll move allocation of tables here */ | 2884 | /* later we'll move allocation of tables here */ |
3453 | } | 2885 | } |
3454 | return driver; | 2886 | return driver; |
3455 | } | 2887 | } |
2888 | EXPORT_SYMBOL(alloc_tty_driver); | ||
3456 | 2889 | ||
3457 | void put_tty_driver(struct tty_driver *driver) | 2890 | static void destruct_tty_driver(struct kref *kref) |
3458 | { | 2891 | { |
2892 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | ||
2893 | int i; | ||
2894 | struct ktermios *tp; | ||
2895 | void *p; | ||
2896 | |||
2897 | if (driver->flags & TTY_DRIVER_INSTALLED) { | ||
2898 | /* | ||
2899 | * Free the termios and termios_locked structures because | ||
2900 | * we don't want to get memory leaks when modular tty | ||
2901 | * drivers are removed from the kernel. | ||
2902 | */ | ||
2903 | for (i = 0; i < driver->num; i++) { | ||
2904 | tp = driver->termios[i]; | ||
2905 | if (tp) { | ||
2906 | driver->termios[i] = NULL; | ||
2907 | kfree(tp); | ||
2908 | } | ||
2909 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | ||
2910 | tty_unregister_device(driver, i); | ||
2911 | } | ||
2912 | p = driver->ttys; | ||
2913 | proc_tty_unregister_driver(driver); | ||
2914 | driver->ttys = NULL; | ||
2915 | driver->termios = NULL; | ||
2916 | kfree(p); | ||
2917 | cdev_del(&driver->cdev); | ||
2918 | } | ||
3459 | kfree(driver); | 2919 | kfree(driver); |
3460 | } | 2920 | } |
3461 | 2921 | ||
2922 | void tty_driver_kref_put(struct tty_driver *driver) | ||
2923 | { | ||
2924 | kref_put(&driver->kref, destruct_tty_driver); | ||
2925 | } | ||
2926 | EXPORT_SYMBOL(tty_driver_kref_put); | ||
2927 | |||
3462 | void tty_set_operations(struct tty_driver *driver, | 2928 | void tty_set_operations(struct tty_driver *driver, |
3463 | const struct tty_operations *op) | 2929 | const struct tty_operations *op) |
3464 | { | 2930 | { |
3465 | driver->ops = op; | 2931 | driver->ops = op; |
3466 | }; | 2932 | }; |
2933 | EXPORT_SYMBOL(tty_set_operations); | ||
3467 | 2934 | ||
3468 | EXPORT_SYMBOL(alloc_tty_driver); | 2935 | void put_tty_driver(struct tty_driver *d) |
2936 | { | ||
2937 | tty_driver_kref_put(d); | ||
2938 | } | ||
3469 | EXPORT_SYMBOL(put_tty_driver); | 2939 | EXPORT_SYMBOL(put_tty_driver); |
3470 | EXPORT_SYMBOL(tty_set_operations); | ||
3471 | 2940 | ||
3472 | /* | 2941 | /* |
3473 | * Called by a tty driver to register itself. | 2942 | * Called by a tty driver to register itself. |
@@ -3479,11 +2948,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3479 | dev_t dev; | 2948 | dev_t dev; |
3480 | void **p = NULL; | 2949 | void **p = NULL; |
3481 | 2950 | ||
3482 | if (driver->flags & TTY_DRIVER_INSTALLED) | ||
3483 | return 0; | ||
3484 | |||
3485 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | 2951 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
3486 | p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); | 2952 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); |
3487 | if (!p) | 2953 | if (!p) |
3488 | return -ENOMEM; | 2954 | return -ENOMEM; |
3489 | } | 2955 | } |
@@ -3507,12 +2973,9 @@ int tty_register_driver(struct tty_driver *driver) | |||
3507 | if (p) { | 2973 | if (p) { |
3508 | driver->ttys = (struct tty_struct **)p; | 2974 | driver->ttys = (struct tty_struct **)p; |
3509 | driver->termios = (struct ktermios **)(p + driver->num); | 2975 | driver->termios = (struct ktermios **)(p + driver->num); |
3510 | driver->termios_locked = (struct ktermios **) | ||
3511 | (p + driver->num * 2); | ||
3512 | } else { | 2976 | } else { |
3513 | driver->ttys = NULL; | 2977 | driver->ttys = NULL; |
3514 | driver->termios = NULL; | 2978 | driver->termios = NULL; |
3515 | driver->termios_locked = NULL; | ||
3516 | } | 2979 | } |
3517 | 2980 | ||
3518 | cdev_init(&driver->cdev, &tty_fops); | 2981 | cdev_init(&driver->cdev, &tty_fops); |
@@ -3521,7 +2984,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3521 | if (error) { | 2984 | if (error) { |
3522 | unregister_chrdev_region(dev, driver->num); | 2985 | unregister_chrdev_region(dev, driver->num); |
3523 | driver->ttys = NULL; | 2986 | driver->ttys = NULL; |
3524 | driver->termios = driver->termios_locked = NULL; | 2987 | driver->termios = NULL; |
3525 | kfree(p); | 2988 | kfree(p); |
3526 | return error; | 2989 | return error; |
3527 | } | 2990 | } |
@@ -3535,6 +2998,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3535 | tty_register_device(driver, i, NULL); | 2998 | tty_register_device(driver, i, NULL); |
3536 | } | 2999 | } |
3537 | proc_tty_register_driver(driver); | 3000 | proc_tty_register_driver(driver); |
3001 | driver->flags |= TTY_DRIVER_INSTALLED; | ||
3538 | return 0; | 3002 | return 0; |
3539 | } | 3003 | } |
3540 | 3004 | ||
@@ -3545,46 +3009,19 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3545 | */ | 3009 | */ |
3546 | int tty_unregister_driver(struct tty_driver *driver) | 3010 | int tty_unregister_driver(struct tty_driver *driver) |
3547 | { | 3011 | { |
3548 | int i; | 3012 | #if 0 |
3549 | struct ktermios *tp; | 3013 | /* FIXME */ |
3550 | void *p; | ||
3551 | |||
3552 | if (driver->refcount) | 3014 | if (driver->refcount) |
3553 | return -EBUSY; | 3015 | return -EBUSY; |
3554 | 3016 | #endif | |
3555 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3017 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3556 | driver->num); | 3018 | driver->num); |
3557 | mutex_lock(&tty_mutex); | 3019 | mutex_lock(&tty_mutex); |
3558 | list_del(&driver->tty_drivers); | 3020 | list_del(&driver->tty_drivers); |
3559 | mutex_unlock(&tty_mutex); | 3021 | mutex_unlock(&tty_mutex); |
3560 | |||
3561 | /* | ||
3562 | * Free the termios and termios_locked structures because | ||
3563 | * we don't want to get memory leaks when modular tty | ||
3564 | * drivers are removed from the kernel. | ||
3565 | */ | ||
3566 | for (i = 0; i < driver->num; i++) { | ||
3567 | tp = driver->termios[i]; | ||
3568 | if (tp) { | ||
3569 | driver->termios[i] = NULL; | ||
3570 | kfree(tp); | ||
3571 | } | ||
3572 | tp = driver->termios_locked[i]; | ||
3573 | if (tp) { | ||
3574 | driver->termios_locked[i] = NULL; | ||
3575 | kfree(tp); | ||
3576 | } | ||
3577 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | ||
3578 | tty_unregister_device(driver, i); | ||
3579 | } | ||
3580 | p = driver->ttys; | ||
3581 | proc_tty_unregister_driver(driver); | ||
3582 | driver->ttys = NULL; | ||
3583 | driver->termios = driver->termios_locked = NULL; | ||
3584 | kfree(p); | ||
3585 | cdev_del(&driver->cdev); | ||
3586 | return 0; | 3022 | return 0; |
3587 | } | 3023 | } |
3024 | |||
3588 | EXPORT_SYMBOL(tty_unregister_driver); | 3025 | EXPORT_SYMBOL(tty_unregister_driver); |
3589 | 3026 | ||
3590 | dev_t tty_devnum(struct tty_struct *tty) | 3027 | dev_t tty_devnum(struct tty_struct *tty) |
@@ -3595,9 +3032,13 @@ EXPORT_SYMBOL(tty_devnum); | |||
3595 | 3032 | ||
3596 | void proc_clear_tty(struct task_struct *p) | 3033 | void proc_clear_tty(struct task_struct *p) |
3597 | { | 3034 | { |
3598 | spin_lock_irq(&p->sighand->siglock); | 3035 | unsigned long flags; |
3036 | struct tty_struct *tty; | ||
3037 | spin_lock_irqsave(&p->sighand->siglock, flags); | ||
3038 | tty = p->signal->tty; | ||
3599 | p->signal->tty = NULL; | 3039 | p->signal->tty = NULL; |
3600 | spin_unlock_irq(&p->sighand->siglock); | 3040 | spin_unlock_irqrestore(&p->sighand->siglock, flags); |
3041 | tty_kref_put(tty); | ||
3601 | } | 3042 | } |
3602 | 3043 | ||
3603 | /* Called under the sighand lock */ | 3044 | /* Called under the sighand lock */ |
@@ -3613,9 +3054,13 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3613 | tty->pgrp = get_pid(task_pgrp(tsk)); | 3054 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3614 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 3055 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
3615 | tty->session = get_pid(task_session(tsk)); | 3056 | tty->session = get_pid(task_session(tsk)); |
3057 | if (tsk->signal->tty) { | ||
3058 | printk(KERN_DEBUG "tty not NULL!!\n"); | ||
3059 | tty_kref_put(tsk->signal->tty); | ||
3060 | } | ||
3616 | } | 3061 | } |
3617 | put_pid(tsk->signal->tty_old_pgrp); | 3062 | put_pid(tsk->signal->tty_old_pgrp); |
3618 | tsk->signal->tty = tty; | 3063 | tsk->signal->tty = tty_kref_get(tty); |
3619 | tsk->signal->tty_old_pgrp = NULL; | 3064 | tsk->signal->tty_old_pgrp = NULL; |
3620 | } | 3065 | } |
3621 | 3066 | ||
@@ -3629,18 +3074,20 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3629 | struct tty_struct *get_current_tty(void) | 3074 | struct tty_struct *get_current_tty(void) |
3630 | { | 3075 | { |
3631 | struct tty_struct *tty; | 3076 | struct tty_struct *tty; |
3632 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | 3077 | unsigned long flags; |
3633 | tty = current->signal->tty; | 3078 | |
3634 | /* | 3079 | spin_lock_irqsave(¤t->sighand->siglock, flags); |
3635 | * session->tty can be changed/cleared from under us, make sure we | 3080 | tty = tty_kref_get(current->signal->tty); |
3636 | * issue the load. The obtained pointer, when not NULL, is valid as | 3081 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
3637 | * long as we hold tty_mutex. | ||
3638 | */ | ||
3639 | barrier(); | ||
3640 | return tty; | 3082 | return tty; |
3641 | } | 3083 | } |
3642 | EXPORT_SYMBOL_GPL(get_current_tty); | 3084 | EXPORT_SYMBOL_GPL(get_current_tty); |
3643 | 3085 | ||
3086 | void tty_default_fops(struct file_operations *fops) | ||
3087 | { | ||
3088 | *fops = tty_fops; | ||
3089 | } | ||
3090 | |||
3644 | /* | 3091 | /* |
3645 | * Initialize the console device. This is called *early*, so | 3092 | * Initialize the console device. This is called *early*, so |
3646 | * we can't necessarily depend on lots of kernel help here. | 3093 | * we can't necessarily depend on lots of kernel help here. |
@@ -3678,12 +3125,6 @@ postcore_initcall(tty_class_init); | |||
3678 | /* 3/2004 jmc: why do these devices exist? */ | 3125 | /* 3/2004 jmc: why do these devices exist? */ |
3679 | 3126 | ||
3680 | static struct cdev tty_cdev, console_cdev; | 3127 | static struct cdev tty_cdev, console_cdev; |
3681 | #ifdef CONFIG_UNIX98_PTYS | ||
3682 | static struct cdev ptmx_cdev; | ||
3683 | #endif | ||
3684 | #ifdef CONFIG_VT | ||
3685 | static struct cdev vc0_cdev; | ||
3686 | #endif | ||
3687 | 3128 | ||
3688 | /* | 3129 | /* |
3689 | * Ok, now we can initialize the rest of the tty devices and can count | 3130 | * Ok, now we can initialize the rest of the tty devices and can count |
@@ -3695,32 +3136,18 @@ static int __init tty_init(void) | |||
3695 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3136 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3696 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3137 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3697 | panic("Couldn't register /dev/tty driver\n"); | 3138 | panic("Couldn't register /dev/tty driver\n"); |
3698 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, | 3139 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, |
3699 | "tty"); | 3140 | "tty"); |
3700 | 3141 | ||
3701 | cdev_init(&console_cdev, &console_fops); | 3142 | cdev_init(&console_cdev, &console_fops); |
3702 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3143 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3703 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3144 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3704 | panic("Couldn't register /dev/console driver\n"); | 3145 | panic("Couldn't register /dev/console driver\n"); |
3705 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, | 3146 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
3706 | "console"); | 3147 | "console"); |
3707 | 3148 | ||
3708 | #ifdef CONFIG_UNIX98_PTYS | ||
3709 | cdev_init(&ptmx_cdev, &ptmx_fops); | ||
3710 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | ||
3711 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | ||
3712 | panic("Couldn't register /dev/ptmx driver\n"); | ||
3713 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | ||
3714 | #endif | ||
3715 | |||
3716 | #ifdef CONFIG_VT | 3149 | #ifdef CONFIG_VT |
3717 | cdev_init(&vc0_cdev, &console_fops); | 3150 | vty_init(&console_fops); |
3718 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
3719 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
3720 | panic("Couldn't register /dev/tty0 driver\n"); | ||
3721 | device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
3722 | |||
3723 | vty_init(); | ||
3724 | #endif | 3151 | #endif |
3725 | return 0; | 3152 | return 0; |
3726 | } | 3153 | } |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index bf34e4597421..a408c8e487ec 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -40,6 +40,15 @@ | |||
40 | #define TERMIOS_OLD 8 | 40 | #define TERMIOS_OLD 8 |
41 | 41 | ||
42 | 42 | ||
43 | /** | ||
44 | * tty_chars_in_buffer - characters pending | ||
45 | * @tty: terminal | ||
46 | * | ||
47 | * Return the number of bytes of data in the device private | ||
48 | * output queue. If no private method is supplied there is assumed | ||
49 | * to be no queue on the device. | ||
50 | */ | ||
51 | |||
43 | int tty_chars_in_buffer(struct tty_struct *tty) | 52 | int tty_chars_in_buffer(struct tty_struct *tty) |
44 | { | 53 | { |
45 | if (tty->ops->chars_in_buffer) | 54 | if (tty->ops->chars_in_buffer) |
@@ -47,26 +56,49 @@ int tty_chars_in_buffer(struct tty_struct *tty) | |||
47 | else | 56 | else |
48 | return 0; | 57 | return 0; |
49 | } | 58 | } |
50 | |||
51 | EXPORT_SYMBOL(tty_chars_in_buffer); | 59 | EXPORT_SYMBOL(tty_chars_in_buffer); |
52 | 60 | ||
61 | /** | ||
62 | * tty_write_room - write queue space | ||
63 | * @tty: terminal | ||
64 | * | ||
65 | * Return the number of bytes that can be queued to this device | ||
66 | * at the present time. The result should be treated as a guarantee | ||
67 | * and the driver cannot offer a value it later shrinks by more than | ||
68 | * the number of bytes written. If no method is provided 2K is always | ||
69 | * returned and data may be lost as there will be no flow control. | ||
70 | */ | ||
71 | |||
53 | int tty_write_room(struct tty_struct *tty) | 72 | int tty_write_room(struct tty_struct *tty) |
54 | { | 73 | { |
55 | if (tty->ops->write_room) | 74 | if (tty->ops->write_room) |
56 | return tty->ops->write_room(tty); | 75 | return tty->ops->write_room(tty); |
57 | return 2048; | 76 | return 2048; |
58 | } | 77 | } |
59 | |||
60 | EXPORT_SYMBOL(tty_write_room); | 78 | EXPORT_SYMBOL(tty_write_room); |
61 | 79 | ||
80 | /** | ||
81 | * tty_driver_flush_buffer - discard internal buffer | ||
82 | * @tty: terminal | ||
83 | * | ||
84 | * Discard the internal output buffer for this device. If no method | ||
85 | * is provided then either the buffer cannot be hardware flushed or | ||
86 | * there is no buffer driver side. | ||
87 | */ | ||
62 | void tty_driver_flush_buffer(struct tty_struct *tty) | 88 | void tty_driver_flush_buffer(struct tty_struct *tty) |
63 | { | 89 | { |
64 | if (tty->ops->flush_buffer) | 90 | if (tty->ops->flush_buffer) |
65 | tty->ops->flush_buffer(tty); | 91 | tty->ops->flush_buffer(tty); |
66 | } | 92 | } |
67 | |||
68 | EXPORT_SYMBOL(tty_driver_flush_buffer); | 93 | EXPORT_SYMBOL(tty_driver_flush_buffer); |
69 | 94 | ||
95 | /** | ||
96 | * tty_throttle - flow control | ||
97 | * @tty: terminal | ||
98 | * | ||
99 | * Indicate that a tty should stop transmitting data down the stack. | ||
100 | */ | ||
101 | |||
70 | void tty_throttle(struct tty_struct *tty) | 102 | void tty_throttle(struct tty_struct *tty) |
71 | { | 103 | { |
72 | /* check TTY_THROTTLED first so it indicates our state */ | 104 | /* check TTY_THROTTLED first so it indicates our state */ |
@@ -76,6 +108,13 @@ void tty_throttle(struct tty_struct *tty) | |||
76 | } | 108 | } |
77 | EXPORT_SYMBOL(tty_throttle); | 109 | EXPORT_SYMBOL(tty_throttle); |
78 | 110 | ||
111 | /** | ||
112 | * tty_unthrottle - flow control | ||
113 | * @tty: terminal | ||
114 | * | ||
115 | * Indicate that a tty may continue transmitting data down the stack. | ||
116 | */ | ||
117 | |||
79 | void tty_unthrottle(struct tty_struct *tty) | 118 | void tty_unthrottle(struct tty_struct *tty) |
80 | { | 119 | { |
81 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 120 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && |
@@ -112,6 +151,11 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout) | |||
112 | } | 151 | } |
113 | EXPORT_SYMBOL(tty_wait_until_sent); | 152 | EXPORT_SYMBOL(tty_wait_until_sent); |
114 | 153 | ||
154 | |||
155 | /* | ||
156 | * Termios Helper Methods | ||
157 | */ | ||
158 | |||
115 | static void unset_locked_termios(struct ktermios *termios, | 159 | static void unset_locked_termios(struct ktermios *termios, |
116 | struct ktermios *old, | 160 | struct ktermios *old, |
117 | struct ktermios *locked) | 161 | struct ktermios *locked) |
@@ -346,6 +390,16 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, | |||
346 | } | 390 | } |
347 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | 391 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); |
348 | 392 | ||
393 | /** | ||
394 | * tty_encode_baud_rate - set baud rate of the tty | ||
395 | * @ibaud: input baud rate | ||
396 | * @obad: output baud rate | ||
397 | * | ||
398 | * Update the current termios data for the tty with the new speed | ||
399 | * settings. The caller must hold the termios_mutex for the tty in | ||
400 | * question. | ||
401 | */ | ||
402 | |||
349 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 403 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) |
350 | { | 404 | { |
351 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); | 405 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); |
@@ -430,12 +484,11 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
430 | * is a bit of layering violation here with n_tty in terms of the | 484 | * is a bit of layering violation here with n_tty in terms of the |
431 | * internal knowledge of this function. | 485 | * internal knowledge of this function. |
432 | * | 486 | * |
433 | * Locking: termios_sem | 487 | * Locking: termios_mutex |
434 | */ | 488 | */ |
435 | 489 | ||
436 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 490 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) |
437 | { | 491 | { |
438 | int canon_change; | ||
439 | struct ktermios old_termios; | 492 | struct ktermios old_termios; |
440 | struct tty_ldisc *ld; | 493 | struct tty_ldisc *ld; |
441 | unsigned long flags; | 494 | unsigned long flags; |
@@ -451,18 +504,6 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
451 | old_termios = *tty->termios; | 504 | old_termios = *tty->termios; |
452 | *tty->termios = *new_termios; | 505 | *tty->termios = *new_termios; |
453 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 506 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); |
454 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; | ||
455 | if (canon_change) { | ||
456 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | ||
457 | tty->canon_head = tty->read_tail; | ||
458 | tty->canon_data = 0; | ||
459 | tty->erasing = 0; | ||
460 | } | ||
461 | |||
462 | /* This bit should be in the ldisc code */ | ||
463 | if (canon_change && !L_ICANON(tty) && tty->read_cnt) | ||
464 | /* Get characters left over from canonical mode. */ | ||
465 | wake_up_interruptible(&tty->read_wait); | ||
466 | 507 | ||
467 | /* See if packet mode change of state. */ | 508 | /* See if packet mode change of state. */ |
468 | if (tty->link && tty->link->packet) { | 509 | if (tty->link && tty->link->packet) { |
@@ -508,7 +549,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
508 | * functions before using change_termios to do the actual changes. | 549 | * functions before using change_termios to do the actual changes. |
509 | * | 550 | * |
510 | * Locking: | 551 | * Locking: |
511 | * Called functions take ldisc and termios_sem locks | 552 | * Called functions take ldisc and termios_mutex locks |
512 | */ | 553 | */ |
513 | 554 | ||
514 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | 555 | static int set_termios(struct tty_struct *tty, void __user *arg, int opt) |
@@ -579,25 +620,51 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio) | |||
579 | return 0; | 620 | return 0; |
580 | } | 621 | } |
581 | 622 | ||
582 | static unsigned long inq_canon(struct tty_struct *tty) | 623 | |
624 | #ifdef TCGETX | ||
625 | |||
626 | /** | ||
627 | * set_termiox - set termiox fields if possible | ||
628 | * @tty: terminal | ||
629 | * @arg: termiox structure from user | ||
630 | * @opt: option flags for ioctl type | ||
631 | * | ||
632 | * Implement the device calling points for the SYS5 termiox ioctl | ||
633 | * interface in Linux | ||
634 | */ | ||
635 | |||
636 | static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | ||
583 | { | 637 | { |
584 | int nr, head, tail; | 638 | struct termiox tnew; |
639 | struct tty_ldisc *ld; | ||
585 | 640 | ||
586 | if (!tty->canon_data || !tty->read_buf) | 641 | if (tty->termiox == NULL) |
587 | return 0; | 642 | return -EINVAL; |
588 | head = tty->canon_head; | 643 | if (copy_from_user(&tnew, arg, sizeof(struct termiox))) |
589 | tail = tty->read_tail; | 644 | return -EFAULT; |
590 | nr = (head - tail) & (N_TTY_BUF_SIZE-1); | 645 | |
591 | /* Skip EOF-chars.. */ | 646 | ld = tty_ldisc_ref(tty); |
592 | while (head != tail) { | 647 | if (ld != NULL) { |
593 | if (test_bit(tail, tty->read_flags) && | 648 | if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
594 | tty->read_buf[tail] == __DISABLED_CHAR) | 649 | ld->ops->flush_buffer(tty); |
595 | nr--; | 650 | tty_ldisc_deref(ld); |
596 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | ||
597 | } | 651 | } |
598 | return nr; | 652 | if (opt & TERMIOS_WAIT) { |
653 | tty_wait_until_sent(tty, 0); | ||
654 | if (signal_pending(current)) | ||
655 | return -EINTR; | ||
656 | } | ||
657 | |||
658 | mutex_lock(&tty->termios_mutex); | ||
659 | if (tty->ops->set_termiox) | ||
660 | tty->ops->set_termiox(tty, &tnew); | ||
661 | mutex_unlock(&tty->termios_mutex); | ||
662 | return 0; | ||
599 | } | 663 | } |
600 | 664 | ||
665 | #endif | ||
666 | |||
667 | |||
601 | #ifdef TIOCGETP | 668 | #ifdef TIOCGETP |
602 | /* | 669 | /* |
603 | * These are deprecated, but there is limited support.. | 670 | * These are deprecated, but there is limited support.. |
@@ -671,7 +738,7 @@ static void set_sgflags(struct ktermios *termios, int flags) | |||
671 | * Updates a terminal from the legacy BSD style terminal information | 738 | * Updates a terminal from the legacy BSD style terminal information |
672 | * structure. | 739 | * structure. |
673 | * | 740 | * |
674 | * Locking: termios_sem | 741 | * Locking: termios_mutex |
675 | */ | 742 | */ |
676 | 743 | ||
677 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | 744 | static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
@@ -849,6 +916,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
849 | { | 916 | { |
850 | struct tty_struct *real_tty; | 917 | struct tty_struct *real_tty; |
851 | void __user *p = (void __user *)arg; | 918 | void __user *p = (void __user *)arg; |
919 | int ret = 0; | ||
852 | 920 | ||
853 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 921 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
854 | tty->driver->subtype == PTY_TYPE_MASTER) | 922 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -884,18 +952,24 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
884 | return set_termios(real_tty, p, TERMIOS_OLD); | 952 | return set_termios(real_tty, p, TERMIOS_OLD); |
885 | #ifndef TCGETS2 | 953 | #ifndef TCGETS2 |
886 | case TCGETS: | 954 | case TCGETS: |
955 | mutex_lock(&real_tty->termios_mutex); | ||
887 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) | 956 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) |
888 | return -EFAULT; | 957 | ret = -EFAULT; |
889 | return 0; | 958 | mutex_unlock(&real_tty->termios_mutex); |
959 | return ret; | ||
890 | #else | 960 | #else |
891 | case TCGETS: | 961 | case TCGETS: |
962 | mutex_lock(&real_tty->termios_mutex); | ||
892 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) | 963 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) |
893 | return -EFAULT; | 964 | ret = -EFAULT; |
894 | return 0; | 965 | mutex_unlock(&real_tty->termios_mutex); |
966 | return ret; | ||
895 | case TCGETS2: | 967 | case TCGETS2: |
968 | mutex_lock(&real_tty->termios_mutex); | ||
896 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) | 969 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) |
897 | return -EFAULT; | 970 | ret = -EFAULT; |
898 | return 0; | 971 | mutex_unlock(&real_tty->termios_mutex); |
972 | return ret; | ||
899 | case TCSETSF2: | 973 | case TCSETSF2: |
900 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); | 974 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); |
901 | case TCSETSW2: | 975 | case TCSETSW2: |
@@ -913,34 +987,59 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
913 | return set_termios(real_tty, p, TERMIOS_TERMIO); | 987 | return set_termios(real_tty, p, TERMIOS_TERMIO); |
914 | #ifndef TCGETS2 | 988 | #ifndef TCGETS2 |
915 | case TIOCGLCKTRMIOS: | 989 | case TIOCGLCKTRMIOS: |
990 | mutex_lock(&real_tty->termios_mutex); | ||
916 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) | 991 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) |
917 | return -EFAULT; | 992 | ret = -EFAULT; |
918 | return 0; | 993 | mutex_unlock(&real_tty->termios_mutex); |
994 | return ret; | ||
919 | case TIOCSLCKTRMIOS: | 995 | case TIOCSLCKTRMIOS: |
920 | if (!capable(CAP_SYS_ADMIN)) | 996 | if (!capable(CAP_SYS_ADMIN)) |
921 | return -EPERM; | 997 | return -EPERM; |
998 | mutex_lock(&real_tty->termios_mutex); | ||
922 | if (user_termios_to_kernel_termios(real_tty->termios_locked, | 999 | if (user_termios_to_kernel_termios(real_tty->termios_locked, |
923 | (struct termios __user *) arg)) | 1000 | (struct termios __user *) arg)) |
924 | return -EFAULT; | 1001 | ret = -EFAULT; |
925 | return 0; | 1002 | mutex_unlock(&real_tty->termios_mutex); |
1003 | return ret; | ||
926 | #else | 1004 | #else |
927 | case TIOCGLCKTRMIOS: | 1005 | case TIOCGLCKTRMIOS: |
1006 | mutex_lock(&real_tty->termios_mutex); | ||
928 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) | 1007 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) |
929 | return -EFAULT; | 1008 | ret = -EFAULT; |
930 | return 0; | 1009 | mutex_unlock(&real_tty->termios_mutex); |
1010 | return ret; | ||
931 | case TIOCSLCKTRMIOS: | 1011 | case TIOCSLCKTRMIOS: |
932 | if (!capable(CAP_SYS_ADMIN)) | 1012 | if (!capable(CAP_SYS_ADMIN)) |
933 | return -EPERM; | 1013 | ret = -EPERM; |
1014 | mutex_lock(&real_tty->termios_mutex); | ||
934 | if (user_termios_to_kernel_termios_1(real_tty->termios_locked, | 1015 | if (user_termios_to_kernel_termios_1(real_tty->termios_locked, |
935 | (struct termios __user *) arg)) | 1016 | (struct termios __user *) arg)) |
936 | return -EFAULT; | 1017 | ret = -EFAULT; |
937 | return 0; | 1018 | mutex_unlock(&real_tty->termios_mutex); |
1019 | return ret; | ||
938 | #endif | 1020 | #endif |
1021 | #ifdef TCGETX | ||
1022 | case TCGETX: | ||
1023 | if (real_tty->termiox == NULL) | ||
1024 | return -EINVAL; | ||
1025 | mutex_lock(&real_tty->termios_mutex); | ||
1026 | if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox))) | ||
1027 | ret = -EFAULT; | ||
1028 | mutex_unlock(&real_tty->termios_mutex); | ||
1029 | return ret; | ||
1030 | case TCSETX: | ||
1031 | return set_termiox(real_tty, p, 0); | ||
1032 | case TCSETXW: | ||
1033 | return set_termiox(real_tty, p, TERMIOS_WAIT); | ||
1034 | case TCSETXF: | ||
1035 | return set_termiox(real_tty, p, TERMIOS_FLUSH); | ||
1036 | #endif | ||
939 | case TIOCGSOFTCAR: | 1037 | case TIOCGSOFTCAR: |
940 | /* FIXME: for correctness we may need to take the termios | 1038 | mutex_lock(&real_tty->termios_mutex); |
941 | lock here - review */ | 1039 | ret = put_user(C_CLOCAL(real_tty) ? 1 : 0, |
942 | return put_user(C_CLOCAL(real_tty) ? 1 : 0, | ||
943 | (int __user *)arg); | 1040 | (int __user *)arg); |
1041 | mutex_unlock(&real_tty->termios_mutex); | ||
1042 | return ret; | ||
944 | case TIOCSSOFTCAR: | 1043 | case TIOCSSOFTCAR: |
945 | if (get_user(arg, (unsigned int __user *) arg)) | 1044 | if (get_user(arg, (unsigned int __user *) arg)) |
946 | return -EFAULT; | 1045 | return -EFAULT; |
@@ -980,7 +1079,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
980 | } | 1079 | } |
981 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1080 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
982 | 1081 | ||
983 | int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 1082 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
984 | unsigned int cmd, unsigned long arg) | 1083 | unsigned int cmd, unsigned long arg) |
985 | { | 1084 | { |
986 | unsigned long flags; | 1085 | unsigned long flags; |
@@ -1018,13 +1117,6 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1018 | return 0; | 1117 | return 0; |
1019 | case TCFLSH: | 1118 | case TCFLSH: |
1020 | return tty_perform_flush(tty, arg); | 1119 | return tty_perform_flush(tty, arg); |
1021 | case TIOCOUTQ: | ||
1022 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1023 | case TIOCINQ: | ||
1024 | retval = tty->read_cnt; | ||
1025 | if (L_ICANON(tty)) | ||
1026 | retval = inq_canon(tty); | ||
1027 | return put_user(retval, (unsigned int __user *) arg); | ||
1028 | case TIOCPKT: | 1120 | case TIOCPKT: |
1029 | { | 1121 | { |
1030 | int pktmode; | 1122 | int pktmode; |
@@ -1050,4 +1142,4 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1050 | return tty_mode_ioctl(tty, file, cmd, arg); | 1142 | return tty_mode_ioctl(tty, file, cmd, arg); |
1051 | } | 1143 | } |
1052 | } | 1144 | } |
1053 | EXPORT_SYMBOL(n_tty_ioctl); | 1145 | EXPORT_SYMBOL(n_tty_ioctl_helper); |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c new file mode 100644 index 000000000000..553b0e9d8d17 --- /dev/null +++ b/drivers/char/tty_port.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Tty port functions | ||
3 | */ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/tty.h> | ||
8 | #include <linux/tty_driver.h> | ||
9 | #include <linux/tty_flip.h> | ||
10 | #include <linux/timer.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | void tty_port_init(struct tty_port *port) | ||
21 | { | ||
22 | memset(port, 0, sizeof(*port)); | ||
23 | init_waitqueue_head(&port->open_wait); | ||
24 | init_waitqueue_head(&port->close_wait); | ||
25 | mutex_init(&port->mutex); | ||
26 | spin_lock_init(&port->lock); | ||
27 | port->close_delay = (50 * HZ) / 100; | ||
28 | port->closing_wait = (3000 * HZ) / 100; | ||
29 | } | ||
30 | EXPORT_SYMBOL(tty_port_init); | ||
31 | |||
32 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
33 | { | ||
34 | /* We may sleep in get_zeroed_page() */ | ||
35 | mutex_lock(&port->mutex); | ||
36 | if (port->xmit_buf == NULL) | ||
37 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
38 | mutex_unlock(&port->mutex); | ||
39 | if (port->xmit_buf == NULL) | ||
40 | return -ENOMEM; | ||
41 | return 0; | ||
42 | } | ||
43 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
44 | |||
45 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
46 | { | ||
47 | mutex_lock(&port->mutex); | ||
48 | if (port->xmit_buf != NULL) { | ||
49 | free_page((unsigned long)port->xmit_buf); | ||
50 | port->xmit_buf = NULL; | ||
51 | } | ||
52 | mutex_unlock(&port->mutex); | ||
53 | } | ||
54 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
55 | |||
56 | |||
57 | /** | ||
58 | * tty_port_tty_get - get a tty reference | ||
59 | * @port: tty port | ||
60 | * | ||
61 | * Return a refcount protected tty instance or NULL if the port is not | ||
62 | * associated with a tty (eg due to close or hangup) | ||
63 | */ | ||
64 | |||
65 | struct tty_struct *tty_port_tty_get(struct tty_port *port) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | struct tty_struct *tty; | ||
69 | |||
70 | spin_lock_irqsave(&port->lock, flags); | ||
71 | tty = tty_kref_get(port->tty); | ||
72 | spin_unlock_irqrestore(&port->lock, flags); | ||
73 | return tty; | ||
74 | } | ||
75 | EXPORT_SYMBOL(tty_port_tty_get); | ||
76 | |||
77 | /** | ||
78 | * tty_port_tty_set - set the tty of a port | ||
79 | * @port: tty port | ||
80 | * @tty: the tty | ||
81 | * | ||
82 | * Associate the port and tty pair. Manages any internal refcounts. | ||
83 | * Pass NULL to deassociate a port | ||
84 | */ | ||
85 | |||
86 | void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&port->lock, flags); | ||
91 | if (port->tty) | ||
92 | tty_kref_put(port->tty); | ||
93 | port->tty = tty; | ||
94 | spin_unlock_irqrestore(&port->lock, flags); | ||
95 | } | ||
96 | EXPORT_SYMBOL(tty_port_tty_set); | ||
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index c2ae52dd53d1..4f3b3f95fc42 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -481,10 +481,10 @@ static struct class *vc_class; | |||
481 | 481 | ||
482 | void vcs_make_sysfs(struct tty_struct *tty) | 482 | void vcs_make_sysfs(struct tty_struct *tty) |
483 | { | 483 | { |
484 | device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), | 484 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL, |
485 | NULL, "vcs%u", tty->index + 1); | 485 | "vcs%u", tty->index + 1); |
486 | device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), | 486 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL, |
487 | NULL, "vcsa%u", tty->index + 1); | 487 | "vcsa%u", tty->index + 1); |
488 | } | 488 | } |
489 | 489 | ||
490 | void vcs_remove_sysfs(struct tty_struct *tty) | 490 | void vcs_remove_sysfs(struct tty_struct *tty) |
@@ -499,7 +499,7 @@ int __init vcs_init(void) | |||
499 | panic("unable to get major %d for vcs device", VCS_MAJOR); | 499 | panic("unable to get major %d for vcs device", VCS_MAJOR); |
500 | vc_class = class_create(THIS_MODULE, "vc"); | 500 | vc_class = class_create(THIS_MODULE, "vc"); |
501 | 501 | ||
502 | device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); | 502 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); |
503 | device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); | 503 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); |
504 | return 0; | 504 | return 0; |
505 | } | 505 | } |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 7a70a40ad639..ffc9254f7e02 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
886 | state[i].cur_part = 0; | 886 | state[i].cur_part = 0; |
887 | for (j = 0; j < MAX_PARTITIONS; ++j) | 887 | for (j = 0; j < MAX_PARTITIONS; ++j) |
888 | state[i].part_stat_rwi[j] = VIOT_IDLE; | 888 | state[i].part_stat_rwi[j] = VIOT_IDLE; |
889 | device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), | 889 | device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, |
890 | NULL, "iseries!vt%d", i); | 890 | "iseries!vt%d", i); |
891 | device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), | 891 | device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL, |
892 | NULL, "iseries!nvt%d", i); | 892 | "iseries!nvt%d", i); |
893 | printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " | 893 | printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " |
894 | "resource %10.10s type %4.4s, model %3.3s\n", | 894 | "resource %10.10s type %4.4s, model %3.3s\n", |
895 | i, viotape_unitinfo[i].rsrcname, | 895 | i, viotape_unitinfo[i].rsrcname, |
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index ffe9b4e3072e..54c837288d19 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev) | |||
641 | } | 641 | } |
642 | 642 | ||
643 | irq = platform_get_irq(dev, 0); | 643 | irq = platform_get_irq(dev, 0); |
644 | if (irq < 0 || irq >= NR_IRQS) | 644 | if (irq < 0 || irq >= nr_irqs) |
645 | return -EBUSY; | 645 | return -EBUSY; |
646 | 646 | ||
647 | return cascade_irq(irq, giu_get_irq); | 647 | return cascade_irq(irq, giu_get_irq); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 60359c360912..d8f83e26e4a4 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -59,7 +59,7 @@ | |||
59 | * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998 | 59 | * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998 |
60 | * | 60 | * |
61 | * Removed old-style timers, introduced console_timer, made timer | 61 | * Removed old-style timers, introduced console_timer, made timer |
62 | * deletion SMP-safe. 17Jun00, Andrew Morton <andrewm@uow.edu.au> | 62 | * deletion SMP-safe. 17Jun00, Andrew Morton |
63 | * | 63 | * |
64 | * Removed console_lock, enabled interrupts across all console operations | 64 | * Removed console_lock, enabled interrupts across all console operations |
65 | * 13 March 2001, Andrew Morton | 65 | * 13 March 2001, Andrew Morton |
@@ -100,10 +100,10 @@ | |||
100 | #include <linux/font.h> | 100 | #include <linux/font.h> |
101 | #include <linux/bitops.h> | 101 | #include <linux/bitops.h> |
102 | #include <linux/notifier.h> | 102 | #include <linux/notifier.h> |
103 | 103 | #include <linux/device.h> | |
104 | #include <asm/io.h> | 104 | #include <linux/io.h> |
105 | #include <asm/system.h> | 105 | #include <asm/system.h> |
106 | #include <asm/uaccess.h> | 106 | #include <linux/uaccess.h> |
107 | 107 | ||
108 | #define MAX_NR_CON_DRIVER 16 | 108 | #define MAX_NR_CON_DRIVER 16 |
109 | 109 | ||
@@ -301,7 +301,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
301 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 301 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
302 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); | 302 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); |
303 | scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); | 303 | scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); |
304 | scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_scrl_erase_char, | 304 | scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, |
305 | vc->vc_size_row * nr); | 305 | vc->vc_size_row * nr); |
306 | } | 306 | } |
307 | 307 | ||
@@ -319,7 +319,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
319 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 319 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
320 | step = vc->vc_cols * nr; | 320 | step = vc->vc_cols * nr; |
321 | scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); | 321 | scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); |
322 | scr_memsetw(s, vc->vc_scrl_erase_char, 2 * step); | 322 | scr_memsetw(s, vc->vc_video_erase_char, 2 * step); |
323 | } | 323 | } |
324 | 324 | ||
325 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) | 325 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) |
@@ -434,7 +434,6 @@ static void update_attr(struct vc_data *vc) | |||
434 | vc->vc_blink, vc->vc_underline, | 434 | vc->vc_blink, vc->vc_underline, |
435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); | 435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); |
436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; | 436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; |
437 | vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, vc->vc_decscnm, false) << 8) | ' '; | ||
438 | } | 437 | } |
439 | 438 | ||
440 | /* Note: inverting the screen twice should revert to the original state */ | 439 | /* Note: inverting the screen twice should revert to the original state */ |
@@ -2136,27 +2135,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2136 | release_console_sem(); | 2135 | release_console_sem(); |
2137 | return 0; | 2136 | return 0; |
2138 | } | 2137 | } |
2139 | release_console_sem(); | ||
2140 | |||
2141 | orig_buf = buf; | 2138 | orig_buf = buf; |
2142 | orig_count = count; | 2139 | orig_count = count; |
2143 | 2140 | ||
2144 | /* At this point 'buf' is guaranteed to be a kernel buffer | ||
2145 | * and therefore no access to userspace (and therefore sleeping) | ||
2146 | * will be needed. The con_buf_mtx serializes all tty based | ||
2147 | * console rendering and vcs write/read operations. We hold | ||
2148 | * the console spinlock during the entire write. | ||
2149 | */ | ||
2150 | |||
2151 | acquire_console_sem(); | ||
2152 | |||
2153 | vc = tty->driver_data; | ||
2154 | if (vc == NULL) { | ||
2155 | printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n"); | ||
2156 | release_console_sem(); | ||
2157 | goto out; | ||
2158 | } | ||
2159 | |||
2160 | himask = vc->vc_hi_font_mask; | 2141 | himask = vc->vc_hi_font_mask; |
2161 | charmask = himask ? 0x1ff : 0xff; | 2142 | charmask = himask ? 0x1ff : 0xff; |
2162 | 2143 | ||
@@ -2370,8 +2351,6 @@ rescan_last_byte: | |||
2370 | FLUSH | 2351 | FLUSH |
2371 | console_conditional_schedule(); | 2352 | console_conditional_schedule(); |
2372 | release_console_sem(); | 2353 | release_console_sem(); |
2373 | |||
2374 | out: | ||
2375 | notify_update(vc); | 2354 | notify_update(vc); |
2376 | return n; | 2355 | return n; |
2377 | #undef FLUSH | 2356 | #undef FLUSH |
@@ -2583,8 +2562,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2583 | int lines; | 2562 | int lines; |
2584 | int ret; | 2563 | int ret; |
2585 | 2564 | ||
2586 | if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) | ||
2587 | return -EINVAL; | ||
2588 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) | 2565 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) |
2589 | return -EPERM; | 2566 | return -EPERM; |
2590 | if (get_user(type, p)) | 2567 | if (get_user(type, p)) |
@@ -2778,6 +2755,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2778 | ret = vc_allocate(currcons); | 2755 | ret = vc_allocate(currcons); |
2779 | if (ret == 0) { | 2756 | if (ret == 0) { |
2780 | struct vc_data *vc = vc_cons[currcons].d; | 2757 | struct vc_data *vc = vc_cons[currcons].d; |
2758 | |||
2759 | /* Still being freed */ | ||
2760 | if (vc->vc_tty) { | ||
2761 | release_console_sem(); | ||
2762 | return -ERESTARTSYS; | ||
2763 | } | ||
2781 | tty->driver_data = vc; | 2764 | tty->driver_data = vc; |
2782 | vc->vc_tty = tty; | 2765 | vc->vc_tty = tty; |
2783 | 2766 | ||
@@ -2798,34 +2781,20 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2798 | return ret; | 2781 | return ret; |
2799 | } | 2782 | } |
2800 | 2783 | ||
2801 | /* | ||
2802 | * We take tty_mutex in here to prevent another thread from coming in via init_dev | ||
2803 | * and taking a ref against the tty while we're in the process of forgetting | ||
2804 | * about it and cleaning things up. | ||
2805 | * | ||
2806 | * This is because vcs_remove_sysfs() can sleep and will drop the BKL. | ||
2807 | */ | ||
2808 | static void con_close(struct tty_struct *tty, struct file *filp) | 2784 | static void con_close(struct tty_struct *tty, struct file *filp) |
2809 | { | 2785 | { |
2810 | mutex_lock(&tty_mutex); | 2786 | /* Nothing to do - we defer to shutdown */ |
2811 | acquire_console_sem(); | 2787 | } |
2812 | if (tty && tty->count == 1) { | ||
2813 | struct vc_data *vc = tty->driver_data; | ||
2814 | 2788 | ||
2815 | if (vc) | 2789 | static void con_shutdown(struct tty_struct *tty) |
2816 | vc->vc_tty = NULL; | 2790 | { |
2817 | tty->driver_data = NULL; | 2791 | struct vc_data *vc = tty->driver_data; |
2818 | vcs_remove_sysfs(tty); | 2792 | BUG_ON(vc == NULL); |
2819 | release_console_sem(); | 2793 | acquire_console_sem(); |
2820 | mutex_unlock(&tty_mutex); | 2794 | vc->vc_tty = NULL; |
2821 | /* | 2795 | vcs_remove_sysfs(tty); |
2822 | * tty_mutex is released, but we still hold BKL, so there is | ||
2823 | * still exclusion against init_dev() | ||
2824 | */ | ||
2825 | return; | ||
2826 | } | ||
2827 | release_console_sem(); | 2796 | release_console_sem(); |
2828 | mutex_unlock(&tty_mutex); | 2797 | tty_shutdown(tty); |
2829 | } | 2798 | } |
2830 | 2799 | ||
2831 | static int default_italic_color = 2; // green (ASCII) | 2800 | static int default_italic_color = 2; // green (ASCII) |
@@ -2950,10 +2919,19 @@ static const struct tty_operations con_ops = { | |||
2950 | .throttle = con_throttle, | 2919 | .throttle = con_throttle, |
2951 | .unthrottle = con_unthrottle, | 2920 | .unthrottle = con_unthrottle, |
2952 | .resize = vt_resize, | 2921 | .resize = vt_resize, |
2922 | .shutdown = con_shutdown | ||
2953 | }; | 2923 | }; |
2954 | 2924 | ||
2955 | int __init vty_init(void) | 2925 | static struct cdev vc0_cdev; |
2926 | |||
2927 | int __init vty_init(const struct file_operations *console_fops) | ||
2956 | { | 2928 | { |
2929 | cdev_init(&vc0_cdev, console_fops); | ||
2930 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
2931 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
2932 | panic("Couldn't register /dev/tty0 driver\n"); | ||
2933 | device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
2934 | |||
2957 | vcs_init(); | 2935 | vcs_init(); |
2958 | 2936 | ||
2959 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); | 2937 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); |
@@ -2972,7 +2950,6 @@ int __init vty_init(void) | |||
2972 | tty_set_operations(console_driver, &con_ops); | 2950 | tty_set_operations(console_driver, &con_ops); |
2973 | if (tty_register_driver(console_driver)) | 2951 | if (tty_register_driver(console_driver)) |
2974 | panic("Couldn't register console driver\n"); | 2952 | panic("Couldn't register console driver\n"); |
2975 | |||
2976 | kbd_init(); | 2953 | kbd_init(); |
2977 | console_map_init(); | 2954 | console_map_init(); |
2978 | #ifdef CONFIG_PROM_CONSOLE | 2955 | #ifdef CONFIG_PROM_CONSOLE |
@@ -3466,7 +3443,7 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
3466 | if (retval) | 3443 | if (retval) |
3467 | goto err; | 3444 | goto err; |
3468 | 3445 | ||
3469 | con_driver->dev = device_create_drvdata(vtconsole_class, NULL, | 3446 | con_driver->dev = device_create(vtconsole_class, NULL, |
3470 | MKDEV(0, con_driver->node), | 3447 | MKDEV(0, con_driver->node), |
3471 | NULL, "vtcon%i", | 3448 | NULL, "vtcon%i", |
3472 | con_driver->node); | 3449 | con_driver->node); |
@@ -3577,7 +3554,7 @@ static int __init vtconsole_class_init(void) | |||
3577 | struct con_driver *con = ®istered_con_driver[i]; | 3554 | struct con_driver *con = ®istered_con_driver[i]; |
3578 | 3555 | ||
3579 | if (con->con && !con->dev) { | 3556 | if (con->con && !con->dev) { |
3580 | con->dev = device_create_drvdata(vtconsole_class, NULL, | 3557 | con->dev = device_create(vtconsole_class, NULL, |
3581 | MKDEV(0, con->node), | 3558 | MKDEV(0, con->node), |
3582 | NULL, "vtcon%i", | 3559 | NULL, "vtcon%i", |
3583 | con->node); | 3560 | con->node); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c904e9ad4a71..8944ce508e2f 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -395,6 +395,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
395 | 395 | ||
396 | kbd = kbd_table + console; | 396 | kbd = kbd_table + console; |
397 | switch (cmd) { | 397 | switch (cmd) { |
398 | case TIOCLINUX: | ||
399 | return tioclinux(tty, arg); | ||
398 | case KIOCSOUND: | 400 | case KIOCSOUND: |
399 | if (!perm) | 401 | if (!perm) |
400 | goto eperm; | 402 | goto eperm; |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 278c9857bcf5..ed132fe55d3d 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -657,8 +657,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, | |||
657 | goto failed3; | 657 | goto failed3; |
658 | } | 658 | } |
659 | 659 | ||
660 | device_create_drvdata(icap_class, dev, devt, NULL, | 660 | device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id); |
661 | "%s%d", DRIVER_NAME, id); | ||
662 | return 0; /* success */ | 661 | return 0; /* success */ |
663 | 662 | ||
664 | failed3: | 663 | failed3: |