aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/atm/speedtch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/atm/speedtch.c')
-rw-r--r--drivers/usb/atm/speedtch.c97
1 files changed, 79 insertions, 18 deletions
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 7c7b507af29d..a823486495c3 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;
79static int enable_isoc = DEFAULT_ENABLE_ISOC; 78static int enable_isoc = DEFAULT_ENABLE_ISOC;
80static int sw_buffering = DEFAULT_SW_BUFFERING; 79static 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
84static 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
88static unsigned int BMaxDSL = DEFAULT_B_MAX_DSL;
89static unsigned char ModemMode = DEFAULT_MODEM_MODE;
90static unsigned char ModemOption[MODEM_OPTION_LENGTH];
91static int num_ModemOption;
92
82module_param(altsetting, uint, S_IRUGO | S_IWUSR); 93module_param(altsetting, uint, S_IRUGO | S_IWUSR);
83MODULE_PARM_DESC(altsetting, 94MODULE_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
114module_param(BMaxDSL, uint, S_IRUGO | S_IWUSR);
115MODULE_PARM_DESC(BMaxDSL,
116 "default: " __MODULE_STRING(DEFAULT_B_MAX_DSL));
117
118module_param(ModemMode, byte, S_IRUGO | S_IWUSR);
119MODULE_PARM_DESC(ModemMode,
120 "default: " __MODULE_STRING(DEFAULT_MODEM_MODE));
121
122module_param_array(ModemOption, byte, &num_ModemOption, S_IRUGO);
123MODULE_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
133struct speedtch_params {
134 unsigned int altsetting;
135 unsigned int BMaxDSL;
136 unsigned char ModemMode;
137 unsigned char ModemOption[MODEM_OPTION_LENGTH];
138};
139
111struct speedtch_instance_data { 140struct 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
191static int speedtch_upload_firmware(struct speedtch_instance_data *instance, 248static 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 */
@@ -773,8 +834,8 @@ static int speedtch_bind(struct usbatm_data *usbatm,
773 const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc; 834 const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
774 835
775 if ((endpoint_desc->bEndpointAddress == target_address)) { 836 if ((endpoint_desc->bEndpointAddress == target_address)) {
776 use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 837 use_isoc =
777 USB_ENDPOINT_XFER_ISOC; 838 usb_endpoint_xfer_isoc(endpoint_desc);
778 break; 839 break;
779 } 840 }
780 } 841 }
@@ -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