aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hvc_console.c31
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c10
-rw-r--r--drivers/char/tty_buffer.c4
-rw-r--r--drivers/char/tty_port.c2
-rw-r--r--drivers/char/virtio_console.c15
-rw-r--r--drivers/char/vt_ioctl.c39
7 files changed, 67 insertions, 38 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e481c5938bad..9c5eea3ea4de 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -215,9 +215,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
215 else 215 else
216 v &= ~0xffff; 216 v &= ~0xffff;
217 217
218 for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; 218 for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
219 irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
220
221 if (irq >= nr_irqs) { 219 if (irq >= nr_irqs) {
222 irq = HPET_MAX_IRQ; 220 irq = HPET_MAX_IRQ;
223 break; 221 break;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 465185fc0f52..ba55bba151b9 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
312 spin_lock_irqsave(&hp->lock, flags); 312 spin_lock_irqsave(&hp->lock, flags);
313 /* Check and then increment for fast path open. */ 313 /* Check and then increment for fast path open. */
314 if (hp->count++ > 0) { 314 if (hp->count++ > 0) {
315 tty_kref_get(tty);
315 spin_unlock_irqrestore(&hp->lock, flags); 316 spin_unlock_irqrestore(&hp->lock, flags);
316 hvc_kick(); 317 hvc_kick();
317 return 0; 318 return 0;
@@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
319 320
320 tty->driver_data = hp; 321 tty->driver_data = hp;
321 322
322 hp->tty = tty; 323 hp->tty = tty_kref_get(tty);
323 324
324 spin_unlock_irqrestore(&hp->lock, flags); 325 spin_unlock_irqrestore(&hp->lock, flags);
325 326
@@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
336 spin_lock_irqsave(&hp->lock, flags); 337 spin_lock_irqsave(&hp->lock, flags);
337 hp->tty = NULL; 338 hp->tty = NULL;
338 spin_unlock_irqrestore(&hp->lock, flags); 339 spin_unlock_irqrestore(&hp->lock, flags);
340 tty_kref_put(tty);
339 tty->driver_data = NULL; 341 tty->driver_data = NULL;
340 kref_put(&hp->kref, destroy_hvc_struct); 342 kref_put(&hp->kref, destroy_hvc_struct);
341 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); 343 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
363 return; 365 return;
364 366
365 hp = tty->driver_data; 367 hp = tty->driver_data;
368
366 spin_lock_irqsave(&hp->lock, flags); 369 spin_lock_irqsave(&hp->lock, flags);
370 tty_kref_get(tty);
367 371
368 if (--hp->count == 0) { 372 if (--hp->count == 0) {
369 /* We are done with the tty pointer now. */ 373 /* We are done with the tty pointer now. */
370 hp->tty = NULL; 374 hp->tty = NULL;
371 spin_unlock_irqrestore(&hp->lock, flags); 375 spin_unlock_irqrestore(&hp->lock, flags);
372 376
377 /* Put the ref obtained in hvc_open() */
378 tty_kref_put(tty);
379
373 if (hp->ops->notifier_del) 380 if (hp->ops->notifier_del)
374 hp->ops->notifier_del(hp, hp->data); 381 hp->ops->notifier_del(hp, hp->data);
375 382
@@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
389 spin_unlock_irqrestore(&hp->lock, flags); 396 spin_unlock_irqrestore(&hp->lock, flags);
390 } 397 }
391 398
399 tty_kref_put(tty);
392 kref_put(&hp->kref, destroy_hvc_struct); 400 kref_put(&hp->kref, destroy_hvc_struct);
393} 401}
394 402
@@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty)
424 spin_unlock_irqrestore(&hp->lock, flags); 432 spin_unlock_irqrestore(&hp->lock, flags);
425 433
426 if (hp->ops->notifier_hangup) 434 if (hp->ops->notifier_hangup)
427 hp->ops->notifier_hangup(hp, hp->data); 435 hp->ops->notifier_hangup(hp, hp->data);
428 436
429 while(temp_open_count) { 437 while(temp_open_count) {
430 --temp_open_count; 438 --temp_open_count;
439 tty_kref_put(tty);
431 kref_put(&hp->kref, destroy_hvc_struct); 440 kref_put(&hp->kref, destroy_hvc_struct);
432 } 441 }
433} 442}
@@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
592 } 601 }
593 602
594 /* No tty attached, just skip */ 603 /* No tty attached, just skip */
595 tty = hp->tty; 604 tty = tty_kref_get(hp->tty);
596 if (tty == NULL) 605 if (tty == NULL)
597 goto bail; 606 goto bail;
598 607
@@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)
672 681
673 tty_flip_buffer_push(tty); 682 tty_flip_buffer_push(tty);
674 } 683 }
684 if (tty)
685 tty_kref_put(tty);
675 686
676 return poll_mask; 687 return poll_mask;
677} 688}
@@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)
807 struct tty_struct *tty; 818 struct tty_struct *tty;
808 819
809 spin_lock_irqsave(&hp->lock, flags); 820 spin_lock_irqsave(&hp->lock, flags);
810 tty = hp->tty; 821 tty = tty_kref_get(hp->tty);
811 822
812 if (hp->index < MAX_NR_HVC_CONSOLES) 823 if (hp->index < MAX_NR_HVC_CONSOLES)
813 vtermnos[hp->index] = -1; 824 vtermnos[hp->index] = -1;
@@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp)
819 /* 830 /*
820 * We 'put' the instance that was grabbed when the kref instance 831 * We 'put' the instance that was grabbed when the kref instance
821 * was initialized using kref_init(). Let the last holder of this 832 * was initialized using kref_init(). Let the last holder of this
822 * kref cause it to be removed, which will probably be the tty_hangup 833 * kref cause it to be removed, which will probably be the tty_vhangup
823 * below. 834 * below.
824 */ 835 */
825 kref_put(&hp->kref, destroy_hvc_struct); 836 kref_put(&hp->kref, destroy_hvc_struct);
826 837
827 /* 838 /*
828 * This function call will auto chain call hvc_hangup. The tty should 839 * This function call will auto chain call hvc_hangup.
829 * always be valid at this time unless a simultaneous tty close already
830 * cleaned up the hvc_struct.
831 */ 840 */
832 if (tty) 841 if (tty) {
833 tty_hangup(tty); 842 tty_vhangup(tty);
843 tty_kref_put(tty);
844 }
834 return 0; 845 return 0;
835} 846}
836EXPORT_SYMBOL_GPL(hvc_remove); 847EXPORT_SYMBOL_GPL(hvc_remove);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index ec5e3f8df648..c6ad4234378d 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc)
2272 bmc->device_id_attr.attr.name = "device_id"; 2272 bmc->device_id_attr.attr.name = "device_id";
2273 bmc->device_id_attr.attr.mode = S_IRUGO; 2273 bmc->device_id_attr.attr.mode = S_IRUGO;
2274 bmc->device_id_attr.show = device_id_show; 2274 bmc->device_id_attr.show = device_id_show;
2275 sysfs_attr_init(&bmc->device_id_attr.attr);
2275 2276
2276 bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; 2277 bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
2277 bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; 2278 bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
2278 bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; 2279 bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
2280 sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
2279 2281
2280 bmc->revision_attr.attr.name = "revision"; 2282 bmc->revision_attr.attr.name = "revision";
2281 bmc->revision_attr.attr.mode = S_IRUGO; 2283 bmc->revision_attr.attr.mode = S_IRUGO;
2282 bmc->revision_attr.show = revision_show; 2284 bmc->revision_attr.show = revision_show;
2285 sysfs_attr_init(&bmc->revision_attr.attr);
2283 2286
2284 bmc->firmware_rev_attr.attr.name = "firmware_revision"; 2287 bmc->firmware_rev_attr.attr.name = "firmware_revision";
2285 bmc->firmware_rev_attr.attr.mode = S_IRUGO; 2288 bmc->firmware_rev_attr.attr.mode = S_IRUGO;
2286 bmc->firmware_rev_attr.show = firmware_rev_show; 2289 bmc->firmware_rev_attr.show = firmware_rev_show;
2290 sysfs_attr_init(&bmc->firmware_rev_attr.attr);
2287 2291
2288 bmc->version_attr.attr.name = "ipmi_version"; 2292 bmc->version_attr.attr.name = "ipmi_version";
2289 bmc->version_attr.attr.mode = S_IRUGO; 2293 bmc->version_attr.attr.mode = S_IRUGO;
2290 bmc->version_attr.show = ipmi_version_show; 2294 bmc->version_attr.show = ipmi_version_show;
2295 sysfs_attr_init(&bmc->version_attr.attr);
2291 2296
2292 bmc->add_dev_support_attr.attr.name = "additional_device_support"; 2297 bmc->add_dev_support_attr.attr.name = "additional_device_support";
2293 bmc->add_dev_support_attr.attr.mode = S_IRUGO; 2298 bmc->add_dev_support_attr.attr.mode = S_IRUGO;
2294 bmc->add_dev_support_attr.show = add_dev_support_show; 2299 bmc->add_dev_support_attr.show = add_dev_support_show;
2300 sysfs_attr_init(&bmc->add_dev_support_attr.attr);
2295 2301
2296 bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; 2302 bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
2297 bmc->manufacturer_id_attr.attr.mode = S_IRUGO; 2303 bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
2298 bmc->manufacturer_id_attr.show = manufacturer_id_show; 2304 bmc->manufacturer_id_attr.show = manufacturer_id_show;
2305 sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
2299 2306
2300 bmc->product_id_attr.attr.name = "product_id"; 2307 bmc->product_id_attr.attr.name = "product_id";
2301 bmc->product_id_attr.attr.mode = S_IRUGO; 2308 bmc->product_id_attr.attr.mode = S_IRUGO;
2302 bmc->product_id_attr.show = product_id_show; 2309 bmc->product_id_attr.show = product_id_show;
2310 sysfs_attr_init(&bmc->product_id_attr.attr);
2303 2311
2304 bmc->guid_attr.attr.name = "guid"; 2312 bmc->guid_attr.attr.name = "guid";
2305 bmc->guid_attr.attr.mode = S_IRUGO; 2313 bmc->guid_attr.attr.mode = S_IRUGO;
2306 bmc->guid_attr.show = guid_show; 2314 bmc->guid_attr.show = guid_show;
2315 sysfs_attr_init(&bmc->guid_attr.attr);
2307 2316
2308 bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; 2317 bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
2309 bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; 2318 bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
2310 bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; 2319 bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
2320 sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
2311 2321
2312 err = device_create_file(&bmc->dev->dev, 2322 err = device_create_file(&bmc->dev->dev,
2313 &bmc->device_id_attr); 2323 &bmc->device_id_attr);
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index af8d97715728..7ee52164d474 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
248{ 248{
249 int copied = 0; 249 int copied = 0;
250 do { 250 do {
251 int goal = min(size - copied, TTY_BUFFER_PAGE); 251 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
252 int space = tty_buffer_request_room(tty, goal); 252 int space = tty_buffer_request_room(tty, goal);
253 struct tty_buffer *tb = tty->buf.tail; 253 struct tty_buffer *tb = tty->buf.tail;
254 /* If there is no space then tb may be NULL */ 254 /* If there is no space then tb may be NULL */
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
285{ 285{
286 int copied = 0; 286 int copied = 0;
287 do { 287 do {
288 int goal = min(size - copied, TTY_BUFFER_PAGE); 288 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
289 int space = tty_buffer_request_room(tty, goal); 289 int space = tty_buffer_request_room(tty, goal);
290 struct tty_buffer *tb = tty->buf.tail; 290 struct tty_buffer *tb = tty->buf.tail;
291 /* If there is no space then tb may be NULL */ 291 /* If there is no space then tb may be NULL */
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index be492dd66437..a3bd1d0b66cf 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
119static void tty_port_shutdown(struct tty_port *port) 119static void tty_port_shutdown(struct tty_port *port)
120{ 120{
121 mutex_lock(&port->mutex); 121 mutex_lock(&port->mutex);
122 if (port->ops->shutdown && 122 if (port->ops->shutdown && !port->console &&
123 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) 123 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
124 port->ops->shutdown(port); 124 port->ops->shutdown(port);
125 mutex_unlock(&port->mutex); 125 mutex_unlock(&port->mutex);
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index f404ccfc9c20..44288ce0cb45 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -681,6 +681,10 @@ static void resize_console(struct port *port)
681 struct virtio_device *vdev; 681 struct virtio_device *vdev;
682 struct winsize ws; 682 struct winsize ws;
683 683
684 /* The port could have been hot-unplugged */
685 if (!port)
686 return;
687
684 vdev = port->portdev->vdev; 688 vdev = port->portdev->vdev;
685 if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) { 689 if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) {
686 vdev->config->get(vdev, 690 vdev->config->get(vdev,
@@ -947,11 +951,18 @@ static void handle_control_message(struct ports_device *portdev,
947 */ 951 */
948 err = sysfs_create_group(&port->dev->kobj, 952 err = sysfs_create_group(&port->dev->kobj,
949 &port_attribute_group); 953 &port_attribute_group);
950 if (err) 954 if (err) {
951 dev_err(port->dev, 955 dev_err(port->dev,
952 "Error %d creating sysfs device attributes\n", 956 "Error %d creating sysfs device attributes\n",
953 err); 957 err);
954 958 } else {
959 /*
960 * Generate a udev event so that appropriate
961 * symlinks can be created based on udev
962 * rules.
963 */
964 kobject_uevent(&port->dev->kobj, KOBJ_CHANGE);
965 }
955 break; 966 break;
956 case VIRTIO_CONSOLE_PORT_REMOVE: 967 case VIRTIO_CONSOLE_PORT_REMOVE:
957 /* 968 /*
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 87778dcf8727..6aa10284104a 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
888 ret = -EFAULT; 888 ret = -EFAULT;
889 goto out; 889 goto out;
890 } 890 }
891 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) { 891 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
892 ret = -EINVAL; 892 ret = -EINVAL;
893 goto out; 893 goto out;
894 } 894 }
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
1622 * telling it that it has acquired. Also check if it has died and 1622 * telling it that it has acquired. Also check if it has died and
1623 * clean up (similar to logic employed in change_console()) 1623 * clean up (similar to logic employed in change_console())
1624 */ 1624 */
1625 if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { 1625 if (vc->vt_mode.mode == VT_PROCESS) {
1626 /* 1626 /*
1627 * Send the signal as privileged - kill_pid() will 1627 * Send the signal as privileged - kill_pid() will
1628 * tell us if the process has gone or something else 1628 * tell us if the process has gone or something else
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
1682 * vt to auto control. 1682 * vt to auto control.
1683 */ 1683 */
1684 vc = vc_cons[fg_console].d; 1684 vc = vc_cons[fg_console].d;
1685 if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { 1685 if (vc->vt_mode.mode == VT_PROCESS) {
1686 /* 1686 /*
1687 * Send the signal as privileged - kill_pid() will 1687 * Send the signal as privileged - kill_pid() will
1688 * tell us if the process has gone or something else 1688 * tell us if the process has gone or something else
@@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)
1693 */ 1693 */
1694 vc->vt_newvt = new_vc->vc_num; 1694 vc->vt_newvt = new_vc->vc_num;
1695 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { 1695 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1696 if(vc->vt_mode.mode == VT_PROCESS)
1697 /*
1698 * It worked. Mark the vt to switch to and
1699 * return. The process needs to send us a
1700 * VT_RELDISP ioctl to complete the switch.
1701 */
1702 return;
1703 } else {
1704 /* 1696 /*
1705 * The controlling process has died, so we revert back to 1697 * It worked. Mark the vt to switch to and
1706 * normal operation. In this case, we'll also change back 1698 * return. The process needs to send us a
1707 * to KD_TEXT mode. I'm not sure if this is strictly correct 1699 * VT_RELDISP ioctl to complete the switch.
1708 * but it saves the agony when the X server dies and the screen
1709 * remains blanked due to KD_GRAPHICS! It would be nice to do
1710 * this outside of VT_PROCESS but there is no single process
1711 * to account for and tracking tty count may be undesirable.
1712 */ 1700 */
1713 reset_vc(vc); 1701 return;
1714 } 1702 }
1715 1703
1716 /* 1704 /*
1717 * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... 1705 * The controlling process has died, so we revert back to
1706 * normal operation. In this case, we'll also change back
1707 * to KD_TEXT mode. I'm not sure if this is strictly correct
1708 * but it saves the agony when the X server dies and the screen
1709 * remains blanked due to KD_GRAPHICS! It would be nice to do
1710 * this outside of VT_PROCESS but there is no single process
1711 * to account for and tracking tty count may be undesirable.
1712 */
1713 reset_vc(vc);
1714
1715 /*
1716 * Fall through to normal (VT_AUTO) handling of the switch...
1718 */ 1717 */
1719 } 1718 }
1720 1719