diff options
Diffstat (limited to 'drivers/isdn/gigaset/interface.c')
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index c9f28dd40d5c..f45d68620161 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -339,7 +339,8 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file, | |||
339 | static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | 339 | static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) |
340 | { | 340 | { |
341 | struct cardstate *cs; | 341 | struct cardstate *cs; |
342 | int retval = -ENODEV; | 342 | struct cmdbuf_t *cb; |
343 | int retval; | ||
343 | 344 | ||
344 | cs = (struct cardstate *) tty->driver_data; | 345 | cs = (struct cardstate *) tty->driver_data; |
345 | if (!cs) { | 346 | if (!cs) { |
@@ -355,18 +356,39 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
355 | if (!cs->connected) { | 356 | if (!cs->connected) { |
356 | gig_dbg(DEBUG_IF, "not connected"); | 357 | gig_dbg(DEBUG_IF, "not connected"); |
357 | retval = -ENODEV; | 358 | retval = -ENODEV; |
358 | } else if (!cs->open_count) | 359 | goto done; |
360 | } | ||
361 | if (!cs->open_count) { | ||
359 | dev_warn(cs->dev, "%s: device not opened\n", __func__); | 362 | dev_warn(cs->dev, "%s: device not opened\n", __func__); |
360 | else if (cs->mstate != MS_LOCKED) { | 363 | retval = -ENODEV; |
364 | goto done; | ||
365 | } | ||
366 | if (cs->mstate != MS_LOCKED) { | ||
361 | dev_warn(cs->dev, "can't write to unlocked device\n"); | 367 | dev_warn(cs->dev, "can't write to unlocked device\n"); |
362 | retval = -EBUSY; | 368 | retval = -EBUSY; |
363 | } else { | 369 | goto done; |
364 | retval = cs->ops->write_cmd(cs, buf, count, | 370 | } |
365 | &cs->if_wake_tasklet); | 371 | if (count <= 0) { |
372 | /* nothing to do */ | ||
373 | retval = 0; | ||
374 | goto done; | ||
366 | } | 375 | } |
367 | 376 | ||
368 | mutex_unlock(&cs->mutex); | 377 | cb = kmalloc(sizeof(struct cmdbuf_t) + count, GFP_KERNEL); |
378 | if (!cb) { | ||
379 | dev_err(cs->dev, "%s: out of memory\n", __func__); | ||
380 | retval = -ENOMEM; | ||
381 | goto done; | ||
382 | } | ||
369 | 383 | ||
384 | memcpy(cb->buf, buf, count); | ||
385 | cb->len = count; | ||
386 | cb->offset = 0; | ||
387 | cb->next = NULL; | ||
388 | cb->wake_tasklet = &cs->if_wake_tasklet; | ||
389 | retval = cs->ops->write_cmd(cs, cb); | ||
390 | done: | ||
391 | mutex_unlock(&cs->mutex); | ||
370 | return retval; | 392 | return retval; |
371 | } | 393 | } |
372 | 394 | ||