diff options
Diffstat (limited to 'drivers/char')
77 files changed, 2890 insertions, 3485 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d0ac944e1696..700ff9679457 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -8,7 +8,7 @@ config VT | |||
8 | bool "Virtual terminal" if EMBEDDED | 8 | bool "Virtual terminal" if EMBEDDED |
9 | depends on !S390 | 9 | depends on !S390 |
10 | select INPUT | 10 | select INPUT |
11 | default y if !VIOCONS | 11 | default y |
12 | ---help--- | 12 | ---help--- |
13 | If you say Y here, you will get support for terminal devices with | 13 | If you say Y here, you will get support for terminal devices with |
14 | display and keyboard devices. These are called "virtual" because you | 14 | display and keyboard devices. These are called "virtual" because you |
@@ -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 |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 8a161c30e1dc..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 |
@@ -55,7 +55,6 @@ obj-$(CONFIG_RAW_DRIVER) += raw.o | |||
55 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o | 55 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o |
56 | obj-$(CONFIG_MSPEC) += mspec.o | 56 | obj-$(CONFIG_MSPEC) += mspec.o |
57 | obj-$(CONFIG_MMTIMER) += mmtimer.o | 57 | obj-$(CONFIG_MMTIMER) += mmtimer.o |
58 | obj-$(CONFIG_VIOCONS) += viocons.o | ||
59 | obj-$(CONFIG_VIOTAPE) += viotape.o | 58 | obj-$(CONFIG_VIOTAPE) += viotape.o |
60 | obj-$(CONFIG_HVCS) += hvcs.o | 59 | obj-$(CONFIG_HVCS) += hvcs.o |
61 | obj-$(CONFIG_IBM_BSR) += bsr.o | 60 | obj-$(CONFIG_IBM_BSR) += bsr.o |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 81e14bea54bd..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 | }; |
@@ -148,6 +150,9 @@ struct agp_bridge_data { | |||
148 | char minor_version; | 150 | char minor_version; |
149 | struct list_head list; | 151 | struct list_head list; |
150 | u32 apbase_config; | 152 | u32 apbase_config; |
153 | /* list of agp_memory mapped to the aperture */ | ||
154 | struct list_head mapped_list; | ||
155 | spinlock_t mapped_lock; | ||
151 | }; | 156 | }; |
152 | 157 | ||
153 | #define KB(x) ((x) * 1024) | 158 | #define KB(x) ((x) * 1024) |
@@ -274,7 +279,10 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); | |||
274 | 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); |
275 | void agp_generic_free_by_type(struct agp_memory *curr); | 280 | void agp_generic_free_by_type(struct agp_memory *curr); |
276 | 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); | ||
277 | 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); | ||
278 | void agp_free_key(int key); | 286 | void agp_free_key(int key); |
279 | int agp_num_entries(void); | 287 | int agp_num_entries(void); |
280 | 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 1ffb381130c3..31dcd9142d54 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -110,7 +110,8 @@ static int ali_configure(void) | |||
110 | 110 | ||
111 | nlvm_addr+= agp_bridge->gart_bus_addr; | 111 | nlvm_addr+= agp_bridge->gart_bus_addr; |
112 | nlvm_addr|=(agp_bridge->gart_bus_addr>>12); | 112 | nlvm_addr|=(agp_bridge->gart_bus_addr>>12); |
113 | printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr); | 113 | dev_info(&agp_bridge->dev->dev, "nlvm top &base = %8x\n", |
114 | nlvm_addr); | ||
114 | } | 115 | } |
115 | #endif | 116 | #endif |
116 | 117 | ||
@@ -315,8 +316,8 @@ static int __devinit agp_ali_probe(struct pci_dev *pdev, | |||
315 | goto found; | 316 | goto found; |
316 | } | 317 | } |
317 | 318 | ||
318 | printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n", | 319 | dev_err(&pdev->dev, "unsupported ALi chipset [%04x/%04x])\n", |
319 | pdev->device); | 320 | pdev->vendor, pdev->device); |
320 | return -ENODEV; | 321 | return -ENODEV; |
321 | 322 | ||
322 | 323 | ||
@@ -361,8 +362,7 @@ found: | |||
361 | bridge->driver = &ali_generic_bridge; | 362 | bridge->driver = &ali_generic_bridge; |
362 | } | 363 | } |
363 | 364 | ||
364 | printk(KERN_INFO PFX "Detected ALi %s chipset\n", | 365 | dev_info(&pdev->dev, "ALi %s chipset\n", devs[j].chipset_name); |
365 | devs[j].chipset_name); | ||
366 | 366 | ||
367 | /* Fill in the mode register */ | 367 | /* Fill in the mode register */ |
368 | pci_read_config_dword(pdev, | 368 | pci_read_config_dword(pdev, |
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 39a0718bc616..603a986e96af 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -386,7 +386,9 @@ static const struct agp_bridge_driver amd_irongate_driver = { | |||
386 | .alloc_by_type = agp_generic_alloc_by_type, | 386 | .alloc_by_type = agp_generic_alloc_by_type, |
387 | .free_by_type = agp_generic_free_by_type, | 387 | .free_by_type = agp_generic_free_by_type, |
388 | .agp_alloc_page = agp_generic_alloc_page, | 388 | .agp_alloc_page = agp_generic_alloc_page, |
389 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
389 | .agp_destroy_page = agp_generic_destroy_page, | 390 | .agp_destroy_page = agp_generic_destroy_page, |
391 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
390 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 392 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
391 | }; | 393 | }; |
392 | 394 | ||
@@ -419,8 +421,8 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, | |||
419 | return -ENODEV; | 421 | return -ENODEV; |
420 | 422 | ||
421 | j = ent - agp_amdk7_pci_table; | 423 | j = ent - agp_amdk7_pci_table; |
422 | printk(KERN_INFO PFX "Detected AMD %s chipset\n", | 424 | dev_info(&pdev->dev, "AMD %s chipset\n", |
423 | amd_agp_device_ids[j].chipset_name); | 425 | amd_agp_device_ids[j].chipset_name); |
424 | 426 | ||
425 | bridge = agp_alloc_bridge(); | 427 | bridge = agp_alloc_bridge(); |
426 | if (!bridge) | 428 | if (!bridge) |
@@ -442,7 +444,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, | |||
442 | while (!cap_ptr) { | 444 | while (!cap_ptr) { |
443 | gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); | 445 | gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); |
444 | if (!gfxcard) { | 446 | if (!gfxcard) { |
445 | printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n"); | 447 | dev_info(&pdev->dev, "no AGP VGA controller\n"); |
446 | return -ENODEV; | 448 | return -ENODEV; |
447 | } | 449 | } |
448 | cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP); | 450 | cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP); |
@@ -453,7 +455,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, | |||
453 | (if necessary at all). */ | 455 | (if necessary at all). */ |
454 | if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) { | 456 | if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) { |
455 | agp_bridge->flags |= AGP_ERRATA_1X; | 457 | agp_bridge->flags |= AGP_ERRATA_1X; |
456 | printk (KERN_INFO PFX "AMD 751 chipset with NVidia GeForce detected. Forcing to 1X due to errata.\n"); | 458 | dev_info(&pdev->dev, "AMD 751 chipset with NVidia GeForce; forcing 1X due to errata\n"); |
457 | } | 459 | } |
458 | pci_dev_put(gfxcard); | 460 | pci_dev_put(gfxcard); |
459 | } | 461 | } |
@@ -469,7 +471,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, | |||
469 | agp_bridge->flags = AGP_ERRATA_FASTWRITES; | 471 | agp_bridge->flags = AGP_ERRATA_FASTWRITES; |
470 | agp_bridge->flags |= AGP_ERRATA_SBA; | 472 | agp_bridge->flags |= AGP_ERRATA_SBA; |
471 | agp_bridge->flags |= AGP_ERRATA_1X; | 473 | agp_bridge->flags |= AGP_ERRATA_1X; |
472 | printk (KERN_INFO PFX "AMD 761 chipset with errata detected - disabling AGP fast writes & SBA and forcing to 1X.\n"); | 474 | dev_info(&pdev->dev, "AMD 761 chipset with errata; disabling AGP fast writes & SBA and forcing to 1X\n"); |
473 | } | 475 | } |
474 | } | 476 | } |
475 | 477 | ||
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 481ffe87c716..2812ee2b165a 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | static struct resource *aperture_resource; | 35 | static struct resource *aperture_resource; |
36 | static int __initdata agp_try_unsupported = 1; | 36 | static int __initdata agp_try_unsupported = 1; |
37 | static int agp_bridges_found; | ||
37 | 38 | ||
38 | static void amd64_tlbflush(struct agp_memory *temp) | 39 | static void amd64_tlbflush(struct agp_memory *temp) |
39 | { | 40 | { |
@@ -223,7 +224,9 @@ static const struct agp_bridge_driver amd_8151_driver = { | |||
223 | .alloc_by_type = agp_generic_alloc_by_type, | 224 | .alloc_by_type = agp_generic_alloc_by_type, |
224 | .free_by_type = agp_generic_free_by_type, | 225 | .free_by_type = agp_generic_free_by_type, |
225 | .agp_alloc_page = agp_generic_alloc_page, | 226 | .agp_alloc_page = agp_generic_alloc_page, |
227 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
226 | .agp_destroy_page = agp_generic_destroy_page, | 228 | .agp_destroy_page = agp_generic_destroy_page, |
229 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
227 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 230 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
228 | }; | 231 | }; |
229 | 232 | ||
@@ -293,12 +296,13 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, | |||
293 | * so let double check that order, and lets trust the AMD NB settings | 296 | * so let double check that order, and lets trust the AMD NB settings |
294 | */ | 297 | */ |
295 | if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) { | 298 | if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) { |
296 | printk(KERN_INFO "Aperture size %u MB is not right, using settings from NB\n", | 299 | dev_info(&agp->dev, "aperture size %u MB is not right, using settings from NB\n", |
297 | 32 << order); | 300 | 32 << order); |
298 | order = nb_order; | 301 | order = nb_order; |
299 | } | 302 | } |
300 | 303 | ||
301 | printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order); | 304 | dev_info(&agp->dev, "aperture from AGP @ %Lx size %u MB\n", |
305 | aper, 32 << order); | ||
302 | if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order)) | 306 | if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order)) |
303 | return -1; | 307 | return -1; |
304 | 308 | ||
@@ -319,10 +323,10 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) | |||
319 | for (i = 0; i < num_k8_northbridges; i++) { | 323 | for (i = 0; i < num_k8_northbridges; i++) { |
320 | struct pci_dev *dev = k8_northbridges[i]; | 324 | struct pci_dev *dev = k8_northbridges[i]; |
321 | if (fix_northbridge(dev, pdev, cap_ptr) < 0) { | 325 | if (fix_northbridge(dev, pdev, cap_ptr) < 0) { |
322 | printk(KERN_ERR PFX "No usable aperture found.\n"); | 326 | dev_err(&dev->dev, "no usable aperture found\n"); |
323 | #ifdef __x86_64__ | 327 | #ifdef __x86_64__ |
324 | /* should port this to i386 */ | 328 | /* should port this to i386 */ |
325 | printk(KERN_ERR PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n"); | 329 | dev_err(&dev->dev, "consider rebooting with iommu=memaper=2 to get a good aperture\n"); |
326 | #endif | 330 | #endif |
327 | return -1; | 331 | return -1; |
328 | } | 332 | } |
@@ -345,14 +349,14 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data | |||
345 | default: revstring="??"; break; | 349 | default: revstring="??"; break; |
346 | } | 350 | } |
347 | 351 | ||
348 | printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring); | 352 | dev_info(&pdev->dev, "AMD 8151 AGP Bridge rev %s\n", revstring); |
349 | 353 | ||
350 | /* | 354 | /* |
351 | * Work around errata. | 355 | * Work around errata. |
352 | * Chips before B2 stepping incorrectly reporting v3.5 | 356 | * Chips before B2 stepping incorrectly reporting v3.5 |
353 | */ | 357 | */ |
354 | if (pdev->revision < 0x13) { | 358 | if (pdev->revision < 0x13) { |
355 | printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n"); | 359 | dev_info(&pdev->dev, "correcting AGP revision (reports 3.5, is really 3.0)\n"); |
356 | bridge->major_version = 3; | 360 | bridge->major_version = 3; |
357 | bridge->minor_version = 0; | 361 | bridge->minor_version = 0; |
358 | } | 362 | } |
@@ -375,11 +379,11 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) | |||
375 | struct pci_dev *dev1; | 379 | struct pci_dev *dev1; |
376 | int i; | 380 | int i; |
377 | unsigned size = amd64_fetch_size(); | 381 | unsigned size = amd64_fetch_size(); |
378 | printk(KERN_INFO "Setting up ULi AGP.\n"); | 382 | |
383 | dev_info(&pdev->dev, "setting up ULi AGP\n"); | ||
379 | dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0)); | 384 | dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0)); |
380 | if (dev1 == NULL) { | 385 | if (dev1 == NULL) { |
381 | printk(KERN_INFO PFX "Detected a ULi chipset, " | 386 | dev_info(&pdev->dev, "can't find ULi secondary device\n"); |
382 | "but could not fine the secondary device.\n"); | ||
383 | return -ENODEV; | 387 | return -ENODEV; |
384 | } | 388 | } |
385 | 389 | ||
@@ -388,7 +392,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) | |||
388 | break; | 392 | break; |
389 | 393 | ||
390 | if (i == ARRAY_SIZE(uli_sizes)) { | 394 | if (i == ARRAY_SIZE(uli_sizes)) { |
391 | printk(KERN_INFO PFX "No ULi size found for %d\n", size); | 395 | dev_info(&pdev->dev, "no ULi size found for %d\n", size); |
392 | return -ENODEV; | 396 | return -ENODEV; |
393 | } | 397 | } |
394 | 398 | ||
@@ -433,13 +437,11 @@ static int nforce3_agp_init(struct pci_dev *pdev) | |||
433 | int i; | 437 | int i; |
434 | unsigned size = amd64_fetch_size(); | 438 | unsigned size = amd64_fetch_size(); |
435 | 439 | ||
436 | printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); | 440 | dev_info(&pdev->dev, "setting up Nforce3 AGP\n"); |
437 | 441 | ||
438 | dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0)); | 442 | dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0)); |
439 | if (dev1 == NULL) { | 443 | if (dev1 == NULL) { |
440 | printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " | 444 | dev_info(&pdev->dev, "can't find Nforce3 secondary device\n"); |
441 | "nForce3 chipset, but could not find " | ||
442 | "the secondary device.\n"); | ||
443 | return -ENODEV; | 445 | return -ENODEV; |
444 | } | 446 | } |
445 | 447 | ||
@@ -448,7 +450,7 @@ static int nforce3_agp_init(struct pci_dev *pdev) | |||
448 | break; | 450 | break; |
449 | 451 | ||
450 | if (i == ARRAY_SIZE(nforce3_sizes)) { | 452 | if (i == ARRAY_SIZE(nforce3_sizes)) { |
451 | printk(KERN_INFO PFX "No NForce3 size found for %d\n", size); | 453 | dev_info(&pdev->dev, "no NForce3 size found for %d\n", size); |
452 | return -ENODEV; | 454 | return -ENODEV; |
453 | } | 455 | } |
454 | 456 | ||
@@ -462,7 +464,7 @@ static int nforce3_agp_init(struct pci_dev *pdev) | |||
462 | 464 | ||
463 | /* if x86-64 aperture base is beyond 4G, exit here */ | 465 | /* if x86-64 aperture base is beyond 4G, exit here */ |
464 | if ( (apbase & 0x7fff) >> (32 - 25) ) { | 466 | if ( (apbase & 0x7fff) >> (32 - 25) ) { |
465 | printk(KERN_INFO PFX "aperture base > 4G\n"); | 467 | dev_info(&pdev->dev, "aperture base > 4G\n"); |
466 | return -ENODEV; | 468 | return -ENODEV; |
467 | } | 469 | } |
468 | 470 | ||
@@ -489,6 +491,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, | |||
489 | { | 491 | { |
490 | struct agp_bridge_data *bridge; | 492 | struct agp_bridge_data *bridge; |
491 | u8 cap_ptr; | 493 | u8 cap_ptr; |
494 | int err; | ||
492 | 495 | ||
493 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 496 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); |
494 | if (!cap_ptr) | 497 | if (!cap_ptr) |
@@ -504,7 +507,8 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, | |||
504 | pdev->device == PCI_DEVICE_ID_AMD_8151_0) { | 507 | pdev->device == PCI_DEVICE_ID_AMD_8151_0) { |
505 | amd8151_init(pdev, bridge); | 508 | amd8151_init(pdev, bridge); |
506 | } else { | 509 | } else { |
507 | printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn); | 510 | dev_info(&pdev->dev, "AGP bridge [%04x/%04x]\n", |
511 | pdev->vendor, pdev->device); | ||
508 | } | 512 | } |
509 | 513 | ||
510 | bridge->driver = &amd_8151_driver; | 514 | bridge->driver = &amd_8151_driver; |
@@ -536,7 +540,12 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, | |||
536 | } | 540 | } |
537 | 541 | ||
538 | pci_set_drvdata(pdev, bridge); | 542 | pci_set_drvdata(pdev, bridge); |
539 | return agp_add_bridge(bridge); | 543 | err = agp_add_bridge(bridge); |
544 | if (err < 0) | ||
545 | return err; | ||
546 | |||
547 | agp_bridges_found++; | ||
548 | return 0; | ||
540 | } | 549 | } |
541 | 550 | ||
542 | static void __devexit agp_amd64_remove(struct pci_dev *pdev) | 551 | static void __devexit agp_amd64_remove(struct pci_dev *pdev) |
@@ -713,7 +722,11 @@ int __init agp_amd64_init(void) | |||
713 | 722 | ||
714 | if (agp_off) | 723 | if (agp_off) |
715 | return -EINVAL; | 724 | return -EINVAL; |
716 | if (pci_register_driver(&agp_amd64_pci_driver) < 0) { | 725 | err = pci_register_driver(&agp_amd64_pci_driver); |
726 | if (err < 0) | ||
727 | return err; | ||
728 | |||
729 | if (agp_bridges_found == 0) { | ||
717 | struct pci_dev *dev; | 730 | struct pci_dev *dev; |
718 | if (!agp_try_unsupported && !agp_try_unsupported_boot) { | 731 | if (!agp_try_unsupported && !agp_try_unsupported_boot) { |
719 | printk(KERN_INFO PFX "No supported AGP bridge found.\n"); | 732 | printk(KERN_INFO PFX "No supported AGP bridge found.\n"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 3a4566c0d84f..ae2791b926b9 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 | ||
@@ -486,8 +488,8 @@ static int __devinit agp_ati_probe(struct pci_dev *pdev, | |||
486 | goto found; | 488 | goto found; |
487 | } | 489 | } |
488 | 490 | ||
489 | printk(KERN_ERR PFX | 491 | dev_err(&pdev->dev, "unsupported Ati chipset [%04x/%04x])\n", |
490 | "Unsupported Ati chipset (device id: %04x)\n", pdev->device); | 492 | pdev->vendor, pdev->device); |
491 | return -ENODEV; | 493 | return -ENODEV; |
492 | 494 | ||
493 | found: | 495 | found: |
@@ -500,8 +502,7 @@ found: | |||
500 | 502 | ||
501 | bridge->driver = &ati_generic_bridge; | 503 | bridge->driver = &ati_generic_bridge; |
502 | 504 | ||
503 | printk(KERN_INFO PFX "Detected Ati %s chipset\n", | 505 | dev_info(&pdev->dev, "Ati %s chipset\n", devs[j].chipset_name); |
504 | devs[j].chipset_name); | ||
505 | 506 | ||
506 | /* Fill in the mode register */ | 507 | /* Fill in the mode register */ |
507 | pci_read_config_dword(pdev, | 508 | pci_read_config_dword(pdev, |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 1ec87104e68c..3a3cc03d401c 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -144,7 +144,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
144 | void *addr = bridge->driver->agp_alloc_page(bridge); | 144 | void *addr = bridge->driver->agp_alloc_page(bridge); |
145 | 145 | ||
146 | if (!addr) { | 146 | if (!addr) { |
147 | printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); | 147 | dev_err(&bridge->dev->dev, |
148 | "can't get memory for scratch page\n"); | ||
148 | return -ENOMEM; | 149 | return -ENOMEM; |
149 | } | 150 | } |
150 | 151 | ||
@@ -155,13 +156,13 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
155 | 156 | ||
156 | size_value = bridge->driver->fetch_size(); | 157 | size_value = bridge->driver->fetch_size(); |
157 | if (size_value == 0) { | 158 | if (size_value == 0) { |
158 | printk(KERN_ERR PFX "unable to determine aperture size.\n"); | 159 | dev_err(&bridge->dev->dev, "can't determine aperture size\n"); |
159 | rc = -EINVAL; | 160 | rc = -EINVAL; |
160 | goto err_out; | 161 | goto err_out; |
161 | } | 162 | } |
162 | if (bridge->driver->create_gatt_table(bridge)) { | 163 | if (bridge->driver->create_gatt_table(bridge)) { |
163 | printk(KERN_ERR PFX | 164 | dev_err(&bridge->dev->dev, |
164 | "unable to get memory for graphics translation table.\n"); | 165 | "can't get memory for graphics translation table\n"); |
165 | rc = -ENOMEM; | 166 | rc = -ENOMEM; |
166 | goto err_out; | 167 | goto err_out; |
167 | } | 168 | } |
@@ -169,7 +170,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
169 | 170 | ||
170 | bridge->key_list = vmalloc(PAGE_SIZE * 4); | 171 | bridge->key_list = vmalloc(PAGE_SIZE * 4); |
171 | if (bridge->key_list == NULL) { | 172 | if (bridge->key_list == NULL) { |
172 | printk(KERN_ERR PFX "error allocating memory for key lists.\n"); | 173 | dev_err(&bridge->dev->dev, |
174 | "can't allocate memory for key lists\n"); | ||
173 | rc = -ENOMEM; | 175 | rc = -ENOMEM; |
174 | goto err_out; | 176 | goto err_out; |
175 | } | 177 | } |
@@ -179,10 +181,12 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
179 | memset(bridge->key_list, 0, PAGE_SIZE * 4); | 181 | memset(bridge->key_list, 0, PAGE_SIZE * 4); |
180 | 182 | ||
181 | if (bridge->driver->configure()) { | 183 | if (bridge->driver->configure()) { |
182 | printk(KERN_ERR PFX "error configuring host chipset.\n"); | 184 | dev_err(&bridge->dev->dev, "error configuring host chipset\n"); |
183 | rc = -EINVAL; | 185 | rc = -EINVAL; |
184 | goto err_out; | 186 | goto err_out; |
185 | } | 187 | } |
188 | INIT_LIST_HEAD(&bridge->mapped_list); | ||
189 | spin_lock_init(&bridge->mapped_lock); | ||
186 | 190 | ||
187 | return 0; | 191 | return 0; |
188 | 192 | ||
@@ -269,25 +273,27 @@ int agp_add_bridge(struct agp_bridge_data *bridge) | |||
269 | 273 | ||
270 | /* Grab reference on the chipset driver. */ | 274 | /* Grab reference on the chipset driver. */ |
271 | if (!try_module_get(bridge->driver->owner)) { | 275 | if (!try_module_get(bridge->driver->owner)) { |
272 | printk (KERN_INFO PFX "Couldn't lock chipset driver.\n"); | 276 | dev_info(&bridge->dev->dev, "can't lock chipset driver\n"); |
273 | return -EINVAL; | 277 | return -EINVAL; |
274 | } | 278 | } |
275 | 279 | ||
276 | error = agp_backend_initialize(bridge); | 280 | error = agp_backend_initialize(bridge); |
277 | if (error) { | 281 | if (error) { |
278 | printk (KERN_INFO PFX "agp_backend_initialize() failed.\n"); | 282 | dev_info(&bridge->dev->dev, |
283 | "agp_backend_initialize() failed\n"); | ||
279 | goto err_out; | 284 | goto err_out; |
280 | } | 285 | } |
281 | 286 | ||
282 | if (list_empty(&agp_bridges)) { | 287 | if (list_empty(&agp_bridges)) { |
283 | error = agp_frontend_initialize(); | 288 | error = agp_frontend_initialize(); |
284 | if (error) { | 289 | if (error) { |
285 | printk (KERN_INFO PFX "agp_frontend_initialize() failed.\n"); | 290 | dev_info(&bridge->dev->dev, |
291 | "agp_frontend_initialize() failed\n"); | ||
286 | goto frontend_err; | 292 | goto frontend_err; |
287 | } | 293 | } |
288 | 294 | ||
289 | printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n", | 295 | dev_info(&bridge->dev->dev, "AGP aperture is %dM @ 0x%lx\n", |
290 | bridge->driver->fetch_size(), bridge->gart_bus_addr); | 296 | bridge->driver->fetch_size(), bridge->gart_bus_addr); |
291 | 297 | ||
292 | } | 298 | } |
293 | 299 | ||
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 eaa1a355bb32..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 | ||
@@ -429,6 +446,10 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start) | |||
429 | 446 | ||
430 | curr->is_bound = true; | 447 | curr->is_bound = true; |
431 | curr->pg_start = pg_start; | 448 | curr->pg_start = pg_start; |
449 | spin_lock(&agp_bridge->mapped_lock); | ||
450 | list_add(&curr->mapped_list, &agp_bridge->mapped_list); | ||
451 | spin_unlock(&agp_bridge->mapped_lock); | ||
452 | |||
432 | return 0; | 453 | return 0; |
433 | } | 454 | } |
434 | EXPORT_SYMBOL(agp_bind_memory); | 455 | EXPORT_SYMBOL(agp_bind_memory); |
@@ -461,10 +482,34 @@ int agp_unbind_memory(struct agp_memory *curr) | |||
461 | 482 | ||
462 | curr->is_bound = false; | 483 | curr->is_bound = false; |
463 | curr->pg_start = 0; | 484 | curr->pg_start = 0; |
485 | spin_lock(&curr->bridge->mapped_lock); | ||
486 | list_del(&curr->mapped_list); | ||
487 | spin_unlock(&curr->bridge->mapped_lock); | ||
464 | return 0; | 488 | return 0; |
465 | } | 489 | } |
466 | EXPORT_SYMBOL(agp_unbind_memory); | 490 | EXPORT_SYMBOL(agp_unbind_memory); |
467 | 491 | ||
492 | /** | ||
493 | * agp_rebind_emmory - Rewrite the entire GATT, useful on resume | ||
494 | */ | ||
495 | int agp_rebind_memory(void) | ||
496 | { | ||
497 | struct agp_memory *curr; | ||
498 | int ret_val = 0; | ||
499 | |||
500 | spin_lock(&agp_bridge->mapped_lock); | ||
501 | list_for_each_entry(curr, &agp_bridge->mapped_list, mapped_list) { | ||
502 | ret_val = curr->bridge->driver->insert_memory(curr, | ||
503 | curr->pg_start, | ||
504 | curr->type); | ||
505 | if (ret_val != 0) | ||
506 | break; | ||
507 | } | ||
508 | spin_unlock(&agp_bridge->mapped_lock); | ||
509 | return ret_val; | ||
510 | } | ||
511 | EXPORT_SYMBOL(agp_rebind_memory); | ||
512 | |||
468 | /* End - Routines for handling swapping of agp_memory into the GATT */ | 513 | /* End - Routines for handling swapping of agp_memory into the GATT */ |
469 | 514 | ||
470 | 515 | ||
@@ -771,8 +816,8 @@ void agp_device_command(u32 bridge_agpstat, bool agp_v3) | |||
771 | if (!agp) | 816 | if (!agp) |
772 | continue; | 817 | continue; |
773 | 818 | ||
774 | printk(KERN_INFO PFX "Putting AGP V%d device at %s into %dx mode\n", | 819 | dev_info(&device->dev, "putting AGP V%d device into %dx mode\n", |
775 | agp_v3 ? 3 : 2, pci_name(device), mode); | 820 | agp_v3 ? 3 : 2, mode); |
776 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, bridge_agpstat); | 821 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, bridge_agpstat); |
777 | } | 822 | } |
778 | } | 823 | } |
@@ -800,10 +845,8 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) | |||
800 | 845 | ||
801 | get_agp_version(agp_bridge); | 846 | get_agp_version(agp_bridge); |
802 | 847 | ||
803 | printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n", | 848 | dev_info(&agp_bridge->dev->dev, "AGP %d.%d bridge\n", |
804 | agp_bridge->major_version, | 849 | agp_bridge->major_version, agp_bridge->minor_version); |
805 | agp_bridge->minor_version, | ||
806 | pci_name(agp_bridge->dev)); | ||
807 | 850 | ||
808 | pci_read_config_dword(agp_bridge->dev, | 851 | pci_read_config_dword(agp_bridge->dev, |
809 | agp_bridge->capndx + PCI_AGP_STATUS, &bridge_agpstat); | 852 | agp_bridge->capndx + PCI_AGP_STATUS, &bridge_agpstat); |
@@ -832,8 +875,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) | |||
832 | pci_write_config_dword(bridge->dev, | 875 | pci_write_config_dword(bridge->dev, |
833 | bridge->capndx+AGPCTRL, temp); | 876 | bridge->capndx+AGPCTRL, temp); |
834 | 877 | ||
835 | printk(KERN_INFO PFX "Device is in legacy mode," | 878 | dev_info(&bridge->dev->dev, "bridge is in legacy mode, falling back to 2.x\n"); |
836 | " falling back to 2.x\n"); | ||
837 | } | 879 | } |
838 | } | 880 | } |
839 | 881 | ||
@@ -1178,6 +1220,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user); | |||
1178 | * against a maximum value. | 1220 | * against a maximum value. |
1179 | */ | 1221 | */ |
1180 | 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 | |||
1181 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1256 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
1182 | { | 1257 | { |
1183 | struct page * page; | 1258 | struct page * page; |
@@ -1194,6 +1269,37 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
1194 | } | 1269 | } |
1195 | EXPORT_SYMBOL(agp_generic_alloc_page); | 1270 | EXPORT_SYMBOL(agp_generic_alloc_page); |
1196 | 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); | ||
1197 | 1303 | ||
1198 | void agp_generic_destroy_page(void *addr, int flags) | 1304 | void agp_generic_destroy_page(void *addr, int flags) |
1199 | { | 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 df702642ab8f..043e36628d6d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 | 32 | #define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 |
33 | #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 | 33 | #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 |
34 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 | 34 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 |
35 | #define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 | 35 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 |
36 | #define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 | 36 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 |
37 | #define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 | 37 | #define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 |
38 | #define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 | 38 | #define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 |
39 | #define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 | 39 | #define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 |
@@ -55,7 +55,7 @@ | |||
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_IGD_HB) | 58 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) |
59 | 59 | ||
60 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | 60 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ |
61 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | 61 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ |
@@ -161,7 +161,7 @@ static int intel_i810_fetch_size(void) | |||
161 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); | 161 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); |
162 | 162 | ||
163 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { | 163 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { |
164 | printk(KERN_WARNING PFX "i810 is disabled\n"); | 164 | dev_warn(&agp_bridge->dev->dev, "i810 is disabled\n"); |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { | 167 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { |
@@ -193,7 +193,8 @@ static int intel_i810_configure(void) | |||
193 | 193 | ||
194 | intel_private.registers = ioremap(temp, 128 * 4096); | 194 | intel_private.registers = ioremap(temp, 128 * 4096); |
195 | if (!intel_private.registers) { | 195 | if (!intel_private.registers) { |
196 | printk(KERN_ERR PFX "Unable to remap memory.\n"); | 196 | dev_err(&intel_private.pcidev->dev, |
197 | "can't remap memory\n"); | ||
197 | return -ENOMEM; | 198 | return -ENOMEM; |
198 | } | 199 | } |
199 | } | 200 | } |
@@ -201,7 +202,8 @@ static int intel_i810_configure(void) | |||
201 | if ((readl(intel_private.registers+I810_DRAM_CTL) | 202 | if ((readl(intel_private.registers+I810_DRAM_CTL) |
202 | & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { | 203 | & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { |
203 | /* This will need to be dynamically assigned */ | 204 | /* This will need to be dynamically assigned */ |
204 | printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n"); | 205 | dev_info(&intel_private.pcidev->dev, |
206 | "detected 4MB dedicated video ram\n"); | ||
205 | intel_private.num_dcache_entries = 1024; | 207 | intel_private.num_dcache_entries = 1024; |
206 | } | 208 | } |
207 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); | 209 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); |
@@ -500,8 +502,8 @@ static void intel_i830_init_gtt_entries(void) | |||
500 | size = 1024 + 512; | 502 | size = 1024 + 512; |
501 | break; | 503 | break; |
502 | default: | 504 | default: |
503 | printk(KERN_INFO PFX "Unknown page table size, " | 505 | dev_info(&intel_private.pcidev->dev, |
504 | "assuming 512KB\n"); | 506 | "unknown page table size, assuming 512KB\n"); |
505 | size = 512; | 507 | size = 512; |
506 | } | 508 | } |
507 | size += 4; /* add in BIOS popup space */ | 509 | size += 4; /* add in BIOS popup space */ |
@@ -515,8 +517,8 @@ static void intel_i830_init_gtt_entries(void) | |||
515 | size = 2048; | 517 | size = 2048; |
516 | break; | 518 | break; |
517 | default: | 519 | default: |
518 | printk(KERN_INFO PFX "Unknown page table size 0x%x, " | 520 | dev_info(&agp_bridge->dev->dev, |
519 | "assuming 512KB\n", | 521 | "unknown page table size 0x%x, assuming 512KB\n", |
520 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | 522 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); |
521 | size = 512; | 523 | size = 512; |
522 | } | 524 | } |
@@ -627,11 +629,11 @@ static void intel_i830_init_gtt_entries(void) | |||
627 | } | 629 | } |
628 | } | 630 | } |
629 | if (gtt_entries > 0) | 631 | if (gtt_entries > 0) |
630 | printk(KERN_INFO PFX "Detected %dK %s memory.\n", | 632 | dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", |
631 | gtt_entries / KB(1), local ? "local" : "stolen"); | 633 | gtt_entries / KB(1), local ? "local" : "stolen"); |
632 | else | 634 | else |
633 | printk(KERN_INFO PFX | 635 | dev_info(&agp_bridge->dev->dev, |
634 | "No pre-allocated video memory detected.\n"); | 636 | "no pre-allocated video memory detected\n"); |
635 | gtt_entries /= KB(4); | 637 | gtt_entries /= KB(4); |
636 | 638 | ||
637 | intel_private.gtt_entries = gtt_entries; | 639 | intel_private.gtt_entries = gtt_entries; |
@@ -801,10 +803,12 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
801 | num_entries = A_SIZE_FIX(temp)->num_entries; | 803 | num_entries = A_SIZE_FIX(temp)->num_entries; |
802 | 804 | ||
803 | if (pg_start < intel_private.gtt_entries) { | 805 | if (pg_start < intel_private.gtt_entries) { |
804 | printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", | 806 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
805 | pg_start, intel_private.gtt_entries); | 807 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", |
808 | pg_start, intel_private.gtt_entries); | ||
806 | 809 | ||
807 | printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); | 810 | dev_info(&intel_private.pcidev->dev, |
811 | "trying to insert into local/stolen memory\n"); | ||
808 | goto out_err; | 812 | goto out_err; |
809 | } | 813 | } |
810 | 814 | ||
@@ -851,7 +855,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
851 | return 0; | 855 | return 0; |
852 | 856 | ||
853 | if (pg_start < intel_private.gtt_entries) { | 857 | if (pg_start < intel_private.gtt_entries) { |
854 | printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); | 858 | dev_info(&intel_private.pcidev->dev, |
859 | "trying to disable local/stolen memory\n"); | ||
855 | return -EINVAL; | 860 | return -EINVAL; |
856 | } | 861 | } |
857 | 862 | ||
@@ -957,7 +962,7 @@ static void intel_i9xx_setup_flush(void) | |||
957 | if (intel_private.ifp_resource.start) { | 962 | if (intel_private.ifp_resource.start) { |
958 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | 963 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); |
959 | if (!intel_private.i9xx_flush_page) | 964 | if (!intel_private.i9xx_flush_page) |
960 | printk(KERN_INFO "unable to ioremap flush page - no chipset flushing"); | 965 | dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing"); |
961 | } | 966 | } |
962 | } | 967 | } |
963 | 968 | ||
@@ -1028,10 +1033,12 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1028 | num_entries = A_SIZE_FIX(temp)->num_entries; | 1033 | num_entries = A_SIZE_FIX(temp)->num_entries; |
1029 | 1034 | ||
1030 | if (pg_start < intel_private.gtt_entries) { | 1035 | if (pg_start < intel_private.gtt_entries) { |
1031 | printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", | 1036 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
1032 | pg_start, intel_private.gtt_entries); | 1037 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", |
1038 | pg_start, intel_private.gtt_entries); | ||
1033 | 1039 | ||
1034 | printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); | 1040 | dev_info(&intel_private.pcidev->dev, |
1041 | "trying to insert into local/stolen memory\n"); | ||
1035 | goto out_err; | 1042 | goto out_err; |
1036 | } | 1043 | } |
1037 | 1044 | ||
@@ -1078,7 +1085,8 @@ static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
1078 | return 0; | 1085 | return 0; |
1079 | 1086 | ||
1080 | if (pg_start < intel_private.gtt_entries) { | 1087 | if (pg_start < intel_private.gtt_entries) { |
1081 | printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); | 1088 | dev_info(&intel_private.pcidev->dev, |
1089 | "trying to disable local/stolen memory\n"); | ||
1082 | return -EINVAL; | 1090 | return -EINVAL; |
1083 | } | 1091 | } |
1084 | 1092 | ||
@@ -1182,7 +1190,7 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | |||
1182 | static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | 1190 | static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) |
1183 | { | 1191 | { |
1184 | switch (agp_bridge->dev->device) { | 1192 | switch (agp_bridge->dev->device) { |
1185 | case PCI_DEVICE_ID_INTEL_IGD_HB: | 1193 | case PCI_DEVICE_ID_INTEL_GM45_HB: |
1186 | case PCI_DEVICE_ID_INTEL_IGD_E_HB: | 1194 | case PCI_DEVICE_ID_INTEL_IGD_E_HB: |
1187 | case PCI_DEVICE_ID_INTEL_Q45_HB: | 1195 | case PCI_DEVICE_ID_INTEL_Q45_HB: |
1188 | case PCI_DEVICE_ID_INTEL_G45_HB: | 1196 | case PCI_DEVICE_ID_INTEL_G45_HB: |
@@ -1379,7 +1387,7 @@ static int intel_815_configure(void) | |||
1379 | /* the Intel 815 chipset spec. says that bits 29-31 in the | 1387 | /* the Intel 815 chipset spec. says that bits 29-31 in the |
1380 | * ATTBASE register are reserved -> try not to write them */ | 1388 | * ATTBASE register are reserved -> try not to write them */ |
1381 | if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { | 1389 | if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { |
1382 | printk(KERN_EMERG PFX "gatt bus addr too high"); | 1390 | dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high"); |
1383 | return -EINVAL; | 1391 | return -EINVAL; |
1384 | } | 1392 | } |
1385 | 1393 | ||
@@ -1703,7 +1711,9 @@ static const struct agp_bridge_driver intel_generic_driver = { | |||
1703 | .alloc_by_type = agp_generic_alloc_by_type, | 1711 | .alloc_by_type = agp_generic_alloc_by_type, |
1704 | .free_by_type = agp_generic_free_by_type, | 1712 | .free_by_type = agp_generic_free_by_type, |
1705 | .agp_alloc_page = agp_generic_alloc_page, | 1713 | .agp_alloc_page = agp_generic_alloc_page, |
1714 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1706 | .agp_destroy_page = agp_generic_destroy_page, | 1715 | .agp_destroy_page = agp_generic_destroy_page, |
1716 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1707 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1717 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1708 | }; | 1718 | }; |
1709 | 1719 | ||
@@ -1728,7 +1738,9 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1728 | .alloc_by_type = intel_i810_alloc_by_type, | 1738 | .alloc_by_type = intel_i810_alloc_by_type, |
1729 | .free_by_type = intel_i810_free_by_type, | 1739 | .free_by_type = intel_i810_free_by_type, |
1730 | .agp_alloc_page = agp_generic_alloc_page, | 1740 | .agp_alloc_page = agp_generic_alloc_page, |
1741 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1731 | .agp_destroy_page = agp_generic_destroy_page, | 1742 | .agp_destroy_page = agp_generic_destroy_page, |
1743 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1732 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1744 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1733 | }; | 1745 | }; |
1734 | 1746 | ||
@@ -1752,7 +1764,9 @@ static const struct agp_bridge_driver intel_815_driver = { | |||
1752 | .alloc_by_type = agp_generic_alloc_by_type, | 1764 | .alloc_by_type = agp_generic_alloc_by_type, |
1753 | .free_by_type = agp_generic_free_by_type, | 1765 | .free_by_type = agp_generic_free_by_type, |
1754 | .agp_alloc_page = agp_generic_alloc_page, | 1766 | .agp_alloc_page = agp_generic_alloc_page, |
1767 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1755 | .agp_destroy_page = agp_generic_destroy_page, | 1768 | .agp_destroy_page = agp_generic_destroy_page, |
1769 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1756 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1770 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1757 | }; | 1771 | }; |
1758 | 1772 | ||
@@ -1777,7 +1791,9 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1777 | .alloc_by_type = intel_i830_alloc_by_type, | 1791 | .alloc_by_type = intel_i830_alloc_by_type, |
1778 | .free_by_type = intel_i810_free_by_type, | 1792 | .free_by_type = intel_i810_free_by_type, |
1779 | .agp_alloc_page = agp_generic_alloc_page, | 1793 | .agp_alloc_page = agp_generic_alloc_page, |
1794 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1780 | .agp_destroy_page = agp_generic_destroy_page, | 1795 | .agp_destroy_page = agp_generic_destroy_page, |
1796 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1781 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1797 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1782 | .chipset_flush = intel_i830_chipset_flush, | 1798 | .chipset_flush = intel_i830_chipset_flush, |
1783 | }; | 1799 | }; |
@@ -1802,7 +1818,9 @@ static const struct agp_bridge_driver intel_820_driver = { | |||
1802 | .alloc_by_type = agp_generic_alloc_by_type, | 1818 | .alloc_by_type = agp_generic_alloc_by_type, |
1803 | .free_by_type = agp_generic_free_by_type, | 1819 | .free_by_type = agp_generic_free_by_type, |
1804 | .agp_alloc_page = agp_generic_alloc_page, | 1820 | .agp_alloc_page = agp_generic_alloc_page, |
1821 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1805 | .agp_destroy_page = agp_generic_destroy_page, | 1822 | .agp_destroy_page = agp_generic_destroy_page, |
1823 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1806 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1824 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1807 | }; | 1825 | }; |
1808 | 1826 | ||
@@ -1826,7 +1844,9 @@ static const struct agp_bridge_driver intel_830mp_driver = { | |||
1826 | .alloc_by_type = agp_generic_alloc_by_type, | 1844 | .alloc_by_type = agp_generic_alloc_by_type, |
1827 | .free_by_type = agp_generic_free_by_type, | 1845 | .free_by_type = agp_generic_free_by_type, |
1828 | .agp_alloc_page = agp_generic_alloc_page, | 1846 | .agp_alloc_page = agp_generic_alloc_page, |
1847 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1829 | .agp_destroy_page = agp_generic_destroy_page, | 1848 | .agp_destroy_page = agp_generic_destroy_page, |
1849 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1830 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1850 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1831 | }; | 1851 | }; |
1832 | 1852 | ||
@@ -1850,7 +1870,9 @@ static const struct agp_bridge_driver intel_840_driver = { | |||
1850 | .alloc_by_type = agp_generic_alloc_by_type, | 1870 | .alloc_by_type = agp_generic_alloc_by_type, |
1851 | .free_by_type = agp_generic_free_by_type, | 1871 | .free_by_type = agp_generic_free_by_type, |
1852 | .agp_alloc_page = agp_generic_alloc_page, | 1872 | .agp_alloc_page = agp_generic_alloc_page, |
1873 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1853 | .agp_destroy_page = agp_generic_destroy_page, | 1874 | .agp_destroy_page = agp_generic_destroy_page, |
1875 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1854 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1876 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1855 | }; | 1877 | }; |
1856 | 1878 | ||
@@ -1874,7 +1896,9 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
1874 | .alloc_by_type = agp_generic_alloc_by_type, | 1896 | .alloc_by_type = agp_generic_alloc_by_type, |
1875 | .free_by_type = agp_generic_free_by_type, | 1897 | .free_by_type = agp_generic_free_by_type, |
1876 | .agp_alloc_page = agp_generic_alloc_page, | 1898 | .agp_alloc_page = agp_generic_alloc_page, |
1899 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1877 | .agp_destroy_page = agp_generic_destroy_page, | 1900 | .agp_destroy_page = agp_generic_destroy_page, |
1901 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1878 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1902 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1879 | .chipset_flush = intel_i830_chipset_flush, | 1903 | .chipset_flush = intel_i830_chipset_flush, |
1880 | }; | 1904 | }; |
@@ -1899,7 +1923,9 @@ static const struct agp_bridge_driver intel_850_driver = { | |||
1899 | .alloc_by_type = agp_generic_alloc_by_type, | 1923 | .alloc_by_type = agp_generic_alloc_by_type, |
1900 | .free_by_type = agp_generic_free_by_type, | 1924 | .free_by_type = agp_generic_free_by_type, |
1901 | .agp_alloc_page = agp_generic_alloc_page, | 1925 | .agp_alloc_page = agp_generic_alloc_page, |
1926 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1902 | .agp_destroy_page = agp_generic_destroy_page, | 1927 | .agp_destroy_page = agp_generic_destroy_page, |
1928 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1903 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1929 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1904 | }; | 1930 | }; |
1905 | 1931 | ||
@@ -1923,7 +1949,9 @@ static const struct agp_bridge_driver intel_860_driver = { | |||
1923 | .alloc_by_type = agp_generic_alloc_by_type, | 1949 | .alloc_by_type = agp_generic_alloc_by_type, |
1924 | .free_by_type = agp_generic_free_by_type, | 1950 | .free_by_type = agp_generic_free_by_type, |
1925 | .agp_alloc_page = agp_generic_alloc_page, | 1951 | .agp_alloc_page = agp_generic_alloc_page, |
1952 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1926 | .agp_destroy_page = agp_generic_destroy_page, | 1953 | .agp_destroy_page = agp_generic_destroy_page, |
1954 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1927 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1955 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1928 | }; | 1956 | }; |
1929 | 1957 | ||
@@ -1948,7 +1976,9 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1948 | .alloc_by_type = intel_i830_alloc_by_type, | 1976 | .alloc_by_type = intel_i830_alloc_by_type, |
1949 | .free_by_type = intel_i810_free_by_type, | 1977 | .free_by_type = intel_i810_free_by_type, |
1950 | .agp_alloc_page = agp_generic_alloc_page, | 1978 | .agp_alloc_page = agp_generic_alloc_page, |
1979 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1951 | .agp_destroy_page = agp_generic_destroy_page, | 1980 | .agp_destroy_page = agp_generic_destroy_page, |
1981 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1952 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1982 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1953 | .chipset_flush = intel_i915_chipset_flush, | 1983 | .chipset_flush = intel_i915_chipset_flush, |
1954 | }; | 1984 | }; |
@@ -1974,7 +2004,9 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1974 | .alloc_by_type = intel_i830_alloc_by_type, | 2004 | .alloc_by_type = intel_i830_alloc_by_type, |
1975 | .free_by_type = intel_i810_free_by_type, | 2005 | .free_by_type = intel_i810_free_by_type, |
1976 | .agp_alloc_page = agp_generic_alloc_page, | 2006 | .agp_alloc_page = agp_generic_alloc_page, |
2007 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1977 | .agp_destroy_page = agp_generic_destroy_page, | 2008 | .agp_destroy_page = agp_generic_destroy_page, |
2009 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1978 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2010 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1979 | .chipset_flush = intel_i915_chipset_flush, | 2011 | .chipset_flush = intel_i915_chipset_flush, |
1980 | }; | 2012 | }; |
@@ -1999,7 +2031,9 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
1999 | .alloc_by_type = agp_generic_alloc_by_type, | 2031 | .alloc_by_type = agp_generic_alloc_by_type, |
2000 | .free_by_type = agp_generic_free_by_type, | 2032 | .free_by_type = agp_generic_free_by_type, |
2001 | .agp_alloc_page = agp_generic_alloc_page, | 2033 | .agp_alloc_page = agp_generic_alloc_page, |
2034 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2002 | .agp_destroy_page = agp_generic_destroy_page, | 2035 | .agp_destroy_page = agp_generic_destroy_page, |
2036 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
2003 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 2037 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
2004 | }; | 2038 | }; |
2005 | 2039 | ||
@@ -2024,7 +2058,9 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
2024 | .alloc_by_type = intel_i830_alloc_by_type, | 2058 | .alloc_by_type = intel_i830_alloc_by_type, |
2025 | .free_by_type = intel_i810_free_by_type, | 2059 | .free_by_type = intel_i810_free_by_type, |
2026 | .agp_alloc_page = agp_generic_alloc_page, | 2060 | .agp_alloc_page = agp_generic_alloc_page, |
2061 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
2027 | .agp_destroy_page = agp_generic_destroy_page, | 2062 | .agp_destroy_page = agp_generic_destroy_page, |
2063 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
2028 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2064 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2029 | .chipset_flush = intel_i915_chipset_flush, | 2065 | .chipset_flush = intel_i915_chipset_flush, |
2030 | }; | 2066 | }; |
@@ -2117,8 +2153,8 @@ static const struct intel_driver_description { | |||
2117 | NULL, &intel_g33_driver }, | 2153 | NULL, &intel_g33_driver }, |
2118 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", | 2154 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", |
2119 | NULL, &intel_g33_driver }, | 2155 | NULL, &intel_g33_driver }, |
2120 | { PCI_DEVICE_ID_INTEL_IGD_HB, PCI_DEVICE_ID_INTEL_IGD_IG, 0, | 2156 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, |
2121 | "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, | 2157 | "Mobile Intel? GM45 Express", NULL, &intel_i965_driver }, |
2122 | { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, | 2158 | { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, |
2123 | "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, | 2159 | "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, |
2124 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, | 2160 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, |
@@ -2163,8 +2199,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2163 | 2199 | ||
2164 | if (intel_agp_chipsets[i].name == NULL) { | 2200 | if (intel_agp_chipsets[i].name == NULL) { |
2165 | if (cap_ptr) | 2201 | if (cap_ptr) |
2166 | printk(KERN_WARNING PFX "Unsupported Intel chipset" | 2202 | dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n", |
2167 | "(device id: %04x)\n", pdev->device); | 2203 | pdev->vendor, pdev->device); |
2168 | agp_put_bridge(bridge); | 2204 | agp_put_bridge(bridge); |
2169 | return -ENODEV; | 2205 | return -ENODEV; |
2170 | } | 2206 | } |
@@ -2172,9 +2208,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2172 | if (bridge->driver == NULL) { | 2208 | if (bridge->driver == NULL) { |
2173 | /* bridge has no AGP and no IGD detected */ | 2209 | /* bridge has no AGP and no IGD detected */ |
2174 | if (cap_ptr) | 2210 | if (cap_ptr) |
2175 | printk(KERN_WARNING PFX "Failed to find bridge device " | 2211 | dev_warn(&pdev->dev, "can't find bridge device (chip_id: %04x)\n", |
2176 | "(chip_id: %04x)\n", | 2212 | intel_agp_chipsets[i].gmch_chip_id); |
2177 | intel_agp_chipsets[i].gmch_chip_id); | ||
2178 | agp_put_bridge(bridge); | 2213 | agp_put_bridge(bridge); |
2179 | return -ENODEV; | 2214 | return -ENODEV; |
2180 | } | 2215 | } |
@@ -2183,8 +2218,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2183 | bridge->capndx = cap_ptr; | 2218 | bridge->capndx = cap_ptr; |
2184 | bridge->dev_private_data = &intel_private; | 2219 | bridge->dev_private_data = &intel_private; |
2185 | 2220 | ||
2186 | printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", | 2221 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
2187 | intel_agp_chipsets[i].name); | ||
2188 | 2222 | ||
2189 | /* | 2223 | /* |
2190 | * The following fixes the case where the BIOS has "forgotten" to | 2224 | * The following fixes the case where the BIOS has "forgotten" to |
@@ -2194,7 +2228,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2194 | r = &pdev->resource[0]; | 2228 | r = &pdev->resource[0]; |
2195 | if (!r->start && r->end) { | 2229 | if (!r->start && r->end) { |
2196 | if (pci_assign_resource(pdev, 0)) { | 2230 | if (pci_assign_resource(pdev, 0)) { |
2197 | printk(KERN_ERR PFX "could not assign resource 0\n"); | 2231 | dev_err(&pdev->dev, "can't assign resource 0\n"); |
2198 | agp_put_bridge(bridge); | 2232 | agp_put_bridge(bridge); |
2199 | return -ENODEV; | 2233 | return -ENODEV; |
2200 | } | 2234 | } |
@@ -2206,7 +2240,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2206 | * 20030610 - hamish@zot.org | 2240 | * 20030610 - hamish@zot.org |
2207 | */ | 2241 | */ |
2208 | if (pci_enable_device(pdev)) { | 2242 | if (pci_enable_device(pdev)) { |
2209 | printk(KERN_ERR PFX "Unable to Enable PCI device\n"); | 2243 | dev_err(&pdev->dev, "can't enable PCI device\n"); |
2210 | agp_put_bridge(bridge); | 2244 | agp_put_bridge(bridge); |
2211 | return -ENODEV; | 2245 | return -ENODEV; |
2212 | } | 2246 | } |
@@ -2238,6 +2272,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) | |||
2238 | static int agp_intel_resume(struct pci_dev *pdev) | 2272 | static int agp_intel_resume(struct pci_dev *pdev) |
2239 | { | 2273 | { |
2240 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 2274 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
2275 | int ret_val; | ||
2241 | 2276 | ||
2242 | pci_restore_state(pdev); | 2277 | pci_restore_state(pdev); |
2243 | 2278 | ||
@@ -2265,6 +2300,10 @@ static int agp_intel_resume(struct pci_dev *pdev) | |||
2265 | else if (bridge->driver == &intel_i965_driver) | 2300 | else if (bridge->driver == &intel_i965_driver) |
2266 | intel_i915_configure(); | 2301 | intel_i915_configure(); |
2267 | 2302 | ||
2303 | ret_val = agp_rebind_memory(); | ||
2304 | if (ret_val != 0) | ||
2305 | return ret_val; | ||
2306 | |||
2268 | return 0; | 2307 | return 0; |
2269 | } | 2308 | } |
2270 | #endif | 2309 | #endif |
@@ -2315,7 +2354,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2315 | ID(PCI_DEVICE_ID_INTEL_G33_HB), | 2354 | ID(PCI_DEVICE_ID_INTEL_G33_HB), |
2316 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), | 2355 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
2317 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), | 2356 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
2318 | ID(PCI_DEVICE_ID_INTEL_IGD_HB), | 2357 | ID(PCI_DEVICE_ID_INTEL_GM45_HB), |
2319 | ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), | 2358 | ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), |
2320 | ID(PCI_DEVICE_ID_INTEL_Q45_HB), | 2359 | ID(PCI_DEVICE_ID_INTEL_Q45_HB), |
2321 | ID(PCI_DEVICE_ID_INTEL_G45_HB), | 2360 | ID(PCI_DEVICE_ID_INTEL_G45_HB), |
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c index 3f9ccde62377..c73385cc4b8a 100644 --- a/drivers/char/agp/isoch.c +++ b/drivers/char/agp/isoch.c | |||
@@ -153,7 +153,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, | |||
153 | 153 | ||
154 | /* Check if this configuration has any chance of working */ | 154 | /* Check if this configuration has any chance of working */ |
155 | if (tot_bw > target.maxbw) { | 155 | if (tot_bw > target.maxbw) { |
156 | printk(KERN_ERR PFX "isochronous bandwidth required " | 156 | dev_err(&td->dev, "isochronous bandwidth required " |
157 | "by AGP 3.0 devices exceeds that which is supported by " | 157 | "by AGP 3.0 devices exceeds that which is supported by " |
158 | "the AGP 3.0 bridge!\n"); | 158 | "the AGP 3.0 bridge!\n"); |
159 | ret = -ENODEV; | 159 | ret = -ENODEV; |
@@ -188,7 +188,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, | |||
188 | /* Exit if the minimal ISOCH_N allocation among the masters is more | 188 | /* Exit if the minimal ISOCH_N allocation among the masters is more |
189 | * than the target can handle. */ | 189 | * than the target can handle. */ |
190 | if (tot_n > target.n) { | 190 | if (tot_n > target.n) { |
191 | printk(KERN_ERR PFX "number of isochronous " | 191 | dev_err(&td->dev, "number of isochronous " |
192 | "transactions per period required by AGP 3.0 devices " | 192 | "transactions per period required by AGP 3.0 devices " |
193 | "exceeds that which is supported by the AGP 3.0 " | 193 | "exceeds that which is supported by the AGP 3.0 " |
194 | "bridge!\n"); | 194 | "bridge!\n"); |
@@ -229,7 +229,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, | |||
229 | /* Exit if the minimal RQ needs of the masters exceeds what the target | 229 | /* Exit if the minimal RQ needs of the masters exceeds what the target |
230 | * can provide. */ | 230 | * can provide. */ |
231 | if (tot_rq > rq_isoch) { | 231 | if (tot_rq > rq_isoch) { |
232 | printk(KERN_ERR PFX "number of request queue slots " | 232 | dev_err(&td->dev, "number of request queue slots " |
233 | "required by the isochronous bandwidth requested by " | 233 | "required by the isochronous bandwidth requested by " |
234 | "AGP 3.0 devices exceeds the number provided by the " | 234 | "AGP 3.0 devices exceeds the number provided by the " |
235 | "AGP 3.0 bridge!\n"); | 235 | "AGP 3.0 bridge!\n"); |
@@ -359,8 +359,9 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) | |||
359 | case 0x0001: /* Unclassified device */ | 359 | case 0x0001: /* Unclassified device */ |
360 | /* Don't know what this is, but log it for investigation. */ | 360 | /* Don't know what this is, but log it for investigation. */ |
361 | if (mcapndx != 0) { | 361 | if (mcapndx != 0) { |
362 | printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n", | 362 | dev_info(&td->dev, "wacky, found unclassified AGP device %s [%04x/%04x]\n", |
363 | dev->vendor, dev->device); | 363 | pci_name(dev), |
364 | dev->vendor, dev->device); | ||
364 | } | 365 | } |
365 | continue; | 366 | continue; |
366 | 367 | ||
@@ -407,17 +408,18 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) | |||
407 | } | 408 | } |
408 | 409 | ||
409 | if (mcapndx == 0) { | 410 | if (mcapndx == 0) { |
410 | printk(KERN_ERR PFX "woah! Non-AGP device " | 411 | dev_err(&td->dev, "woah! Non-AGP device %s on " |
411 | "found on the secondary bus of an AGP 3.5 bridge!\n"); | 412 | "secondary bus of AGP 3.5 bridge!\n", |
413 | pci_name(dev)); | ||
412 | ret = -ENODEV; | 414 | ret = -ENODEV; |
413 | goto free_and_exit; | 415 | goto free_and_exit; |
414 | } | 416 | } |
415 | 417 | ||
416 | mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; | 418 | mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; |
417 | if (mmajor < 3) { | 419 | if (mmajor < 3) { |
418 | printk(KERN_ERR PFX "woah! AGP 2.0 device " | 420 | dev_err(&td->dev, "woah! AGP 2.0 device %s on " |
419 | "found on the secondary bus of an AGP 3.5 " | 421 | "secondary bus of AGP 3.5 bridge operating " |
420 | "bridge operating with AGP 3.0 electricals!\n"); | 422 | "with AGP 3.0 electricals!\n", pci_name(dev)); |
421 | ret = -ENODEV; | 423 | ret = -ENODEV; |
422 | goto free_and_exit; | 424 | goto free_and_exit; |
423 | } | 425 | } |
@@ -427,10 +429,10 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) | |||
427 | pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus); | 429 | pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus); |
428 | 430 | ||
429 | if (((mstatus >> 3) & 0x1) == 0) { | 431 | if (((mstatus >> 3) & 0x1) == 0) { |
430 | printk(KERN_ERR PFX "woah! AGP 3.x device " | 432 | dev_err(&td->dev, "woah! AGP 3.x device %s not " |
431 | "not operating in AGP 3.x mode found on the " | 433 | "operating in AGP 3.x mode on secondary bus " |
432 | "secondary bus of an AGP 3.5 bridge operating " | 434 | "of AGP 3.5 bridge operating with AGP 3.0 " |
433 | "with AGP 3.0 electricals!\n"); | 435 | "electricals!\n", pci_name(dev)); |
434 | ret = -ENODEV; | 436 | ret = -ENODEV; |
435 | goto free_and_exit; | 437 | goto free_and_exit; |
436 | } | 438 | } |
@@ -444,9 +446,9 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) | |||
444 | if (isoch) { | 446 | if (isoch) { |
445 | ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs); | 447 | ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs); |
446 | if (ret) { | 448 | if (ret) { |
447 | printk(KERN_INFO PFX "Something bad happened setting " | 449 | dev_info(&td->dev, "something bad happened setting " |
448 | "up isochronous xfers. Falling back to " | 450 | "up isochronous xfers; falling back to " |
449 | "non-isochronous xfer mode.\n"); | 451 | "non-isochronous xfer mode\n"); |
450 | } else { | 452 | } else { |
451 | goto free_and_exit; | 453 | goto free_and_exit; |
452 | } | 454 | } |
@@ -466,4 +468,3 @@ free_and_exit: | |||
466 | get_out: | 468 | get_out: |
467 | return ret; | 469 | return ret; |
468 | } | 470 | } |
469 | |||
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index eaceb61ba2dc..dc70d3771811 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -312,7 +312,9 @@ static const struct agp_bridge_driver nvidia_driver = { | |||
312 | .alloc_by_type = agp_generic_alloc_by_type, | 312 | .alloc_by_type = agp_generic_alloc_by_type, |
313 | .free_by_type = agp_generic_free_by_type, | 313 | .free_by_type = agp_generic_free_by_type, |
314 | .agp_alloc_page = agp_generic_alloc_page, | 314 | .agp_alloc_page = agp_generic_alloc_page, |
315 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
315 | .agp_destroy_page = agp_generic_destroy_page, | 316 | .agp_destroy_page = agp_generic_destroy_page, |
317 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
316 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 318 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
317 | }; | 319 | }; |
318 | 320 | ||
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 8c42dcc5958c..f2492ecf0824 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 b6791846809f..6c3837a0184d 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -79,10 +79,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) | |||
79 | u32 command; | 79 | u32 command; |
80 | int rate; | 80 | int rate; |
81 | 81 | ||
82 | printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n", | 82 | dev_info(&agp_bridge->dev->dev, "AGP %d.%d bridge\n", |
83 | agp_bridge->major_version, | 83 | agp_bridge->major_version, agp_bridge->minor_version); |
84 | agp_bridge->minor_version, | ||
85 | pci_name(agp_bridge->dev)); | ||
86 | 84 | ||
87 | pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command); | 85 | pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command); |
88 | command = agp_collect_device_status(bridge, mode, command); | 86 | command = agp_collect_device_status(bridge, mode, command); |
@@ -94,8 +92,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) | |||
94 | if (!agp) | 92 | if (!agp) |
95 | continue; | 93 | continue; |
96 | 94 | ||
97 | printk(KERN_INFO PFX "Putting AGP V3 device at %s into %dx mode\n", | 95 | dev_info(&agp_bridge->dev->dev, "putting AGP V3 device at %s into %dx mode\n", |
98 | pci_name(device), rate); | 96 | pci_name(device), rate); |
99 | 97 | ||
100 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); | 98 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); |
101 | 99 | ||
@@ -105,7 +103,7 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode) | |||
105 | * cannot be configured | 103 | * cannot be configured |
106 | */ | 104 | */ |
107 | if (device->device == bridge->dev->device) { | 105 | if (device->device == bridge->dev->device) { |
108 | printk(KERN_INFO PFX "SiS delay workaround: giving bridge time to recover.\n"); | 106 | dev_info(&agp_bridge->dev->dev, "SiS delay workaround: giving bridge time to recover\n"); |
109 | msleep(10); | 107 | msleep(10); |
110 | } | 108 | } |
111 | } | 109 | } |
@@ -142,7 +140,9 @@ static struct agp_bridge_driver sis_driver = { | |||
142 | .alloc_by_type = agp_generic_alloc_by_type, | 140 | .alloc_by_type = agp_generic_alloc_by_type, |
143 | .free_by_type = agp_generic_free_by_type, | 141 | .free_by_type = agp_generic_free_by_type, |
144 | .agp_alloc_page = agp_generic_alloc_page, | 142 | .agp_alloc_page = agp_generic_alloc_page, |
143 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
145 | .agp_destroy_page = agp_generic_destroy_page, | 144 | .agp_destroy_page = agp_generic_destroy_page, |
145 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
146 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 146 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
147 | }; | 147 | }; |
148 | 148 | ||
@@ -190,7 +190,8 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev, | |||
190 | return -ENODEV; | 190 | return -ENODEV; |
191 | 191 | ||
192 | 192 | ||
193 | printk(KERN_INFO PFX "Detected SiS chipset - id:%i\n", pdev->device); | 193 | dev_info(&pdev->dev, "SiS chipset [%04x/%04x]\n", |
194 | pdev->vendor, pdev->device); | ||
194 | bridge = agp_alloc_bridge(); | 195 | bridge = agp_alloc_bridge(); |
195 | if (!bridge) | 196 | if (!bridge) |
196 | return -ENOMEM; | 197 | return -ENOMEM; |
@@ -242,7 +243,7 @@ static struct pci_device_id agp_sis_pci_table[] = { | |||
242 | .class = (PCI_CLASS_BRIDGE_HOST << 8), | 243 | .class = (PCI_CLASS_BRIDGE_HOST << 8), |
243 | .class_mask = ~0, | 244 | .class_mask = ~0, |
244 | .vendor = PCI_VENDOR_ID_SI, | 245 | .vendor = PCI_VENDOR_ID_SI, |
245 | .device = PCI_DEVICE_ID_SI_5591_AGP, | 246 | .device = PCI_DEVICE_ID_SI_5591, |
246 | .subvendor = PCI_ANY_ID, | 247 | .subvendor = PCI_ANY_ID, |
247 | .subdevice = PCI_ANY_ID, | 248 | .subdevice = PCI_ANY_ID, |
248 | }, | 249 | }, |
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 0e054c134490..6224df8b7f0a 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -241,7 +241,8 @@ static void serverworks_tlbflush(struct agp_memory *temp) | |||
241 | while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) { | 241 | while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) { |
242 | cpu_relax(); | 242 | cpu_relax(); |
243 | if (time_after(jiffies, timeout)) { | 243 | if (time_after(jiffies, timeout)) { |
244 | printk(KERN_ERR PFX "TLB post flush took more than 3 seconds\n"); | 244 | dev_err(&serverworks_private.svrwrks_dev->dev, |
245 | "TLB post flush took more than 3 seconds\n"); | ||
245 | break; | 246 | break; |
246 | } | 247 | } |
247 | } | 248 | } |
@@ -251,7 +252,8 @@ static void serverworks_tlbflush(struct agp_memory *temp) | |||
251 | while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) { | 252 | while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) { |
252 | cpu_relax(); | 253 | cpu_relax(); |
253 | if (time_after(jiffies, timeout)) { | 254 | if (time_after(jiffies, timeout)) { |
254 | printk(KERN_ERR PFX "TLB Dir flush took more than 3 seconds\n"); | 255 | dev_err(&serverworks_private.svrwrks_dev->dev, |
256 | "TLB Dir flush took more than 3 seconds\n"); | ||
255 | break; | 257 | break; |
256 | } | 258 | } |
257 | } | 259 | } |
@@ -271,7 +273,7 @@ static int serverworks_configure(void) | |||
271 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 273 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
272 | serverworks_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); | 274 | serverworks_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); |
273 | if (!serverworks_private.registers) { | 275 | if (!serverworks_private.registers) { |
274 | printk (KERN_ERR PFX "Unable to ioremap() memory.\n"); | 276 | dev_err(&agp_bridge->dev->dev, "can't ioremap(%#x)\n", temp); |
275 | return -ENOMEM; | 277 | return -ENOMEM; |
276 | } | 278 | } |
277 | 279 | ||
@@ -435,7 +437,9 @@ static const struct agp_bridge_driver sworks_driver = { | |||
435 | .alloc_by_type = agp_generic_alloc_by_type, | 437 | .alloc_by_type = agp_generic_alloc_by_type, |
436 | .free_by_type = agp_generic_free_by_type, | 438 | .free_by_type = agp_generic_free_by_type, |
437 | .agp_alloc_page = agp_generic_alloc_page, | 439 | .agp_alloc_page = agp_generic_alloc_page, |
440 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
438 | .agp_destroy_page = agp_generic_destroy_page, | 441 | .agp_destroy_page = agp_generic_destroy_page, |
442 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
439 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 443 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
440 | }; | 444 | }; |
441 | 445 | ||
@@ -451,7 +455,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
451 | 455 | ||
452 | switch (pdev->device) { | 456 | switch (pdev->device) { |
453 | case 0x0006: | 457 | case 0x0006: |
454 | printk (KERN_ERR PFX "ServerWorks CNB20HE is unsupported due to lack of documentation.\n"); | 458 | dev_err(&pdev->dev, "ServerWorks CNB20HE is unsupported due to lack of documentation\n"); |
455 | return -ENODEV; | 459 | return -ENODEV; |
456 | 460 | ||
457 | case PCI_DEVICE_ID_SERVERWORKS_HE: | 461 | case PCI_DEVICE_ID_SERVERWORKS_HE: |
@@ -461,8 +465,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
461 | 465 | ||
462 | default: | 466 | default: |
463 | if (cap_ptr) | 467 | if (cap_ptr) |
464 | printk(KERN_ERR PFX "Unsupported Serverworks chipset " | 468 | dev_err(&pdev->dev, "unsupported Serverworks chipset " |
465 | "(device id: %04x)\n", pdev->device); | 469 | "[%04x/%04x]\n", pdev->vendor, pdev->device); |
466 | return -ENODEV; | 470 | return -ENODEV; |
467 | } | 471 | } |
468 | 472 | ||
@@ -470,8 +474,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
470 | bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, | 474 | bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, |
471 | PCI_DEVFN(0, 1)); | 475 | PCI_DEVFN(0, 1)); |
472 | if (!bridge_dev) { | 476 | if (!bridge_dev) { |
473 | printk(KERN_INFO PFX "Detected a Serverworks chipset " | 477 | dev_info(&pdev->dev, "can't find secondary device\n"); |
474 | "but could not find the secondary device.\n"); | ||
475 | return -ENODEV; | 478 | return -ENODEV; |
476 | } | 479 | } |
477 | 480 | ||
@@ -482,8 +485,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
482 | if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { | 485 | if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { |
483 | pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2); | 486 | pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2); |
484 | if (temp2 != 0) { | 487 | if (temp2 != 0) { |
485 | printk(KERN_INFO PFX "Detected 64 bit aperture address, " | 488 | dev_info(&pdev->dev, "64 bit aperture address, " |
486 | "but top bits are not zero. Disabling agp\n"); | 489 | "but top bits are not zero; disabling AGP\n"); |
487 | return -ENODEV; | 490 | return -ENODEV; |
488 | } | 491 | } |
489 | serverworks_private.mm_addr_ofs = 0x18; | 492 | serverworks_private.mm_addr_ofs = 0x18; |
@@ -495,8 +498,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
495 | pci_read_config_dword(pdev, | 498 | pci_read_config_dword(pdev, |
496 | serverworks_private.mm_addr_ofs + 4, &temp2); | 499 | serverworks_private.mm_addr_ofs + 4, &temp2); |
497 | if (temp2 != 0) { | 500 | if (temp2 != 0) { |
498 | printk(KERN_INFO PFX "Detected 64 bit MMIO address, " | 501 | dev_info(&pdev->dev, "64 bit MMIO address, but top " |
499 | "but top bits are not zero. Disabling agp\n"); | 502 | "bits are not zero; disabling AGP\n"); |
500 | return -ENODEV; | 503 | return -ENODEV; |
501 | } | 504 | } |
502 | } | 505 | } |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index d2fa3cfca02a..0f004b65ec03 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -46,8 +46,8 @@ static int uninorth_fetch_size(void) | |||
46 | break; | 46 | break; |
47 | 47 | ||
48 | if (i == agp_bridge->driver->num_aperture_sizes) { | 48 | if (i == agp_bridge->driver->num_aperture_sizes) { |
49 | printk(KERN_ERR PFX "Invalid aperture size, using" | 49 | dev_err(&agp_bridge->dev->dev, "invalid aperture size, " |
50 | " default\n"); | 50 | "using default\n"); |
51 | size = 0; | 51 | size = 0; |
52 | aperture = NULL; | 52 | aperture = NULL; |
53 | } | 53 | } |
@@ -108,8 +108,8 @@ static int uninorth_configure(void) | |||
108 | 108 | ||
109 | current_size = A_SIZE_32(agp_bridge->current_size); | 109 | current_size = A_SIZE_32(agp_bridge->current_size); |
110 | 110 | ||
111 | printk(KERN_INFO PFX "configuring for size idx: %d\n", | 111 | dev_info(&agp_bridge->dev->dev, "configuring for size idx: %d\n", |
112 | current_size->size_value); | 112 | current_size->size_value); |
113 | 113 | ||
114 | /* aperture size and gatt addr */ | 114 | /* aperture size and gatt addr */ |
115 | pci_write_config_dword(agp_bridge->dev, | 115 | pci_write_config_dword(agp_bridge->dev, |
@@ -197,8 +197,9 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
197 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; | 197 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; |
198 | for (i = 0; i < mem->page_count; ++i) { | 198 | for (i = 0; i < mem->page_count; ++i) { |
199 | if (gp[i]) { | 199 | if (gp[i]) { |
200 | printk("u3_insert_memory: entry 0x%x occupied (%x)\n", | 200 | dev_info(&agp_bridge->dev->dev, |
201 | i, gp[i]); | 201 | "u3_insert_memory: entry 0x%x occupied (%x)\n", |
202 | i, gp[i]); | ||
202 | return -EBUSY; | 203 | return -EBUSY; |
203 | } | 204 | } |
204 | } | 205 | } |
@@ -276,8 +277,8 @@ static void uninorth_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
276 | &scratch); | 277 | &scratch); |
277 | } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000); | 278 | } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000); |
278 | if ((scratch & PCI_AGP_COMMAND_AGP) == 0) | 279 | if ((scratch & PCI_AGP_COMMAND_AGP) == 0) |
279 | printk(KERN_ERR PFX "failed to write UniNorth AGP" | 280 | dev_err(&bridge->dev->dev, "can't write UniNorth AGP " |
280 | " command register\n"); | 281 | "command register\n"); |
281 | 282 | ||
282 | if (uninorth_rev >= 0x30) { | 283 | if (uninorth_rev >= 0x30) { |
283 | /* This is an AGP V3 */ | 284 | /* This is an AGP V3 */ |
@@ -330,8 +331,8 @@ static int agp_uninorth_suspend(struct pci_dev *pdev) | |||
330 | pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd); | 331 | pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd); |
331 | if (!(cmd & PCI_AGP_COMMAND_AGP)) | 332 | if (!(cmd & PCI_AGP_COMMAND_AGP)) |
332 | continue; | 333 | continue; |
333 | printk("uninorth-agp: disabling AGP on device %s\n", | 334 | dev_info(&pdev->dev, "disabling AGP on device %s\n", |
334 | pci_name(device)); | 335 | pci_name(device)); |
335 | cmd &= ~PCI_AGP_COMMAND_AGP; | 336 | cmd &= ~PCI_AGP_COMMAND_AGP; |
336 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd); | 337 | pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd); |
337 | } | 338 | } |
@@ -341,8 +342,7 @@ static int agp_uninorth_suspend(struct pci_dev *pdev) | |||
341 | pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); | 342 | pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); |
342 | bridge->dev_private_data = (void *)(long)cmd; | 343 | bridge->dev_private_data = (void *)(long)cmd; |
343 | if (cmd & PCI_AGP_COMMAND_AGP) { | 344 | if (cmd & PCI_AGP_COMMAND_AGP) { |
344 | printk("uninorth-agp: disabling AGP on bridge %s\n", | 345 | dev_info(&pdev->dev, "disabling AGP on bridge\n"); |
345 | pci_name(pdev)); | ||
346 | cmd &= ~PCI_AGP_COMMAND_AGP; | 346 | cmd &= ~PCI_AGP_COMMAND_AGP; |
347 | pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd); | 347 | pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd); |
348 | } | 348 | } |
@@ -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, |
@@ -591,14 +595,14 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev, | |||
591 | /* probe for known chipsets */ | 595 | /* probe for known chipsets */ |
592 | for (j = 0; devs[j].chipset_name != NULL; ++j) { | 596 | for (j = 0; devs[j].chipset_name != NULL; ++j) { |
593 | if (pdev->device == devs[j].device_id) { | 597 | if (pdev->device == devs[j].device_id) { |
594 | printk(KERN_INFO PFX "Detected Apple %s chipset\n", | 598 | dev_info(&pdev->dev, "Apple %s chipset\n", |
595 | devs[j].chipset_name); | 599 | devs[j].chipset_name); |
596 | goto found; | 600 | goto found; |
597 | } | 601 | } |
598 | } | 602 | } |
599 | 603 | ||
600 | printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n", | 604 | dev_err(&pdev->dev, "unsupported Apple chipset [%04x/%04x]\n", |
601 | pdev->device); | 605 | pdev->vendor, pdev->device); |
602 | return -ENODEV; | 606 | return -ENODEV; |
603 | 607 | ||
604 | found: | 608 | found: |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 7b36476dff41..9f4d49e1b59a 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 | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 3530ff417a51..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")) |
@@ -1254,7 +1248,7 @@ static int rs_break(struct tty_struct *tty, int break_state) | |||
1254 | unsigned long flags; | 1248 | unsigned long flags; |
1255 | 1249 | ||
1256 | if (serial_paranoia_check(info, tty->name, "rs_break")) | 1250 | if (serial_paranoia_check(info, tty->name, "rs_break")) |
1257 | return; | 1251 | return -EINVAL; |
1258 | 1252 | ||
1259 | local_irq_save(flags); | 1253 | local_irq_save(flags); |
1260 | if (break_state == -1) | 1254 | if (break_state == -1) |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 31d08b641f5b..b899d9182c7d 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -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/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/ds1620.c b/drivers/char/ds1620.c index 34275c6f1da2..74e9cd81b5b2 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/smp_lock.h> | 11 | #include <linux/smp_lock.h> |
12 | 12 | ||
13 | #include <asm/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #include <asm/mach-types.h> | 14 | #include <asm/mach-types.h> |
15 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
16 | #include <asm/therm.h> | 16 | #include <asm/therm.h> |
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 67fbd7aab5db..34d15d548236 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/rtc.h> | 37 | #include <linux/rtc.h> |
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/efi.h> | 39 | #include <linux/efi.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
42 | 41 | ||
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 456e4ede049f..4998b2761e8f 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 | } |
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..f3cfb4c76125 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 02aac104842d..ec7aded0a2df 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -322,11 +322,10 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
322 | 322 | ||
323 | hp->tty = tty; | 323 | hp->tty = tty; |
324 | 324 | ||
325 | if (hp->ops->notifier_add) | ||
326 | rc = hp->ops->notifier_add(hp, hp->data); | ||
327 | |||
328 | spin_unlock_irqrestore(&hp->lock, flags); | 325 | spin_unlock_irqrestore(&hp->lock, flags); |
329 | 326 | ||
327 | if (hp->ops->notifier_add) | ||
328 | rc = hp->ops->notifier_add(hp, hp->data); | ||
330 | 329 | ||
331 | /* | 330 | /* |
332 | * If the notifier fails we return an error. The tty layer | 331 | * If the notifier fails we return an error. The tty layer |
@@ -820,11 +819,11 @@ static int hvc_init(void) | |||
820 | hvc_driver = drv; | 819 | hvc_driver = drv; |
821 | return 0; | 820 | return 0; |
822 | 821 | ||
823 | put_tty: | ||
824 | put_tty_driver(hvc_driver); | ||
825 | stop_thread: | 822 | stop_thread: |
826 | kthread_stop(hvc_task); | 823 | kthread_stop(hvc_task); |
827 | hvc_task = NULL; | 824 | hvc_task = NULL; |
825 | put_tty: | ||
826 | put_tty_driver(drv); | ||
828 | out: | 827 | out: |
829 | return err; | 828 | return err; |
830 | } | 829 | } |
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index d9ce10915625..9790201718ae 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Ryan S. Arnold <rsa@us.ibm.com> | 6 | * Ryan S. Arnold <rsa@us.ibm.com> |
7 | * | 7 | * |
8 | * hvc_console header information: | 8 | * hvc_console header information: |
9 | * moved here from include/asm-powerpc/hvconsole.h | 9 | * moved here from arch/powerpc/include/asm/hvconsole.h |
10 | * and drivers/char/hvc_console.c | 10 | * and drivers/char/hvc_console.c |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
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/hvcs.c b/drivers/char/hvcs.c index 786d518e9477..473d9b14439a 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -114,7 +114,7 @@ | |||
114 | * the hvcs_final_close() function in order to get it out of the spinlock. | 114 | * the hvcs_final_close() function in order to get it out of the spinlock. |
115 | * Rearranged hvcs_close(). Cleaned up some printks and did some housekeeping | 115 | * Rearranged hvcs_close(). Cleaned up some printks and did some housekeeping |
116 | * on the changelog. Removed local CLC_LENGTH and used HVCS_CLC_LENGTH from | 116 | * on the changelog. Removed local CLC_LENGTH and used HVCS_CLC_LENGTH from |
117 | * include/asm-powerpc/hvcserver.h | 117 | * arch/powerepc/include/asm/hvcserver.h |
118 | * | 118 | * |
119 | * 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to | 119 | * 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to |
120 | * prevent possible lockup with realtime scheduling as similarily pointed out by | 120 | * prevent possible lockup with realtime scheduling as similarily pointed out by |
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c index bab43ca32ac1..263567f5f392 100644 --- a/drivers/char/hw_random/ixp4xx-rng.c +++ b/drivers/char/hw_random/ixp4xx-rng.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/hw_random.h> | 23 | #include <linux/hw_random.h> |
24 | 24 | ||
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | #include <asm/hardware.h> | 26 | #include <mach/hardware.h> |
27 | 27 | ||
28 | 28 | ||
29 | static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer) | 29 | static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer) |
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/via-rng.c b/drivers/char/hw_random/via-rng.c index f7feae4ebb5e..128202e18fc9 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include <asm/msr.h> | 32 | #include <asm/msr.h> |
33 | #include <asm/cpufeature.h> | 33 | #include <asm/cpufeature.h> |
34 | #include <asm/i387.h> | ||
34 | 35 | ||
35 | 36 | ||
36 | #define PFX KBUILD_MODNAME ": " | 37 | #define PFX KBUILD_MODNAME ": " |
@@ -67,16 +68,23 @@ enum { | |||
67 | * Another possible performance boost may come from simply buffering | 68 | * Another possible performance boost may come from simply buffering |
68 | * until we have 4 bytes, thus returning a u32 at a time, | 69 | * until we have 4 bytes, thus returning a u32 at a time, |
69 | * instead of the current u8-at-a-time. | 70 | * instead of the current u8-at-a-time. |
71 | * | ||
72 | * Padlock instructions can generate a spurious DNA fault, so | ||
73 | * we have to call them in the context of irq_ts_save/restore() | ||
70 | */ | 74 | */ |
71 | 75 | ||
72 | static inline u32 xstore(u32 *addr, u32 edx_in) | 76 | static inline u32 xstore(u32 *addr, u32 edx_in) |
73 | { | 77 | { |
74 | u32 eax_out; | 78 | u32 eax_out; |
79 | int ts_state; | ||
80 | |||
81 | ts_state = irq_ts_save(); | ||
75 | 82 | ||
76 | asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" | 83 | asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" |
77 | :"=m"(*addr), "=a"(eax_out) | 84 | :"=m"(*addr), "=a"(eax_out) |
78 | :"D"(addr), "d"(edx_in)); | 85 | :"D"(addr), "d"(edx_in)); |
79 | 86 | ||
87 | irq_ts_restore(ts_state); | ||
80 | return eax_out; | 88 | return eax_out; |
81 | } | 89 | } |
82 | 90 | ||
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..6774572d3759 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_drvdata(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_drvdata(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/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 192688344ed2..8e8afb6141f9 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -66,8 +66,8 @@ | |||
66 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
67 | 67 | ||
68 | #ifdef CONFIG_PPC_OF | 68 | #ifdef CONFIG_PPC_OF |
69 | #include <asm/of_device.h> | 69 | #include <linux/of_device.h> |
70 | #include <asm/of_platform.h> | 70 | #include <linux/of_platform.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #define PFX "ipmi_si: " | 73 | #define PFX "ipmi_si: " |
@@ -2695,15 +2695,13 @@ 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 | |||
2699 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2700 | if (!info) | ||
2701 | return; | ||
2702 | |||
2703 | #ifdef CONFIG_PPC_MERGE | 2698 | #ifdef CONFIG_PPC_MERGE |
2704 | if (check_legacy_ioport(ipmi_defaults[i].port)) | 2699 | if (check_legacy_ioport(ipmi_defaults[i].port)) |
2705 | continue; | 2700 | continue; |
2706 | #endif | 2701 | #endif |
2702 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2703 | if (!info) | ||
2704 | return; | ||
2707 | 2705 | ||
2708 | info->addr_source = NULL; | 2706 | info->addr_source = NULL; |
2709 | 2707 | ||
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..505d7a1f6b8c 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: |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index d3d7864e0c1e..5df4003ad873 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); |
@@ -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 e30575e87648..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,14 +1606,17 @@ 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; |
1612 | 1613 | ||
1613 | switch (cmd) { | 1614 | switch (cmd) { |
1614 | case MOXA_GET_MAJOR: | 1615 | case MOXA_GET_MAJOR: |
1615 | printk(KERN_WARNING "mxser: '%s' uses deprecated ioctl %x, fix " | 1616 | if (printk_ratelimit()) |
1616 | "your userspace\n", current->comm, cmd); | 1617 | printk(KERN_WARNING "mxser: '%s' uses deprecated ioctl " |
1618 | "%x (GET_MAJOR), fix your userspace\n", | ||
1619 | current->comm, cmd); | ||
1617 | return put_user(ttymajor, (int __user *)argp); | 1620 | return put_user(ttymajor, (int __user *)argp); |
1618 | 1621 | ||
1619 | case MOXA_CHKPORTENABLE: | 1622 | case MOXA_CHKPORTENABLE: |
@@ -1641,12 +1644,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1641 | 1644 | ||
1642 | if (!port->ioaddr) | 1645 | if (!port->ioaddr) |
1643 | goto copy; | 1646 | goto copy; |
1647 | |||
1648 | tty = tty_port_tty_get(&port->port); | ||
1644 | 1649 | ||
1645 | if (!port->port.tty || !port->port.tty->termios) | 1650 | if (!tty || !tty->termios) |
1646 | ms.cflag = port->normal_termios.c_cflag; | 1651 | ms.cflag = port->normal_termios.c_cflag; |
1647 | else | 1652 | else |
1648 | ms.cflag = port->port.tty->termios->c_cflag; | 1653 | ms.cflag = tty->termios->c_cflag; |
1649 | 1654 | tty_kref_put(tty); | |
1650 | status = inb(port->ioaddr + UART_MSR); | 1655 | status = inb(port->ioaddr + UART_MSR); |
1651 | if (status & UART_MSR_DCD) | 1656 | if (status & UART_MSR_DCD) |
1652 | ms.dcd = 1; | 1657 | ms.dcd = 1; |
@@ -1702,15 +1707,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1702 | me->up_txcnt[p] = port->mon_data.up_txcnt; | 1707 | me->up_txcnt[p] = port->mon_data.up_txcnt; |
1703 | me->modem_status[p] = | 1708 | me->modem_status[p] = |
1704 | port->mon_data.modem_status; | 1709 | port->mon_data.modem_status; |
1705 | me->baudrate[p] = tty_get_baud_rate(port->port.tty); | 1710 | tty = tty_port_tty_get(&port->port); |
1706 | 1711 | ||
1707 | if (!port->port.tty || !port->port.tty->termios) { | 1712 | if (!tty || !tty->termios) { |
1708 | cflag = port->normal_termios.c_cflag; | 1713 | cflag = port->normal_termios.c_cflag; |
1709 | iflag = port->normal_termios.c_iflag; | 1714 | iflag = port->normal_termios.c_iflag; |
1715 | me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); | ||
1710 | } else { | 1716 | } else { |
1711 | cflag = port->port.tty->termios->c_cflag; | 1717 | cflag = tty->termios->c_cflag; |
1712 | iflag = port->port.tty->termios->c_iflag; | 1718 | iflag = tty->termios->c_iflag; |
1719 | me->baudrate[p] = tty_get_baud_rate(tty); | ||
1713 | } | 1720 | } |
1721 | tty_kref_put(tty); | ||
1714 | 1722 | ||
1715 | me->databits[p] = cflag & CSIZE; | 1723 | me->databits[p] = cflag & CSIZE; |
1716 | me->stopbits[p] = cflag & CSTOPB; | 1724 | me->stopbits[p] = cflag & CSTOPB; |
@@ -1820,12 +1828,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1820 | switch (cmd) { | 1828 | switch (cmd) { |
1821 | case TIOCGSERIAL: | 1829 | case TIOCGSERIAL: |
1822 | lock_kernel(); | 1830 | lock_kernel(); |
1823 | retval = mxser_get_serial_info(info, argp); | 1831 | retval = mxser_get_serial_info(tty, argp); |
1824 | unlock_kernel(); | 1832 | unlock_kernel(); |
1825 | return retval; | 1833 | return retval; |
1826 | case TIOCSSERIAL: | 1834 | case TIOCSSERIAL: |
1827 | lock_kernel(); | 1835 | lock_kernel(); |
1828 | retval = mxser_set_serial_info(info, argp); | 1836 | retval = mxser_set_serial_info(tty, argp); |
1829 | unlock_kernel(); | 1837 | unlock_kernel(); |
1830 | return retval; | 1838 | return retval; |
1831 | case TIOCSERGETLSR: /* Get line status register */ | 1839 | case TIOCSERGETLSR: /* Get line status register */ |
@@ -1894,7 +1902,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1894 | 1902 | ||
1895 | lock_kernel(); | 1903 | lock_kernel(); |
1896 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1904 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1897 | mxser_check_modem_status(info, status); | 1905 | mxser_check_modem_status(tty, info, status); |
1898 | 1906 | ||
1899 | mcr = inb(info->ioaddr + UART_MCR); | 1907 | mcr = inb(info->ioaddr + UART_MCR); |
1900 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1908 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
@@ -1907,7 +1915,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1907 | else | 1915 | else |
1908 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | 1916 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; |
1909 | 1917 | ||
1910 | if (info->port.tty->hw_stopped) | 1918 | if (tty->hw_stopped) |
1911 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1919 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1912 | else | 1920 | else |
1913 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1921 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
@@ -1956,7 +1964,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1956 | } | 1964 | } |
1957 | } | 1965 | } |
1958 | 1966 | ||
1959 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 1967 | if (tty->termios->c_cflag & CRTSCTS) { |
1960 | info->MCR &= ~UART_MCR_RTS; | 1968 | info->MCR &= ~UART_MCR_RTS; |
1961 | outb(info->MCR, info->ioaddr + UART_MCR); | 1969 | outb(info->MCR, info->ioaddr + UART_MCR); |
1962 | } | 1970 | } |
@@ -1993,7 +2001,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1993 | } | 2001 | } |
1994 | } | 2002 | } |
1995 | 2003 | ||
1996 | if (info->port.tty->termios->c_cflag & CRTSCTS) { | 2004 | if (tty->termios->c_cflag & CRTSCTS) { |
1997 | info->MCR |= UART_MCR_RTS; | 2005 | info->MCR |= UART_MCR_RTS; |
1998 | outb(info->MCR, info->ioaddr + UART_MCR); | 2006 | outb(info->MCR, info->ioaddr + UART_MCR); |
1999 | } | 2007 | } |
@@ -2038,7 +2046,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
2038 | unsigned long flags; | 2046 | unsigned long flags; |
2039 | 2047 | ||
2040 | spin_lock_irqsave(&info->slock, flags); | 2048 | spin_lock_irqsave(&info->slock, flags); |
2041 | mxser_change_speed(info, old_termios); | 2049 | mxser_change_speed(tty, old_termios); |
2042 | spin_unlock_irqrestore(&info->slock, flags); | 2050 | spin_unlock_irqrestore(&info->slock, flags); |
2043 | 2051 | ||
2044 | if ((old_termios->c_cflag & CRTSCTS) && | 2052 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -2136,10 +2144,10 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2136 | struct mxser_port *info = tty->driver_data; | 2144 | struct mxser_port *info = tty->driver_data; |
2137 | 2145 | ||
2138 | mxser_flush_buffer(tty); | 2146 | mxser_flush_buffer(tty); |
2139 | mxser_shutdown(info); | 2147 | mxser_shutdown(tty); |
2140 | info->port.count = 0; | 2148 | info->port.count = 0; |
2141 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 2149 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
2142 | info->port.tty = NULL; | 2150 | tty_port_tty_set(&info->port, NULL); |
2143 | wake_up_interruptible(&info->port.open_wait); | 2151 | wake_up_interruptible(&info->port.open_wait); |
2144 | } | 2152 | } |
2145 | 2153 | ||
@@ -2162,9 +2170,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state) | |||
2162 | return 0; | 2170 | return 0; |
2163 | } | 2171 | } |
2164 | 2172 | ||
2165 | 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) | ||
2166 | { | 2175 | { |
2167 | struct tty_struct *tty = port->port.tty; | ||
2168 | unsigned char ch, gdl; | 2176 | unsigned char ch, gdl; |
2169 | int ignored = 0; | 2177 | int ignored = 0; |
2170 | int cnt = 0; | 2178 | int cnt = 0; |
@@ -2172,9 +2180,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status) | |||
2172 | int max = 256; | 2180 | int max = 256; |
2173 | 2181 | ||
2174 | recv_room = tty->receive_room; | 2182 | recv_room = tty->receive_room; |
2175 | if ((recv_room == 0) && (!port->ldisc_stop_rx)) | 2183 | if (recv_room == 0 && !port->ldisc_stop_rx) |
2176 | mxser_stoprx(tty); | 2184 | mxser_stoprx(tty); |
2177 | |||
2178 | if (port->board->chip_flag != MOXA_OTHER_UART) { | 2185 | if (port->board->chip_flag != MOXA_OTHER_UART) { |
2179 | 2186 | ||
2180 | if (*status & UART_LSR_SPECIAL) | 2187 | if (*status & UART_LSR_SPECIAL) |
@@ -2251,7 +2258,7 @@ intr_old: | |||
2251 | } while (*status & UART_LSR_DR); | 2258 | } while (*status & UART_LSR_DR); |
2252 | 2259 | ||
2253 | end_intr: | 2260 | end_intr: |
2254 | mxvar_log.rxcnt[port->port.tty->index] += cnt; | 2261 | mxvar_log.rxcnt[tty->index] += cnt; |
2255 | port->mon_data.rxcnt += cnt; | 2262 | port->mon_data.rxcnt += cnt; |
2256 | port->mon_data.up_rxcnt += cnt; | 2263 | port->mon_data.up_rxcnt += cnt; |
2257 | 2264 | ||
@@ -2265,14 +2272,14 @@ end_intr: | |||
2265 | spin_lock(&port->slock); | 2272 | spin_lock(&port->slock); |
2266 | } | 2273 | } |
2267 | 2274 | ||
2268 | static void mxser_transmit_chars(struct mxser_port *port) | 2275 | static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) |
2269 | { | 2276 | { |
2270 | int count, cnt; | 2277 | int count, cnt; |
2271 | 2278 | ||
2272 | if (port->x_char) { | 2279 | if (port->x_char) { |
2273 | outb(port->x_char, port->ioaddr + UART_TX); | 2280 | outb(port->x_char, port->ioaddr + UART_TX); |
2274 | port->x_char = 0; | 2281 | port->x_char = 0; |
2275 | mxvar_log.txcnt[port->port.tty->index]++; | 2282 | mxvar_log.txcnt[tty->index]++; |
2276 | port->mon_data.txcnt++; | 2283 | port->mon_data.txcnt++; |
2277 | port->mon_data.up_txcnt++; | 2284 | port->mon_data.up_txcnt++; |
2278 | port->icount.tx++; | 2285 | port->icount.tx++; |
@@ -2282,8 +2289,8 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2282 | if (port->port.xmit_buf == NULL) | 2289 | if (port->port.xmit_buf == NULL) |
2283 | return; | 2290 | return; |
2284 | 2291 | ||
2285 | if ((port->xmit_cnt <= 0) || port->port.tty->stopped || | 2292 | if (port->xmit_cnt <= 0 || tty->stopped || |
2286 | (port->port.tty->hw_stopped && | 2293 | (tty->hw_stopped && |
2287 | (port->type != PORT_16550A) && | 2294 | (port->type != PORT_16550A) && |
2288 | (!port->board->chip_flag))) { | 2295 | (!port->board->chip_flag))) { |
2289 | port->IER &= ~UART_IER_THRI; | 2296 | port->IER &= ~UART_IER_THRI; |
@@ -2300,14 +2307,14 @@ static void mxser_transmit_chars(struct mxser_port *port) | |||
2300 | if (--port->xmit_cnt <= 0) | 2307 | if (--port->xmit_cnt <= 0) |
2301 | break; | 2308 | break; |
2302 | } while (--count > 0); | 2309 | } while (--count > 0); |
2303 | mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); | 2310 | mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); |
2304 | 2311 | ||
2305 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | 2312 | port->mon_data.txcnt += (cnt - port->xmit_cnt); |
2306 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | 2313 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); |
2307 | port->icount.tx += (cnt - port->xmit_cnt); | 2314 | port->icount.tx += (cnt - port->xmit_cnt); |
2308 | 2315 | ||
2309 | if (port->xmit_cnt < WAKEUP_CHARS) | 2316 | if (port->xmit_cnt < WAKEUP_CHARS && tty) |
2310 | tty_wakeup(port->port.tty); | 2317 | tty_wakeup(tty); |
2311 | 2318 | ||
2312 | if (port->xmit_cnt <= 0) { | 2319 | if (port->xmit_cnt <= 0) { |
2313 | port->IER &= ~UART_IER_THRI; | 2320 | port->IER &= ~UART_IER_THRI; |
@@ -2326,6 +2333,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2326 | int max, irqbits, bits, msr; | 2333 | int max, irqbits, bits, msr; |
2327 | unsigned int int_cnt, pass_counter = 0; | 2334 | unsigned int int_cnt, pass_counter = 0; |
2328 | int handled = IRQ_NONE; | 2335 | int handled = IRQ_NONE; |
2336 | struct tty_struct *tty; | ||
2329 | 2337 | ||
2330 | for (i = 0; i < MXSER_BOARDS; i++) | 2338 | for (i = 0; i < MXSER_BOARDS; i++) |
2331 | if (dev_id == &mxser_boards[i]) { | 2339 | if (dev_id == &mxser_boards[i]) { |
@@ -2358,13 +2366,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2358 | if (iir & UART_IIR_NO_INT) | 2366 | if (iir & UART_IIR_NO_INT) |
2359 | break; | 2367 | break; |
2360 | iir &= MOXA_MUST_IIR_MASK; | 2368 | iir &= MOXA_MUST_IIR_MASK; |
2361 | if (!port->port.tty || | 2369 | tty = tty_port_tty_get(&port->port); |
2370 | if (!tty || | ||
2362 | (port->port.flags & ASYNC_CLOSING) || | 2371 | (port->port.flags & ASYNC_CLOSING) || |
2363 | !(port->port.flags & | 2372 | !(port->port.flags & |
2364 | ASYNC_INITIALIZED)) { | 2373 | ASYNC_INITIALIZED)) { |
2365 | status = inb(port->ioaddr + UART_LSR); | 2374 | status = inb(port->ioaddr + UART_LSR); |
2366 | outb(0x27, port->ioaddr + UART_FCR); | 2375 | outb(0x27, port->ioaddr + UART_FCR); |
2367 | inb(port->ioaddr + UART_MSR); | 2376 | inb(port->ioaddr + UART_MSR); |
2377 | tty_kref_put(tty); | ||
2368 | break; | 2378 | break; |
2369 | } | 2379 | } |
2370 | 2380 | ||
@@ -2385,27 +2395,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
2385 | iir == MOXA_MUST_IIR_RDA || | 2395 | iir == MOXA_MUST_IIR_RDA || |
2386 | iir == MOXA_MUST_IIR_RTO || | 2396 | iir == MOXA_MUST_IIR_RTO || |
2387 | iir == MOXA_MUST_IIR_LSR) | 2397 | iir == MOXA_MUST_IIR_LSR) |
2388 | mxser_receive_chars(port, | 2398 | mxser_receive_chars(tty, port, |
2389 | &status); | 2399 | &status); |
2390 | 2400 | ||
2391 | } else { | 2401 | } else { |
2392 | status &= port->read_status_mask; | 2402 | status &= port->read_status_mask; |
2393 | if (status & UART_LSR_DR) | 2403 | if (status & UART_LSR_DR) |
2394 | mxser_receive_chars(port, | 2404 | mxser_receive_chars(tty, port, |
2395 | &status); | 2405 | &status); |
2396 | } | 2406 | } |
2397 | msr = inb(port->ioaddr + UART_MSR); | 2407 | msr = inb(port->ioaddr + UART_MSR); |
2398 | if (msr & UART_MSR_ANY_DELTA) | 2408 | if (msr & UART_MSR_ANY_DELTA) |
2399 | mxser_check_modem_status(port, msr); | 2409 | mxser_check_modem_status(tty, port, msr); |
2400 | 2410 | ||
2401 | if (port->board->chip_flag) { | 2411 | if (port->board->chip_flag) { |
2402 | if (iir == 0x02 && (status & | 2412 | if (iir == 0x02 && (status & |
2403 | UART_LSR_THRE)) | 2413 | UART_LSR_THRE)) |
2404 | mxser_transmit_chars(port); | 2414 | mxser_transmit_chars(tty, port); |
2405 | } else { | 2415 | } else { |
2406 | if (status & UART_LSR_THRE) | 2416 | if (status & UART_LSR_THRE) |
2407 | mxser_transmit_chars(port); | 2417 | mxser_transmit_chars(tty, port); |
2408 | } | 2418 | } |
2419 | tty_kref_put(tty); | ||
2409 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | 2420 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); |
2410 | spin_unlock(&port->slock); | 2421 | spin_unlock(&port->slock); |
2411 | } | 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/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index b1414507997c..569f2f7743a7 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/tty_driver.h> | 29 | #include <linux/tty_driver.h> |
30 | #include <linux/tty_flip.h> | 30 | #include <linux/tty_flip.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/version.h> | ||
33 | 32 | ||
34 | #include "tty.h" | 33 | #include "tty.h" |
35 | #include "network.h" | 34 | #include "network.h" |
@@ -277,6 +276,7 @@ static int ipw_write_room(struct tty_struct *linux_tty) | |||
277 | struct ipw_tty *tty = linux_tty->driver_data; | 276 | struct ipw_tty *tty = linux_tty->driver_data; |
278 | int room; | 277 | int room; |
279 | 278 | ||
279 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
280 | if (!tty) | 280 | if (!tty) |
281 | return -ENODEV; | 281 | return -ENODEV; |
282 | 282 | ||
@@ -398,6 +398,7 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set, | |||
398 | 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) |
399 | { | 399 | { |
400 | 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 .. */ | ||
401 | 402 | ||
402 | if (!tty) | 403 | if (!tty) |
403 | return -ENODEV; | 404 | return -ENODEV; |
@@ -413,6 +414,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, struct file *file, | |||
413 | unsigned int set, unsigned int clear) | 414 | unsigned int set, unsigned int clear) |
414 | { | 415 | { |
415 | 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 .. */ | ||
416 | 418 | ||
417 | if (!tty) | 419 | if (!tty) |
418 | return -ENODEV; | 420 | return -ENODEV; |
@@ -434,6 +436,8 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
434 | if (!tty->open_count) | 436 | if (!tty->open_count) |
435 | return -EINVAL; | 437 | return -EINVAL; |
436 | 438 | ||
439 | /* FIXME: Exactly how is the tty object locked here .. */ | ||
440 | |||
437 | switch (cmd) { | 441 | switch (cmd) { |
438 | case TIOCGSERIAL: | 442 | case TIOCGSERIAL: |
439 | return ipwireless_get_serial_info(tty, (void __user *) arg); | 443 | return ipwireless_get_serial_info(tty, (void __user *) arg); |
@@ -468,13 +472,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
468 | } | 472 | } |
469 | return 0; | 473 | return 0; |
470 | 474 | ||
471 | case TCGETS: | ||
472 | case TCGETA: | ||
473 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
474 | |||
475 | case TCFLSH: | ||
476 | return n_tty_ioctl(linux_tty, file, cmd, arg); | ||
477 | |||
478 | case FIONREAD: | 475 | case FIONREAD: |
479 | { | 476 | { |
480 | int val = 0; | 477 | int val = 0; |
@@ -483,10 +480,11 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, | |||
483 | return -EFAULT; | 480 | return -EFAULT; |
484 | } | 481 | } |
485 | return 0; | 482 | return 0; |
483 | case TCFLSH: | ||
484 | return tty_perform_flush(linux_tty, arg); | ||
486 | } | 485 | } |
487 | } | 486 | } |
488 | 487 | return tty_mode_ioctl(linux_tty, file, cmd , arg); | |
489 | return -ENOIOCTLCMD; | ||
490 | } | 488 | } |
491 | 489 | ||
492 | static int add_tty(dev_node_t *nodesp, int j, | 490 | static int add_tty(dev_node_t *nodesp, int j, |
@@ -589,6 +587,8 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
589 | tty_hangup(ttyj->linux_tty); | 587 | tty_hangup(ttyj->linux_tty); |
590 | /* Wait till the tty_hangup has completed */ | 588 | /* Wait till the tty_hangup has completed */ |
591 | flush_scheduled_work(); | 589 | flush_scheduled_work(); |
590 | /* FIXME: Exactly how is the tty object locked here | ||
591 | against a parallel ioctl etc */ | ||
592 | mutex_lock(&ttyj->ipw_tty_mutex); | 592 | mutex_lock(&ttyj->ipw_tty_mutex); |
593 | } | 593 | } |
594 | 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 05bf9c55ecc2..9a626e50b793 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -232,7 +232,6 @@ typedef struct _mgslpc_info { | |||
232 | 232 | ||
233 | /* SPPP/Cisco HDLC device parts */ | 233 | /* SPPP/Cisco HDLC device parts */ |
234 | int netcount; | 234 | int netcount; |
235 | int dosyncppp; | ||
236 | spinlock_t netlock; | 235 | spinlock_t netlock; |
237 | 236 | ||
238 | #if SYNCLINK_GENERIC_HDLC | 237 | #if SYNCLINK_GENERIC_HDLC |
@@ -459,13 +458,11 @@ static int ttymajor=0; | |||
459 | 458 | ||
460 | static int debug_level = 0; | 459 | static int debug_level = 0; |
461 | static int maxframe[MAX_DEVICE_COUNT] = {0,}; | 460 | static int maxframe[MAX_DEVICE_COUNT] = {0,}; |
462 | static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1}; | ||
463 | 461 | ||
464 | module_param(break_on_load, bool, 0); | 462 | module_param(break_on_load, bool, 0); |
465 | module_param(ttymajor, int, 0); | 463 | module_param(ttymajor, int, 0); |
466 | module_param(debug_level, int, 0); | 464 | module_param(debug_level, int, 0); |
467 | module_param_array(maxframe, int, NULL, 0); | 465 | module_param_array(maxframe, int, NULL, 0); |
468 | module_param_array(dosyncppp, int, NULL, 0); | ||
469 | 466 | ||
470 | MODULE_LICENSE("GPL"); | 467 | MODULE_LICENSE("GPL"); |
471 | 468 | ||
@@ -2915,7 +2912,6 @@ static void mgslpc_add_device(MGSLPC_INFO *info) | |||
2915 | if (info->line < MAX_DEVICE_COUNT) { | 2912 | if (info->line < MAX_DEVICE_COUNT) { |
2916 | if (maxframe[info->line]) | 2913 | if (maxframe[info->line]) |
2917 | info->max_frame_size = maxframe[info->line]; | 2914 | info->max_frame_size = maxframe[info->line]; |
2918 | info->dosyncppp = dosyncppp[info->line]; | ||
2919 | } | 2915 | } |
2920 | 2916 | ||
2921 | mgslpc_device_count++; | 2917 | mgslpc_device_count++; |
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 e0d0e371909c..6af435b89867 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -407,7 +407,7 @@ struct entropy_store { | |||
407 | /* read-write data: */ | 407 | /* read-write data: */ |
408 | spinlock_t lock; | 408 | spinlock_t lock; |
409 | unsigned add_ptr; | 409 | unsigned add_ptr; |
410 | int entropy_count; | 410 | int entropy_count; /* Must at no time exceed ->POOLBITS! */ |
411 | int input_rotate; | 411 | int input_rotate; |
412 | }; | 412 | }; |
413 | 413 | ||
@@ -520,6 +520,7 @@ static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes) | |||
520 | static void credit_entropy_bits(struct entropy_store *r, int nbits) | 520 | static void credit_entropy_bits(struct entropy_store *r, int nbits) |
521 | { | 521 | { |
522 | unsigned long flags; | 522 | unsigned long flags; |
523 | int entropy_count; | ||
523 | 524 | ||
524 | if (!nbits) | 525 | if (!nbits) |
525 | return; | 526 | return; |
@@ -527,20 +528,20 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) | |||
527 | spin_lock_irqsave(&r->lock, flags); | 528 | spin_lock_irqsave(&r->lock, flags); |
528 | 529 | ||
529 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | 530 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); |
530 | r->entropy_count += nbits; | 531 | entropy_count = r->entropy_count; |
531 | if (r->entropy_count < 0) { | 532 | entropy_count += nbits; |
533 | if (entropy_count < 0) { | ||
532 | DEBUG_ENT("negative entropy/overflow\n"); | 534 | DEBUG_ENT("negative entropy/overflow\n"); |
533 | r->entropy_count = 0; | 535 | entropy_count = 0; |
534 | } else if (r->entropy_count > r->poolinfo->POOLBITS) | 536 | } else if (entropy_count > r->poolinfo->POOLBITS) |
535 | r->entropy_count = r->poolinfo->POOLBITS; | 537 | entropy_count = r->poolinfo->POOLBITS; |
538 | r->entropy_count = entropy_count; | ||
536 | 539 | ||
537 | /* should we wake readers? */ | 540 | /* should we wake readers? */ |
538 | if (r == &input_pool && | 541 | if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) { |
539 | r->entropy_count >= random_read_wakeup_thresh) { | ||
540 | wake_up_interruptible(&random_read_wait); | 542 | wake_up_interruptible(&random_read_wait); |
541 | kill_fasync(&fasync, SIGIO, POLL_IN); | 543 | kill_fasync(&fasync, SIGIO, POLL_IN); |
542 | } | 544 | } |
543 | |||
544 | spin_unlock_irqrestore(&r->lock, flags); | 545 | spin_unlock_irqrestore(&r->lock, flags); |
545 | } | 546 | } |
546 | 547 | ||
@@ -660,10 +661,10 @@ void add_disk_randomness(struct gendisk *disk) | |||
660 | if (!disk || !disk->random) | 661 | if (!disk || !disk->random) |
661 | return; | 662 | return; |
662 | /* first major is 1, so we get >= 0x200 here */ | 663 | /* first major is 1, so we get >= 0x200 here */ |
663 | DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor); | 664 | DEBUG_ENT("disk event %d:%d\n", |
665 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
664 | 666 | ||
665 | add_timer_randomness(disk->random, | 667 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
666 | 0x100 + MKDEV(disk->major, disk->first_minor)); | ||
667 | } | 668 | } |
668 | #endif | 669 | #endif |
669 | 670 | ||
@@ -1571,6 +1572,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | |||
1571 | 1572 | ||
1572 | return half_md4_transform(hash, keyptr->secret); | 1573 | return half_md4_transform(hash, keyptr->secret); |
1573 | } | 1574 | } |
1575 | EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); | ||
1574 | 1576 | ||
1575 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1577 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1576 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, | 1578 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index d9799e2bcfbf..b47710c17885 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -78,7 +78,6 @@ | |||
78 | #include <linux/wait.h> | 78 | #include <linux/wait.h> |
79 | #include <linux/bcd.h> | 79 | #include <linux/bcd.h> |
80 | #include <linux/delay.h> | 80 | #include <linux/delay.h> |
81 | #include <linux/smp_lock.h> | ||
82 | #include <linux/uaccess.h> | 81 | #include <linux/uaccess.h> |
83 | 82 | ||
84 | #include <asm/current.h> | 83 | #include <asm/current.h> |
@@ -89,12 +88,12 @@ | |||
89 | #endif | 88 | #endif |
90 | 89 | ||
91 | #ifdef CONFIG_SPARC32 | 90 | #ifdef CONFIG_SPARC32 |
92 | #include <linux/pci.h> | 91 | #include <linux/of.h> |
93 | #include <linux/jiffies.h> | 92 | #include <linux/of_device.h> |
94 | #include <asm/ebus.h> | 93 | #include <asm/io.h> |
95 | 94 | ||
96 | static unsigned long rtc_port; | 95 | static unsigned long rtc_port; |
97 | static int rtc_irq = PCI_IRQ_NONE; | 96 | static int rtc_irq; |
98 | #endif | 97 | #endif |
99 | 98 | ||
100 | #ifdef CONFIG_HPET_RTC_IRQ | 99 | #ifdef CONFIG_HPET_RTC_IRQ |
@@ -974,8 +973,8 @@ static int __init rtc_init(void) | |||
974 | char *guess = NULL; | 973 | char *guess = NULL; |
975 | #endif | 974 | #endif |
976 | #ifdef CONFIG_SPARC32 | 975 | #ifdef CONFIG_SPARC32 |
977 | struct linux_ebus *ebus; | 976 | struct device_node *ebus_dp; |
978 | struct linux_ebus_device *edev; | 977 | struct of_device *op; |
979 | #else | 978 | #else |
980 | void *r; | 979 | void *r; |
981 | #ifdef RTC_IRQ | 980 | #ifdef RTC_IRQ |
@@ -984,12 +983,16 @@ static int __init rtc_init(void) | |||
984 | #endif | 983 | #endif |
985 | 984 | ||
986 | #ifdef CONFIG_SPARC32 | 985 | #ifdef CONFIG_SPARC32 |
987 | for_each_ebus(ebus) { | 986 | for_each_node_by_name(ebus_dp, "ebus") { |
988 | for_each_ebusdev(edev, ebus) { | 987 | struct device_node *dp; |
989 | if (strcmp(edev->prom_node->name, "rtc") == 0) { | 988 | for (dp = ebus_dp; dp; dp = dp->sibling) { |
990 | rtc_port = edev->resource[0].start; | 989 | if (!strcmp(dp->name, "rtc")) { |
991 | rtc_irq = edev->irqs[0]; | 990 | op = of_find_device_by_node(dp); |
992 | goto found; | 991 | if (op) { |
992 | rtc_port = op->resource[0].start; | ||
993 | rtc_irq = op->irqs[0]; | ||
994 | goto found; | ||
995 | } | ||
993 | } | 996 | } |
994 | } | 997 | } |
995 | } | 998 | } |
@@ -998,7 +1001,7 @@ static int __init rtc_init(void) | |||
998 | return -EIO; | 1001 | return -EIO; |
999 | 1002 | ||
1000 | found: | 1003 | found: |
1001 | if (rtc_irq == PCI_IRQ_NONE) { | 1004 | if (!rtc_irq) { |
1002 | rtc_has_irq = 0; | 1005 | rtc_has_irq = 0; |
1003 | goto no_irq; | 1006 | goto no_irq; |
1004 | } | 1007 | } |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 19db1eb87c26..8b8f07a7f505 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 | /*****************************************************************************/ |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index c385206f9db5..5b8d7a1aa3e6 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 | pci_iounmap(pdev, 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 { |
@@ -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 | pci_iounmap(pdev, 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/synclink.c b/drivers/char/synclink.c index ef6706f09061..500f5176b6ba 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -304,7 +304,6 @@ struct mgsl_struct { | |||
304 | 304 | ||
305 | /* generic HDLC device parts */ | 305 | /* generic HDLC device parts */ |
306 | int netcount; | 306 | int netcount; |
307 | int dosyncppp; | ||
308 | spinlock_t netlock; | 307 | spinlock_t netlock; |
309 | 308 | ||
310 | #if SYNCLINK_GENERIC_HDLC | 309 | #if SYNCLINK_GENERIC_HDLC |
@@ -868,7 +867,6 @@ static int irq[MAX_ISA_DEVICES]; | |||
868 | static int dma[MAX_ISA_DEVICES]; | 867 | static int dma[MAX_ISA_DEVICES]; |
869 | static int debug_level; | 868 | static int debug_level; |
870 | static int maxframe[MAX_TOTAL_DEVICES]; | 869 | static int maxframe[MAX_TOTAL_DEVICES]; |
871 | static int dosyncppp[MAX_TOTAL_DEVICES]; | ||
872 | static int txdmabufs[MAX_TOTAL_DEVICES]; | 870 | static int txdmabufs[MAX_TOTAL_DEVICES]; |
873 | static int txholdbufs[MAX_TOTAL_DEVICES]; | 871 | static int txholdbufs[MAX_TOTAL_DEVICES]; |
874 | 872 | ||
@@ -879,7 +877,6 @@ module_param_array(irq, int, NULL, 0); | |||
879 | module_param_array(dma, int, NULL, 0); | 877 | module_param_array(dma, int, NULL, 0); |
880 | module_param(debug_level, int, 0); | 878 | module_param(debug_level, int, 0); |
881 | module_param_array(maxframe, int, NULL, 0); | 879 | module_param_array(maxframe, int, NULL, 0); |
882 | module_param_array(dosyncppp, int, NULL, 0); | ||
883 | module_param_array(txdmabufs, int, NULL, 0); | 880 | module_param_array(txdmabufs, int, NULL, 0); |
884 | module_param_array(txholdbufs, int, NULL, 0); | 881 | module_param_array(txholdbufs, int, NULL, 0); |
885 | 882 | ||
@@ -4258,7 +4255,6 @@ static void mgsl_add_device( struct mgsl_struct *info ) | |||
4258 | if (info->line < MAX_TOTAL_DEVICES) { | 4255 | if (info->line < MAX_TOTAL_DEVICES) { |
4259 | if (maxframe[info->line]) | 4256 | if (maxframe[info->line]) |
4260 | info->max_frame_size = maxframe[info->line]; | 4257 | info->max_frame_size = maxframe[info->line]; |
4261 | info->dosyncppp = dosyncppp[info->line]; | ||
4262 | 4258 | ||
4263 | if (txdmabufs[info->line]) { | 4259 | if (txdmabufs[info->line]) { |
4264 | info->num_tx_dma_buffers = txdmabufs[info->line]; | 4260 | info->num_tx_dma_buffers = txdmabufs[info->line]; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 3e9058993e41..08911ed66494 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -47,7 +47,6 @@ | |||
47 | 47 | ||
48 | 48 | ||
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/version.h> | ||
51 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
52 | #include <linux/signal.h> | 51 | #include <linux/signal.h> |
53 | #include <linux/sched.h> | 52 | #include <linux/sched.h> |
@@ -128,17 +127,14 @@ static int slgt_device_count; | |||
128 | static int ttymajor; | 127 | static int ttymajor; |
129 | static int debug_level; | 128 | static int debug_level; |
130 | static int maxframe[MAX_DEVICES]; | 129 | static int maxframe[MAX_DEVICES]; |
131 | static int dosyncppp[MAX_DEVICES]; | ||
132 | 130 | ||
133 | module_param(ttymajor, int, 0); | 131 | module_param(ttymajor, int, 0); |
134 | module_param(debug_level, int, 0); | 132 | module_param(debug_level, int, 0); |
135 | module_param_array(maxframe, int, NULL, 0); | 133 | module_param_array(maxframe, int, NULL, 0); |
136 | module_param_array(dosyncppp, int, NULL, 0); | ||
137 | 134 | ||
138 | MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); | 135 | MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); |
139 | MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); | 136 | MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); |
140 | MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); | 137 | MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); |
141 | MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable"); | ||
142 | 138 | ||
143 | /* | 139 | /* |
144 | * tty support and callbacks | 140 | * tty support and callbacks |
@@ -349,7 +345,6 @@ struct slgt_info { | |||
349 | /* SPPP/Cisco HDLC device parts */ | 345 | /* SPPP/Cisco HDLC device parts */ |
350 | 346 | ||
351 | int netcount; | 347 | int netcount; |
352 | int dosyncppp; | ||
353 | spinlock_t netlock; | 348 | spinlock_t netlock; |
354 | #if SYNCLINK_GENERIC_HDLC | 349 | #if SYNCLINK_GENERIC_HDLC |
355 | struct net_device *netdev; | 350 | struct net_device *netdev; |
@@ -3405,7 +3400,6 @@ static void add_device(struct slgt_info *info) | |||
3405 | if (info->line < MAX_DEVICES) { | 3400 | if (info->line < MAX_DEVICES) { |
3406 | if (maxframe[info->line]) | 3401 | if (maxframe[info->line]) |
3407 | info->max_frame_size = maxframe[info->line]; | 3402 | info->max_frame_size = maxframe[info->line]; |
3408 | info->dosyncppp = dosyncppp[info->line]; | ||
3409 | } | 3403 | } |
3410 | 3404 | ||
3411 | slgt_device_count++; | 3405 | slgt_device_count++; |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index c0490cbd0db2..6bdb44f7bec2 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -270,7 +270,6 @@ typedef struct _synclinkmp_info { | |||
270 | 270 | ||
271 | /* SPPP/Cisco HDLC device parts */ | 271 | /* SPPP/Cisco HDLC device parts */ |
272 | int netcount; | 272 | int netcount; |
273 | int dosyncppp; | ||
274 | spinlock_t netlock; | 273 | spinlock_t netlock; |
275 | 274 | ||
276 | #if SYNCLINK_GENERIC_HDLC | 275 | #if SYNCLINK_GENERIC_HDLC |
@@ -469,13 +468,11 @@ static int ttymajor = 0; | |||
469 | */ | 468 | */ |
470 | static int debug_level = 0; | 469 | static int debug_level = 0; |
471 | static int maxframe[MAX_DEVICES] = {0,}; | 470 | static int maxframe[MAX_DEVICES] = {0,}; |
472 | static int dosyncppp[MAX_DEVICES] = {0,}; | ||
473 | 471 | ||
474 | module_param(break_on_load, bool, 0); | 472 | module_param(break_on_load, bool, 0); |
475 | module_param(ttymajor, int, 0); | 473 | module_param(ttymajor, int, 0); |
476 | module_param(debug_level, int, 0); | 474 | module_param(debug_level, int, 0); |
477 | module_param_array(maxframe, int, NULL, 0); | 475 | module_param_array(maxframe, int, NULL, 0); |
478 | module_param_array(dosyncppp, int, NULL, 0); | ||
479 | 476 | ||
480 | static char *driver_name = "SyncLink MultiPort driver"; | 477 | static char *driver_name = "SyncLink MultiPort driver"; |
481 | static char *driver_version = "$Revision: 4.38 $"; | 478 | static char *driver_version = "$Revision: 4.38 $"; |
@@ -3752,7 +3749,6 @@ static void add_device(SLMP_INFO *info) | |||
3752 | if (info->line < MAX_DEVICES) { | 3749 | if (info->line < MAX_DEVICES) { |
3753 | if (maxframe[info->line]) | 3750 | if (maxframe[info->line]) |
3754 | info->max_frame_size = maxframe[info->line]; | 3751 | info->max_frame_size = maxframe[info->line]; |
3755 | info->dosyncppp = dosyncppp[info->line]; | ||
3756 | } | 3752 | } |
3757 | 3753 | ||
3758 | synclinkmp_device_count++; | 3754 | synclinkmp_device_count++; |
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..1fee7034a386 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -954,72 +954,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel); | |||
954 | 954 | ||
955 | /* | 955 | /* |
956 | * Device file system interface to the TPM | 956 | * Device file system interface to the TPM |
957 | * | ||
958 | * It's assured that the chip will be opened just once, | ||
959 | * by the check of is_open variable, which is protected | ||
960 | * by driver_lock. | ||
957 | */ | 961 | */ |
958 | int tpm_open(struct inode *inode, struct file *file) | 962 | int tpm_open(struct inode *inode, struct file *file) |
959 | { | 963 | { |
960 | int rc = 0, minor = iminor(inode); | 964 | int minor = iminor(inode); |
961 | struct tpm_chip *chip = NULL, *pos; | 965 | struct tpm_chip *chip = NULL, *pos; |
962 | 966 | ||
963 | lock_kernel(); | 967 | rcu_read_lock(); |
964 | spin_lock(&driver_lock); | 968 | 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) { | 969 | if (pos->vendor.miscdev.minor == minor) { |
968 | chip = pos; | 970 | chip = pos; |
971 | get_device(chip->dev); | ||
969 | break; | 972 | break; |
970 | } | 973 | } |
971 | } | 974 | } |
975 | rcu_read_unlock(); | ||
972 | 976 | ||
973 | if (chip == NULL) { | 977 | if (!chip) |
974 | rc = -ENODEV; | 978 | return -ENODEV; |
975 | goto err_out; | ||
976 | } | ||
977 | 979 | ||
978 | if (chip->num_opens) { | 980 | if (test_and_set_bit(0, &chip->is_open)) { |
979 | dev_dbg(chip->dev, "Another process owns this TPM\n"); | 981 | dev_dbg(chip->dev, "Another process owns this TPM\n"); |
980 | rc = -EBUSY; | 982 | put_device(chip->dev); |
981 | goto err_out; | 983 | return -EBUSY; |
982 | } | 984 | } |
983 | 985 | ||
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); | 986 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); |
990 | if (chip->data_buffer == NULL) { | 987 | if (chip->data_buffer == NULL) { |
991 | chip->num_opens--; | 988 | clear_bit(0, &chip->is_open); |
992 | put_device(chip->dev); | 989 | put_device(chip->dev); |
993 | unlock_kernel(); | ||
994 | return -ENOMEM; | 990 | return -ENOMEM; |
995 | } | 991 | } |
996 | 992 | ||
997 | atomic_set(&chip->data_pending, 0); | 993 | atomic_set(&chip->data_pending, 0); |
998 | 994 | ||
999 | file->private_data = chip; | 995 | file->private_data = chip; |
1000 | unlock_kernel(); | ||
1001 | return 0; | 996 | return 0; |
1002 | |||
1003 | err_out: | ||
1004 | spin_unlock(&driver_lock); | ||
1005 | unlock_kernel(); | ||
1006 | return rc; | ||
1007 | } | 997 | } |
1008 | EXPORT_SYMBOL_GPL(tpm_open); | 998 | EXPORT_SYMBOL_GPL(tpm_open); |
1009 | 999 | ||
1000 | /* | ||
1001 | * Called on file close | ||
1002 | */ | ||
1010 | int tpm_release(struct inode *inode, struct file *file) | 1003 | int tpm_release(struct inode *inode, struct file *file) |
1011 | { | 1004 | { |
1012 | struct tpm_chip *chip = file->private_data; | 1005 | struct tpm_chip *chip = file->private_data; |
1013 | 1006 | ||
1007 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1014 | flush_scheduled_work(); | 1008 | flush_scheduled_work(); |
1015 | spin_lock(&driver_lock); | ||
1016 | file->private_data = NULL; | 1009 | file->private_data = NULL; |
1017 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1018 | atomic_set(&chip->data_pending, 0); | 1010 | atomic_set(&chip->data_pending, 0); |
1019 | chip->num_opens--; | ||
1020 | put_device(chip->dev); | ||
1021 | kfree(chip->data_buffer); | 1011 | kfree(chip->data_buffer); |
1022 | spin_unlock(&driver_lock); | 1012 | clear_bit(0, &chip->is_open); |
1013 | put_device(chip->dev); | ||
1023 | return 0; | 1014 | return 0; |
1024 | } | 1015 | } |
1025 | EXPORT_SYMBOL_GPL(tpm_release); | 1016 | EXPORT_SYMBOL_GPL(tpm_release); |
@@ -1093,13 +1084,11 @@ void tpm_remove_hardware(struct device *dev) | |||
1093 | } | 1084 | } |
1094 | 1085 | ||
1095 | spin_lock(&driver_lock); | 1086 | spin_lock(&driver_lock); |
1096 | 1087 | list_del_rcu(&chip->list); | |
1097 | list_del(&chip->list); | ||
1098 | |||
1099 | spin_unlock(&driver_lock); | 1088 | spin_unlock(&driver_lock); |
1089 | synchronize_rcu(); | ||
1100 | 1090 | ||
1101 | misc_deregister(&chip->vendor.miscdev); | 1091 | misc_deregister(&chip->vendor.miscdev); |
1102 | |||
1103 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); | 1092 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); |
1104 | tpm_bios_log_teardown(chip->bios_dir); | 1093 | tpm_bios_log_teardown(chip->bios_dir); |
1105 | 1094 | ||
@@ -1144,25 +1133,33 @@ int tpm_pm_resume(struct device *dev) | |||
1144 | } | 1133 | } |
1145 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 1134 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
1146 | 1135 | ||
1136 | /* In case vendor provided release function, call it too.*/ | ||
1137 | |||
1138 | void tpm_dev_vendor_release(struct tpm_chip *chip) | ||
1139 | { | ||
1140 | if (chip->vendor.release) | ||
1141 | chip->vendor.release(chip->dev); | ||
1142 | |||
1143 | clear_bit(chip->dev_num, dev_mask); | ||
1144 | kfree(chip->vendor.miscdev.name); | ||
1145 | } | ||
1146 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | ||
1147 | |||
1148 | |||
1147 | /* | 1149 | /* |
1148 | * Once all references to platform device are down to 0, | 1150 | * Once all references to platform device are down to 0, |
1149 | * release all allocated structures. | 1151 | * release all allocated structures. |
1150 | * In case vendor provided release function, | ||
1151 | * call it too. | ||
1152 | */ | 1152 | */ |
1153 | static void tpm_dev_release(struct device *dev) | 1153 | static void tpm_dev_release(struct device *dev) |
1154 | { | 1154 | { |
1155 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1155 | struct tpm_chip *chip = dev_get_drvdata(dev); |
1156 | 1156 | ||
1157 | if (chip->vendor.release) | 1157 | tpm_dev_vendor_release(chip); |
1158 | chip->vendor.release(dev); | ||
1159 | 1158 | ||
1160 | chip->release(dev); | 1159 | chip->release(dev); |
1161 | |||
1162 | clear_bit(chip->dev_num, dev_mask); | ||
1163 | kfree(chip->vendor.miscdev.name); | ||
1164 | kfree(chip); | 1160 | kfree(chip); |
1165 | } | 1161 | } |
1162 | EXPORT_SYMBOL_GPL(tpm_dev_release); | ||
1166 | 1163 | ||
1167 | /* | 1164 | /* |
1168 | * Called from tpm_<specific>.c probe function only for devices | 1165 | * Called from tpm_<specific>.c probe function only for devices |
@@ -1171,8 +1168,8 @@ static void tpm_dev_release(struct device *dev) | |||
1171 | * upon errant exit from this function specific probe function should call | 1168 | * upon errant exit from this function specific probe function should call |
1172 | * pci_disable_device | 1169 | * pci_disable_device |
1173 | */ | 1170 | */ |
1174 | struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific | 1171 | struct tpm_chip *tpm_register_hardware(struct device *dev, |
1175 | *entry) | 1172 | const struct tpm_vendor_specific *entry) |
1176 | { | 1173 | { |
1177 | #define DEVNAME_SIZE 7 | 1174 | #define DEVNAME_SIZE 7 |
1178 | 1175 | ||
@@ -1231,21 +1228,20 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1231 | return NULL; | 1228 | return NULL; |
1232 | } | 1229 | } |
1233 | 1230 | ||
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)) { | 1231 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { |
1241 | list_del(&chip->list); | ||
1242 | misc_deregister(&chip->vendor.miscdev); | 1232 | misc_deregister(&chip->vendor.miscdev); |
1243 | put_device(chip->dev); | 1233 | put_device(chip->dev); |
1234 | |||
1244 | return NULL; | 1235 | return NULL; |
1245 | } | 1236 | } |
1246 | 1237 | ||
1247 | chip->bios_dir = tpm_bios_log_setup(devname); | 1238 | chip->bios_dir = tpm_bios_log_setup(devname); |
1248 | 1239 | ||
1240 | /* Make chip available */ | ||
1241 | spin_lock(&driver_lock); | ||
1242 | list_add_rcu(&chip->list, &tpm_chip_list); | ||
1243 | spin_unlock(&driver_lock); | ||
1244 | |||
1249 | return chip; | 1245 | return chip; |
1250 | } | 1246 | } |
1251 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 1247 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
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 e1b46bc7e43c..7053d6333692 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 | } |
@@ -695,13 +294,23 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
695 | { | 294 | { |
696 | struct tty_driver *p, *res = NULL; | 295 | struct tty_driver *p, *res = NULL; |
697 | int tty_line = 0; | 296 | int tty_line = 0; |
297 | int len; | ||
698 | char *str; | 298 | char *str; |
699 | 299 | ||
300 | for (str = name; *str; str++) | ||
301 | if ((*str >= '0' && *str <= '9') || *str == ',') | ||
302 | break; | ||
303 | if (!*str) | ||
304 | return NULL; | ||
305 | |||
306 | len = str - name; | ||
307 | tty_line = simple_strtoul(str, &str, 10); | ||
308 | |||
700 | mutex_lock(&tty_mutex); | 309 | mutex_lock(&tty_mutex); |
701 | /* Search through the tty devices to look for a match */ | 310 | /* Search through the tty devices to look for a match */ |
702 | list_for_each_entry(p, &tty_drivers, tty_drivers) { | 311 | list_for_each_entry(p, &tty_drivers, tty_drivers) { |
703 | str = name + strlen(p->name); | 312 | if (strncmp(name, p->name, len) != 0) |
704 | tty_line = simple_strtoul(str, &str, 10); | 313 | continue; |
705 | if (*str == ',') | 314 | if (*str == ',') |
706 | str++; | 315 | str++; |
707 | if (*str == '\0') | 316 | if (*str == '\0') |
@@ -709,7 +318,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
709 | 318 | ||
710 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 319 | if (tty_line >= 0 && tty_line <= p->num && p->ops && |
711 | 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)) { |
712 | res = p; | 321 | res = tty_driver_kref_get(p); |
713 | *line = tty_line; | 322 | *line = tty_line; |
714 | break; | 323 | break; |
715 | } | 324 | } |
@@ -809,20 +418,6 @@ static const struct file_operations tty_fops = { | |||
809 | .fasync = tty_fasync, | 418 | .fasync = tty_fasync, |
810 | }; | 419 | }; |
811 | 420 | ||
812 | #ifdef CONFIG_UNIX98_PTYS | ||
813 | static const struct file_operations ptmx_fops = { | ||
814 | .llseek = no_llseek, | ||
815 | .read = tty_read, | ||
816 | .write = tty_write, | ||
817 | .poll = tty_poll, | ||
818 | .unlocked_ioctl = tty_ioctl, | ||
819 | .compat_ioctl = tty_compat_ioctl, | ||
820 | .open = ptmx_open, | ||
821 | .release = tty_release, | ||
822 | .fasync = tty_fasync, | ||
823 | }; | ||
824 | #endif | ||
825 | |||
826 | static const struct file_operations console_fops = { | 421 | static const struct file_operations console_fops = { |
827 | .llseek = no_llseek, | 422 | .llseek = no_llseek, |
828 | .read = tty_read, | 423 | .read = tty_read, |
@@ -943,6 +538,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
943 | struct tty_ldisc *ld; | 538 | struct tty_ldisc *ld; |
944 | int closecount = 0, n; | 539 | int closecount = 0, n; |
945 | unsigned long flags; | 540 | unsigned long flags; |
541 | int refs = 0; | ||
946 | 542 | ||
947 | if (!tty) | 543 | if (!tty) |
948 | return; | 544 | return; |
@@ -1009,8 +605,12 @@ static void do_tty_hangup(struct work_struct *work) | |||
1009 | if (tty->session) { | 605 | if (tty->session) { |
1010 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { | 606 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
1011 | spin_lock_irq(&p->sighand->siglock); | 607 | spin_lock_irq(&p->sighand->siglock); |
1012 | if (p->signal->tty == tty) | 608 | if (p->signal->tty == tty) { |
1013 | p->signal->tty = NULL; | 609 | p->signal->tty = NULL; |
610 | /* We defer the dereferences outside fo | ||
611 | the tasklist lock */ | ||
612 | refs++; | ||
613 | } | ||
1014 | if (!p->signal->leader) { | 614 | if (!p->signal->leader) { |
1015 | spin_unlock_irq(&p->sighand->siglock); | 615 | spin_unlock_irq(&p->sighand->siglock); |
1016 | continue; | 616 | continue; |
@@ -1036,6 +636,10 @@ static void do_tty_hangup(struct work_struct *work) | |||
1036 | tty->ctrl_status = 0; | 636 | tty->ctrl_status = 0; |
1037 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 637 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1038 | 638 | ||
639 | /* Account for the p->signal references we killed */ | ||
640 | while (refs--) | ||
641 | tty_kref_put(tty); | ||
642 | |||
1039 | /* | 643 | /* |
1040 | * If one of the devices matches a console pointer, we | 644 | * If one of the devices matches a console pointer, we |
1041 | * cannot just call hangup() because that will cause | 645 | * cannot just call hangup() because that will cause |
@@ -1105,6 +709,23 @@ void tty_vhangup(struct tty_struct *tty) | |||
1105 | EXPORT_SYMBOL(tty_vhangup); | 709 | EXPORT_SYMBOL(tty_vhangup); |
1106 | 710 | ||
1107 | /** | 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 | /** | ||
1108 | * tty_hung_up_p - was tty hung up | 729 | * tty_hung_up_p - was tty hung up |
1109 | * @filp: file pointer of tty | 730 | * @filp: file pointer of tty |
1110 | * | 731 | * |
@@ -1157,16 +778,14 @@ void disassociate_ctty(int on_exit) | |||
1157 | struct pid *tty_pgrp = NULL; | 778 | struct pid *tty_pgrp = NULL; |
1158 | 779 | ||
1159 | 780 | ||
1160 | mutex_lock(&tty_mutex); | ||
1161 | tty = get_current_tty(); | 781 | tty = get_current_tty(); |
1162 | if (tty) { | 782 | if (tty) { |
1163 | tty_pgrp = get_pid(tty->pgrp); | 783 | tty_pgrp = get_pid(tty->pgrp); |
1164 | mutex_unlock(&tty_mutex); | ||
1165 | lock_kernel(); | 784 | lock_kernel(); |
1166 | /* XXX: here we race, there is nothing protecting tty */ | ||
1167 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 785 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1168 | tty_vhangup(tty); | 786 | tty_vhangup(tty); |
1169 | unlock_kernel(); | 787 | unlock_kernel(); |
788 | tty_kref_put(tty); | ||
1170 | } else if (on_exit) { | 789 | } else if (on_exit) { |
1171 | struct pid *old_pgrp; | 790 | struct pid *old_pgrp; |
1172 | spin_lock_irq(¤t->sighand->siglock); | 791 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1178,7 +797,6 @@ void disassociate_ctty(int on_exit) | |||
1178 | kill_pgrp(old_pgrp, SIGCONT, on_exit); | 797 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
1179 | put_pid(old_pgrp); | 798 | put_pid(old_pgrp); |
1180 | } | 799 | } |
1181 | mutex_unlock(&tty_mutex); | ||
1182 | return; | 800 | return; |
1183 | } | 801 | } |
1184 | if (tty_pgrp) { | 802 | if (tty_pgrp) { |
@@ -1193,8 +811,6 @@ void disassociate_ctty(int on_exit) | |||
1193 | current->signal->tty_old_pgrp = NULL; | 811 | current->signal->tty_old_pgrp = NULL; |
1194 | spin_unlock_irq(¤t->sighand->siglock); | 812 | spin_unlock_irq(¤t->sighand->siglock); |
1195 | 813 | ||
1196 | mutex_lock(&tty_mutex); | ||
1197 | /* It is possible that do_tty_hangup has free'd this tty */ | ||
1198 | tty = get_current_tty(); | 814 | tty = get_current_tty(); |
1199 | if (tty) { | 815 | if (tty) { |
1200 | unsigned long flags; | 816 | unsigned long flags; |
@@ -1204,13 +820,13 @@ void disassociate_ctty(int on_exit) | |||
1204 | tty->session = NULL; | 820 | tty->session = NULL; |
1205 | tty->pgrp = NULL; | 821 | tty->pgrp = NULL; |
1206 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 822 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
823 | tty_kref_put(tty); | ||
1207 | } else { | 824 | } else { |
1208 | #ifdef TTY_DEBUG_HANGUP | 825 | #ifdef TTY_DEBUG_HANGUP |
1209 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 826 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
1210 | " = NULL", tty); | 827 | " = NULL", tty); |
1211 | #endif | 828 | #endif |
1212 | } | 829 | } |
1213 | mutex_unlock(&tty_mutex); | ||
1214 | 830 | ||
1215 | /* Now clear signal->tty under the lock */ | 831 | /* Now clear signal->tty under the lock */ |
1216 | read_lock(&tasklist_lock); | 832 | read_lock(&tasklist_lock); |
@@ -1410,19 +1026,19 @@ static inline ssize_t do_tty_write( | |||
1410 | 1026 | ||
1411 | /* 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 */ |
1412 | if (tty->write_cnt < chunk) { | 1028 | if (tty->write_cnt < chunk) { |
1413 | unsigned char *buf; | 1029 | unsigned char *buf_chunk; |
1414 | 1030 | ||
1415 | if (chunk < 1024) | 1031 | if (chunk < 1024) |
1416 | chunk = 1024; | 1032 | chunk = 1024; |
1417 | 1033 | ||
1418 | buf = kmalloc(chunk, GFP_KERNEL); | 1034 | buf_chunk = kmalloc(chunk, GFP_KERNEL); |
1419 | if (!buf) { | 1035 | if (!buf_chunk) { |
1420 | ret = -ENOMEM; | 1036 | ret = -ENOMEM; |
1421 | goto out; | 1037 | goto out; |
1422 | } | 1038 | } |
1423 | kfree(tty->write_buf); | 1039 | kfree(tty->write_buf); |
1424 | tty->write_cnt = chunk; | 1040 | tty->write_cnt = chunk; |
1425 | tty->write_buf = buf; | 1041 | tty->write_buf = buf_chunk; |
1426 | } | 1042 | } |
1427 | 1043 | ||
1428 | /* Do the write .. */ | 1044 | /* Do the write .. */ |
@@ -1456,6 +1072,31 @@ out: | |||
1456 | return ret; | 1072 | return ret; |
1457 | } | 1073 | } |
1458 | 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 | |||
1459 | 1100 | ||
1460 | /** | 1101 | /** |
1461 | * tty_write - write method for tty device file | 1102 | * tty_write - write method for tty device file |
@@ -1523,42 +1164,6 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
1523 | return tty_write(file, buf, count, ppos); | 1164 | return tty_write(file, buf, count, ppos); |
1524 | } | 1165 | } |
1525 | 1166 | ||
1526 | void tty_port_init(struct tty_port *port) | ||
1527 | { | ||
1528 | memset(port, 0, sizeof(*port)); | ||
1529 | init_waitqueue_head(&port->open_wait); | ||
1530 | init_waitqueue_head(&port->close_wait); | ||
1531 | mutex_init(&port->mutex); | ||
1532 | port->close_delay = (50 * HZ) / 100; | ||
1533 | port->closing_wait = (3000 * HZ) / 100; | ||
1534 | } | ||
1535 | EXPORT_SYMBOL(tty_port_init); | ||
1536 | |||
1537 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
1538 | { | ||
1539 | /* We may sleep in get_zeroed_page() */ | ||
1540 | mutex_lock(&port->mutex); | ||
1541 | if (port->xmit_buf == NULL) | ||
1542 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
1543 | mutex_unlock(&port->mutex); | ||
1544 | if (port->xmit_buf == NULL) | ||
1545 | return -ENOMEM; | ||
1546 | return 0; | ||
1547 | } | ||
1548 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
1549 | |||
1550 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
1551 | { | ||
1552 | mutex_lock(&port->mutex); | ||
1553 | if (port->xmit_buf != NULL) { | ||
1554 | free_page((unsigned long)port->xmit_buf); | ||
1555 | port->xmit_buf = NULL; | ||
1556 | } | ||
1557 | mutex_unlock(&port->mutex); | ||
1558 | } | ||
1559 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
1560 | |||
1561 | |||
1562 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1167 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1563 | 1168 | ||
1564 | /** | 1169 | /** |
@@ -1582,7 +1187,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1582 | } | 1187 | } |
1583 | 1188 | ||
1584 | /** | 1189 | /** |
1585 | * pty_line_name - generate name for a tty | 1190 | * tty_line_name - generate name for a tty |
1586 | * @driver: the tty driver in use | 1191 | * @driver: the tty driver in use |
1587 | * @index: the minor number | 1192 | * @index: the minor number |
1588 | * @p: output buffer of at least 7 bytes | 1193 | * @p: output buffer of at least 7 bytes |
@@ -1598,10 +1203,148 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1598 | } | 1203 | } |
1599 | 1204 | ||
1600 | /** | 1205 | /** |
1601 | * 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 | ||
1602 | * @driver: tty driver we are opening a device on | 1344 | * @driver: tty driver we are opening a device on |
1603 | * @idx: device index | 1345 | * @idx: device index |
1604 | * @tty: returned tty structure | 1346 | * @ret_tty: returned tty structure |
1347 | * @first_ok: ok to open a new device (used by ptmx) | ||
1605 | * | 1348 | * |
1606 | * 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 |
1607 | * could also be an active device. The pty drivers require special | 1350 | * could also be an active device. The pty drivers require special |
@@ -1621,37 +1364,16 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p) | |||
1621 | * relaxed for the (most common) case of reopening a tty. | 1364 | * relaxed for the (most common) case of reopening a tty. |
1622 | */ | 1365 | */ |
1623 | 1366 | ||
1624 | static int init_dev(struct tty_driver *driver, int idx, | 1367 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, |
1625 | struct tty_struct **ret_tty) | 1368 | int first_ok) |
1626 | { | 1369 | { |
1627 | struct tty_struct *tty, *o_tty; | 1370 | struct tty_struct *tty; |
1628 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1371 | int retval; |
1629 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | ||
1630 | int retval = 0; | ||
1631 | 1372 | ||
1632 | /* check whether we're reopening an existing tty */ | 1373 | /* Check if pty master is being opened multiple times */ |
1633 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1374 | if (driver->subtype == PTY_TYPE_MASTER && |
1634 | tty = devpts_get_tty(idx); | 1375 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) |
1635 | /* | 1376 | return ERR_PTR(-EIO); |
1636 | * If we don't have a tty here on a slave open, it's because | ||
1637 | * the master already started the close process and there's | ||
1638 | * no relation between devpts file and tty anymore. | ||
1639 | */ | ||
1640 | if (!tty && driver->subtype == PTY_TYPE_SLAVE) { | ||
1641 | retval = -EIO; | ||
1642 | goto end_init; | ||
1643 | } | ||
1644 | /* | ||
1645 | * It's safe from now on because init_dev() is called with | ||
1646 | * tty_mutex held and release_dev() won't change tty->count | ||
1647 | * or tty->flags without having to grab tty_mutex | ||
1648 | */ | ||
1649 | if (tty && driver->subtype == PTY_TYPE_MASTER) | ||
1650 | tty = tty->link; | ||
1651 | } else { | ||
1652 | tty = driver->ttys[idx]; | ||
1653 | } | ||
1654 | if (tty) goto fast_track; | ||
1655 | 1377 | ||
1656 | /* | 1378 | /* |
1657 | * First time open is complex, especially for PTY devices. | 1379 | * First time open is complex, especially for PTY devices. |
@@ -1661,189 +1383,69 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1661 | * and locked termios may be retained.) | 1383 | * and locked termios may be retained.) |
1662 | */ | 1384 | */ |
1663 | 1385 | ||
1664 | if (!try_module_get(driver->owner)) { | 1386 | if (!try_module_get(driver->owner)) |
1665 | retval = -ENODEV; | 1387 | return ERR_PTR(-ENODEV); |
1666 | goto end_init; | ||
1667 | } | ||
1668 | |||
1669 | o_tty = NULL; | ||
1670 | tp = o_tp = NULL; | ||
1671 | ltp = o_ltp = NULL; | ||
1672 | 1388 | ||
1673 | tty = alloc_tty_struct(); | 1389 | tty = alloc_tty_struct(); |
1674 | if (!tty) | 1390 | if (!tty) |
1675 | goto fail_no_mem; | 1391 | goto fail_no_mem; |
1676 | initialize_tty_struct(tty); | 1392 | initialize_tty_struct(tty, driver, idx); |
1677 | tty->driver = driver; | ||
1678 | tty->ops = driver->ops; | ||
1679 | tty->index = idx; | ||
1680 | tty_line_name(driver, idx, tty->name); | ||
1681 | |||
1682 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1683 | tp_loc = &tty->termios; | ||
1684 | ltp_loc = &tty->termios_locked; | ||
1685 | } else { | ||
1686 | tp_loc = &driver->termios[idx]; | ||
1687 | ltp_loc = &driver->termios_locked[idx]; | ||
1688 | } | ||
1689 | |||
1690 | if (!*tp_loc) { | ||
1691 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1692 | if (!tp) | ||
1693 | goto free_mem_out; | ||
1694 | *tp = driver->init_termios; | ||
1695 | } | ||
1696 | |||
1697 | if (!*ltp_loc) { | ||
1698 | ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1699 | if (!ltp) | ||
1700 | goto free_mem_out; | ||
1701 | } | ||
1702 | |||
1703 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | ||
1704 | o_tty = alloc_tty_struct(); | ||
1705 | if (!o_tty) | ||
1706 | goto free_mem_out; | ||
1707 | initialize_tty_struct(o_tty); | ||
1708 | o_tty->driver = driver->other; | ||
1709 | o_tty->ops = driver->ops; | ||
1710 | o_tty->index = idx; | ||
1711 | tty_line_name(driver->other, idx, o_tty->name); | ||
1712 | |||
1713 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | ||
1714 | o_tp_loc = &o_tty->termios; | ||
1715 | o_ltp_loc = &o_tty->termios_locked; | ||
1716 | } else { | ||
1717 | o_tp_loc = &driver->other->termios[idx]; | ||
1718 | o_ltp_loc = &driver->other->termios_locked[idx]; | ||
1719 | } | ||
1720 | |||
1721 | if (!*o_tp_loc) { | ||
1722 | o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1723 | if (!o_tp) | ||
1724 | goto free_mem_out; | ||
1725 | *o_tp = driver->other->init_termios; | ||
1726 | } | ||
1727 | 1393 | ||
1728 | if (!*o_ltp_loc) { | 1394 | retval = tty_driver_install_tty(driver, tty); |
1729 | o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL); | 1395 | if (retval < 0) { |
1730 | if (!o_ltp) | 1396 | free_tty_struct(tty); |
1731 | goto free_mem_out; | 1397 | module_put(driver->owner); |
1732 | } | 1398 | return ERR_PTR(retval); |
1733 | |||
1734 | /* | ||
1735 | * Everything allocated ... set up the o_tty structure. | ||
1736 | */ | ||
1737 | if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1738 | driver->other->ttys[idx] = o_tty; | ||
1739 | if (!*o_tp_loc) | ||
1740 | *o_tp_loc = o_tp; | ||
1741 | if (!*o_ltp_loc) | ||
1742 | *o_ltp_loc = o_ltp; | ||
1743 | o_tty->termios = *o_tp_loc; | ||
1744 | o_tty->termios_locked = *o_ltp_loc; | ||
1745 | driver->other->refcount++; | ||
1746 | if (driver->subtype == PTY_TYPE_MASTER) | ||
1747 | o_tty->count++; | ||
1748 | |||
1749 | /* Establish the links in both directions */ | ||
1750 | tty->link = o_tty; | ||
1751 | o_tty->link = tty; | ||
1752 | } | 1399 | } |
1753 | 1400 | ||
1754 | /* | 1401 | /* |
1755 | * All structures have been allocated, so now we install them. | ||
1756 | * Failures after this point use release_tty to clean up, so | ||
1757 | * there's no need to null out the local pointers. | ||
1758 | */ | ||
1759 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) | ||
1760 | driver->ttys[idx] = tty; | ||
1761 | |||
1762 | if (!*tp_loc) | ||
1763 | *tp_loc = tp; | ||
1764 | if (!*ltp_loc) | ||
1765 | *ltp_loc = ltp; | ||
1766 | tty->termios = *tp_loc; | ||
1767 | tty->termios_locked = *ltp_loc; | ||
1768 | /* Compatibility until drivers always set this */ | ||
1769 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1770 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1771 | driver->refcount++; | ||
1772 | tty->count++; | ||
1773 | |||
1774 | /* | ||
1775 | * Structures all installed ... call the ldisc open routines. | 1402 | * Structures all installed ... call the ldisc open routines. |
1776 | * 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 |
1777 | * to decrement the use counts, as release_tty doesn't care. | 1404 | * to decrement the use counts, as release_tty doesn't care. |
1778 | */ | 1405 | */ |
1779 | 1406 | ||
1780 | retval = tty_ldisc_setup(tty, o_tty); | 1407 | retval = tty_ldisc_setup(tty, tty->link); |
1781 | |||
1782 | if (retval) | 1408 | if (retval) |
1783 | goto release_mem_out; | 1409 | goto release_mem_out; |
1784 | goto success; | 1410 | return tty; |
1785 | |||
1786 | /* | ||
1787 | * This fast open can be used if the tty is already open. | ||
1788 | * No memory is allocated, and the only failures are from | ||
1789 | * attempting to open a closing tty or attempting multiple | ||
1790 | * opens on a pty master. | ||
1791 | */ | ||
1792 | fast_track: | ||
1793 | if (test_bit(TTY_CLOSING, &tty->flags)) { | ||
1794 | retval = -EIO; | ||
1795 | goto end_init; | ||
1796 | } | ||
1797 | if (driver->type == TTY_DRIVER_TYPE_PTY && | ||
1798 | driver->subtype == PTY_TYPE_MASTER) { | ||
1799 | /* | ||
1800 | * special case for PTY masters: only one open permitted, | ||
1801 | * and the slave side open count is incremented as well. | ||
1802 | */ | ||
1803 | if (tty->count) { | ||
1804 | retval = -EIO; | ||
1805 | goto end_init; | ||
1806 | } | ||
1807 | tty->link->count++; | ||
1808 | } | ||
1809 | tty->count++; | ||
1810 | tty->driver = driver; /* N.B. why do this every time?? */ | ||
1811 | |||
1812 | /* FIXME */ | ||
1813 | if (!test_bit(TTY_LDISC, &tty->flags)) | ||
1814 | printk(KERN_ERR "init_dev but no ldisc\n"); | ||
1815 | success: | ||
1816 | *ret_tty = tty; | ||
1817 | |||
1818 | /* All paths come through here to release the mutex */ | ||
1819 | end_init: | ||
1820 | return retval; | ||
1821 | |||
1822 | /* Release locally allocated memory ... nothing placed in slots */ | ||
1823 | free_mem_out: | ||
1824 | kfree(o_tp); | ||
1825 | if (o_tty) | ||
1826 | free_tty_struct(o_tty); | ||
1827 | kfree(ltp); | ||
1828 | kfree(tp); | ||
1829 | free_tty_struct(tty); | ||
1830 | 1411 | ||
1831 | fail_no_mem: | 1412 | fail_no_mem: |
1832 | module_put(driver->owner); | 1413 | module_put(driver->owner); |
1833 | retval = -ENOMEM; | 1414 | return ERR_PTR(-ENOMEM); |
1834 | goto end_init; | ||
1835 | 1415 | ||
1836 | /* call the tty release_tty routine to clean out this slot */ | 1416 | /* call the tty release_tty routine to clean out this slot */ |
1837 | release_mem_out: | 1417 | release_mem_out: |
1838 | if (printk_ratelimit()) | 1418 | if (printk_ratelimit()) |
1839 | printk(KERN_INFO "init_dev: ldisc open failed, " | 1419 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1840 | "clearing slot %d\n", idx); | 1420 | "clearing slot %d\n", idx); |
1841 | release_tty(tty, idx); | 1421 | release_tty(tty, idx); |
1842 | goto end_init; | 1422 | return ERR_PTR(retval); |
1843 | } | 1423 | } |
1844 | 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 | |||
1845 | /** | 1446 | /** |
1846 | * release_one_tty - release tty structure memory | 1447 | * release_one_tty - release tty structure memory |
1448 | * @kref: kref of tty we are obliterating | ||
1847 | * | 1449 | * |
1848 | * Releases memory associated with a tty structure, and clears out the | 1450 | * Releases memory associated with a tty structure, and clears out the |
1849 | * 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 |
@@ -1853,31 +1455,19 @@ release_mem_out: | |||
1853 | * tty_mutex - sometimes only | 1455 | * tty_mutex - sometimes only |
1854 | * takes the file list lock internally when working on the list | 1456 | * takes the file list lock internally when working on the list |
1855 | * of ttys that the driver keeps. | 1457 | * of ttys that the driver keeps. |
1856 | * FIXME: should we require tty_mutex is held here ?? | ||
1857 | */ | 1458 | */ |
1858 | static void release_one_tty(struct tty_struct *tty, int idx) | 1459 | static void release_one_tty(struct kref *kref) |
1859 | { | 1460 | { |
1860 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 1461 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1861 | struct ktermios *tp; | 1462 | struct tty_driver *driver = tty->driver; |
1862 | |||
1863 | if (!devpts) | ||
1864 | tty->driver->ttys[idx] = NULL; | ||
1865 | |||
1866 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
1867 | tp = tty->termios; | ||
1868 | if (!devpts) | ||
1869 | tty->driver->termios[idx] = NULL; | ||
1870 | kfree(tp); | ||
1871 | |||
1872 | tp = tty->termios_locked; | ||
1873 | if (!devpts) | ||
1874 | tty->driver->termios_locked[idx] = NULL; | ||
1875 | kfree(tp); | ||
1876 | } | ||
1877 | |||
1878 | 1463 | ||
1464 | if (tty->ops->shutdown) | ||
1465 | tty->ops->shutdown(tty); | ||
1466 | else | ||
1467 | tty_shutdown(tty); | ||
1879 | tty->magic = 0; | 1468 | tty->magic = 0; |
1880 | tty->driver->refcount--; | 1469 | tty_driver_kref_put(driver); |
1470 | module_put(driver->owner); | ||
1881 | 1471 | ||
1882 | file_list_lock(); | 1472 | file_list_lock(); |
1883 | list_del_init(&tty->tty_files); | 1473 | list_del_init(&tty->tty_files); |
@@ -1887,6 +1477,21 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1887 | } | 1477 | } |
1888 | 1478 | ||
1889 | /** | 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 | /** | ||
1890 | * release_tty - release tty structure memory | 1495 | * release_tty - release tty structure memory |
1891 | * | 1496 | * |
1892 | * Release both @tty and a possible linked partner (think pty pair), | 1497 | * Release both @tty and a possible linked partner (think pty pair), |
@@ -1897,15 +1502,16 @@ static void release_one_tty(struct tty_struct *tty, int idx) | |||
1897 | * takes the file list lock internally when working on the list | 1502 | * takes the file list lock internally when working on the list |
1898 | * of ttys that the driver keeps. | 1503 | * of ttys that the driver keeps. |
1899 | * FIXME: should we require tty_mutex is held here ?? | 1504 | * FIXME: should we require tty_mutex is held here ?? |
1505 | * | ||
1900 | */ | 1506 | */ |
1901 | static void release_tty(struct tty_struct *tty, int idx) | 1507 | static void release_tty(struct tty_struct *tty, int idx) |
1902 | { | 1508 | { |
1903 | struct tty_driver *driver = tty->driver; | 1509 | /* This should always be true but check for the moment */ |
1510 | WARN_ON(tty->index != idx); | ||
1904 | 1511 | ||
1905 | if (tty->link) | 1512 | if (tty->link) |
1906 | release_one_tty(tty->link, idx); | 1513 | tty_kref_put(tty->link); |
1907 | release_one_tty(tty, idx); | 1514 | tty_kref_put(tty); |
1908 | module_put(driver->owner); | ||
1909 | } | 1515 | } |
1910 | 1516 | ||
1911 | /* | 1517 | /* |
@@ -1916,20 +1522,21 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1916 | * 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 |
1917 | * lead to double frees or releasing memory still in use. | 1523 | * lead to double frees or releasing memory still in use. |
1918 | */ | 1524 | */ |
1919 | static void release_dev(struct file *filp) | 1525 | void tty_release_dev(struct file *filp) |
1920 | { | 1526 | { |
1921 | struct tty_struct *tty, *o_tty; | 1527 | struct tty_struct *tty, *o_tty; |
1922 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1528 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1923 | int devpts; | 1529 | int devpts; |
1924 | int idx; | 1530 | int idx; |
1925 | char buf[64]; | 1531 | char buf[64]; |
1532 | struct inode *inode; | ||
1926 | 1533 | ||
1534 | inode = filp->f_path.dentry->d_inode; | ||
1927 | tty = (struct tty_struct *)filp->private_data; | 1535 | tty = (struct tty_struct *)filp->private_data; |
1928 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, | 1536 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1929 | "release_dev")) | ||
1930 | return; | 1537 | return; |
1931 | 1538 | ||
1932 | check_tty_count(tty, "release_dev"); | 1539 | check_tty_count(tty, "tty_release_dev"); |
1933 | 1540 | ||
1934 | tty_fasync(-1, filp, 0); | 1541 | tty_fasync(-1, filp, 0); |
1935 | 1542 | ||
@@ -1941,33 +1548,27 @@ static void release_dev(struct file *filp) | |||
1941 | 1548 | ||
1942 | #ifdef TTY_PARANOIA_CHECK | 1549 | #ifdef TTY_PARANOIA_CHECK |
1943 | if (idx < 0 || idx >= tty->driver->num) { | 1550 | if (idx < 0 || idx >= tty->driver->num) { |
1944 | printk(KERN_DEBUG "release_dev: bad idx when trying to " | 1551 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1945 | "free (%s)\n", tty->name); | 1552 | "free (%s)\n", tty->name); |
1946 | return; | 1553 | return; |
1947 | } | 1554 | } |
1948 | if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1555 | if (!devpts) { |
1949 | if (tty != tty->driver->ttys[idx]) { | 1556 | if (tty != tty->driver->ttys[idx]) { |
1950 | printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " | 1557 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1951 | "for (%s)\n", idx, tty->name); | 1558 | "for (%s)\n", idx, tty->name); |
1952 | return; | 1559 | return; |
1953 | } | 1560 | } |
1954 | if (tty->termios != tty->driver->termios[idx]) { | 1561 | if (tty->termios != tty->driver->termios[idx]) { |
1955 | printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " | 1562 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1956 | "for (%s)\n", | 1563 | "for (%s)\n", |
1957 | idx, tty->name); | 1564 | idx, tty->name); |
1958 | return; | 1565 | return; |
1959 | } | 1566 | } |
1960 | if (tty->termios_locked != tty->driver->termios_locked[idx]) { | ||
1961 | printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not " | ||
1962 | "termios_locked for (%s)\n", | ||
1963 | idx, tty->name); | ||
1964 | return; | ||
1965 | } | ||
1966 | } | 1567 | } |
1967 | #endif | 1568 | #endif |
1968 | 1569 | ||
1969 | #ifdef TTY_DEBUG_HANGUP | 1570 | #ifdef TTY_DEBUG_HANGUP |
1970 | printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", | 1571 | printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", |
1971 | tty_name(tty, buf), tty->count); | 1572 | tty_name(tty, buf), tty->count); |
1972 | #endif | 1573 | #endif |
1973 | 1574 | ||
@@ -1975,26 +1576,19 @@ static void release_dev(struct file *filp) | |||
1975 | if (tty->driver->other && | 1576 | if (tty->driver->other && |
1976 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1577 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1977 | if (o_tty != tty->driver->other->ttys[idx]) { | 1578 | if (o_tty != tty->driver->other->ttys[idx]) { |
1978 | printk(KERN_DEBUG "release_dev: other->table[%d] " | 1579 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1979 | "not o_tty for (%s)\n", | 1580 | "not o_tty for (%s)\n", |
1980 | idx, tty->name); | 1581 | idx, tty->name); |
1981 | return; | 1582 | return; |
1982 | } | 1583 | } |
1983 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1584 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1984 | printk(KERN_DEBUG "release_dev: other->termios[%d] " | 1585 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1985 | "not o_termios for (%s)\n", | 1586 | "not o_termios for (%s)\n", |
1986 | idx, tty->name); | 1587 | idx, tty->name); |
1987 | return; | 1588 | return; |
1988 | } | 1589 | } |
1989 | if (o_tty->termios_locked != | ||
1990 | tty->driver->other->termios_locked[idx]) { | ||
1991 | printk(KERN_DEBUG "release_dev: other->termios_locked[" | ||
1992 | "%d] not o_termios_locked for (%s)\n", | ||
1993 | idx, tty->name); | ||
1994 | return; | ||
1995 | } | ||
1996 | if (o_tty->link != tty) { | 1590 | if (o_tty->link != tty) { |
1997 | printk(KERN_DEBUG "release_dev: bad pty pointers\n"); | 1591 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
1998 | return; | 1592 | return; |
1999 | } | 1593 | } |
2000 | } | 1594 | } |
@@ -2052,7 +1646,7 @@ static void release_dev(struct file *filp) | |||
2052 | if (!do_sleep) | 1646 | if (!do_sleep) |
2053 | break; | 1647 | break; |
2054 | 1648 | ||
2055 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " | 1649 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
2056 | "active!\n", tty_name(tty, buf)); | 1650 | "active!\n", tty_name(tty, buf)); |
2057 | mutex_unlock(&tty_mutex); | 1651 | mutex_unlock(&tty_mutex); |
2058 | schedule(); | 1652 | schedule(); |
@@ -2065,14 +1659,14 @@ static void release_dev(struct file *filp) | |||
2065 | */ | 1659 | */ |
2066 | if (pty_master) { | 1660 | if (pty_master) { |
2067 | if (--o_tty->count < 0) { | 1661 | if (--o_tty->count < 0) { |
2068 | printk(KERN_WARNING "release_dev: bad pty slave count " | 1662 | printk(KERN_WARNING "tty_release_dev: bad pty slave count " |
2069 | "(%d) for %s\n", | 1663 | "(%d) for %s\n", |
2070 | o_tty->count, tty_name(o_tty, buf)); | 1664 | o_tty->count, tty_name(o_tty, buf)); |
2071 | o_tty->count = 0; | 1665 | o_tty->count = 0; |
2072 | } | 1666 | } |
2073 | } | 1667 | } |
2074 | if (--tty->count < 0) { | 1668 | if (--tty->count < 0) { |
2075 | 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", |
2076 | tty->count, tty_name(tty, buf)); | 1670 | tty->count, tty_name(tty, buf)); |
2077 | tty->count = 0; | 1671 | tty->count = 0; |
2078 | } | 1672 | } |
@@ -2135,11 +1729,11 @@ static void release_dev(struct file *filp) | |||
2135 | 1729 | ||
2136 | /* Make this pty number available for reallocation */ | 1730 | /* Make this pty number available for reallocation */ |
2137 | if (devpts) | 1731 | if (devpts) |
2138 | devpts_kill_index(idx); | 1732 | devpts_kill_index(inode, idx); |
2139 | } | 1733 | } |
2140 | 1734 | ||
2141 | /** | 1735 | /** |
2142 | * tty_open - open a tty device | 1736 | * __tty_open - open a tty device |
2143 | * @inode: inode of device file | 1737 | * @inode: inode of device file |
2144 | * @filp: file pointer to tty | 1738 | * @filp: file pointer to tty |
2145 | * | 1739 | * |
@@ -2154,14 +1748,14 @@ static void release_dev(struct file *filp) | |||
2154 | * 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 |
2155 | * settings don't persist across reuse. | 1749 | * settings don't persist across reuse. |
2156 | * | 1750 | * |
2157 | * 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. |
2158 | * tty->count should protect the rest. | 1752 | * tty->count should protect the rest. |
2159 | * ->siglock protects ->signal/->sighand | 1753 | * ->siglock protects ->signal/->sighand |
2160 | */ | 1754 | */ |
2161 | 1755 | ||
2162 | static int __tty_open(struct inode *inode, struct file *filp) | 1756 | static int __tty_open(struct inode *inode, struct file *filp) |
2163 | { | 1757 | { |
2164 | struct tty_struct *tty; | 1758 | struct tty_struct *tty = NULL; |
2165 | int noctty, retval; | 1759 | int noctty, retval; |
2166 | struct tty_driver *driver; | 1760 | struct tty_driver *driver; |
2167 | int index; | 1761 | int index; |
@@ -2183,23 +1777,25 @@ retry_open: | |||
2183 | mutex_unlock(&tty_mutex); | 1777 | mutex_unlock(&tty_mutex); |
2184 | return -ENXIO; | 1778 | return -ENXIO; |
2185 | } | 1779 | } |
2186 | driver = tty->driver; | 1780 | driver = tty_driver_kref_get(tty->driver); |
2187 | index = tty->index; | 1781 | index = tty->index; |
2188 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 1782 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
2189 | /* noctty = 1; */ | 1783 | /* noctty = 1; */ |
1784 | /* FIXME: Should we take a driver reference ? */ | ||
1785 | tty_kref_put(tty); | ||
2190 | goto got_driver; | 1786 | goto got_driver; |
2191 | } | 1787 | } |
2192 | #ifdef CONFIG_VT | 1788 | #ifdef CONFIG_VT |
2193 | if (device == MKDEV(TTY_MAJOR, 0)) { | 1789 | if (device == MKDEV(TTY_MAJOR, 0)) { |
2194 | extern struct tty_driver *console_driver; | 1790 | extern struct tty_driver *console_driver; |
2195 | driver = console_driver; | 1791 | driver = tty_driver_kref_get(console_driver); |
2196 | index = fg_console; | 1792 | index = fg_console; |
2197 | noctty = 1; | 1793 | noctty = 1; |
2198 | goto got_driver; | 1794 | goto got_driver; |
2199 | } | 1795 | } |
2200 | #endif | 1796 | #endif |
2201 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | 1797 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { |
2202 | driver = console_device(&index); | 1798 | driver = tty_driver_kref_get(console_device(&index)); |
2203 | if (driver) { | 1799 | if (driver) { |
2204 | /* Don't let /dev/console block */ | 1800 | /* Don't let /dev/console block */ |
2205 | filp->f_flags |= O_NONBLOCK; | 1801 | filp->f_flags |= O_NONBLOCK; |
@@ -2216,10 +1812,25 @@ retry_open: | |||
2216 | return -ENODEV; | 1812 | return -ENODEV; |
2217 | } | 1813 | } |
2218 | got_driver: | 1814 | got_driver: |
2219 | 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 | |||
2220 | mutex_unlock(&tty_mutex); | 1830 | mutex_unlock(&tty_mutex); |
2221 | if (retval) | 1831 | tty_driver_kref_put(driver); |
2222 | return retval; | 1832 | if (IS_ERR(tty)) |
1833 | return PTR_ERR(tty); | ||
2223 | 1834 | ||
2224 | filp->private_data = tty; | 1835 | filp->private_data = tty; |
2225 | file_move(filp, &tty->tty_files); | 1836 | file_move(filp, &tty->tty_files); |
@@ -2247,7 +1858,7 @@ got_driver: | |||
2247 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1858 | printk(KERN_DEBUG "error %d in opening %s...", retval, |
2248 | tty->name); | 1859 | tty->name); |
2249 | #endif | 1860 | #endif |
2250 | release_dev(filp); | 1861 | tty_release_dev(filp); |
2251 | if (retval != -ERESTARTSYS) | 1862 | if (retval != -ERESTARTSYS) |
2252 | return retval; | 1863 | return retval; |
2253 | if (signal_pending(current)) | 1864 | if (signal_pending(current)) |
@@ -2286,69 +1897,6 @@ static int tty_open(struct inode *inode, struct file *filp) | |||
2286 | 1897 | ||
2287 | 1898 | ||
2288 | 1899 | ||
2289 | #ifdef CONFIG_UNIX98_PTYS | ||
2290 | /** | ||
2291 | * ptmx_open - open a unix 98 pty master | ||
2292 | * @inode: inode of device file | ||
2293 | * @filp: file pointer to tty | ||
2294 | * | ||
2295 | * Allocate a unix98 pty master device from the ptmx driver. | ||
2296 | * | ||
2297 | * Locking: tty_mutex protects theinit_dev work. tty->count should | ||
2298 | * protect the rest. | ||
2299 | * allocated_ptys_lock handles the list of free pty numbers | ||
2300 | */ | ||
2301 | |||
2302 | static int __ptmx_open(struct inode *inode, struct file *filp) | ||
2303 | { | ||
2304 | struct tty_struct *tty; | ||
2305 | int retval; | ||
2306 | int index; | ||
2307 | |||
2308 | nonseekable_open(inode, filp); | ||
2309 | |||
2310 | /* find a device that is not in use. */ | ||
2311 | index = devpts_new_index(); | ||
2312 | if (index < 0) | ||
2313 | return index; | ||
2314 | |||
2315 | mutex_lock(&tty_mutex); | ||
2316 | retval = init_dev(ptm_driver, index, &tty); | ||
2317 | mutex_unlock(&tty_mutex); | ||
2318 | |||
2319 | if (retval) | ||
2320 | goto out; | ||
2321 | |||
2322 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | ||
2323 | filp->private_data = tty; | ||
2324 | file_move(filp, &tty->tty_files); | ||
2325 | |||
2326 | retval = devpts_pty_new(tty->link); | ||
2327 | if (retval) | ||
2328 | goto out1; | ||
2329 | |||
2330 | check_tty_count(tty, "ptmx_open"); | ||
2331 | retval = ptm_driver->ops->open(tty, filp); | ||
2332 | if (!retval) | ||
2333 | return 0; | ||
2334 | out1: | ||
2335 | release_dev(filp); | ||
2336 | return retval; | ||
2337 | out: | ||
2338 | devpts_kill_index(index); | ||
2339 | return retval; | ||
2340 | } | ||
2341 | |||
2342 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
2343 | { | ||
2344 | int ret; | ||
2345 | |||
2346 | lock_kernel(); | ||
2347 | ret = __ptmx_open(inode, filp); | ||
2348 | unlock_kernel(); | ||
2349 | return ret; | ||
2350 | } | ||
2351 | #endif | ||
2352 | 1900 | ||
2353 | /** | 1901 | /** |
2354 | * tty_release - vfs callback for close | 1902 | * tty_release - vfs callback for close |
@@ -2359,13 +1907,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
2359 | * this tty. There may however be several such references. | 1907 | * this tty. There may however be several such references. |
2360 | * | 1908 | * |
2361 | * Locking: | 1909 | * Locking: |
2362 | * Takes bkl. See release_dev | 1910 | * Takes bkl. See tty_release_dev |
2363 | */ | 1911 | */ |
2364 | 1912 | ||
2365 | static int tty_release(struct inode *inode, struct file *filp) | 1913 | static int tty_release(struct inode *inode, struct file *filp) |
2366 | { | 1914 | { |
2367 | lock_kernel(); | 1915 | lock_kernel(); |
2368 | release_dev(filp); | 1916 | tty_release_dev(filp); |
2369 | unlock_kernel(); | 1917 | unlock_kernel(); |
2370 | return 0; | 1918 | return 0; |
2371 | } | 1919 | } |
@@ -2496,45 +2044,26 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2496 | } | 2044 | } |
2497 | 2045 | ||
2498 | /** | 2046 | /** |
2499 | * tiocswinsz - implement window size set ioctl | 2047 | * tty_do_resize - resize event |
2500 | * @tty; tty | 2048 | * @tty: tty being resized |
2501 | * @arg: user buffer for result | 2049 | * @real_tty: real tty (not the same as tty if using a pty/tty pair) |
2502 | * | 2050 | * @rows: rows (character) |
2503 | * Copies the user idea of the window size to the kernel. Traditionally | 2051 | * @cols: cols (character) |
2504 | * this is just advisory information but for the Linux console it | ||
2505 | * actually has driver level meaning and triggers a VC resize. | ||
2506 | * | 2052 | * |
2507 | * Locking: | 2053 | * Update the termios variables and send the neccessary signals to |
2508 | * Called function use the console_sem is used to ensure we do | 2054 | * peform a terminal resize correctly |
2509 | * not try and resize the console twice at once. | ||
2510 | * The tty->termios_mutex is used to ensure we don't double | ||
2511 | * resize and get confused. Lock order - tty->termios_mutex before | ||
2512 | * console sem | ||
2513 | */ | 2055 | */ |
2514 | 2056 | ||
2515 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2057 | int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, |
2516 | struct winsize __user *arg) | 2058 | struct winsize *ws) |
2517 | { | 2059 | { |
2518 | struct winsize tmp_ws; | ||
2519 | struct pid *pgrp, *rpgrp; | 2060 | struct pid *pgrp, *rpgrp; |
2520 | unsigned long flags; | 2061 | unsigned long flags; |
2521 | 2062 | ||
2522 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | 2063 | /* For a PTY we need to lock the tty side */ |
2523 | return -EFAULT; | 2064 | mutex_lock(&real_tty->termios_mutex); |
2524 | 2065 | if (!memcmp(ws, &real_tty->winsize, sizeof(*ws))) | |
2525 | mutex_lock(&tty->termios_mutex); | ||
2526 | if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg))) | ||
2527 | goto done; | 2066 | goto done; |
2528 | |||
2529 | #ifdef CONFIG_VT | ||
2530 | if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) { | ||
2531 | if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col, | ||
2532 | tmp_ws.ws_row)) { | ||
2533 | mutex_unlock(&tty->termios_mutex); | ||
2534 | return -ENXIO; | ||
2535 | } | ||
2536 | } | ||
2537 | #endif | ||
2538 | /* Get the PID values and reference them so we can | 2067 | /* Get the PID values and reference them so we can |
2539 | avoid holding the tty ctrl lock while sending signals */ | 2068 | avoid holding the tty ctrl lock while sending signals */ |
2540 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2069 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
@@ -2550,14 +2079,42 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2550 | put_pid(pgrp); | 2079 | put_pid(pgrp); |
2551 | put_pid(rpgrp); | 2080 | put_pid(rpgrp); |
2552 | 2081 | ||
2553 | tty->winsize = tmp_ws; | 2082 | tty->winsize = *ws; |
2554 | real_tty->winsize = tmp_ws; | 2083 | real_tty->winsize = *ws; |
2555 | done: | 2084 | done: |
2556 | mutex_unlock(&tty->termios_mutex); | 2085 | mutex_unlock(&real_tty->termios_mutex); |
2557 | return 0; | 2086 | return 0; |
2558 | } | 2087 | } |
2559 | 2088 | ||
2560 | /** | 2089 | /** |
2090 | * tiocswinsz - implement window size set ioctl | ||
2091 | * @tty; tty | ||
2092 | * @arg: user buffer for result | ||
2093 | * | ||
2094 | * Copies the user idea of the window size to the kernel. Traditionally | ||
2095 | * this is just advisory information but for the Linux console it | ||
2096 | * actually has driver level meaning and triggers a VC resize. | ||
2097 | * | ||
2098 | * Locking: | ||
2099 | * Driver dependant. The default do_resize method takes the | ||
2100 | * tty termios mutex and ctrl_lock. The console takes its own lock | ||
2101 | * then calls into the default method. | ||
2102 | */ | ||
2103 | |||
2104 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | ||
2105 | struct winsize __user *arg) | ||
2106 | { | ||
2107 | struct winsize tmp_ws; | ||
2108 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | ||
2109 | return -EFAULT; | ||
2110 | |||
2111 | if (tty->ops->resize) | ||
2112 | return tty->ops->resize(tty, real_tty, &tmp_ws); | ||
2113 | else | ||
2114 | return tty_do_resize(tty, real_tty, &tmp_ws); | ||
2115 | } | ||
2116 | |||
2117 | /** | ||
2561 | * tioccons - allow admin to move logical console | 2118 | * tioccons - allow admin to move logical console |
2562 | * @file: the file to become console | 2119 | * @file: the file to become console |
2563 | * | 2120 | * |
@@ -2977,7 +2534,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2977 | case TIOCSTI: | 2534 | case TIOCSTI: |
2978 | return tiocsti(tty, p); | 2535 | return tiocsti(tty, p); |
2979 | case TIOCGWINSZ: | 2536 | case TIOCGWINSZ: |
2980 | return tiocgwinsz(tty, p); | 2537 | return tiocgwinsz(real_tty, p); |
2981 | case TIOCSWINSZ: | 2538 | case TIOCSWINSZ: |
2982 | return tiocswinsz(tty, real_tty, p); | 2539 | return tiocswinsz(tty, real_tty, p); |
2983 | case TIOCCONS: | 2540 | case TIOCCONS: |
@@ -3007,10 +2564,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3007 | return put_user(tty->ldisc.ops->num, (int __user *)p); | 2564 | return put_user(tty->ldisc.ops->num, (int __user *)p); |
3008 | case TIOCSETD: | 2565 | case TIOCSETD: |
3009 | return tiocsetd(tty, p); | 2566 | return tiocsetd(tty, p); |
3010 | #ifdef CONFIG_VT | ||
3011 | case TIOCLINUX: | ||
3012 | return tioclinux(tty, arg); | ||
3013 | #endif | ||
3014 | /* | 2567 | /* |
3015 | * Break handling | 2568 | * Break handling |
3016 | */ | 2569 | */ |
@@ -3201,113 +2754,6 @@ void do_SAK(struct tty_struct *tty) | |||
3201 | EXPORT_SYMBOL(do_SAK); | 2754 | EXPORT_SYMBOL(do_SAK); |
3202 | 2755 | ||
3203 | /** | 2756 | /** |
3204 | * flush_to_ldisc | ||
3205 | * @work: tty structure passed from work queue. | ||
3206 | * | ||
3207 | * This routine is called out of the software interrupt to flush data | ||
3208 | * from the buffer chain to the line discipline. | ||
3209 | * | ||
3210 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
3211 | * while invoking the line discipline receive_buf method. The | ||
3212 | * receive_buf method is single threaded for each tty instance. | ||
3213 | */ | ||
3214 | |||
3215 | static void flush_to_ldisc(struct work_struct *work) | ||
3216 | { | ||
3217 | struct tty_struct *tty = | ||
3218 | container_of(work, struct tty_struct, buf.work.work); | ||
3219 | unsigned long flags; | ||
3220 | struct tty_ldisc *disc; | ||
3221 | struct tty_buffer *tbuf, *head; | ||
3222 | char *char_buf; | ||
3223 | unsigned char *flag_buf; | ||
3224 | |||
3225 | disc = tty_ldisc_ref(tty); | ||
3226 | if (disc == NULL) /* !TTY_LDISC */ | ||
3227 | return; | ||
3228 | |||
3229 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3230 | /* So we know a flush is running */ | ||
3231 | set_bit(TTY_FLUSHING, &tty->flags); | ||
3232 | head = tty->buf.head; | ||
3233 | if (head != NULL) { | ||
3234 | tty->buf.head = NULL; | ||
3235 | for (;;) { | ||
3236 | int count = head->commit - head->read; | ||
3237 | if (!count) { | ||
3238 | if (head->next == NULL) | ||
3239 | break; | ||
3240 | tbuf = head; | ||
3241 | head = head->next; | ||
3242 | tty_buffer_free(tty, tbuf); | ||
3243 | continue; | ||
3244 | } | ||
3245 | /* Ldisc or user is trying to flush the buffers | ||
3246 | we are feeding to the ldisc, stop feeding the | ||
3247 | line discipline as we want to empty the queue */ | ||
3248 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | ||
3249 | break; | ||
3250 | if (!tty->receive_room) { | ||
3251 | schedule_delayed_work(&tty->buf.work, 1); | ||
3252 | break; | ||
3253 | } | ||
3254 | if (count > tty->receive_room) | ||
3255 | count = tty->receive_room; | ||
3256 | char_buf = head->char_buf_ptr + head->read; | ||
3257 | flag_buf = head->flag_buf_ptr + head->read; | ||
3258 | head->read += count; | ||
3259 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3260 | disc->ops->receive_buf(tty, char_buf, | ||
3261 | flag_buf, count); | ||
3262 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3263 | } | ||
3264 | /* Restore the queue head */ | ||
3265 | tty->buf.head = head; | ||
3266 | } | ||
3267 | /* We may have a deferred request to flush the input buffer, | ||
3268 | if so pull the chain under the lock and empty the queue */ | ||
3269 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { | ||
3270 | __tty_buffer_flush(tty); | ||
3271 | clear_bit(TTY_FLUSHPENDING, &tty->flags); | ||
3272 | wake_up(&tty->read_wait); | ||
3273 | } | ||
3274 | clear_bit(TTY_FLUSHING, &tty->flags); | ||
3275 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3276 | |||
3277 | tty_ldisc_deref(disc); | ||
3278 | } | ||
3279 | |||
3280 | /** | ||
3281 | * tty_flip_buffer_push - terminal | ||
3282 | * @tty: tty to push | ||
3283 | * | ||
3284 | * Queue a push of the terminal flip buffers to the line discipline. This | ||
3285 | * function must not be called from IRQ context if tty->low_latency is set. | ||
3286 | * | ||
3287 | * In the event of the queue being busy for flipping the work will be | ||
3288 | * held off and retried later. | ||
3289 | * | ||
3290 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
3291 | */ | ||
3292 | |||
3293 | void tty_flip_buffer_push(struct tty_struct *tty) | ||
3294 | { | ||
3295 | unsigned long flags; | ||
3296 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
3297 | if (tty->buf.tail != NULL) | ||
3298 | tty->buf.tail->commit = tty->buf.tail->used; | ||
3299 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
3300 | |||
3301 | if (tty->low_latency) | ||
3302 | flush_to_ldisc(&tty->buf.work.work); | ||
3303 | else | ||
3304 | schedule_delayed_work(&tty->buf.work, 1); | ||
3305 | } | ||
3306 | |||
3307 | EXPORT_SYMBOL(tty_flip_buffer_push); | ||
3308 | |||
3309 | |||
3310 | /** | ||
3311 | * initialize_tty_struct | 2757 | * initialize_tty_struct |
3312 | * @tty: tty to initialize | 2758 | * @tty: tty to initialize |
3313 | * | 2759 | * |
@@ -3317,9 +2763,11 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
3317 | * 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 |
3318 | */ | 2764 | */ |
3319 | 2765 | ||
3320 | 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) | ||
3321 | { | 2768 | { |
3322 | memset(tty, 0, sizeof(struct tty_struct)); | 2769 | memset(tty, 0, sizeof(struct tty_struct)); |
2770 | kref_init(&tty->kref); | ||
3323 | tty->magic = TTY_MAGIC; | 2771 | tty->magic = TTY_MAGIC; |
3324 | tty_ldisc_init(tty); | 2772 | tty_ldisc_init(tty); |
3325 | tty->session = NULL; | 2773 | tty->session = NULL; |
@@ -3327,7 +2775,6 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3327 | tty->overrun_time = jiffies; | 2775 | tty->overrun_time = jiffies; |
3328 | tty->buf.head = tty->buf.tail = NULL; | 2776 | tty->buf.head = tty->buf.tail = NULL; |
3329 | tty_buffer_init(tty); | 2777 | tty_buffer_init(tty); |
3330 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | ||
3331 | mutex_init(&tty->termios_mutex); | 2778 | mutex_init(&tty->termios_mutex); |
3332 | init_waitqueue_head(&tty->write_wait); | 2779 | init_waitqueue_head(&tty->write_wait); |
3333 | init_waitqueue_head(&tty->read_wait); | 2780 | init_waitqueue_head(&tty->read_wait); |
@@ -3338,6 +2785,11 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3338 | spin_lock_init(&tty->ctrl_lock); | 2785 | spin_lock_init(&tty->ctrl_lock); |
3339 | INIT_LIST_HEAD(&tty->tty_files); | 2786 | INIT_LIST_HEAD(&tty->tty_files); |
3340 | 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); | ||
3341 | } | 2793 | } |
3342 | 2794 | ||
3343 | /** | 2795 | /** |
@@ -3358,10 +2810,9 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch) | |||
3358 | return tty->ops->put_char(tty, ch); | 2810 | return tty->ops->put_char(tty, ch); |
3359 | return tty->ops->write(tty, &ch, 1); | 2811 | return tty->ops->write(tty, &ch, 1); |
3360 | } | 2812 | } |
3361 | |||
3362 | EXPORT_SYMBOL_GPL(tty_put_char); | 2813 | EXPORT_SYMBOL_GPL(tty_put_char); |
3363 | 2814 | ||
3364 | static struct class *tty_class; | 2815 | struct class *tty_class; |
3365 | 2816 | ||
3366 | /** | 2817 | /** |
3367 | * tty_register_device - register a tty device | 2818 | * tty_register_device - register a tty device |
@@ -3401,6 +2852,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3401 | 2852 | ||
3402 | return device_create_drvdata(tty_class, device, dev, NULL, name); | 2853 | return device_create_drvdata(tty_class, device, dev, NULL, name); |
3403 | } | 2854 | } |
2855 | EXPORT_SYMBOL(tty_register_device); | ||
3404 | 2856 | ||
3405 | /** | 2857 | /** |
3406 | * tty_unregister_device - unregister a tty device | 2858 | * tty_unregister_device - unregister a tty device |
@@ -3418,8 +2870,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3418 | device_destroy(tty_class, | 2870 | device_destroy(tty_class, |
3419 | MKDEV(driver->major, driver->minor_start) + index); | 2871 | MKDEV(driver->major, driver->minor_start) + index); |
3420 | } | 2872 | } |
3421 | |||
3422 | EXPORT_SYMBOL(tty_register_device); | ||
3423 | EXPORT_SYMBOL(tty_unregister_device); | 2873 | EXPORT_SYMBOL(tty_unregister_device); |
3424 | 2874 | ||
3425 | struct tty_driver *alloc_tty_driver(int lines) | 2875 | struct tty_driver *alloc_tty_driver(int lines) |
@@ -3428,27 +2878,65 @@ struct tty_driver *alloc_tty_driver(int lines) | |||
3428 | 2878 | ||
3429 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 2879 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3430 | if (driver) { | 2880 | if (driver) { |
2881 | kref_init(&driver->kref); | ||
3431 | driver->magic = TTY_DRIVER_MAGIC; | 2882 | driver->magic = TTY_DRIVER_MAGIC; |
3432 | driver->num = lines; | 2883 | driver->num = lines; |
3433 | /* later we'll move allocation of tables here */ | 2884 | /* later we'll move allocation of tables here */ |
3434 | } | 2885 | } |
3435 | return driver; | 2886 | return driver; |
3436 | } | 2887 | } |
2888 | EXPORT_SYMBOL(alloc_tty_driver); | ||
3437 | 2889 | ||
3438 | void put_tty_driver(struct tty_driver *driver) | 2890 | static void destruct_tty_driver(struct kref *kref) |
3439 | { | 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 | } | ||
3440 | kfree(driver); | 2919 | kfree(driver); |
3441 | } | 2920 | } |
3442 | 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 | |||
3443 | void tty_set_operations(struct tty_driver *driver, | 2928 | void tty_set_operations(struct tty_driver *driver, |
3444 | const struct tty_operations *op) | 2929 | const struct tty_operations *op) |
3445 | { | 2930 | { |
3446 | driver->ops = op; | 2931 | driver->ops = op; |
3447 | }; | 2932 | }; |
2933 | EXPORT_SYMBOL(tty_set_operations); | ||
3448 | 2934 | ||
3449 | EXPORT_SYMBOL(alloc_tty_driver); | 2935 | void put_tty_driver(struct tty_driver *d) |
2936 | { | ||
2937 | tty_driver_kref_put(d); | ||
2938 | } | ||
3450 | EXPORT_SYMBOL(put_tty_driver); | 2939 | EXPORT_SYMBOL(put_tty_driver); |
3451 | EXPORT_SYMBOL(tty_set_operations); | ||
3452 | 2940 | ||
3453 | /* | 2941 | /* |
3454 | * Called by a tty driver to register itself. | 2942 | * Called by a tty driver to register itself. |
@@ -3460,11 +2948,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3460 | dev_t dev; | 2948 | dev_t dev; |
3461 | void **p = NULL; | 2949 | void **p = NULL; |
3462 | 2950 | ||
3463 | if (driver->flags & TTY_DRIVER_INSTALLED) | ||
3464 | return 0; | ||
3465 | |||
3466 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | 2951 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
3467 | p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); | 2952 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); |
3468 | if (!p) | 2953 | if (!p) |
3469 | return -ENOMEM; | 2954 | return -ENOMEM; |
3470 | } | 2955 | } |
@@ -3488,12 +2973,9 @@ int tty_register_driver(struct tty_driver *driver) | |||
3488 | if (p) { | 2973 | if (p) { |
3489 | driver->ttys = (struct tty_struct **)p; | 2974 | driver->ttys = (struct tty_struct **)p; |
3490 | driver->termios = (struct ktermios **)(p + driver->num); | 2975 | driver->termios = (struct ktermios **)(p + driver->num); |
3491 | driver->termios_locked = (struct ktermios **) | ||
3492 | (p + driver->num * 2); | ||
3493 | } else { | 2976 | } else { |
3494 | driver->ttys = NULL; | 2977 | driver->ttys = NULL; |
3495 | driver->termios = NULL; | 2978 | driver->termios = NULL; |
3496 | driver->termios_locked = NULL; | ||
3497 | } | 2979 | } |
3498 | 2980 | ||
3499 | cdev_init(&driver->cdev, &tty_fops); | 2981 | cdev_init(&driver->cdev, &tty_fops); |
@@ -3502,7 +2984,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3502 | if (error) { | 2984 | if (error) { |
3503 | unregister_chrdev_region(dev, driver->num); | 2985 | unregister_chrdev_region(dev, driver->num); |
3504 | driver->ttys = NULL; | 2986 | driver->ttys = NULL; |
3505 | driver->termios = driver->termios_locked = NULL; | 2987 | driver->termios = NULL; |
3506 | kfree(p); | 2988 | kfree(p); |
3507 | return error; | 2989 | return error; |
3508 | } | 2990 | } |
@@ -3516,6 +2998,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3516 | tty_register_device(driver, i, NULL); | 2998 | tty_register_device(driver, i, NULL); |
3517 | } | 2999 | } |
3518 | proc_tty_register_driver(driver); | 3000 | proc_tty_register_driver(driver); |
3001 | driver->flags |= TTY_DRIVER_INSTALLED; | ||
3519 | return 0; | 3002 | return 0; |
3520 | } | 3003 | } |
3521 | 3004 | ||
@@ -3526,46 +3009,19 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3526 | */ | 3009 | */ |
3527 | int tty_unregister_driver(struct tty_driver *driver) | 3010 | int tty_unregister_driver(struct tty_driver *driver) |
3528 | { | 3011 | { |
3529 | int i; | 3012 | #if 0 |
3530 | struct ktermios *tp; | 3013 | /* FIXME */ |
3531 | void *p; | ||
3532 | |||
3533 | if (driver->refcount) | 3014 | if (driver->refcount) |
3534 | return -EBUSY; | 3015 | return -EBUSY; |
3535 | 3016 | #endif | |
3536 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3017 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3537 | driver->num); | 3018 | driver->num); |
3538 | mutex_lock(&tty_mutex); | 3019 | mutex_lock(&tty_mutex); |
3539 | list_del(&driver->tty_drivers); | 3020 | list_del(&driver->tty_drivers); |
3540 | mutex_unlock(&tty_mutex); | 3021 | mutex_unlock(&tty_mutex); |
3541 | |||
3542 | /* | ||
3543 | * Free the termios and termios_locked structures because | ||
3544 | * we don't want to get memory leaks when modular tty | ||
3545 | * drivers are removed from the kernel. | ||
3546 | */ | ||
3547 | for (i = 0; i < driver->num; i++) { | ||
3548 | tp = driver->termios[i]; | ||
3549 | if (tp) { | ||
3550 | driver->termios[i] = NULL; | ||
3551 | kfree(tp); | ||
3552 | } | ||
3553 | tp = driver->termios_locked[i]; | ||
3554 | if (tp) { | ||
3555 | driver->termios_locked[i] = NULL; | ||
3556 | kfree(tp); | ||
3557 | } | ||
3558 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | ||
3559 | tty_unregister_device(driver, i); | ||
3560 | } | ||
3561 | p = driver->ttys; | ||
3562 | proc_tty_unregister_driver(driver); | ||
3563 | driver->ttys = NULL; | ||
3564 | driver->termios = driver->termios_locked = NULL; | ||
3565 | kfree(p); | ||
3566 | cdev_del(&driver->cdev); | ||
3567 | return 0; | 3022 | return 0; |
3568 | } | 3023 | } |
3024 | |||
3569 | EXPORT_SYMBOL(tty_unregister_driver); | 3025 | EXPORT_SYMBOL(tty_unregister_driver); |
3570 | 3026 | ||
3571 | dev_t tty_devnum(struct tty_struct *tty) | 3027 | dev_t tty_devnum(struct tty_struct *tty) |
@@ -3576,9 +3032,12 @@ EXPORT_SYMBOL(tty_devnum); | |||
3576 | 3032 | ||
3577 | void proc_clear_tty(struct task_struct *p) | 3033 | void proc_clear_tty(struct task_struct *p) |
3578 | { | 3034 | { |
3035 | struct tty_struct *tty; | ||
3579 | spin_lock_irq(&p->sighand->siglock); | 3036 | spin_lock_irq(&p->sighand->siglock); |
3037 | tty = p->signal->tty; | ||
3580 | p->signal->tty = NULL; | 3038 | p->signal->tty = NULL; |
3581 | spin_unlock_irq(&p->sighand->siglock); | 3039 | spin_unlock_irq(&p->sighand->siglock); |
3040 | tty_kref_put(tty); | ||
3582 | } | 3041 | } |
3583 | 3042 | ||
3584 | /* Called under the sighand lock */ | 3043 | /* Called under the sighand lock */ |
@@ -3594,9 +3053,13 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3594 | tty->pgrp = get_pid(task_pgrp(tsk)); | 3053 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3595 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 3054 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
3596 | tty->session = get_pid(task_session(tsk)); | 3055 | tty->session = get_pid(task_session(tsk)); |
3056 | if (tsk->signal->tty) { | ||
3057 | printk(KERN_DEBUG "tty not NULL!!\n"); | ||
3058 | tty_kref_put(tsk->signal->tty); | ||
3059 | } | ||
3597 | } | 3060 | } |
3598 | put_pid(tsk->signal->tty_old_pgrp); | 3061 | put_pid(tsk->signal->tty_old_pgrp); |
3599 | tsk->signal->tty = tty; | 3062 | tsk->signal->tty = tty_kref_get(tty); |
3600 | tsk->signal->tty_old_pgrp = NULL; | 3063 | tsk->signal->tty_old_pgrp = NULL; |
3601 | } | 3064 | } |
3602 | 3065 | ||
@@ -3610,18 +3073,20 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | |||
3610 | struct tty_struct *get_current_tty(void) | 3073 | struct tty_struct *get_current_tty(void) |
3611 | { | 3074 | { |
3612 | struct tty_struct *tty; | 3075 | struct tty_struct *tty; |
3613 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | 3076 | unsigned long flags; |
3614 | tty = current->signal->tty; | 3077 | |
3615 | /* | 3078 | spin_lock_irqsave(¤t->sighand->siglock, flags); |
3616 | * session->tty can be changed/cleared from under us, make sure we | 3079 | tty = tty_kref_get(current->signal->tty); |
3617 | * issue the load. The obtained pointer, when not NULL, is valid as | 3080 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
3618 | * long as we hold tty_mutex. | ||
3619 | */ | ||
3620 | barrier(); | ||
3621 | return tty; | 3081 | return tty; |
3622 | } | 3082 | } |
3623 | EXPORT_SYMBOL_GPL(get_current_tty); | 3083 | EXPORT_SYMBOL_GPL(get_current_tty); |
3624 | 3084 | ||
3085 | void tty_default_fops(struct file_operations *fops) | ||
3086 | { | ||
3087 | *fops = tty_fops; | ||
3088 | } | ||
3089 | |||
3625 | /* | 3090 | /* |
3626 | * Initialize the console device. This is called *early*, so | 3091 | * Initialize the console device. This is called *early*, so |
3627 | * we can't necessarily depend on lots of kernel help here. | 3092 | * we can't necessarily depend on lots of kernel help here. |
@@ -3659,12 +3124,6 @@ postcore_initcall(tty_class_init); | |||
3659 | /* 3/2004 jmc: why do these devices exist? */ | 3124 | /* 3/2004 jmc: why do these devices exist? */ |
3660 | 3125 | ||
3661 | static struct cdev tty_cdev, console_cdev; | 3126 | static struct cdev tty_cdev, console_cdev; |
3662 | #ifdef CONFIG_UNIX98_PTYS | ||
3663 | static struct cdev ptmx_cdev; | ||
3664 | #endif | ||
3665 | #ifdef CONFIG_VT | ||
3666 | static struct cdev vc0_cdev; | ||
3667 | #endif | ||
3668 | 3127 | ||
3669 | /* | 3128 | /* |
3670 | * Ok, now we can initialize the rest of the tty devices and can count | 3129 | * Ok, now we can initialize the rest of the tty devices and can count |
@@ -3676,32 +3135,18 @@ static int __init tty_init(void) | |||
3676 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3135 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3677 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3136 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3678 | panic("Couldn't register /dev/tty driver\n"); | 3137 | panic("Couldn't register /dev/tty driver\n"); |
3679 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, | 3138 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, |
3680 | "tty"); | 3139 | "tty"); |
3681 | 3140 | ||
3682 | cdev_init(&console_cdev, &console_fops); | 3141 | cdev_init(&console_cdev, &console_fops); |
3683 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3142 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3684 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3143 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3685 | panic("Couldn't register /dev/console driver\n"); | 3144 | panic("Couldn't register /dev/console driver\n"); |
3686 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, | 3145 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
3687 | "console"); | 3146 | "console"); |
3688 | 3147 | ||
3689 | #ifdef CONFIG_UNIX98_PTYS | ||
3690 | cdev_init(&ptmx_cdev, &ptmx_fops); | ||
3691 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | ||
3692 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | ||
3693 | panic("Couldn't register /dev/ptmx driver\n"); | ||
3694 | device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | ||
3695 | #endif | ||
3696 | |||
3697 | #ifdef CONFIG_VT | 3148 | #ifdef CONFIG_VT |
3698 | cdev_init(&vc0_cdev, &console_fops); | 3149 | vty_init(&console_fops); |
3699 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
3700 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
3701 | panic("Couldn't register /dev/tty0 driver\n"); | ||
3702 | device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
3703 | |||
3704 | vty_init(); | ||
3705 | #endif | 3150 | #endif |
3706 | return 0; | 3151 | return 0; |
3707 | } | 3152 | } |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index ea9fc5d03b99..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,36 +987,63 @@ 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 | return put_user(C_CLOCAL(tty) ? 1 : 0, | 1038 | mutex_lock(&real_tty->termios_mutex); |
1039 | ret = put_user(C_CLOCAL(real_tty) ? 1 : 0, | ||
941 | (int __user *)arg); | 1040 | (int __user *)arg); |
1041 | mutex_unlock(&real_tty->termios_mutex); | ||
1042 | return ret; | ||
942 | case TIOCSSOFTCAR: | 1043 | case TIOCSSOFTCAR: |
943 | if (get_user(arg, (unsigned int __user *) arg)) | 1044 | if (get_user(arg, (unsigned int __user *) arg)) |
944 | return -EFAULT; | 1045 | return -EFAULT; |
945 | return tty_change_softcar(tty, arg); | 1046 | return tty_change_softcar(real_tty, arg); |
946 | default: | 1047 | default: |
947 | return -ENOIOCTLCMD; | 1048 | return -ENOIOCTLCMD; |
948 | } | 1049 | } |
@@ -978,7 +1079,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
978 | } | 1079 | } |
979 | EXPORT_SYMBOL_GPL(tty_perform_flush); | 1080 | EXPORT_SYMBOL_GPL(tty_perform_flush); |
980 | 1081 | ||
981 | int n_tty_ioctl(struct tty_struct *tty, struct file *file, | 1082 | int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
982 | unsigned int cmd, unsigned long arg) | 1083 | unsigned int cmd, unsigned long arg) |
983 | { | 1084 | { |
984 | unsigned long flags; | 1085 | unsigned long flags; |
@@ -1016,13 +1117,6 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1016 | return 0; | 1117 | return 0; |
1017 | case TCFLSH: | 1118 | case TCFLSH: |
1018 | return tty_perform_flush(tty, arg); | 1119 | return tty_perform_flush(tty, arg); |
1019 | case TIOCOUTQ: | ||
1020 | return put_user(tty_chars_in_buffer(tty), (int __user *) arg); | ||
1021 | case TIOCINQ: | ||
1022 | retval = tty->read_cnt; | ||
1023 | if (L_ICANON(tty)) | ||
1024 | retval = inq_canon(tty); | ||
1025 | return put_user(retval, (unsigned int __user *) arg); | ||
1026 | case TIOCPKT: | 1120 | case TIOCPKT: |
1027 | { | 1121 | { |
1028 | int pktmode; | 1122 | int pktmode; |
@@ -1048,4 +1142,4 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
1048 | return tty_mode_ioctl(tty, file, cmd, arg); | 1142 | return tty_mode_ioctl(tty, file, cmd, arg); |
1049 | } | 1143 | } |
1050 | } | 1144 | } |
1051 | EXPORT_SYMBOL(n_tty_ioctl); | 1145 | EXPORT_SYMBOL(n_tty_ioctl_helper); |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 241cbdea65ab..f307f135cbfb 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -169,7 +169,7 @@ static int tty_ldisc_get(int disc, struct tty_ldisc *ld) | |||
169 | if (disc < N_TTY || disc >= NR_LDISCS) | 169 | if (disc < N_TTY || disc >= NR_LDISCS) |
170 | return -EINVAL; | 170 | return -EINVAL; |
171 | err = tty_ldisc_try_get(disc, ld); | 171 | err = tty_ldisc_try_get(disc, ld); |
172 | if (err == -EAGAIN) { | 172 | if (err < 0) { |
173 | request_module("tty-ldisc-%d", disc); | 173 | request_module("tty-ldisc-%d", disc); |
174 | err = tty_ldisc_try_get(disc, ld); | 174 | err = tty_ldisc_try_get(disc, ld); |
175 | } | 175 | } |
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/viocons.c b/drivers/char/viocons.c deleted file mode 100644 index 65fb848e1cce..000000000000 --- a/drivers/char/viocons.c +++ /dev/null | |||
@@ -1,1171 +0,0 @@ | |||
1 | /* -*- linux-c -*- | ||
2 | * | ||
3 | * drivers/char/viocons.c | ||
4 | * | ||
5 | * iSeries Virtual Terminal | ||
6 | * | ||
7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | ||
8 | * Ryan Arnold <ryanarn@us.ibm.com> | ||
9 | * Colin Devilbiss <devilbis@us.ibm.com> | ||
10 | * Stephen Rothwell | ||
11 | * | ||
12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of the | ||
17 | * License, or (at your option) anyu later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, but | ||
20 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
22 | * General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software Foundation, | ||
26 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | */ | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/proc_fs.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/vmalloc.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/console.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <asm/uaccess.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/wait.h> | ||
38 | #include <linux/spinlock.h> | ||
39 | #include <asm/ioctls.h> | ||
40 | #include <linux/kd.h> | ||
41 | #include <linux/tty.h> | ||
42 | #include <linux/tty_flip.h> | ||
43 | #include <linux/sysrq.h> | ||
44 | |||
45 | #include <asm/firmware.h> | ||
46 | #include <asm/iseries/vio.h> | ||
47 | #include <asm/iseries/hv_lp_event.h> | ||
48 | #include <asm/iseries/hv_call_event.h> | ||
49 | #include <asm/iseries/hv_lp_config.h> | ||
50 | #include <asm/iseries/hv_call.h> | ||
51 | |||
52 | #ifdef CONFIG_VT | ||
53 | #error You must turn off CONFIG_VT to use CONFIG_VIOCONS | ||
54 | #endif | ||
55 | |||
56 | #define VIOTTY_MAGIC (0x0DCB) | ||
57 | #define VTTY_PORTS 10 | ||
58 | |||
59 | #define VIOCONS_KERN_WARN KERN_WARNING "viocons: " | ||
60 | #define VIOCONS_KERN_INFO KERN_INFO "viocons: " | ||
61 | |||
62 | static DEFINE_SPINLOCK(consolelock); | ||
63 | static DEFINE_SPINLOCK(consoleloglock); | ||
64 | |||
65 | static int vio_sysrq_pressed; | ||
66 | |||
67 | #define VIOCHAR_NUM_BUF 16 | ||
68 | |||
69 | /* | ||
70 | * Our port information. We store a pointer to one entry in the | ||
71 | * tty_driver_data | ||
72 | */ | ||
73 | static struct port_info { | ||
74 | int magic; | ||
75 | struct tty_struct *tty; | ||
76 | HvLpIndex lp; | ||
77 | u8 vcons; | ||
78 | u64 seq; /* sequence number of last HV send */ | ||
79 | u64 ack; /* last ack from HV */ | ||
80 | /* | ||
81 | * When we get writes faster than we can send it to the partition, | ||
82 | * buffer the data here. Note that used is a bit map of used buffers. | ||
83 | * It had better have enough bits to hold VIOCHAR_NUM_BUF the bitops assume | ||
84 | * it is a multiple of unsigned long | ||
85 | */ | ||
86 | unsigned long used; | ||
87 | u8 *buffer[VIOCHAR_NUM_BUF]; | ||
88 | int bufferBytes[VIOCHAR_NUM_BUF]; | ||
89 | int curbuf; | ||
90 | int bufferOverflow; | ||
91 | int overflowMessage; | ||
92 | } port_info[VTTY_PORTS]; | ||
93 | |||
94 | #define viochar_is_console(pi) ((pi) == &port_info[0]) | ||
95 | #define viochar_port(pi) ((pi) - &port_info[0]) | ||
96 | |||
97 | static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp); | ||
98 | |||
99 | static struct tty_driver *viotty_driver; | ||
100 | |||
101 | static void hvlog(char *fmt, ...) | ||
102 | { | ||
103 | int i; | ||
104 | unsigned long flags; | ||
105 | va_list args; | ||
106 | static char buf[256]; | ||
107 | |||
108 | spin_lock_irqsave(&consoleloglock, flags); | ||
109 | va_start(args, fmt); | ||
110 | i = vscnprintf(buf, sizeof(buf) - 1, fmt, args); | ||
111 | va_end(args); | ||
112 | buf[i++] = '\r'; | ||
113 | HvCall_writeLogBuffer(buf, i); | ||
114 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
115 | } | ||
116 | |||
117 | static void hvlogOutput(const char *buf, int count) | ||
118 | { | ||
119 | unsigned long flags; | ||
120 | int begin; | ||
121 | int index; | ||
122 | static const char cr = '\r'; | ||
123 | |||
124 | begin = 0; | ||
125 | spin_lock_irqsave(&consoleloglock, flags); | ||
126 | for (index = 0; index < count; index++) { | ||
127 | if (buf[index] == '\n') { | ||
128 | /* | ||
129 | * Start right after the last '\n' or at the zeroth | ||
130 | * array position and output the number of characters | ||
131 | * including the newline. | ||
132 | */ | ||
133 | HvCall_writeLogBuffer(&buf[begin], index - begin + 1); | ||
134 | begin = index + 1; | ||
135 | HvCall_writeLogBuffer(&cr, 1); | ||
136 | } | ||
137 | } | ||
138 | if ((index - begin) > 0) | ||
139 | HvCall_writeLogBuffer(&buf[begin], index - begin); | ||
140 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Make sure we're pointing to a valid port_info structure. Shamelessly | ||
145 | * plagerized from serial.c | ||
146 | */ | ||
147 | static inline int viotty_paranoia_check(struct port_info *pi, | ||
148 | char *name, const char *routine) | ||
149 | { | ||
150 | static const char *bad_pi_addr = VIOCONS_KERN_WARN | ||
151 | "warning: bad address for port_info struct (%s) in %s\n"; | ||
152 | static const char *badmagic = VIOCONS_KERN_WARN | ||
153 | "warning: bad magic number for port_info struct (%s) in %s\n"; | ||
154 | |||
155 | if ((pi < &port_info[0]) || (viochar_port(pi) > VTTY_PORTS)) { | ||
156 | printk(bad_pi_addr, name, routine); | ||
157 | return 1; | ||
158 | } | ||
159 | if (pi->magic != VIOTTY_MAGIC) { | ||
160 | printk(badmagic, name, routine); | ||
161 | return 1; | ||
162 | } | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * Add data to our pending-send buffers. | ||
168 | * | ||
169 | * NOTE: Don't use printk in here because it gets nastily recursive. | ||
170 | * hvlog can be used to log to the hypervisor buffer | ||
171 | */ | ||
172 | static int buffer_add(struct port_info *pi, const char *buf, size_t len) | ||
173 | { | ||
174 | size_t bleft; | ||
175 | size_t curlen; | ||
176 | const char *curbuf; | ||
177 | int nextbuf; | ||
178 | |||
179 | curbuf = buf; | ||
180 | bleft = len; | ||
181 | while (bleft > 0) { | ||
182 | /* | ||
183 | * If there is no space left in the current buffer, we have | ||
184 | * filled everything up, so return. If we filled the previous | ||
185 | * buffer we would already have moved to the next one. | ||
186 | */ | ||
187 | if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) { | ||
188 | hvlog ("\n\rviocons: No overflow buffer available for memcpy().\n"); | ||
189 | pi->bufferOverflow++; | ||
190 | pi->overflowMessage = 1; | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Turn on the "used" bit for this buffer. If it's already on, | ||
196 | * that's fine. | ||
197 | */ | ||
198 | set_bit(pi->curbuf, &pi->used); | ||
199 | |||
200 | /* | ||
201 | * See if this buffer has been allocated. If not, allocate it. | ||
202 | */ | ||
203 | if (pi->buffer[pi->curbuf] == NULL) { | ||
204 | pi->buffer[pi->curbuf] = | ||
205 | kmalloc(VIOCHAR_MAX_DATA, GFP_ATOMIC); | ||
206 | if (pi->buffer[pi->curbuf] == NULL) { | ||
207 | hvlog("\n\rviocons: kmalloc failed allocating spaces for buffer %d.", | ||
208 | pi->curbuf); | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* Figure out how much we can copy into this buffer. */ | ||
214 | if (bleft < (VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf])) | ||
215 | curlen = bleft; | ||
216 | else | ||
217 | curlen = VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf]; | ||
218 | |||
219 | /* Copy the data into the buffer. */ | ||
220 | memcpy(pi->buffer[pi->curbuf] + pi->bufferBytes[pi->curbuf], | ||
221 | curbuf, curlen); | ||
222 | |||
223 | pi->bufferBytes[pi->curbuf] += curlen; | ||
224 | curbuf += curlen; | ||
225 | bleft -= curlen; | ||
226 | |||
227 | /* | ||
228 | * Now see if we've filled this buffer. If not then | ||
229 | * we'll try to use it again later. If we've filled it | ||
230 | * up then we'll advance the curbuf to the next in the | ||
231 | * circular queue. | ||
232 | */ | ||
233 | if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) { | ||
234 | nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF; | ||
235 | /* | ||
236 | * Move to the next buffer if it hasn't been used yet | ||
237 | */ | ||
238 | if (test_bit(nextbuf, &pi->used) == 0) | ||
239 | pi->curbuf = nextbuf; | ||
240 | } | ||
241 | } | ||
242 | return len - bleft; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Send pending data | ||
247 | * | ||
248 | * NOTE: Don't use printk in here because it gets nastily recursive. | ||
249 | * hvlog can be used to log to the hypervisor buffer | ||
250 | */ | ||
251 | static void send_buffers(struct port_info *pi) | ||
252 | { | ||
253 | HvLpEvent_Rc hvrc; | ||
254 | int nextbuf; | ||
255 | struct viocharlpevent *viochar; | ||
256 | unsigned long flags; | ||
257 | |||
258 | spin_lock_irqsave(&consolelock, flags); | ||
259 | |||
260 | viochar = (struct viocharlpevent *) | ||
261 | vio_get_event_buffer(viomajorsubtype_chario); | ||
262 | |||
263 | /* Make sure we got a buffer */ | ||
264 | if (viochar == NULL) { | ||
265 | hvlog("\n\rviocons: Can't get viochar buffer in sendBuffers()."); | ||
266 | spin_unlock_irqrestore(&consolelock, flags); | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | if (pi->used == 0) { | ||
271 | hvlog("\n\rviocons: in sendbuffers(), but no buffers used.\n"); | ||
272 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
273 | spin_unlock_irqrestore(&consolelock, flags); | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * curbuf points to the buffer we're filling. We want to | ||
279 | * start sending AFTER this one. | ||
280 | */ | ||
281 | nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF; | ||
282 | |||
283 | /* | ||
284 | * Loop until we find a buffer with the used bit on | ||
285 | */ | ||
286 | while (test_bit(nextbuf, &pi->used) == 0) | ||
287 | nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF; | ||
288 | |||
289 | initDataEvent(viochar, pi->lp); | ||
290 | |||
291 | /* | ||
292 | * While we have buffers with data, and our send window | ||
293 | * is open, send them | ||
294 | */ | ||
295 | while ((test_bit(nextbuf, &pi->used)) && | ||
296 | ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) { | ||
297 | viochar->len = pi->bufferBytes[nextbuf]; | ||
298 | viochar->event.xCorrelationToken = pi->seq++; | ||
299 | viochar->event.xSizeMinus1 = | ||
300 | offsetof(struct viocharlpevent, data) + viochar->len; | ||
301 | |||
302 | memcpy(viochar->data, pi->buffer[nextbuf], viochar->len); | ||
303 | |||
304 | hvrc = HvCallEvent_signalLpEvent(&viochar->event); | ||
305 | if (hvrc) { | ||
306 | /* | ||
307 | * MUST unlock the spinlock before doing a printk | ||
308 | */ | ||
309 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
310 | spin_unlock_irqrestore(&consolelock, flags); | ||
311 | |||
312 | printk(VIOCONS_KERN_WARN | ||
313 | "error sending event! return code %d\n", | ||
314 | (int)hvrc); | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * clear the used bit, zero the number of bytes in | ||
320 | * this buffer, and move to the next buffer | ||
321 | */ | ||
322 | clear_bit(nextbuf, &pi->used); | ||
323 | pi->bufferBytes[nextbuf] = 0; | ||
324 | nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF; | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * If we have emptied all the buffers, start at 0 again. | ||
329 | * this will re-use any allocated buffers | ||
330 | */ | ||
331 | if (pi->used == 0) { | ||
332 | pi->curbuf = 0; | ||
333 | |||
334 | if (pi->overflowMessage) | ||
335 | pi->overflowMessage = 0; | ||
336 | |||
337 | if (pi->tty) { | ||
338 | tty_wakeup(pi->tty); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
343 | spin_unlock_irqrestore(&consolelock, flags); | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * Our internal writer. Gets called both from the console device and | ||
348 | * the tty device. the tty pointer will be NULL if called from the console. | ||
349 | * Return total number of bytes "written". | ||
350 | * | ||
351 | * NOTE: Don't use printk in here because it gets nastily recursive. hvlog | ||
352 | * can be used to log to the hypervisor buffer | ||
353 | */ | ||
354 | static int internal_write(struct port_info *pi, const char *buf, size_t len) | ||
355 | { | ||
356 | HvLpEvent_Rc hvrc; | ||
357 | size_t bleft; | ||
358 | size_t curlen; | ||
359 | const char *curbuf; | ||
360 | unsigned long flags; | ||
361 | struct viocharlpevent *viochar; | ||
362 | |||
363 | /* | ||
364 | * Write to the hvlog of inbound data are now done prior to | ||
365 | * calling internal_write() since internal_write() is only called in | ||
366 | * the event that an lp event path is active, which isn't the case for | ||
367 | * logging attempts prior to console initialization. | ||
368 | * | ||
369 | * If there is already data queued for this port, send it prior to | ||
370 | * attempting to send any new data. | ||
371 | */ | ||
372 | if (pi->used) | ||
373 | send_buffers(pi); | ||
374 | |||
375 | spin_lock_irqsave(&consolelock, flags); | ||
376 | |||
377 | viochar = vio_get_event_buffer(viomajorsubtype_chario); | ||
378 | if (viochar == NULL) { | ||
379 | spin_unlock_irqrestore(&consolelock, flags); | ||
380 | hvlog("\n\rviocons: Can't get vio buffer in internal_write()."); | ||
381 | return -EAGAIN; | ||
382 | } | ||
383 | initDataEvent(viochar, pi->lp); | ||
384 | |||
385 | curbuf = buf; | ||
386 | bleft = len; | ||
387 | |||
388 | while ((bleft > 0) && (pi->used == 0) && | ||
389 | ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) { | ||
390 | if (bleft > VIOCHAR_MAX_DATA) | ||
391 | curlen = VIOCHAR_MAX_DATA; | ||
392 | else | ||
393 | curlen = bleft; | ||
394 | |||
395 | viochar->event.xCorrelationToken = pi->seq++; | ||
396 | memcpy(viochar->data, curbuf, curlen); | ||
397 | viochar->len = curlen; | ||
398 | viochar->event.xSizeMinus1 = | ||
399 | offsetof(struct viocharlpevent, data) + curlen; | ||
400 | |||
401 | hvrc = HvCallEvent_signalLpEvent(&viochar->event); | ||
402 | if (hvrc) { | ||
403 | hvlog("viocons: error sending event! %d\n", (int)hvrc); | ||
404 | goto out; | ||
405 | } | ||
406 | curbuf += curlen; | ||
407 | bleft -= curlen; | ||
408 | } | ||
409 | |||
410 | /* If we didn't send it all, buffer as much of it as we can. */ | ||
411 | if (bleft > 0) | ||
412 | bleft -= buffer_add(pi, curbuf, bleft); | ||
413 | out: | ||
414 | vio_free_event_buffer(viomajorsubtype_chario, viochar); | ||
415 | spin_unlock_irqrestore(&consolelock, flags); | ||
416 | return len - bleft; | ||
417 | } | ||
418 | |||
419 | static struct port_info *get_port_data(struct tty_struct *tty) | ||
420 | { | ||
421 | unsigned long flags; | ||
422 | struct port_info *pi; | ||
423 | |||
424 | spin_lock_irqsave(&consolelock, flags); | ||
425 | if (tty) { | ||
426 | pi = (struct port_info *)tty->driver_data; | ||
427 | if (!pi || viotty_paranoia_check(pi, tty->name, | ||
428 | "get_port_data")) { | ||
429 | pi = NULL; | ||
430 | } | ||
431 | } else | ||
432 | /* | ||
433 | * If this is the console device, use the lp from | ||
434 | * the first port entry | ||
435 | */ | ||
436 | pi = &port_info[0]; | ||
437 | spin_unlock_irqrestore(&consolelock, flags); | ||
438 | return pi; | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Initialize the common fields in a charLpEvent | ||
443 | */ | ||
444 | static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp) | ||
445 | { | ||
446 | struct HvLpEvent *hev = &viochar->event; | ||
447 | |||
448 | memset(viochar, 0, sizeof(struct viocharlpevent)); | ||
449 | |||
450 | hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK | | ||
451 | HV_LP_EVENT_INT; | ||
452 | hev->xType = HvLpEvent_Type_VirtualIo; | ||
453 | hev->xSubtype = viomajorsubtype_chario | viochardata; | ||
454 | hev->xSourceLp = HvLpConfig_getLpIndex(); | ||
455 | hev->xTargetLp = lp; | ||
456 | hev->xSizeMinus1 = sizeof(struct viocharlpevent); | ||
457 | hev->xSourceInstanceId = viopath_sourceinst(lp); | ||
458 | hev->xTargetInstanceId = viopath_targetinst(lp); | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * early console device write | ||
463 | */ | ||
464 | static void viocons_write_early(struct console *co, const char *s, unsigned count) | ||
465 | { | ||
466 | hvlogOutput(s, count); | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * console device write | ||
471 | */ | ||
472 | static void viocons_write(struct console *co, const char *s, unsigned count) | ||
473 | { | ||
474 | int index; | ||
475 | int begin; | ||
476 | struct port_info *pi; | ||
477 | |||
478 | static const char cr = '\r'; | ||
479 | |||
480 | /* | ||
481 | * Check port data first because the target LP might be valid but | ||
482 | * simply not active, in which case we want to hvlog the output. | ||
483 | */ | ||
484 | pi = get_port_data(NULL); | ||
485 | if (pi == NULL) { | ||
486 | hvlog("\n\rviocons_write: unable to get port data."); | ||
487 | return; | ||
488 | } | ||
489 | |||
490 | hvlogOutput(s, count); | ||
491 | |||
492 | if (!viopath_isactive(pi->lp)) | ||
493 | return; | ||
494 | |||
495 | /* | ||
496 | * Any newline character found will cause a | ||
497 | * carriage return character to be emitted as well. | ||
498 | */ | ||
499 | begin = 0; | ||
500 | for (index = 0; index < count; index++) { | ||
501 | if (s[index] == '\n') { | ||
502 | /* | ||
503 | * Newline found. Print everything up to and | ||
504 | * including the newline | ||
505 | */ | ||
506 | internal_write(pi, &s[begin], index - begin + 1); | ||
507 | begin = index + 1; | ||
508 | /* Emit a carriage return as well */ | ||
509 | internal_write(pi, &cr, 1); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | /* If any characters left to write, write them now */ | ||
514 | if ((index - begin) > 0) | ||
515 | internal_write(pi, &s[begin], index - begin); | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * Work out the device associate with this console | ||
520 | */ | ||
521 | static struct tty_driver *viocons_device(struct console *c, int *index) | ||
522 | { | ||
523 | *index = c->index; | ||
524 | return viotty_driver; | ||
525 | } | ||
526 | |||
527 | /* | ||
528 | * console device I/O methods | ||
529 | */ | ||
530 | static struct console viocons_early = { | ||
531 | .name = "viocons", | ||
532 | .write = viocons_write_early, | ||
533 | .flags = CON_PRINTBUFFER, | ||
534 | .index = -1, | ||
535 | }; | ||
536 | |||
537 | static struct console viocons = { | ||
538 | .name = "viocons", | ||
539 | .write = viocons_write, | ||
540 | .device = viocons_device, | ||
541 | .flags = CON_PRINTBUFFER, | ||
542 | .index = -1, | ||
543 | }; | ||
544 | |||
545 | /* | ||
546 | * TTY Open method | ||
547 | */ | ||
548 | static int viotty_open(struct tty_struct *tty, struct file *filp) | ||
549 | { | ||
550 | int port; | ||
551 | unsigned long flags; | ||
552 | struct port_info *pi; | ||
553 | |||
554 | port = tty->index; | ||
555 | |||
556 | if ((port < 0) || (port >= VTTY_PORTS)) | ||
557 | return -ENODEV; | ||
558 | |||
559 | spin_lock_irqsave(&consolelock, flags); | ||
560 | |||
561 | pi = &port_info[port]; | ||
562 | /* If some other TTY is already connected here, reject the open */ | ||
563 | if ((pi->tty) && (pi->tty != tty)) { | ||
564 | spin_unlock_irqrestore(&consolelock, flags); | ||
565 | printk(VIOCONS_KERN_WARN | ||
566 | "attempt to open device twice from different ttys\n"); | ||
567 | return -EBUSY; | ||
568 | } | ||
569 | tty->driver_data = pi; | ||
570 | pi->tty = tty; | ||
571 | spin_unlock_irqrestore(&consolelock, flags); | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | /* | ||
577 | * TTY Close method | ||
578 | */ | ||
579 | static void viotty_close(struct tty_struct *tty, struct file *filp) | ||
580 | { | ||
581 | unsigned long flags; | ||
582 | struct port_info *pi; | ||
583 | |||
584 | spin_lock_irqsave(&consolelock, flags); | ||
585 | pi = (struct port_info *)tty->driver_data; | ||
586 | |||
587 | if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_close")) { | ||
588 | spin_unlock_irqrestore(&consolelock, flags); | ||
589 | return; | ||
590 | } | ||
591 | if (tty->count == 1) | ||
592 | pi->tty = NULL; | ||
593 | spin_unlock_irqrestore(&consolelock, flags); | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * TTY Write method | ||
598 | */ | ||
599 | static int viotty_write(struct tty_struct *tty, const unsigned char *buf, | ||
600 | int count) | ||
601 | { | ||
602 | struct port_info *pi; | ||
603 | |||
604 | pi = get_port_data(tty); | ||
605 | if (pi == NULL) { | ||
606 | hvlog("\n\rviotty_write: no port data."); | ||
607 | return -ENODEV; | ||
608 | } | ||
609 | |||
610 | if (viochar_is_console(pi)) | ||
611 | hvlogOutput(buf, count); | ||
612 | |||
613 | /* | ||
614 | * If the path to this LP is closed, don't bother doing anything more. | ||
615 | * just dump the data on the floor and return count. For some reason | ||
616 | * some user level programs will attempt to probe available tty's and | ||
617 | * they'll attempt a viotty_write on an invalid port which maps to an | ||
618 | * invalid target lp. If this is the case then ignore the | ||
619 | * viotty_write call and, since the viopath isn't active to this | ||
620 | * partition, return count. | ||
621 | */ | ||
622 | if (!viopath_isactive(pi->lp)) | ||
623 | return count; | ||
624 | |||
625 | return internal_write(pi, buf, count); | ||
626 | } | ||
627 | |||
628 | /* | ||
629 | * TTY put_char method | ||
630 | */ | ||
631 | static int viotty_put_char(struct tty_struct *tty, unsigned char ch) | ||
632 | { | ||
633 | struct port_info *pi; | ||
634 | |||
635 | pi = get_port_data(tty); | ||
636 | if (pi == NULL) | ||
637 | return 0; | ||
638 | |||
639 | /* This will append '\r' as well if the char is '\n' */ | ||
640 | if (viochar_is_console(pi)) | ||
641 | hvlogOutput(&ch, 1); | ||
642 | |||
643 | if (viopath_isactive(pi->lp)) | ||
644 | internal_write(pi, &ch, 1); | ||
645 | return 1; | ||
646 | } | ||
647 | |||
648 | /* | ||
649 | * TTY write_room method | ||
650 | */ | ||
651 | static int viotty_write_room(struct tty_struct *tty) | ||
652 | { | ||
653 | int i; | ||
654 | int room = 0; | ||
655 | struct port_info *pi; | ||
656 | unsigned long flags; | ||
657 | |||
658 | spin_lock_irqsave(&consolelock, flags); | ||
659 | pi = (struct port_info *)tty->driver_data; | ||
660 | if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_write_room")) { | ||
661 | spin_unlock_irqrestore(&consolelock, flags); | ||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | /* If no buffers are used, return the max size. */ | ||
666 | if (pi->used == 0) { | ||
667 | spin_unlock_irqrestore(&consolelock, flags); | ||
668 | return VIOCHAR_MAX_DATA * VIOCHAR_NUM_BUF; | ||
669 | } | ||
670 | |||
671 | /* | ||
672 | * We retain the spinlock because we want to get an accurate | ||
673 | * count and it can change on us between each operation if we | ||
674 | * don't hold the spinlock. | ||
675 | */ | ||
676 | for (i = 0; ((i < VIOCHAR_NUM_BUF) && (room < VIOCHAR_MAX_DATA)); i++) | ||
677 | room += (VIOCHAR_MAX_DATA - pi->bufferBytes[i]); | ||
678 | spin_unlock_irqrestore(&consolelock, flags); | ||
679 | |||
680 | if (room > VIOCHAR_MAX_DATA) | ||
681 | room = VIOCHAR_MAX_DATA; | ||
682 | return room; | ||
683 | } | ||
684 | |||
685 | /* | ||
686 | * TTY chars_in_buffer method | ||
687 | */ | ||
688 | static int viotty_chars_in_buffer(struct tty_struct *tty) | ||
689 | { | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int viotty_ioctl(struct tty_struct *tty, struct file *file, | ||
694 | unsigned int cmd, unsigned long arg) | ||
695 | { | ||
696 | switch (cmd) { | ||
697 | /* | ||
698 | * the ioctls below read/set the flags usually shown in the leds | ||
699 | * don't use them - they will go away without warning | ||
700 | */ | ||
701 | case KDGETLED: | ||
702 | case KDGKBLED: | ||
703 | return put_user(0, (char *)arg); | ||
704 | |||
705 | case KDSKBLED: | ||
706 | return 0; | ||
707 | } | ||
708 | /* FIXME: WTF is this being called for ??? */ | ||
709 | lock_kernel(); | ||
710 | ret = n_tty_ioctl(tty, file, cmd, arg); | ||
711 | unlock_kernel(); | ||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | /* | ||
716 | * Handle an open charLpEvent. Could be either interrupt or ack | ||
717 | */ | ||
718 | static void vioHandleOpenEvent(struct HvLpEvent *event) | ||
719 | { | ||
720 | unsigned long flags; | ||
721 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
722 | u8 port = cevent->virtual_device; | ||
723 | struct port_info *pi; | ||
724 | int reject = 0; | ||
725 | |||
726 | if (hvlpevent_is_ack(event)) { | ||
727 | if (port >= VTTY_PORTS) | ||
728 | return; | ||
729 | |||
730 | spin_lock_irqsave(&consolelock, flags); | ||
731 | /* Got the lock, don't cause console output */ | ||
732 | |||
733 | pi = &port_info[port]; | ||
734 | if (event->xRc == HvLpEvent_Rc_Good) { | ||
735 | pi->seq = pi->ack = 0; | ||
736 | /* | ||
737 | * This line allows connections from the primary | ||
738 | * partition but once one is connected from the | ||
739 | * primary partition nothing short of a reboot | ||
740 | * of linux will allow access from the hosting | ||
741 | * partition again without a required iSeries fix. | ||
742 | */ | ||
743 | pi->lp = event->xTargetLp; | ||
744 | } | ||
745 | |||
746 | spin_unlock_irqrestore(&consolelock, flags); | ||
747 | if (event->xRc != HvLpEvent_Rc_Good) | ||
748 | printk(VIOCONS_KERN_WARN | ||
749 | "handle_open_event: event->xRc == (%d).\n", | ||
750 | event->xRc); | ||
751 | |||
752 | if (event->xCorrelationToken != 0) { | ||
753 | atomic_t *aptr= (atomic_t *)event->xCorrelationToken; | ||
754 | atomic_set(aptr, 1); | ||
755 | } else | ||
756 | printk(VIOCONS_KERN_WARN | ||
757 | "weird...got open ack without atomic\n"); | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | /* This had better require an ack, otherwise complain */ | ||
762 | if (!hvlpevent_need_ack(event)) { | ||
763 | printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n"); | ||
764 | return; | ||
765 | } | ||
766 | |||
767 | spin_lock_irqsave(&consolelock, flags); | ||
768 | /* Got the lock, don't cause console output */ | ||
769 | |||
770 | /* Make sure this is a good virtual tty */ | ||
771 | if (port >= VTTY_PORTS) { | ||
772 | event->xRc = HvLpEvent_Rc_SubtypeError; | ||
773 | cevent->subtype_result_code = viorc_openRejected; | ||
774 | /* | ||
775 | * Flag state here since we can't printk while holding | ||
776 | * a spinlock. | ||
777 | */ | ||
778 | reject = 1; | ||
779 | } else { | ||
780 | pi = &port_info[port]; | ||
781 | if ((pi->lp != HvLpIndexInvalid) && | ||
782 | (pi->lp != event->xSourceLp)) { | ||
783 | /* | ||
784 | * If this is tty is already connected to a different | ||
785 | * partition, fail. | ||
786 | */ | ||
787 | event->xRc = HvLpEvent_Rc_SubtypeError; | ||
788 | cevent->subtype_result_code = viorc_openRejected; | ||
789 | reject = 2; | ||
790 | } else { | ||
791 | pi->lp = event->xSourceLp; | ||
792 | event->xRc = HvLpEvent_Rc_Good; | ||
793 | cevent->subtype_result_code = viorc_good; | ||
794 | pi->seq = pi->ack = 0; | ||
795 | reject = 0; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | spin_unlock_irqrestore(&consolelock, flags); | ||
800 | |||
801 | if (reject == 1) | ||
802 | printk(VIOCONS_KERN_WARN "open rejected: bad virtual tty.\n"); | ||
803 | else if (reject == 2) | ||
804 | printk(VIOCONS_KERN_WARN | ||
805 | "open rejected: console in exclusive use by another partition.\n"); | ||
806 | |||
807 | /* Return the acknowledgement */ | ||
808 | HvCallEvent_ackLpEvent(event); | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * Handle a close charLpEvent. This should ONLY be an Interrupt because the | ||
813 | * virtual console should never actually issue a close event to the hypervisor | ||
814 | * because the virtual console never goes away. A close event coming from the | ||
815 | * hypervisor simply means that there are no client consoles connected to the | ||
816 | * virtual console. | ||
817 | * | ||
818 | * Regardless of the number of connections masqueraded on the other side of | ||
819 | * the hypervisor ONLY ONE close event should be called to accompany the ONE | ||
820 | * open event that is called. The close event should ONLY be called when NO | ||
821 | * MORE connections (masqueraded or not) exist on the other side of the | ||
822 | * hypervisor. | ||
823 | */ | ||
824 | static void vioHandleCloseEvent(struct HvLpEvent *event) | ||
825 | { | ||
826 | unsigned long flags; | ||
827 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
828 | u8 port = cevent->virtual_device; | ||
829 | |||
830 | if (hvlpevent_is_int(event)) { | ||
831 | if (port >= VTTY_PORTS) { | ||
832 | printk(VIOCONS_KERN_WARN | ||
833 | "close message from invalid virtual device.\n"); | ||
834 | return; | ||
835 | } | ||
836 | |||
837 | /* For closes, just mark the console partition invalid */ | ||
838 | spin_lock_irqsave(&consolelock, flags); | ||
839 | /* Got the lock, don't cause console output */ | ||
840 | |||
841 | if (port_info[port].lp == event->xSourceLp) | ||
842 | port_info[port].lp = HvLpIndexInvalid; | ||
843 | |||
844 | spin_unlock_irqrestore(&consolelock, flags); | ||
845 | printk(VIOCONS_KERN_INFO "close from %d\n", event->xSourceLp); | ||
846 | } else | ||
847 | printk(VIOCONS_KERN_WARN | ||
848 | "got unexpected close acknowlegement\n"); | ||
849 | } | ||
850 | |||
851 | /* | ||
852 | * Handle a config charLpEvent. Could be either interrupt or ack | ||
853 | */ | ||
854 | static void vioHandleConfig(struct HvLpEvent *event) | ||
855 | { | ||
856 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
857 | |||
858 | HvCall_writeLogBuffer(cevent->data, cevent->len); | ||
859 | |||
860 | if (cevent->data[0] == 0x01) | ||
861 | printk(VIOCONS_KERN_INFO "window resized to %d: %d: %d: %d\n", | ||
862 | cevent->data[1], cevent->data[2], | ||
863 | cevent->data[3], cevent->data[4]); | ||
864 | else | ||
865 | printk(VIOCONS_KERN_WARN "unknown config event\n"); | ||
866 | } | ||
867 | |||
868 | /* | ||
869 | * Handle a data charLpEvent. | ||
870 | */ | ||
871 | static void vioHandleData(struct HvLpEvent *event) | ||
872 | { | ||
873 | struct tty_struct *tty; | ||
874 | unsigned long flags; | ||
875 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
876 | struct port_info *pi; | ||
877 | int index; | ||
878 | int num_pushed; | ||
879 | u8 port = cevent->virtual_device; | ||
880 | |||
881 | if (port >= VTTY_PORTS) { | ||
882 | printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n", | ||
883 | port); | ||
884 | return; | ||
885 | } | ||
886 | |||
887 | /* | ||
888 | * Hold the spinlock so that we don't take an interrupt that | ||
889 | * changes tty between the time we fetch the port_info | ||
890 | * pointer and the time we paranoia check. | ||
891 | */ | ||
892 | spin_lock_irqsave(&consolelock, flags); | ||
893 | pi = &port_info[port]; | ||
894 | |||
895 | /* | ||
896 | * Change 05/01/2003 - Ryan Arnold: If a partition other than | ||
897 | * the current exclusive partition tries to send us data | ||
898 | * events then just drop them on the floor because we don't | ||
899 | * want his stinking data. He isn't authorized to receive | ||
900 | * data because he wasn't the first one to get the console, | ||
901 | * therefore he shouldn't be allowed to send data either. | ||
902 | * This will work without an iSeries fix. | ||
903 | */ | ||
904 | if (pi->lp != event->xSourceLp) { | ||
905 | spin_unlock_irqrestore(&consolelock, flags); | ||
906 | return; | ||
907 | } | ||
908 | |||
909 | tty = pi->tty; | ||
910 | if (tty == NULL) { | ||
911 | spin_unlock_irqrestore(&consolelock, flags); | ||
912 | printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n", | ||
913 | port); | ||
914 | return; | ||
915 | } | ||
916 | |||
917 | if (tty->magic != TTY_MAGIC) { | ||
918 | spin_unlock_irqrestore(&consolelock, flags); | ||
919 | printk(VIOCONS_KERN_WARN "tty bad magic\n"); | ||
920 | return; | ||
921 | } | ||
922 | |||
923 | /* | ||
924 | * Just to be paranoid, make sure the tty points back to this port | ||
925 | */ | ||
926 | pi = (struct port_info *)tty->driver_data; | ||
927 | if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) { | ||
928 | spin_unlock_irqrestore(&consolelock, flags); | ||
929 | return; | ||
930 | } | ||
931 | spin_unlock_irqrestore(&consolelock, flags); | ||
932 | |||
933 | /* | ||
934 | * Change 07/21/2003 - Ryan Arnold: functionality added to | ||
935 | * support sysrq utilizing ^O as the sysrq key. The sysrq | ||
936 | * functionality will only work if built into the kernel and | ||
937 | * then only if sysrq is enabled through the proc filesystem. | ||
938 | */ | ||
939 | num_pushed = 0; | ||
940 | for (index = 0; index < cevent->len; index++) { | ||
941 | /* | ||
942 | * Will be optimized away if !CONFIG_MAGIC_SYSRQ: | ||
943 | */ | ||
944 | if (sysrq_on()) { | ||
945 | /* 0x0f is the ascii character for ^O */ | ||
946 | if (cevent->data[index] == '\x0f') { | ||
947 | vio_sysrq_pressed = 1; | ||
948 | /* | ||
949 | * continue because we don't want to add | ||
950 | * the sysrq key into the data string. | ||
951 | */ | ||
952 | continue; | ||
953 | } else if (vio_sysrq_pressed) { | ||
954 | handle_sysrq(cevent->data[index], tty); | ||
955 | vio_sysrq_pressed = 0; | ||
956 | /* | ||
957 | * continue because we don't want to add | ||
958 | * the sysrq sequence into the data string. | ||
959 | */ | ||
960 | continue; | ||
961 | } | ||
962 | } | ||
963 | /* | ||
964 | * The sysrq sequence isn't included in this check if | ||
965 | * sysrq is enabled and compiled into the kernel because | ||
966 | * the sequence will never get inserted into the buffer. | ||
967 | * Don't attempt to copy more data into the buffer than we | ||
968 | * have room for because it would fail without indication. | ||
969 | */ | ||
970 | if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) { | ||
971 | printk(VIOCONS_KERN_WARN "input buffer overflow!\n"); | ||
972 | break; | ||
973 | } | ||
974 | num_pushed++; | ||
975 | } | ||
976 | |||
977 | if (num_pushed) | ||
978 | tty_flip_buffer_push(tty); | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Handle an ack charLpEvent. | ||
983 | */ | ||
984 | static void vioHandleAck(struct HvLpEvent *event) | ||
985 | { | ||
986 | struct viocharlpevent *cevent = (struct viocharlpevent *)event; | ||
987 | unsigned long flags; | ||
988 | u8 port = cevent->virtual_device; | ||
989 | |||
990 | if (port >= VTTY_PORTS) { | ||
991 | printk(VIOCONS_KERN_WARN "data on invalid virtual device\n"); | ||
992 | return; | ||
993 | } | ||
994 | |||
995 | spin_lock_irqsave(&consolelock, flags); | ||
996 | port_info[port].ack = event->xCorrelationToken; | ||
997 | spin_unlock_irqrestore(&consolelock, flags); | ||
998 | |||
999 | if (port_info[port].used) | ||
1000 | send_buffers(&port_info[port]); | ||
1001 | } | ||
1002 | |||
1003 | /* | ||
1004 | * Handle charLpEvents and route to the appropriate routine | ||
1005 | */ | ||
1006 | static void vioHandleCharEvent(struct HvLpEvent *event) | ||
1007 | { | ||
1008 | int charminor; | ||
1009 | |||
1010 | if (event == NULL) | ||
1011 | return; | ||
1012 | |||
1013 | charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; | ||
1014 | switch (charminor) { | ||
1015 | case viocharopen: | ||
1016 | vioHandleOpenEvent(event); | ||
1017 | break; | ||
1018 | case viocharclose: | ||
1019 | vioHandleCloseEvent(event); | ||
1020 | break; | ||
1021 | case viochardata: | ||
1022 | vioHandleData(event); | ||
1023 | break; | ||
1024 | case viocharack: | ||
1025 | vioHandleAck(event); | ||
1026 | break; | ||
1027 | case viocharconfig: | ||
1028 | vioHandleConfig(event); | ||
1029 | break; | ||
1030 | default: | ||
1031 | if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) { | ||
1032 | event->xRc = HvLpEvent_Rc_InvalidSubtype; | ||
1033 | HvCallEvent_ackLpEvent(event); | ||
1034 | } | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * Send an open event | ||
1040 | */ | ||
1041 | static int send_open(HvLpIndex remoteLp, void *sem) | ||
1042 | { | ||
1043 | return HvCallEvent_signalLpEventFast(remoteLp, | ||
1044 | HvLpEvent_Type_VirtualIo, | ||
1045 | viomajorsubtype_chario | viocharopen, | ||
1046 | HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | ||
1047 | viopath_sourceinst(remoteLp), | ||
1048 | viopath_targetinst(remoteLp), | ||
1049 | (u64)(unsigned long)sem, VIOVERSION << 16, | ||
1050 | 0, 0, 0, 0); | ||
1051 | } | ||
1052 | |||
1053 | static const struct tty_operations serial_ops = { | ||
1054 | .open = viotty_open, | ||
1055 | .close = viotty_close, | ||
1056 | .write = viotty_write, | ||
1057 | .put_char = viotty_put_char, | ||
1058 | .write_room = viotty_write_room, | ||
1059 | .chars_in_buffer = viotty_chars_in_buffer, | ||
1060 | .ioctl = viotty_ioctl, | ||
1061 | }; | ||
1062 | |||
1063 | static int __init viocons_init2(void) | ||
1064 | { | ||
1065 | atomic_t wait_flag; | ||
1066 | int rc; | ||
1067 | |||
1068 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1069 | return -ENODEV; | ||
1070 | |||
1071 | /* +2 for fudge */ | ||
1072 | rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), | ||
1073 | viomajorsubtype_chario, VIOCHAR_WINDOW + 2); | ||
1074 | if (rc) | ||
1075 | printk(VIOCONS_KERN_WARN "error opening to primary %d\n", rc); | ||
1076 | |||
1077 | if (viopath_hostLp == HvLpIndexInvalid) | ||
1078 | vio_set_hostlp(); | ||
1079 | |||
1080 | /* | ||
1081 | * And if the primary is not the same as the hosting LP, open to the | ||
1082 | * hosting lp | ||
1083 | */ | ||
1084 | if ((viopath_hostLp != HvLpIndexInvalid) && | ||
1085 | (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) { | ||
1086 | printk(VIOCONS_KERN_INFO "open path to hosting (%d)\n", | ||
1087 | viopath_hostLp); | ||
1088 | rc = viopath_open(viopath_hostLp, viomajorsubtype_chario, | ||
1089 | VIOCHAR_WINDOW + 2); /* +2 for fudge */ | ||
1090 | if (rc) | ||
1091 | printk(VIOCONS_KERN_WARN | ||
1092 | "error opening to partition %d: %d\n", | ||
1093 | viopath_hostLp, rc); | ||
1094 | } | ||
1095 | |||
1096 | if (vio_setHandler(viomajorsubtype_chario, vioHandleCharEvent) < 0) | ||
1097 | printk(VIOCONS_KERN_WARN | ||
1098 | "error seting handler for console events!\n"); | ||
1099 | |||
1100 | /* | ||
1101 | * First, try to open the console to the hosting lp. | ||
1102 | * Wait on a semaphore for the response. | ||
1103 | */ | ||
1104 | atomic_set(&wait_flag, 0); | ||
1105 | if ((viopath_isactive(viopath_hostLp)) && | ||
1106 | (send_open(viopath_hostLp, (void *)&wait_flag) == 0)) { | ||
1107 | printk(VIOCONS_KERN_INFO "hosting partition %d\n", | ||
1108 | viopath_hostLp); | ||
1109 | while (atomic_read(&wait_flag) == 0) | ||
1110 | mb(); | ||
1111 | atomic_set(&wait_flag, 0); | ||
1112 | } | ||
1113 | |||
1114 | /* | ||
1115 | * If we don't have an active console, try the primary | ||
1116 | */ | ||
1117 | if ((!viopath_isactive(port_info[0].lp)) && | ||
1118 | (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) && | ||
1119 | (send_open(HvLpConfig_getPrimaryLpIndex(), (void *)&wait_flag) | ||
1120 | == 0)) { | ||
1121 | printk(VIOCONS_KERN_INFO "opening console to primary partition\n"); | ||
1122 | while (atomic_read(&wait_flag) == 0) | ||
1123 | mb(); | ||
1124 | } | ||
1125 | |||
1126 | /* Initialize the tty_driver structure */ | ||
1127 | viotty_driver = alloc_tty_driver(VTTY_PORTS); | ||
1128 | viotty_driver->owner = THIS_MODULE; | ||
1129 | viotty_driver->driver_name = "vioconsole"; | ||
1130 | viotty_driver->name = "tty"; | ||
1131 | viotty_driver->name_base = 1; | ||
1132 | viotty_driver->major = TTY_MAJOR; | ||
1133 | viotty_driver->minor_start = 1; | ||
1134 | viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE; | ||
1135 | viotty_driver->subtype = 1; | ||
1136 | viotty_driver->init_termios = tty_std_termios; | ||
1137 | viotty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; | ||
1138 | tty_set_operations(viotty_driver, &serial_ops); | ||
1139 | |||
1140 | if (tty_register_driver(viotty_driver)) { | ||
1141 | printk(VIOCONS_KERN_WARN "couldn't register console driver\n"); | ||
1142 | put_tty_driver(viotty_driver); | ||
1143 | viotty_driver = NULL; | ||
1144 | } | ||
1145 | |||
1146 | unregister_console(&viocons_early); | ||
1147 | register_console(&viocons); | ||
1148 | |||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | static int __init viocons_init(void) | ||
1153 | { | ||
1154 | int i; | ||
1155 | |||
1156 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1157 | return -ENODEV; | ||
1158 | |||
1159 | printk(VIOCONS_KERN_INFO "registering console\n"); | ||
1160 | for (i = 0; i < VTTY_PORTS; i++) { | ||
1161 | port_info[i].lp = HvLpIndexInvalid; | ||
1162 | port_info[i].magic = VIOTTY_MAGIC; | ||
1163 | } | ||
1164 | HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437); | ||
1165 | add_preferred_console("viocons", 0, NULL); | ||
1166 | register_console(&viocons_early); | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | console_initcall(viocons_init); | ||
1171 | module_init(viocons_init2); | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 82a51f38a546..57029fefd64a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -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 | ||
@@ -803,7 +803,25 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, | |||
803 | */ | 803 | */ |
804 | #define VC_RESIZE_MAXCOL (32767) | 804 | #define VC_RESIZE_MAXCOL (32767) |
805 | #define VC_RESIZE_MAXROW (32767) | 805 | #define VC_RESIZE_MAXROW (32767) |
806 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | 806 | |
807 | /** | ||
808 | * vc_do_resize - resizing method for the tty | ||
809 | * @tty: tty being resized | ||
810 | * @real_tty: real tty (different to tty if a pty/tty pair) | ||
811 | * @vc: virtual console private data | ||
812 | * @cols: columns | ||
813 | * @lines: lines | ||
814 | * | ||
815 | * Resize a virtual console, clipping according to the actual constraints. | ||
816 | * If the caller passes a tty structure then update the termios winsize | ||
817 | * information and perform any neccessary signal handling. | ||
818 | * | ||
819 | * Caller must hold the console semaphore. Takes the termios mutex and | ||
820 | * ctrl_lock of the tty IFF a tty is passed. | ||
821 | */ | ||
822 | |||
823 | static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | ||
824 | struct vc_data *vc, unsigned int cols, unsigned int lines) | ||
807 | { | 825 | { |
808 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; | 826 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; |
809 | unsigned int old_cols, old_rows, old_row_size, old_screen_size; | 827 | unsigned int old_cols, old_rows, old_row_size, old_screen_size; |
@@ -907,26 +925,15 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
907 | gotoxy(vc, vc->vc_x, vc->vc_y); | 925 | gotoxy(vc, vc->vc_x, vc->vc_y); |
908 | save_cur(vc); | 926 | save_cur(vc); |
909 | 927 | ||
910 | if (vc->vc_tty) { | 928 | if (tty) { |
911 | struct winsize ws, *cws = &vc->vc_tty->winsize; | 929 | /* Rewrite the requested winsize data with the actual |
912 | struct pid *pgrp = NULL; | 930 | resulting sizes */ |
913 | 931 | struct winsize ws; | |
914 | memset(&ws, 0, sizeof(ws)); | 932 | memset(&ws, 0, sizeof(ws)); |
915 | ws.ws_row = vc->vc_rows; | 933 | ws.ws_row = vc->vc_rows; |
916 | ws.ws_col = vc->vc_cols; | 934 | ws.ws_col = vc->vc_cols; |
917 | ws.ws_ypixel = vc->vc_scan_lines; | 935 | ws.ws_ypixel = vc->vc_scan_lines; |
918 | 936 | tty_do_resize(tty, real_tty, &ws); | |
919 | mutex_lock(&vc->vc_tty->termios_mutex); | ||
920 | spin_lock_irq(&vc->vc_tty->ctrl_lock); | ||
921 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) | ||
922 | pgrp = get_pid(vc->vc_tty->pgrp); | ||
923 | spin_unlock_irq(&vc->vc_tty->ctrl_lock); | ||
924 | if (pgrp) { | ||
925 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); | ||
926 | put_pid(pgrp); | ||
927 | } | ||
928 | *cws = ws; | ||
929 | mutex_unlock(&vc->vc_tty->termios_mutex); | ||
930 | } | 937 | } |
931 | 938 | ||
932 | if (CON_IS_VISIBLE(vc)) | 939 | if (CON_IS_VISIBLE(vc)) |
@@ -934,14 +941,47 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
934 | return err; | 941 | return err; |
935 | } | 942 | } |
936 | 943 | ||
937 | int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | 944 | /** |
945 | * vc_resize - resize a VT | ||
946 | * @vc: virtual console | ||
947 | * @cols: columns | ||
948 | * @rows: rows | ||
949 | * | ||
950 | * Resize a virtual console as seen from the console end of things. We | ||
951 | * use the common vc_do_resize methods to update the structures. The | ||
952 | * caller must hold the console sem to protect console internals and | ||
953 | * vc->vc_tty | ||
954 | */ | ||
955 | |||
956 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) | ||
938 | { | 957 | { |
939 | int rc; | 958 | return vc_do_resize(vc->vc_tty, vc->vc_tty, vc, cols, rows); |
959 | } | ||
960 | |||
961 | /** | ||
962 | * vt_resize - resize a VT | ||
963 | * @tty: tty to resize | ||
964 | * @real_tty: tty if a pty/tty pair | ||
965 | * @ws: winsize attributes | ||
966 | * | ||
967 | * Resize a virtual terminal. This is called by the tty layer as we | ||
968 | * register our own handler for resizing. The mutual helper does all | ||
969 | * the actual work. | ||
970 | * | ||
971 | * Takes the console sem and the called methods then take the tty | ||
972 | * termios_mutex and the tty ctrl_lock in that order. | ||
973 | */ | ||
974 | |||
975 | int vt_resize(struct tty_struct *tty, struct tty_struct *real_tty, | ||
976 | struct winsize *ws) | ||
977 | { | ||
978 | struct vc_data *vc = tty->driver_data; | ||
979 | int ret; | ||
940 | 980 | ||
941 | acquire_console_sem(); | 981 | acquire_console_sem(); |
942 | rc = vc_resize(vc, cols, lines); | 982 | ret = vc_do_resize(tty, real_tty, vc, ws->ws_col, ws->ws_row); |
943 | release_console_sem(); | 983 | release_console_sem(); |
944 | return rc; | 984 | return ret; |
945 | } | 985 | } |
946 | 986 | ||
947 | void vc_deallocate(unsigned int currcons) | 987 | void vc_deallocate(unsigned int currcons) |
@@ -2096,27 +2136,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2096 | release_console_sem(); | 2136 | release_console_sem(); |
2097 | return 0; | 2137 | return 0; |
2098 | } | 2138 | } |
2099 | release_console_sem(); | ||
2100 | |||
2101 | orig_buf = buf; | 2139 | orig_buf = buf; |
2102 | orig_count = count; | 2140 | orig_count = count; |
2103 | 2141 | ||
2104 | /* At this point 'buf' is guaranteed to be a kernel buffer | ||
2105 | * and therefore no access to userspace (and therefore sleeping) | ||
2106 | * will be needed. The con_buf_mtx serializes all tty based | ||
2107 | * console rendering and vcs write/read operations. We hold | ||
2108 | * the console spinlock during the entire write. | ||
2109 | */ | ||
2110 | |||
2111 | acquire_console_sem(); | ||
2112 | |||
2113 | vc = tty->driver_data; | ||
2114 | if (vc == NULL) { | ||
2115 | printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n"); | ||
2116 | release_console_sem(); | ||
2117 | goto out; | ||
2118 | } | ||
2119 | |||
2120 | himask = vc->vc_hi_font_mask; | 2142 | himask = vc->vc_hi_font_mask; |
2121 | charmask = himask ? 0x1ff : 0xff; | 2143 | charmask = himask ? 0x1ff : 0xff; |
2122 | 2144 | ||
@@ -2330,8 +2352,6 @@ rescan_last_byte: | |||
2330 | FLUSH | 2352 | FLUSH |
2331 | console_conditional_schedule(); | 2353 | console_conditional_schedule(); |
2332 | release_console_sem(); | 2354 | release_console_sem(); |
2333 | |||
2334 | out: | ||
2335 | notify_update(vc); | 2355 | notify_update(vc); |
2336 | return n; | 2356 | return n; |
2337 | #undef FLUSH | 2357 | #undef FLUSH |
@@ -2543,8 +2563,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2543 | int lines; | 2563 | int lines; |
2544 | int ret; | 2564 | int ret; |
2545 | 2565 | ||
2546 | if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) | ||
2547 | return -EINVAL; | ||
2548 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) | 2566 | if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) |
2549 | return -EPERM; | 2567 | return -EPERM; |
2550 | if (get_user(type, p)) | 2568 | if (get_user(type, p)) |
@@ -2738,6 +2756,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2738 | ret = vc_allocate(currcons); | 2756 | ret = vc_allocate(currcons); |
2739 | if (ret == 0) { | 2757 | if (ret == 0) { |
2740 | struct vc_data *vc = vc_cons[currcons].d; | 2758 | struct vc_data *vc = vc_cons[currcons].d; |
2759 | |||
2760 | /* Still being freed */ | ||
2761 | if (vc->vc_tty) { | ||
2762 | release_console_sem(); | ||
2763 | return -ERESTARTSYS; | ||
2764 | } | ||
2741 | tty->driver_data = vc; | 2765 | tty->driver_data = vc; |
2742 | vc->vc_tty = tty; | 2766 | vc->vc_tty = tty; |
2743 | 2767 | ||
@@ -2758,34 +2782,20 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2758 | return ret; | 2782 | return ret; |
2759 | } | 2783 | } |
2760 | 2784 | ||
2761 | /* | ||
2762 | * We take tty_mutex in here to prevent another thread from coming in via init_dev | ||
2763 | * and taking a ref against the tty while we're in the process of forgetting | ||
2764 | * about it and cleaning things up. | ||
2765 | * | ||
2766 | * This is because vcs_remove_sysfs() can sleep and will drop the BKL. | ||
2767 | */ | ||
2768 | static void con_close(struct tty_struct *tty, struct file *filp) | 2785 | static void con_close(struct tty_struct *tty, struct file *filp) |
2769 | { | 2786 | { |
2770 | mutex_lock(&tty_mutex); | 2787 | /* Nothing to do - we defer to shutdown */ |
2771 | acquire_console_sem(); | 2788 | } |
2772 | if (tty && tty->count == 1) { | ||
2773 | struct vc_data *vc = tty->driver_data; | ||
2774 | 2789 | ||
2775 | if (vc) | 2790 | static void con_shutdown(struct tty_struct *tty) |
2776 | vc->vc_tty = NULL; | 2791 | { |
2777 | tty->driver_data = NULL; | 2792 | struct vc_data *vc = tty->driver_data; |
2778 | vcs_remove_sysfs(tty); | 2793 | BUG_ON(vc == NULL); |
2779 | release_console_sem(); | 2794 | acquire_console_sem(); |
2780 | mutex_unlock(&tty_mutex); | 2795 | vc->vc_tty = NULL; |
2781 | /* | 2796 | vcs_remove_sysfs(tty); |
2782 | * tty_mutex is released, but we still hold BKL, so there is | ||
2783 | * still exclusion against init_dev() | ||
2784 | */ | ||
2785 | return; | ||
2786 | } | ||
2787 | release_console_sem(); | 2797 | release_console_sem(); |
2788 | mutex_unlock(&tty_mutex); | 2798 | tty_shutdown(tty); |
2789 | } | 2799 | } |
2790 | 2800 | ||
2791 | static int default_italic_color = 2; // green (ASCII) | 2801 | static int default_italic_color = 2; // green (ASCII) |
@@ -2909,10 +2919,20 @@ static const struct tty_operations con_ops = { | |||
2909 | .start = con_start, | 2919 | .start = con_start, |
2910 | .throttle = con_throttle, | 2920 | .throttle = con_throttle, |
2911 | .unthrottle = con_unthrottle, | 2921 | .unthrottle = con_unthrottle, |
2922 | .resize = vt_resize, | ||
2923 | .shutdown = con_shutdown | ||
2912 | }; | 2924 | }; |
2913 | 2925 | ||
2914 | int __init vty_init(void) | 2926 | static struct cdev vc0_cdev; |
2927 | |||
2928 | int __init vty_init(const struct file_operations *console_fops) | ||
2915 | { | 2929 | { |
2930 | cdev_init(&vc0_cdev, console_fops); | ||
2931 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | ||
2932 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | ||
2933 | panic("Couldn't register /dev/tty0 driver\n"); | ||
2934 | device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | ||
2935 | |||
2916 | vcs_init(); | 2936 | vcs_init(); |
2917 | 2937 | ||
2918 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); | 2938 | console_driver = alloc_tty_driver(MAX_NR_CONSOLES); |
@@ -2931,7 +2951,6 @@ int __init vty_init(void) | |||
2931 | tty_set_operations(console_driver, &con_ops); | 2951 | tty_set_operations(console_driver, &con_ops); |
2932 | if (tty_register_driver(console_driver)) | 2952 | if (tty_register_driver(console_driver)) |
2933 | panic("Couldn't register console driver\n"); | 2953 | panic("Couldn't register console driver\n"); |
2934 | |||
2935 | kbd_init(); | 2954 | kbd_init(); |
2936 | console_map_init(); | 2955 | console_map_init(); |
2937 | #ifdef CONFIG_PROM_CONSOLE | 2956 | #ifdef CONFIG_PROM_CONSOLE |
@@ -3425,7 +3444,7 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
3425 | if (retval) | 3444 | if (retval) |
3426 | goto err; | 3445 | goto err; |
3427 | 3446 | ||
3428 | con_driver->dev = device_create_drvdata(vtconsole_class, NULL, | 3447 | con_driver->dev = device_create(vtconsole_class, NULL, |
3429 | MKDEV(0, con_driver->node), | 3448 | MKDEV(0, con_driver->node), |
3430 | NULL, "vtcon%i", | 3449 | NULL, "vtcon%i", |
3431 | con_driver->node); | 3450 | con_driver->node); |
@@ -3536,7 +3555,7 @@ static int __init vtconsole_class_init(void) | |||
3536 | struct con_driver *con = ®istered_con_driver[i]; | 3555 | struct con_driver *con = ®istered_con_driver[i]; |
3537 | 3556 | ||
3538 | if (con->con && !con->dev) { | 3557 | if (con->con && !con->dev) { |
3539 | con->dev = device_create_drvdata(vtconsole_class, NULL, | 3558 | con->dev = device_create(vtconsole_class, NULL, |
3540 | MKDEV(0, con->node), | 3559 | MKDEV(0, con->node), |
3541 | NULL, "vtcon%i", | 3560 | NULL, "vtcon%i", |
3542 | con->node); | 3561 | con->node); |
@@ -4063,7 +4082,6 @@ EXPORT_SYMBOL(default_blu); | |||
4063 | EXPORT_SYMBOL(update_region); | 4082 | EXPORT_SYMBOL(update_region); |
4064 | EXPORT_SYMBOL(redraw_screen); | 4083 | EXPORT_SYMBOL(redraw_screen); |
4065 | EXPORT_SYMBOL(vc_resize); | 4084 | EXPORT_SYMBOL(vc_resize); |
4066 | EXPORT_SYMBOL(vc_lock_resize); | ||
4067 | EXPORT_SYMBOL(fg_console); | 4085 | EXPORT_SYMBOL(fg_console); |
4068 | EXPORT_SYMBOL(console_blank_hook); | 4086 | EXPORT_SYMBOL(console_blank_hook); |
4069 | EXPORT_SYMBOL(console_blanked); | 4087 | EXPORT_SYMBOL(console_blanked); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 3211afd9d57e..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; |
@@ -947,14 +949,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
947 | get_user(cc, &vtsizes->v_cols)) | 949 | get_user(cc, &vtsizes->v_cols)) |
948 | ret = -EFAULT; | 950 | ret = -EFAULT; |
949 | else { | 951 | else { |
952 | acquire_console_sem(); | ||
950 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 953 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
951 | vc = vc_cons[i].d; | 954 | vc = vc_cons[i].d; |
952 | 955 | ||
953 | if (vc) { | 956 | if (vc) { |
954 | vc->vc_resize_user = 1; | 957 | vc->vc_resize_user = 1; |
955 | vc_lock_resize(vc_cons[i].d, cc, ll); | 958 | vc_resize(vc_cons[i].d, cc, ll); |
956 | } | 959 | } |
957 | } | 960 | } |
961 | release_console_sem(); | ||
958 | } | 962 | } |
959 | break; | 963 | break; |
960 | } | 964 | } |
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.h b/drivers/char/xilinx_hwicap/buffer_icap.h index c5b1840906b2..8b0252bf06e2 100644 --- a/drivers/char/xilinx_hwicap/buffer_icap.h +++ b/drivers/char/xilinx_hwicap/buffer_icap.h | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
41 | #include <linux/version.h> | ||
42 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
43 | 42 | ||
44 | #include <asm/io.h> | 43 | #include <asm/io.h> |
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.h b/drivers/char/xilinx_hwicap/fifo_icap.h index ffabd3ba2bd8..62bda453c90b 100644 --- a/drivers/char/xilinx_hwicap/fifo_icap.h +++ b/drivers/char/xilinx_hwicap/fifo_icap.h | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
41 | #include <linux/version.h> | ||
42 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
43 | 42 | ||
44 | #include <asm/io.h> | 43 | #include <asm/io.h> |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 8bfee5fb7223..278c9857bcf5 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -74,7 +74,6 @@ | |||
74 | * currently programmed in the FPGA. | 74 | * currently programmed in the FPGA. |
75 | */ | 75 | */ |
76 | 76 | ||
77 | #include <linux/version.h> | ||
78 | #include <linux/module.h> | 77 | #include <linux/module.h> |
79 | #include <linux/kernel.h> | 78 | #include <linux/kernel.h> |
80 | #include <linux/types.h> | 79 | #include <linux/types.h> |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h index 1f9c8b082dbe..24d0d9b938fb 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
41 | #include <linux/version.h> | ||
42 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
43 | 42 | ||
44 | #include <asm/io.h> | 43 | #include <asm/io.h> |