summaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/atm')
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/atm/speedtch.c28
-rw-r--r--drivers/usb/atm/ueagle-atm.c22
3 files changed, 35 insertions, 17 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index f383cb42b1d..a845f8b8382 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -1247,7 +1247,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
mutex_unlock(&instance->poll_state_serialize);
if (is_polling)
- cancel_rearming_delayed_work(&instance->poll_work);
+ cancel_delayed_work_sync(&instance->poll_work);
usb_kill_urb(instance->snd_urb);
usb_kill_urb(instance->rcv_urb);
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 4716e707de5..0842cfbf60c 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -139,7 +139,8 @@ struct speedtch_instance_data {
struct speedtch_params params; /* set in probe, constant afterwards */
- struct delayed_work status_checker;
+ struct timer_list status_check_timer;
+ struct work_struct status_check_work;
unsigned char last_status;
@@ -498,7 +499,7 @@ static void speedtch_check_status(struct work_struct *work)
{
struct speedtch_instance_data *instance =
container_of(work, struct speedtch_instance_data,
- status_checker.work);
+ status_check_work);
struct usbatm_data *usbatm = instance->usbatm;
struct atm_dev *atm_dev = usbatm->atm_dev;
unsigned char *buf = instance->scratch_buffer;
@@ -575,11 +576,11 @@ static void speedtch_status_poll(unsigned long data)
{
struct speedtch_instance_data *instance = (void *)data;
- schedule_delayed_work(&instance->status_checker, 0);
+ schedule_work(&instance->status_check_work);
/* The following check is racy, but the race is harmless */
if (instance->poll_delay < MAX_POLL_DELAY)
- mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay));
+ mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(instance->poll_delay));
else
atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n");
}
@@ -595,7 +596,7 @@ static void speedtch_resubmit_int(unsigned long data)
if (int_urb) {
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
if (!ret)
- schedule_delayed_work(&instance->status_checker, 0);
+ schedule_work(&instance->status_check_work);
else {
atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
@@ -624,7 +625,7 @@ static void speedtch_handle_int(struct urb *int_urb)
}
if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) {
- del_timer(&instance->status_checker.timer);
+ del_timer(&instance->status_check_timer);
atm_info(usbatm, "DSL line goes up\n");
} else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) {
atm_info(usbatm, "DSL line goes down\n");
@@ -640,7 +641,7 @@ static void speedtch_handle_int(struct urb *int_urb)
if ((int_urb = instance->int_urb)) {
ret = usb_submit_urb(int_urb, GFP_ATOMIC);
- schedule_delayed_work(&instance->status_checker, 0);
+ schedule_work(&instance->status_check_work);
if (ret < 0) {
atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
goto fail;
@@ -686,7 +687,7 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de
}
/* Start status polling */
- mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000));
+ mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(1000));
return 0;
}
@@ -698,7 +699,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
atm_dbg(usbatm, "%s entered\n", __func__);
- del_timer_sync(&instance->status_checker.timer);
+ del_timer_sync(&instance->status_check_timer);
/*
* Since resubmit_timer and int_urb can schedule themselves and
@@ -717,7 +718,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
del_timer_sync(&instance->resubmit_timer);
usb_free_urb(int_urb);
- flush_scheduled_work();
+ flush_work_sync(&instance->status_check_work);
}
static int speedtch_pre_reset(struct usb_interface *intf)
@@ -869,10 +870,11 @@ static int speedtch_bind(struct usbatm_data *usbatm,
usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
- INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status);
+ INIT_WORK(&instance->status_check_work, speedtch_check_status);
+ init_timer(&instance->status_check_timer);
- instance->status_checker.timer.function = speedtch_status_poll;
- instance->status_checker.timer.data = (unsigned long)instance;
+ instance->status_check_timer.function = speedtch_status_poll;
+ instance->status_check_timer.data = (unsigned long)instance;
instance->last_status = 0xff;
instance->poll_delay = MIN_POLL_DELAY;
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 44447f54942..99ac70e3255 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc)
goto err1;
}
- sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
- if (sc->kthread == ERR_PTR(-ENOMEM)) {
+ /* Create worker thread, but don't start it here. Start it after
+ * all usbatm generic initialization is done.
+ */
+ sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
+ if (IS_ERR(sc->kthread)) {
uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
goto err2;
}
@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = {
static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usb = interface_to_usbdev(intf);
+ int ret;
uea_enters(usb);
uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (UEA_IS_PREFIRM(id))
return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
- return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+ if (ret == 0) {
+ struct usbatm_data *usbatm = usb_get_intfdata(intf);
+ struct uea_softc *sc = usbatm->driver_data;
+
+ /* Ensure carrier is initialized to off as early as possible */
+ UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
+
+ /* Only start the worker thread when all init is done */
+ wake_up_process(sc->kthread);
+ }
+
+ return ret;
}
static void uea_disconnect(struct usb_interface *intf)