diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/atm/speedtch.c | 93 |
1 files changed, 77 insertions, 16 deletions
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 7c7b507af29d..c870c804470f 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -55,7 +55,6 @@ static const char speedtch_driver_name[] = "speedtch"; | |||
55 | #define OFFSET_d 9 /* size 4 */ | 55 | #define OFFSET_d 9 /* size 4 */ |
56 | #define OFFSET_e 13 /* size 1 */ | 56 | #define OFFSET_e 13 /* size 1 */ |
57 | #define OFFSET_f 14 /* size 1 */ | 57 | #define OFFSET_f 14 /* size 1 */ |
58 | #define TOTAL 15 | ||
59 | 58 | ||
60 | #define SIZE_7 1 | 59 | #define SIZE_7 1 |
61 | #define SIZE_b 8 | 60 | #define SIZE_b 8 |
@@ -79,6 +78,18 @@ static int dl_512_first = DEFAULT_DL_512_FIRST; | |||
79 | static int enable_isoc = DEFAULT_ENABLE_ISOC; | 78 | static int enable_isoc = DEFAULT_ENABLE_ISOC; |
80 | static int sw_buffering = DEFAULT_SW_BUFFERING; | 79 | static int sw_buffering = DEFAULT_SW_BUFFERING; |
81 | 80 | ||
81 | #define DEFAULT_B_MAX_DSL 8128 | ||
82 | #define DEFAULT_MODEM_MODE 11 | ||
83 | #define MODEM_OPTION_LENGTH 16 | ||
84 | static const unsigned char DEFAULT_MODEM_OPTION[MODEM_OPTION_LENGTH] = { | ||
85 | 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
86 | }; | ||
87 | |||
88 | static unsigned int BMaxDSL = DEFAULT_B_MAX_DSL; | ||
89 | static unsigned char ModemMode = DEFAULT_MODEM_MODE; | ||
90 | static unsigned char ModemOption[MODEM_OPTION_LENGTH]; | ||
91 | static int num_ModemOption; | ||
92 | |||
82 | module_param(altsetting, uint, S_IRUGO | S_IWUSR); | 93 | module_param(altsetting, uint, S_IRUGO | S_IWUSR); |
83 | MODULE_PARM_DESC(altsetting, | 94 | MODULE_PARM_DESC(altsetting, |
84 | "Alternative setting for data interface (bulk_default: " | 95 | "Alternative setting for data interface (bulk_default: " |
@@ -100,6 +111,17 @@ MODULE_PARM_DESC(sw_buffering, | |||
100 | "Enable software buffering (default: " | 111 | "Enable software buffering (default: " |
101 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); | 112 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); |
102 | 113 | ||
114 | module_param(BMaxDSL, uint, S_IRUGO | S_IWUSR); | ||
115 | MODULE_PARM_DESC(BMaxDSL, | ||
116 | "default: " __MODULE_STRING(DEFAULT_B_MAX_DSL)); | ||
117 | |||
118 | module_param(ModemMode, byte, S_IRUGO | S_IWUSR); | ||
119 | MODULE_PARM_DESC(ModemMode, | ||
120 | "default: " __MODULE_STRING(DEFAULT_MODEM_MODE)); | ||
121 | |||
122 | module_param_array(ModemOption, byte, &num_ModemOption, S_IRUGO); | ||
123 | MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20"); | ||
124 | |||
103 | #define INTERFACE_DATA 1 | 125 | #define INTERFACE_DATA 1 |
104 | #define ENDPOINT_INT 0x81 | 126 | #define ENDPOINT_INT 0x81 |
105 | #define ENDPOINT_BULK_DATA 0x07 | 127 | #define ENDPOINT_BULK_DATA 0x07 |
@@ -108,10 +130,17 @@ MODULE_PARM_DESC(sw_buffering, | |||
108 | 130 | ||
109 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) | 131 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) |
110 | 132 | ||
133 | struct speedtch_params { | ||
134 | unsigned int altsetting; | ||
135 | unsigned int BMaxDSL; | ||
136 | unsigned char ModemMode; | ||
137 | unsigned char ModemOption[MODEM_OPTION_LENGTH]; | ||
138 | }; | ||
139 | |||
111 | struct speedtch_instance_data { | 140 | struct speedtch_instance_data { |
112 | struct usbatm_data *usbatm; | 141 | struct usbatm_data *usbatm; |
113 | 142 | ||
114 | unsigned int altsetting; | 143 | struct speedtch_params params; /* set in probe, constant afterwards */ |
115 | 144 | ||
116 | struct work_struct status_checker; | 145 | struct work_struct status_checker; |
117 | 146 | ||
@@ -123,7 +152,7 @@ struct speedtch_instance_data { | |||
123 | struct urb *int_urb; | 152 | struct urb *int_urb; |
124 | unsigned char int_data[16]; | 153 | unsigned char int_data[16]; |
125 | 154 | ||
126 | unsigned char scratch_buffer[TOTAL]; | 155 | unsigned char scratch_buffer[16]; |
127 | }; | 156 | }; |
128 | 157 | ||
129 | /*************** | 158 | /*************** |
@@ -186,6 +215,34 @@ static void speedtch_test_sequence(struct speedtch_instance_data *instance) | |||
186 | 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); | 215 | 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); |
187 | if (ret < 0) | 216 | if (ret < 0) |
188 | usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); | 217 | usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); |
218 | |||
219 | /* Extra initialisation in recent drivers - gives higher speeds */ | ||
220 | |||
221 | /* URBext1 */ | ||
222 | buf[0] = instance->params.ModemMode; | ||
223 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
224 | 0x01, 0x40, 0x11, 0x00, buf, 1, CTRL_TIMEOUT); | ||
225 | if (ret < 0) | ||
226 | usb_warn(usbatm, "%s failed on URBext1: %d\n", __func__, ret); | ||
227 | |||
228 | /* URBext2 */ | ||
229 | /* This seems to be the one which actually triggers the higher sync | ||
230 | rate -- it does require the new firmware too, although it works OK | ||
231 | with older firmware */ | ||
232 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
233 | 0x01, 0x40, 0x14, 0x00, | ||
234 | instance->params.ModemOption, | ||
235 | MODEM_OPTION_LENGTH, CTRL_TIMEOUT); | ||
236 | if (ret < 0) | ||
237 | usb_warn(usbatm, "%s failed on URBext2: %d\n", __func__, ret); | ||
238 | |||
239 | /* URBext3 */ | ||
240 | buf[0] = instance->params.BMaxDSL & 0xff; | ||
241 | buf[1] = instance->params.BMaxDSL >> 8; | ||
242 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
243 | 0x01, 0x40, 0x12, 0x00, buf, 2, CTRL_TIMEOUT); | ||
244 | if (ret < 0) | ||
245 | usb_warn(usbatm, "%s failed on URBext3: %d\n", __func__, ret); | ||
189 | } | 246 | } |
190 | 247 | ||
191 | static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | 248 | static int speedtch_upload_firmware(struct speedtch_instance_data *instance, |
@@ -285,8 +342,8 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
285 | because we're in our own kernel thread anyway. */ | 342 | because we're in our own kernel thread anyway. */ |
286 | msleep_interruptible(1000); | 343 | msleep_interruptible(1000); |
287 | 344 | ||
288 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | 345 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { |
289 | usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); | 346 | usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret); |
290 | goto out_free; | 347 | goto out_free; |
291 | } | 348 | } |
292 | 349 | ||
@@ -372,7 +429,7 @@ static int speedtch_read_status(struct speedtch_instance_data *instance) | |||
372 | unsigned char *buf = instance->scratch_buffer; | 429 | unsigned char *buf = instance->scratch_buffer; |
373 | int ret; | 430 | int ret; |
374 | 431 | ||
375 | memset(buf, 0, TOTAL); | 432 | memset(buf, 0, 16); |
376 | 433 | ||
377 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 434 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
378 | 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, | 435 | 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, |
@@ -746,17 +803,21 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
746 | 803 | ||
747 | instance->usbatm = usbatm; | 804 | instance->usbatm = usbatm; |
748 | 805 | ||
749 | /* altsetting and enable_isoc may change at any moment, so take a snapshot */ | 806 | /* module parameters may change at any moment, so take a snapshot */ |
750 | instance->altsetting = altsetting; | 807 | instance->params.altsetting = altsetting; |
808 | instance->params.BMaxDSL = BMaxDSL; | ||
809 | instance->params.ModemMode = ModemMode; | ||
810 | memcpy(instance->params.ModemOption, DEFAULT_MODEM_OPTION, MODEM_OPTION_LENGTH); | ||
811 | memcpy(instance->params.ModemOption, ModemOption, num_ModemOption); | ||
751 | use_isoc = enable_isoc; | 812 | use_isoc = enable_isoc; |
752 | 813 | ||
753 | if (instance->altsetting) | 814 | if (instance->params.altsetting) |
754 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | 815 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { |
755 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); | 816 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->params.altsetting, ret); |
756 | instance->altsetting = 0; /* fall back to default */ | 817 | instance->params.altsetting = 0; /* fall back to default */ |
757 | } | 818 | } |
758 | 819 | ||
759 | if (!instance->altsetting && use_isoc) | 820 | if (!instance->params.altsetting && use_isoc) |
760 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { | 821 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { |
761 | usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); | 822 | usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); |
762 | use_isoc = 0; /* fall back to bulk */ | 823 | use_isoc = 0; /* fall back to bulk */ |
@@ -783,14 +844,14 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
783 | usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); | 844 | usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); |
784 | } | 845 | } |
785 | 846 | ||
786 | if (!use_isoc && !instance->altsetting) | 847 | if (!use_isoc && !instance->params.altsetting) |
787 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { | 848 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { |
788 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); | 849 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); |
789 | goto fail_free; | 850 | goto fail_free; |
790 | } | 851 | } |
791 | 852 | ||
792 | if (!instance->altsetting) | 853 | if (!instance->params.altsetting) |
793 | instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; | 854 | instance->params.altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; |
794 | 855 | ||
795 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); | 856 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); |
796 | 857 | ||