diff options
author | Simon Arlott <simon@fire.lp0.eu> | 2007-05-11 02:04:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-06-08 19:24:31 -0400 |
commit | da1f82b5543738d4c127a449490bc0d55e121fe8 (patch) | |
tree | 88562272ac2a5a28f682eee1f44272890f42db52 /drivers/usb/atm/cxacru.c | |
parent | 64b85006f5d473fefc181dece9473710b55966e0 (diff) |
USB: cxacru: create sysfs attributes in atm_start instead of bind
Since usbatm doesn't set the usb_interface driver data until after calling
bind and heavy_init, it would be NULL when the sysfs attributes are read.
Reading the MAC address from atm_dev before atm_dev exists would have been
be possible too.
Calling create_device_file in atm_start will avoid this problem, and the
data is useless until the first status poll runs. However, it must be
ready before a status poll does a printk on line status change otherwise
userspace could react before the files exist.
For completeness I've moved remove_device_file to atm_stop so it's not
called in unbind when it's not needed. There's no point starting ADSL if
atm_start could still fail either.
Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Cc: Duncan Sands <duncan.sands@math.u-psud.fr>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/atm/cxacru.c')
-rw-r--r-- | drivers/usb/atm/cxacru.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 30b7bfbc985a..68cf582fd4fa 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -629,10 +629,22 @@ static int cxacru_card_status(struct cxacru_data *instance) | |||
629 | return 0; | 629 | return 0; |
630 | } | 630 | } |
631 | 631 | ||
632 | static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance, | ||
633 | struct atm_dev *atm_dev) | ||
634 | { | ||
635 | struct usb_interface *intf = usbatm_instance->usb_intf; | ||
636 | |||
637 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
638 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
639 | CXACRU_ALL_FILES(REMOVE); | ||
640 | #undef CXACRU_DEVICE_REMOVE_FILE | ||
641 | } | ||
642 | |||
632 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | 643 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, |
633 | struct atm_dev *atm_dev) | 644 | struct atm_dev *atm_dev) |
634 | { | 645 | { |
635 | struct cxacru_data *instance = usbatm_instance->driver_data; | 646 | struct cxacru_data *instance = usbatm_instance->driver_data; |
647 | struct usb_interface *intf = usbatm_instance->usb_intf; | ||
636 | /* | 648 | /* |
637 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | 649 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; |
638 | */ | 650 | */ |
@@ -649,6 +661,13 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
649 | return ret; | 661 | return ret; |
650 | } | 662 | } |
651 | 663 | ||
664 | #define CXACRU_DEVICE_CREATE_FILE(_name) \ | ||
665 | ret = device_create_file(&intf->dev, &dev_attr_##_name); \ | ||
666 | if (unlikely(ret)) \ | ||
667 | goto fail_sysfs; | ||
668 | CXACRU_ALL_FILES(CREATE); | ||
669 | #undef CXACRU_DEVICE_CREATE_FILE | ||
670 | |||
652 | /* start ADSL */ | 671 | /* start ADSL */ |
653 | mutex_lock(&instance->adsl_state_serialize); | 672 | mutex_lock(&instance->adsl_state_serialize); |
654 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); | 673 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); |
@@ -680,6 +699,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
680 | if (start_polling) | 699 | if (start_polling) |
681 | cxacru_poll_status(&instance->poll_work.work); | 700 | cxacru_poll_status(&instance->poll_work.work); |
682 | return 0; | 701 | return 0; |
702 | |||
703 | fail_sysfs: | ||
704 | usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret); | ||
705 | cxacru_remove_device_files(usbatm_instance, atm_dev); | ||
706 | return ret; | ||
683 | } | 707 | } |
684 | 708 | ||
685 | static void cxacru_poll_status(struct work_struct *work) | 709 | static void cxacru_poll_status(struct work_struct *work) |
@@ -1065,13 +1089,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1065 | goto fail; | 1089 | goto fail; |
1066 | } | 1090 | } |
1067 | 1091 | ||
1068 | #define CXACRU_DEVICE_CREATE_FILE(_name) \ | ||
1069 | ret = device_create_file(&intf->dev, &dev_attr_##_name); \ | ||
1070 | if (unlikely(ret)) \ | ||
1071 | goto fail_sysfs; | ||
1072 | CXACRU_ALL_FILES(CREATE); | ||
1073 | #undef CXACRU_DEVICE_CREATE_FILE | ||
1074 | |||
1075 | usb_fill_int_urb(instance->rcv_urb, | 1092 | usb_fill_int_urb(instance->rcv_urb, |
1076 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), | 1093 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), |
1077 | instance->rcv_buf, PAGE_SIZE, | 1094 | instance->rcv_buf, PAGE_SIZE, |
@@ -1092,14 +1109,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1092 | 1109 | ||
1093 | return 0; | 1110 | return 0; |
1094 | 1111 | ||
1095 | fail_sysfs: | ||
1096 | dbg("cxacru_bind: device_create_file failed (%d)\n", ret); | ||
1097 | |||
1098 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
1099 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
1100 | CXACRU_ALL_FILES(REMOVE); | ||
1101 | #undef CXACRU_DEVICE_REVOVE_FILE | ||
1102 | |||
1103 | fail: | 1112 | fail: |
1104 | free_page((unsigned long) instance->snd_buf); | 1113 | free_page((unsigned long) instance->snd_buf); |
1105 | free_page((unsigned long) instance->rcv_buf); | 1114 | free_page((unsigned long) instance->rcv_buf); |
@@ -1146,11 +1155,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, | |||
1146 | free_page((unsigned long) instance->snd_buf); | 1155 | free_page((unsigned long) instance->snd_buf); |
1147 | free_page((unsigned long) instance->rcv_buf); | 1156 | free_page((unsigned long) instance->rcv_buf); |
1148 | 1157 | ||
1149 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
1150 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
1151 | CXACRU_ALL_FILES(REMOVE); | ||
1152 | #undef CXACRU_DEVICE_REVOVE_FILE | ||
1153 | |||
1154 | kfree(instance); | 1158 | kfree(instance); |
1155 | 1159 | ||
1156 | usbatm_instance->driver_data = NULL; | 1160 | usbatm_instance->driver_data = NULL; |
@@ -1231,6 +1235,7 @@ static struct usbatm_driver cxacru_driver = { | |||
1231 | .heavy_init = cxacru_heavy_init, | 1235 | .heavy_init = cxacru_heavy_init, |
1232 | .unbind = cxacru_unbind, | 1236 | .unbind = cxacru_unbind, |
1233 | .atm_start = cxacru_atm_start, | 1237 | .atm_start = cxacru_atm_start, |
1238 | .atm_stop = cxacru_remove_device_files, | ||
1234 | .bulk_in = CXACRU_EP_DATA, | 1239 | .bulk_in = CXACRU_EP_DATA, |
1235 | .bulk_out = CXACRU_EP_DATA, | 1240 | .bulk_out = CXACRU_EP_DATA, |
1236 | .rx_padding = 3, | 1241 | .rx_padding = 3, |