From 74c76c84576eb2d806f40f6cb2fc8302c01869d8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 7 May 2008 09:22:58 +0200 Subject: [S390] tty3270: fix put_char fail/success conversion. The wrong function got coverted ;) CC drivers/s390/char/tty3270.o drivers/s390/char/tty3270.c:1747: warning: initialization from incompatible pointer type Acked-by: Alan Cox Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index c1f2adefad4..5043150019a 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -965,8 +965,7 @@ tty3270_write_room(struct tty_struct *tty) * Insert character into the screen at the current position with the * current color and highlight. This function does NOT do cursor movement. */ -static int -tty3270_put_character(struct tty3270 *tp, char ch) +static void tty3270_put_character(struct tty3270 *tp, char ch) { struct tty3270_line *line; struct tty3270_cell *cell; @@ -986,7 +985,6 @@ tty3270_put_character(struct tty3270 *tp, char ch) cell->character = tp->view.ascebc[(unsigned int) ch]; cell->highlight = tp->highlight; cell->f_color = tp->f_color; - return 1; } /* @@ -1612,16 +1610,15 @@ tty3270_write(struct tty_struct * tty, /* * Put single characters to the ttys character buffer */ -static void -tty3270_put_char(struct tty_struct *tty, unsigned char ch) +static int tty3270_put_char(struct tty_struct *tty, unsigned char ch) { struct tty3270 *tp; tp = tty->driver_data; - if (!tp) - return; - if (tp->char_count < TTY3270_CHAR_BUF_SIZE) - tp->char_buf[tp->char_count++] = ch; + if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE) + return 0; + tp->char_buf[tp->char_count++] = ch; + return 1; } /* -- cgit v1.2.3 From 3cb2cea15e707dd030b3293d6d08183da369d291 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Thu, 15 May 2008 16:52:32 +0200 Subject: [S390] vmlogrdr: module initialization function should return negative errors Signed-off-by: Marcin Slusarz Signed-off-by: Martin Schwidefsky --- drivers/s390/char/vmlogrdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index d364e0bfae1..e8487347e4d 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -858,7 +858,7 @@ static int __init vmlogrdr_init(void) for (i=0; i < MAXMINOR; ++i ) { sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL); if (!sys_ser[i].buffer) { - rc = ENOMEM; + rc = -ENOMEM; break; } sys_ser[i].current_position = sys_ser[i].buffer; -- cgit v1.2.3 From f455adcff102851629d716815f92bb7010de0c4e Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 15 May 2008 16:52:37 +0200 Subject: [S390] tape: Use ccw_dev_id to build cdev_id. To construct the integer containing the information from the bus_id, it is easier to use the data from ccw_dev_id than to parse the bus_id. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape_core.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 7ad8cf15764..76e44eb7c47 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -76,32 +76,9 @@ const char *tape_op_verbose[TO_SIZE] = [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC", }; -static int -busid_to_int(char *bus_id) +static int devid_to_int(struct ccw_dev_id *dev_id) { - int dec; - int d; - char * s; - - for(s = bus_id, d = 0; *s != '\0' && *s != '.'; s++) - d = (d * 10) + (*s - '0'); - dec = d; - for(s++, d = 0; *s != '\0' && *s != '.'; s++) - d = (d * 10) + (*s - '0'); - dec = (dec << 8) + d; - - for(s++; *s != '\0'; s++) { - if (*s >= '0' && *s <= '9') { - d = *s - '0'; - } else if (*s >= 'a' && *s <= 'f') { - d = *s - 'a' + 10; - } else { - d = *s - 'A' + 10; - } - dec = (dec << 4) + d; - } - - return dec; + return dev_id->devno + (dev_id->ssid << 16); } /* @@ -551,6 +528,7 @@ tape_generic_probe(struct ccw_device *cdev) { struct tape_device *device; int ret; + struct ccw_dev_id dev_id; device = tape_alloc_device(); if (IS_ERR(device)) @@ -565,7 +543,8 @@ tape_generic_probe(struct ccw_device *cdev) cdev->dev.driver_data = device; cdev->handler = __tape_do_irq; device->cdev = cdev; - device->cdev_id = busid_to_int(cdev->dev.bus_id); + ccw_device_get_id(cdev, &dev_id); + device->cdev_id = devid_to_int(&dev_id); PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); return ret; } -- cgit v1.2.3 From c5fb920aec2090a44aa4c33546b9f3c3affa538c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 16 May 2008 17:55:12 -0700 Subject: s390: fix race in device_create There is a race from when a device is created with device_create() and then the drvdata is set with a call to dev_set_drvdata() in which a sysfs file could be open, yet the drvdata will be NULL, causing all sorts of bad things to happen. This patch fixes the problem by using the new function, device_create_drvdata(). Cc: Kay Sievers Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/vmlogrdr.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e8487347e4d..2c2428cc05d 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -762,10 +762,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) device_unregister(dev); return ret; } - priv->class_device = device_create(vmlogrdr_class, dev, - MKDEV(vmlogrdr_major, - priv->minor_num), - "%s", dev->bus_id); + priv->class_device = device_create_drvdata(vmlogrdr_class, dev, + MKDEV(vmlogrdr_major, + priv->minor_num), + priv, "%s", dev->bus_id); if (IS_ERR(priv->class_device)) { ret = PTR_ERR(priv->class_device); priv->class_device=NULL; @@ -773,7 +773,6 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) device_unregister(dev); return ret; } - dev->driver_data = priv; priv->device = dev; return 0; } -- cgit v1.2.3 From f71ad62a264a89cb1952df0c92b167005de8d1b0 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 30 May 2008 10:03:25 +0200 Subject: [S390] tape: Fix race condition in tape block device driver Due to incorrect function call sequence it can happen that a tape block request is finished before the request is taken from the block request queue. The following sequence leads to that condition: * tapeblock_start_request() -> start CCW program * Request finishes -> IO interrupt * tapeblock_end_request() * end_that_request_last() If blkdev_dequeue_request() has not been called before end_that_request_last(), a kernel bug is triggered in end_that_request_last() because the request is still queued. To solve that problem blkdev_dequeue_request() has to be called before starting the CCW program. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape_block.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index ddc4a114e7f..95da72bc17e 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -179,11 +179,11 @@ tapeblock_requeue(struct work_struct *work) { tapeblock_end_request(req, -EIO); continue; } + blkdev_dequeue_request(req); + nr_queued++; spin_unlock_irq(&device->blk_data.request_queue_lock); rc = tapeblock_start_request(device, req); spin_lock_irq(&device->blk_data.request_queue_lock); - blkdev_dequeue_request(req); - nr_queued++; } spin_unlock_irq(&device->blk_data.request_queue_lock); atomic_set(&device->blk_data.requeue_scheduled, 0); -- cgit v1.2.3 From 67060d9c1f5d91c917cc51bed464cb5638eaddbc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 30 May 2008 10:03:27 +0200 Subject: [S390] Fix section mismatch warnings. This fixes the last remaining section mismatch warnings in s390 architecture code. It reveals also a real bug introduced by... me with git commit 2069e978d5a6e7b45d58027e3de7f879b8c5e488 ("[S390] sparsemem vmemmap: initialize memmap.") Calling the generic vmemmap_alloc_block() function to get initialized memory is a nice idea, however that function is __meminit annotated and therefore the function might be gone if we try to call it later. This can happen if a DCSS segment gets added. So basically revert the patch and clear the memmap explicitly to fix the original bug. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9e784d5f7f5..ad05a87bc48 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -40,7 +40,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work) put_online_cpus(); } -static void sclp_cpu_change_notify(struct work_struct *work) +static void __ref sclp_cpu_change_notify(struct work_struct *work) { smp_rescan_cpus(); } -- cgit v1.2.3 From d4820e44b0ae6830b1d634e6d0a425d839388c06 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 30 May 2008 10:03:30 +0200 Subject: [S390] sclp_vt220: fix scheduling while atomic bug. The driver incorrectly assumed that putchar will only be called from schedulable process context and therefore blocked and waited if no free output buffers where available. Since putchar may also be called from BH context this may lead to deadlocks. To fix this just return the number of characters accepted and let the upper layer handle the rest. The console write function will busy wait (sclp_sync_wait) until a buffer is available again. Cc: Peter Oberparleiter Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_vt220.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 35707c04e61..62576af36f4 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -71,9 +71,6 @@ static struct list_head sclp_vt220_outqueue; /* Number of requests in outqueue */ static int sclp_vt220_outqueue_count; -/* Wait queue used to delay write requests while we've run out of buffers */ -static wait_queue_head_t sclp_vt220_waitq; - /* Timer used for delaying write requests to merge subsequent messages into * a single buffer */ static struct timer_list sclp_vt220_timer; @@ -133,7 +130,6 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request) } while (request && __sclp_vt220_emit(request)); if (request == NULL && sclp_vt220_flush_later) sclp_vt220_emit_current(); - wake_up(&sclp_vt220_waitq); /* Check if the tty needs a wake up call */ if (sclp_vt220_tty != NULL) { tty_wakeup(sclp_vt220_tty); @@ -383,7 +379,7 @@ sclp_vt220_timeout(unsigned long data) */ static int __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, - int convertlf, int may_schedule) + int convertlf, int may_fail) { unsigned long flags; void *page; @@ -395,15 +391,14 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, overall_written = 0; spin_lock_irqsave(&sclp_vt220_lock, flags); do { - /* Create a sclp output buffer if none exists yet */ + /* Create an sclp output buffer if none exists yet */ if (sclp_vt220_current_request == NULL) { while (list_empty(&sclp_vt220_empty)) { spin_unlock_irqrestore(&sclp_vt220_lock, flags); - if (in_interrupt() || !may_schedule) - sclp_sync_wait(); + if (may_fail) + goto out; else - wait_event(sclp_vt220_waitq, - !list_empty(&sclp_vt220_empty)); + sclp_sync_wait(); spin_lock_irqsave(&sclp_vt220_lock, flags); } page = (void *) sclp_vt220_empty.next; @@ -437,6 +432,7 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, add_timer(&sclp_vt220_timer); } spin_unlock_irqrestore(&sclp_vt220_lock, flags); +out: return overall_written; } @@ -520,19 +516,11 @@ sclp_vt220_close(struct tty_struct *tty, struct file *filp) * character to the tty device. If the kernel uses this routine, * it must call the flush_chars() routine (if defined) when it is * done stuffing characters into the driver. - * - * NOTE: include/linux/tty_driver.h specifies that a character should be - * ignored if there is no room in the queue. This driver implements a different - * semantic in that it will block when there is no more room left. - * - * FIXME: putchar can currently be called from BH and other non blocking - * handlers so this semantic isn't a good idea. */ static int sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) { - __sclp_vt220_write(&ch, 1, 0, 0, 1); - return 1; + return __sclp_vt220_write(&ch, 1, 0, 0, 1); } /* @@ -653,7 +641,6 @@ static int __init __sclp_vt220_init(void) spin_lock_init(&sclp_vt220_lock); INIT_LIST_HEAD(&sclp_vt220_empty); INIT_LIST_HEAD(&sclp_vt220_outqueue); - init_waitqueue_head(&sclp_vt220_waitq); init_timer(&sclp_vt220_timer); sclp_vt220_current_request = NULL; sclp_vt220_buffered_chars = 0; -- cgit v1.2.3 From 54ad64129cc166b9eec7151f3f9fc83589e33555 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 30 May 2008 10:03:32 +0200 Subject: [S390] 3270: fix race with stack local wait_queue_head_t. A wait_event call with a stack local wait_queue_head_t structure that is used to do the wake up for the wait_event is inherently racy. After the wait_event finished the wake_up call might not have completed yet. Remove the stack local wait_queue_head_t from raw3270_start_init and use the global raw3270_wait_queue instead. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/raw3270.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 0d98f1ff2ed..848ef7e8523 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -549,7 +549,6 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, struct raw3270_request *rq) { unsigned long flags; - wait_queue_head_t wq; int rc; #ifdef CONFIG_TN3270_CONSOLE @@ -566,20 +565,20 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, return rq->rc; } #endif - init_waitqueue_head(&wq); rq->callback = raw3270_wake_init; - rq->callback_data = &wq; + rq->callback_data = &raw3270_wait_queue; spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); rc = __raw3270_start(rp, view, rq); spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags); if (rc) return rc; /* Now wait for the completion. */ - rc = wait_event_interruptible(wq, raw3270_request_final(rq)); + rc = wait_event_interruptible(raw3270_wait_queue, + raw3270_request_final(rq)); if (rc == -ERESTARTSYS) { /* Interrupted by a signal. */ raw3270_halt_io(view->dev, rq); /* No wait for the halt to complete. */ - wait_event(wq, raw3270_request_final(rq)); + wait_event(raw3270_wait_queue, raw3270_request_final(rq)); return -ERESTARTSYS; } return rq->rc; -- cgit v1.2.3 From 4657fb8a98a4e02981a574492bbe470c147b6657 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 30 May 2008 10:03:33 +0200 Subject: [S390] tape: fix race with stack local wait_queue_head_t. A wait_event call with a stack local wait_queue_head_t structure that is used to do the wake up for the wait_event is inherently racy. After the wait_event finished the wake_up call might not have completed yet. Replace the stack local wait_queue_head_t in tape_do_io and tape_do_io_interruptible with a per device wait queue. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape.h | 3 +++ drivers/s390/char/tape_core.c | 16 +++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index dddf8d62c15..d0d565a05df 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -231,6 +231,9 @@ struct tape_device { /* Request queue. */ struct list_head req_queue; + /* Request wait queue. */ + wait_queue_head_t wait_queue; + /* Each tape device has (currently) two minor numbers. */ int first_minor; diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 76e44eb7c47..c20e3c54834 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -449,6 +449,7 @@ tape_alloc_device(void) INIT_LIST_HEAD(&device->req_queue); INIT_LIST_HEAD(&device->node); init_waitqueue_head(&device->state_change_wq); + init_waitqueue_head(&device->wait_queue); device->tape_state = TS_INIT; device->medium_state = MS_UNKNOWN; *device->modeset_byte = 0; @@ -954,21 +955,19 @@ __tape_wake_up(struct tape_request *request, void *data) int tape_do_io(struct tape_device *device, struct tape_request *request) { - wait_queue_head_t wq; int rc; - init_waitqueue_head(&wq); spin_lock_irq(get_ccwdev_lock(device->cdev)); /* Setup callback */ request->callback = __tape_wake_up; - request->callback_data = &wq; + request->callback_data = &device->wait_queue; /* Add request to request queue and try to start it. */ rc = __tape_start_request(device, request); spin_unlock_irq(get_ccwdev_lock(device->cdev)); if (rc) return rc; /* Request added to the queue. Wait for its completion. */ - wait_event(wq, (request->callback == NULL)); + wait_event(device->wait_queue, (request->callback == NULL)); /* Get rc from request */ return request->rc; } @@ -989,20 +988,19 @@ int tape_do_io_interruptible(struct tape_device *device, struct tape_request *request) { - wait_queue_head_t wq; int rc; - init_waitqueue_head(&wq); spin_lock_irq(get_ccwdev_lock(device->cdev)); /* Setup callback */ request->callback = __tape_wake_up_interruptible; - request->callback_data = &wq; + request->callback_data = &device->wait_queue; rc = __tape_start_request(device, request); spin_unlock_irq(get_ccwdev_lock(device->cdev)); if (rc) return rc; /* Request added to the queue. Wait for its completion. */ - rc = wait_event_interruptible(wq, (request->callback == NULL)); + rc = wait_event_interruptible(device->wait_queue, + (request->callback == NULL)); if (rc != -ERESTARTSYS) /* Request finished normally. */ return request->rc; @@ -1015,7 +1013,7 @@ tape_do_io_interruptible(struct tape_device *device, /* Wait for the interrupt that acknowledges the halt. */ do { rc = wait_event_interruptible( - wq, + device->wait_queue, (request->callback == NULL) ); } while (rc == -ERESTARTSYS); -- cgit v1.2.3 From 7b439d25300dc59bba76b53eb344bb9e5a1133f2 Mon Sep 17 00:00:00 2001 From: Carsten Otte Date: Tue, 10 Jun 2008 10:03:22 +0200 Subject: [S390] vt220 console, initialize list head before use This patch fixes a null pointer dereference during initialisation when no sclp event facility is available: sclp vt220 tty driver: could not register vt220 - sclp_register returned -5 Unable to handle kernel paging request at virtual user address 0000000000000000 Oops: 0004 [#1] PREEMPT SMP Modules linked in: CPU: 0 Not tainted 2.6.26-rc3-kvm-bigiron-00968-gd939e93-dirty #30 Process swapper (pid: 0, task: 0000000000600be0, ksp: 000000000064a000) Krnl PSW : 0400000180000000 0000000000320d8c (sclp_unregister+0x48/0x8c) R:0 T:1 IO:0 EX:0 Key:0 M:0 W:0 P:0 AS:0 CC:0 PM:0 EA:3 Krnl GPRS: 0000000000000000 0000000000000000 0000000000630478 0700000000649c20 0000000000000000 0000000000433060 000000000064a660 0000000002e26000 00000000006db000 0000000000000000 0000000000a78578 0000000000649b80 0000000000630dc0 000000000044fa20 0000000000320d76 0000000000649b80 Krnl Code: 0000000000320d7c: e310c0080004 lg %r1,8(%r12) 0000000000320d82: b9040032 lgr %r3,%r2 0000000000320d86: c02000187b79 larl %r2,630478 >0000000000320d8c: e34010000024 stg %r4,0(%r1) 0000000000320d92: e31040080024 stg %r1,8(%r4) 0000000000320d98: c01100200200 lgfi %r1,2097664 0000000000320d9e: e310c0080024 stg %r1,8(%r12) 0000000000320da4: c01100100100 lgfi %r1,1048832 Call Trace: ([<0000000000320d76>] sclp_unregister+0x32/0x8c) [<00000000006657b4>] __sclp_vt220_cleanup+0xc4/0xe0 [<000000000066595c>] __sclp_vt220_init+0x18c/0x1a0 [<0000000000665aba>] sclp_vt220_con_init+0x42/0x68 [<00000000006601ca>] console_init+0x4e/0x68 [<000000000064acae>] start_kernel+0x3a2/0x4dc [<0000000000100020>] _stext+0x20/0x80 INFO: lockdep is turned off. Last Breaking-Event-Address: [<000000000041f964>] _spin_lock_irqsave+0xb0/0xb4 <4>---[ end trace 31fd0ba7d8756001 ]--- The issue is caused by a list_empty() check in __sclp_vt220_cleanup, which usually fails on non-initialized list heads that contain {NULL,NULL} instead. Signed-off-by: Carsten Otte Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_vt220.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 62576af36f4..3e577f655b1 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -773,6 +773,7 @@ sclp_vt220_con_init(void) { int rc; + INIT_LIST_HEAD(&sclp_vt220_register.list); if (!CONSOLE_IS_SCLP) return 0; rc = __sclp_vt220_init(); -- cgit v1.2.3 From 1783e60ff207805a3e75cf522b17ec9bb1604a62 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 10 Jun 2008 10:03:25 +0200 Subject: [S390] tape_3590.c: introduce missing kfree The semantic match that finds the problem is as follows: (http://www.emn.fr/x-info/coccinelle/) @r exists@ expression E,E1; statement S; position p1,p2,p3; @@ E =@p1 \(kmalloc\|kcalloc\|kzalloc\)(...) ... when != E = E1 if (E == NULL || ...) S ... when != E = E1 if@p2 (...) { ... when != kfree(E) } ... when != E = E1 kfree@p3(E); @forall@ position r.p2; expression r.E; int E1 != 0; @@ * if@p2 (...) { ... when != kfree(E) when strict return E1; } Signed-off-by: Julia Lawall Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape_3590.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 8246ef3ab09..42ce7915fc5 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -1598,7 +1598,7 @@ tape_3590_setup_device(struct tape_device *device) rc = tape_3590_read_dev_chars(device, rdc_data); if (rc) { DBF_LH(3, "Read device characteristics failed!\n"); - goto fail_kmalloc; + goto fail_rdc_data; } rc = tape_std_assign(device); if (rc) -- cgit v1.2.3