|
@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
|
|
|
struct tty_struct *tty = acm->tty;
|
|
|
struct acm_ru *rcv;
|
|
|
unsigned long flags;
|
|
|
- int i = 0;
|
|
|
+ unsigned char throttled;
|
|
|
dbg("Entering acm_rx_tasklet");
|
|
|
|
|
|
- if (!ACM_READY(acm) || acm->throttle)
|
|
|
+ if (!ACM_READY(acm))
|
|
|
+ return;
|
|
|
+
|
|
|
+ spin_lock(&acm->throttle_lock);
|
|
|
+ throttled = acm->throttle;
|
|
|
+ spin_unlock(&acm->throttle_lock);
|
|
|
+ if (throttled)
|
|
|
return;
|
|
|
|
|
|
next_buffer:
|
|
@@ -346,22 +352,20 @@ next_buffer:
|
|
|
dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
|
|
|
|
|
|
tty_buffer_request_room(tty, buf->size);
|
|
|
- if (!acm->throttle)
|
|
|
+ spin_lock(&acm->throttle_lock);
|
|
|
+ throttled = acm->throttle;
|
|
|
+ spin_unlock(&acm->throttle_lock);
|
|
|
+ if (!throttled)
|
|
|
tty_insert_flip_string(tty, buf->base, buf->size);
|
|
|
tty_flip_buffer_push(tty);
|
|
|
|
|
|
- spin_lock(&acm->throttle_lock);
|
|
|
- if (acm->throttle) {
|
|
|
- dbg("Throtteling noticed");
|
|
|
- memmove(buf->base, buf->base + i, buf->size - i);
|
|
|
- buf->size -= i;
|
|
|
- spin_unlock(&acm->throttle_lock);
|
|
|
+ if (throttled) {
|
|
|
+ dbg("Throttling noticed");
|
|
|
spin_lock_irqsave(&acm->read_lock, flags);
|
|
|
list_add(&buf->list, &acm->filled_read_bufs);
|
|
|
spin_unlock_irqrestore(&acm->read_lock, flags);
|
|
|
return;
|
|
|
}
|
|
|
- spin_unlock(&acm->throttle_lock);
|
|
|
|
|
|
spin_lock_irqsave(&acm->read_lock, flags);
|
|
|
list_add(&buf->list, &acm->spare_read_bufs);
|
|
@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|
|
goto bail_out;
|
|
|
}
|
|
|
|
|
|
- if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
|
|
|
+ if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
|
|
|
+ (acm->ctrl_caps & USB_CDC_CAP_LINE))
|
|
|
goto full_bailout;
|
|
|
|
|
|
INIT_LIST_HEAD(&acm->spare_read_urbs);
|
|
@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
|
|
|
list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
|
|
|
}
|
|
|
|
|
|
+ acm->throttle = 0;
|
|
|
+
|
|
|
tasklet_schedule(&acm->urb_task);
|
|
|
|
|
|
done:
|