diff options
Diffstat (limited to 'drivers/usb/atm/ueagle-atm.c')
-rw-r--r-- | drivers/usb/atm/ueagle-atm.c | 1395 |
1 files changed, 1121 insertions, 274 deletions
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 8f046659b4e..389c5b164eb 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * Copyright (c) 2003, 2004 | 2 | * Copyright (c) 2003, 2004 |
3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | 3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. |
4 | * | 4 | * |
5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | 5 | * Copyright (c) 2005-2007 Matthieu Castet <castet.matthieu@free.fr> |
6 | * Copyright (c) 2005-2007 Stanislaw Gruszka <stf_xl@wp.pl> | ||
6 | * | 7 | * |
7 | * This software is available to you under a choice of one of two | 8 | * This software is available to you under a choice of one of two |
8 | * licenses. You may choose to be licensed under the terms of the GNU | 9 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -107,18 +108,51 @@ | |||
107 | #define uea_info(usb_dev, format,args...) \ | 108 | #define uea_info(usb_dev, format,args...) \ |
108 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | 109 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) |
109 | 110 | ||
110 | struct uea_cmvs { | 111 | struct intr_pkt; |
112 | |||
113 | /* cmv's from firmware */ | ||
114 | struct uea_cmvs_v1 { | ||
111 | u32 address; | 115 | u32 address; |
112 | u16 offset; | 116 | u16 offset; |
113 | u32 data; | 117 | u32 data; |
114 | } __attribute__ ((packed)); | 118 | } __attribute__ ((packed)); |
115 | 119 | ||
120 | struct uea_cmvs_v2 { | ||
121 | u32 group; | ||
122 | u32 address; | ||
123 | u32 offset; | ||
124 | u32 data; | ||
125 | } __attribute__ ((packed)); | ||
126 | |||
127 | /* information about currently processed cmv */ | ||
128 | struct cmv_dsc_e1 { | ||
129 | u8 function; | ||
130 | u16 idx; | ||
131 | u32 address; | ||
132 | u16 offset; | ||
133 | }; | ||
134 | |||
135 | struct cmv_dsc_e4 { | ||
136 | u16 function; | ||
137 | u16 offset; | ||
138 | u16 address; | ||
139 | u16 group; | ||
140 | }; | ||
141 | |||
142 | union cmv_dsc { | ||
143 | struct cmv_dsc_e1 e1; | ||
144 | struct cmv_dsc_e4 e4; | ||
145 | }; | ||
146 | |||
116 | struct uea_softc { | 147 | struct uea_softc { |
117 | struct usb_device *usb_dev; | 148 | struct usb_device *usb_dev; |
118 | struct usbatm_data *usbatm; | 149 | struct usbatm_data *usbatm; |
119 | 150 | ||
120 | int modem_index; | 151 | int modem_index; |
121 | unsigned int driver_info; | 152 | unsigned int driver_info; |
153 | int annex; | ||
154 | #define ANNEXA 0 | ||
155 | #define ANNEXB 1 | ||
122 | 156 | ||
123 | int booting; | 157 | int booting; |
124 | int reset; | 158 | int reset; |
@@ -127,20 +161,23 @@ struct uea_softc { | |||
127 | 161 | ||
128 | struct task_struct *kthread; | 162 | struct task_struct *kthread; |
129 | u32 data; | 163 | u32 data; |
130 | wait_queue_head_t cmv_ack_wait; | 164 | u32 data1; |
165 | |||
131 | int cmv_ack; | 166 | int cmv_ack; |
167 | union cmv_dsc cmv_dsc; | ||
132 | 168 | ||
133 | struct work_struct task; | 169 | struct work_struct task; |
170 | struct workqueue_struct *work_q; | ||
134 | u16 pageno; | 171 | u16 pageno; |
135 | u16 ovl; | 172 | u16 ovl; |
136 | 173 | ||
137 | const struct firmware *dsp_firm; | 174 | const struct firmware *dsp_firm; |
138 | struct urb *urb_int; | 175 | struct urb *urb_int; |
139 | 176 | ||
140 | u8 cmv_function; | 177 | void (*dispatch_cmv) (struct uea_softc *, struct intr_pkt *); |
141 | u16 cmv_idx; | 178 | void (*schedule_load_page) (struct uea_softc *, struct intr_pkt *); |
142 | u32 cmv_address; | 179 | int (*stat) (struct uea_softc *); |
143 | u16 cmv_offset; | 180 | int (*send_cmvs) (struct uea_softc *); |
144 | 181 | ||
145 | /* keep in sync with eaglectl */ | 182 | /* keep in sync with eaglectl */ |
146 | struct uea_stats { | 183 | struct uea_stats { |
@@ -174,10 +211,34 @@ struct uea_softc { | |||
174 | #define ELSA_PID_PSTFIRM 0x3350 | 211 | #define ELSA_PID_PSTFIRM 0x3350 |
175 | #define ELSA_PID_PREFIRM 0x3351 | 212 | #define ELSA_PID_PREFIRM 0x3351 |
176 | 213 | ||
214 | #define ELSA_PID_A_PREFIRM 0x3352 | ||
215 | #define ELSA_PID_A_PSTFIRM 0x3353 | ||
216 | #define ELSA_PID_B_PREFIRM 0x3362 | ||
217 | #define ELSA_PID_B_PSTFIRM 0x3363 | ||
218 | |||
177 | /* | 219 | /* |
178 | * Sagem USB IDs | 220 | * Devolo IDs : pots if (pid & 0x10) |
179 | */ | 221 | */ |
180 | #define EAGLE_VID 0x1110 | 222 | #define DEVOLO_VID 0x1039 |
223 | #define DEVOLO_EAGLE_I_A_PID_PSTFIRM 0x2110 | ||
224 | #define DEVOLO_EAGLE_I_A_PID_PREFIRM 0x2111 | ||
225 | |||
226 | #define DEVOLO_EAGLE_I_B_PID_PSTFIRM 0x2100 | ||
227 | #define DEVOLO_EAGLE_I_B_PID_PREFIRM 0x2101 | ||
228 | |||
229 | #define DEVOLO_EAGLE_II_A_PID_PSTFIRM 0x2130 | ||
230 | #define DEVOLO_EAGLE_II_A_PID_PREFIRM 0x2131 | ||
231 | |||
232 | #define DEVOLO_EAGLE_II_B_PID_PSTFIRM 0x2120 | ||
233 | #define DEVOLO_EAGLE_II_B_PID_PREFIRM 0x2121 | ||
234 | |||
235 | /* | ||
236 | * Reference design USB IDs | ||
237 | */ | ||
238 | #define ANALOG_VID 0x1110 | ||
239 | #define ADI930_PID_PREFIRM 0x9001 | ||
240 | #define ADI930_PID_PSTFIRM 0x9000 | ||
241 | |||
181 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | 242 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ |
182 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | 243 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ |
183 | 244 | ||
@@ -187,12 +248,12 @@ struct uea_softc { | |||
187 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | 248 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ |
188 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | 249 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ |
189 | 250 | ||
190 | /* | ||
191 | * Eagle III Pid | ||
192 | */ | ||
193 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | 251 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ |
194 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | 252 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ |
195 | 253 | ||
254 | #define EAGLE_IV_PID_PREFIRM 0x9042 /* Eagle IV */ | ||
255 | #define EAGLE_IV_PID_PSTFIRM 0x9041 /* Eagle IV */ | ||
256 | |||
196 | /* | 257 | /* |
197 | * USR USB IDs | 258 | * USR USB IDs |
198 | */ | 259 | */ |
@@ -208,11 +269,15 @@ struct uea_softc { | |||
208 | 269 | ||
209 | #define PREFIRM 0 | 270 | #define PREFIRM 0 |
210 | #define PSTFIRM (1<<7) | 271 | #define PSTFIRM (1<<7) |
272 | #define AUTO_ANNEX_A (1<<8) | ||
273 | #define AUTO_ANNEX_B (1<<9) | ||
274 | |||
211 | enum { | 275 | enum { |
212 | ADI930 = 0, | 276 | ADI930 = 0, |
213 | EAGLE_I, | 277 | EAGLE_I, |
214 | EAGLE_II, | 278 | EAGLE_II, |
215 | EAGLE_III | 279 | EAGLE_III, |
280 | EAGLE_IV | ||
216 | }; | 281 | }; |
217 | 282 | ||
218 | /* macros for both struct usb_device_id and struct uea_softc */ | 283 | /* macros for both struct usb_device_id and struct uea_softc */ |
@@ -221,15 +286,18 @@ enum { | |||
221 | #define UEA_CHIP_VERSION(x) \ | 286 | #define UEA_CHIP_VERSION(x) \ |
222 | ((x)->driver_info & 0xf) | 287 | ((x)->driver_info & 0xf) |
223 | 288 | ||
224 | #define IS_ISDN(usb_dev) \ | 289 | #define IS_ISDN(x) \ |
225 | (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80) | 290 | ((x)->annex & ANNEXB) |
226 | 291 | ||
227 | #define INS_TO_USBDEV(ins) ins->usb_dev | 292 | #define INS_TO_USBDEV(ins) ins->usb_dev |
228 | 293 | ||
229 | #define GET_STATUS(data) \ | 294 | #define GET_STATUS(data) \ |
230 | ((data >> 8) & 0xf) | 295 | ((data >> 8) & 0xf) |
296 | |||
231 | #define IS_OPERATIONAL(sc) \ | 297 | #define IS_OPERATIONAL(sc) \ |
232 | (GET_STATUS(sc->stats.phy.state) == 2) | 298 | ((UEA_CHIP_VERSION(sc) != EAGLE_IV) ? \ |
299 | (GET_STATUS(sc->stats.phy.state) == 2) : \ | ||
300 | (sc->stats.phy.state == 7)) | ||
233 | 301 | ||
234 | /* | 302 | /* |
235 | * Set of macros to handle unaligned data in the firmware blob. | 303 | * Set of macros to handle unaligned data in the firmware blob. |
@@ -259,7 +327,8 @@ enum { | |||
259 | #define UEA_INTR_PIPE 0x04 | 327 | #define UEA_INTR_PIPE 0x04 |
260 | #define UEA_ISO_DATA_PIPE 0x08 | 328 | #define UEA_ISO_DATA_PIPE 0x08 |
261 | 329 | ||
262 | #define UEA_SET_BLOCK 0x0001 | 330 | #define UEA_E1_SET_BLOCK 0x0001 |
331 | #define UEA_E4_SET_BLOCK 0x002c | ||
263 | #define UEA_SET_MODE 0x0003 | 332 | #define UEA_SET_MODE 0x0003 |
264 | #define UEA_SET_2183_DATA 0x0004 | 333 | #define UEA_SET_2183_DATA 0x0004 |
265 | #define UEA_SET_TIMEOUT 0x0011 | 334 | #define UEA_SET_TIMEOUT 0x0011 |
@@ -275,71 +344,179 @@ enum { | |||
275 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | 344 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) |
276 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | 345 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) |
277 | 346 | ||
278 | /* structure describing a block within a DSP page */ | 347 | /* block information in eagle4 dsp firmware */ |
279 | struct block_info { | 348 | struct block_index { |
349 | __le32 PageOffset; | ||
350 | __le32 NotLastBlock; | ||
351 | __le32 dummy; | ||
352 | __le32 PageSize; | ||
353 | __le32 PageAddress; | ||
354 | __le16 dummy1; | ||
355 | __le16 PageNumber; | ||
356 | } __attribute__ ((packed)); | ||
357 | |||
358 | #define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000) | ||
359 | #define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4) | ||
360 | |||
361 | #define E4_L1_STRING_HEADER 0x10 | ||
362 | #define E4_MAX_PAGE_NUMBER 0x58 | ||
363 | #define E4_NO_SWAPPAGE_HEADERS 0x31 | ||
364 | |||
365 | /* l1_code is eagle4 dsp firmware format */ | ||
366 | struct l1_code { | ||
367 | u8 string_header[E4_L1_STRING_HEADER]; | ||
368 | u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER]; | ||
369 | struct block_index page_header[E4_NO_SWAPPAGE_HEADERS]; | ||
370 | u8 code [0]; | ||
371 | } __attribute__ ((packed)); | ||
372 | |||
373 | /* structures describing a block within a DSP page */ | ||
374 | struct block_info_e1 { | ||
280 | __le16 wHdr; | 375 | __le16 wHdr; |
281 | #define UEA_BIHDR 0xabcd | ||
282 | __le16 wAddress; | 376 | __le16 wAddress; |
283 | __le16 wSize; | 377 | __le16 wSize; |
284 | __le16 wOvlOffset; | 378 | __le16 wOvlOffset; |
285 | __le16 wOvl; /* overlay */ | 379 | __le16 wOvl; /* overlay */ |
286 | __le16 wLast; | 380 | __le16 wLast; |
287 | } __attribute__ ((packed)); | 381 | } __attribute__ ((packed)); |
288 | #define BLOCK_INFO_SIZE 12 | 382 | #define E1_BLOCK_INFO_SIZE 12 |
383 | |||
384 | struct block_info_e4 { | ||
385 | __be16 wHdr; | ||
386 | __u8 bBootPage; | ||
387 | __u8 bPageNumber; | ||
388 | __be32 dwSize; | ||
389 | __be32 dwAddress; | ||
390 | __be16 wReserved; | ||
391 | } __attribute__ ((packed)); | ||
392 | #define E4_BLOCK_INFO_SIZE 14 | ||
289 | 393 | ||
290 | /* structure representing a CMV (Configuration and Management Variable) */ | 394 | #define UEA_BIHDR 0xabcd |
291 | struct cmv { | 395 | #define UEA_RESERVED 0xffff |
292 | __le16 wPreamble; | 396 | |
293 | #define PREAMBLE 0x535c | 397 | /* constants describing cmv type */ |
294 | __u8 bDirection; | 398 | #define E1_PREAMBLE 0x535c |
295 | #define MODEMTOHOST 0x01 | 399 | #define E1_MODEMTOHOST 0x01 |
296 | #define HOSTTOMODEM 0x10 | 400 | #define E1_HOSTTOMODEM 0x10 |
297 | __u8 bFunction; | 401 | |
298 | #define FUNCTION_TYPE(f) ((f) >> 4) | 402 | #define E1_MEMACCESS 0x1 |
299 | #define MEMACCESS 0x1 | 403 | #define E1_ADSLDIRECTIVE 0x7 |
300 | #define ADSLDIRECTIVE 0x7 | 404 | #define E1_FUNCTION_TYPE(f) ((f) >> 4) |
405 | #define E1_FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
406 | |||
407 | #define E4_MEMACCESS 0 | ||
408 | #define E4_ADSLDIRECTIVE 0xf | ||
409 | #define E4_FUNCTION_TYPE(f) ((f) >> 8) | ||
410 | #define E4_FUNCTION_SIZE(f) ((f) & 0x0f) | ||
411 | #define E4_FUNCTION_SUBTYPE(f) (((f) >> 4) & 0x0f) | ||
301 | 412 | ||
302 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
303 | /* for MEMACCESS */ | 413 | /* for MEMACCESS */ |
304 | #define REQUESTREAD 0x0 | 414 | #define E1_REQUESTREAD 0x0 |
305 | #define REQUESTWRITE 0x1 | 415 | #define E1_REQUESTWRITE 0x1 |
306 | #define REPLYREAD 0x2 | 416 | #define E1_REPLYREAD 0x2 |
307 | #define REPLYWRITE 0x3 | 417 | #define E1_REPLYWRITE 0x3 |
418 | |||
419 | #define E4_REQUESTREAD 0x0 | ||
420 | #define E4_REQUESTWRITE 0x4 | ||
421 | #define E4_REPLYREAD (E4_REQUESTREAD | 1) | ||
422 | #define E4_REPLYWRITE (E4_REQUESTWRITE | 1) | ||
423 | |||
308 | /* for ADSLDIRECTIVE */ | 424 | /* for ADSLDIRECTIVE */ |
309 | #define KERNELREADY 0x0 | 425 | #define E1_KERNELREADY 0x0 |
310 | #define MODEMREADY 0x1 | 426 | #define E1_MODEMREADY 0x1 |
311 | 427 | ||
312 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | 428 | #define E4_KERNELREADY 0x0 |
313 | __le16 wIndex; | 429 | #define E4_MODEMREADY 0x1 |
314 | __le32 dwSymbolicAddress; | 430 | |
315 | #define MAKESA(a, b, c, d) \ | 431 | #define E1_MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) |
432 | #define E4_MAKEFUNCTION(t, st, s) (((t) & 0xf) << 8 | ((st) & 0xf) << 4 | ((s) & 0xf)) | ||
433 | |||
434 | #define E1_MAKESA(a, b, c, d) \ | ||
316 | (((c) & 0xff) << 24 | \ | 435 | (((c) & 0xff) << 24 | \ |
317 | ((d) & 0xff) << 16 | \ | 436 | ((d) & 0xff) << 16 | \ |
318 | ((a) & 0xff) << 8 | \ | 437 | ((a) & 0xff) << 8 | \ |
319 | ((b) & 0xff)) | 438 | ((b) & 0xff)) |
320 | #define GETSA1(a) ((a >> 8) & 0xff) | 439 | |
321 | #define GETSA2(a) (a & 0xff) | 440 | #define E1_GETSA1(a) ((a >> 8) & 0xff) |
322 | #define GETSA3(a) ((a >> 24) & 0xff) | 441 | #define E1_GETSA2(a) (a & 0xff) |
323 | #define GETSA4(a) ((a >> 16) & 0xff) | 442 | #define E1_GETSA3(a) ((a >> 24) & 0xff) |
324 | 443 | #define E1_GETSA4(a) ((a >> 16) & 0xff) | |
325 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | 444 | |
326 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | 445 | #define E1_SA_CNTL E1_MAKESA('C', 'N', 'T', 'L') |
327 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | 446 | #define E1_SA_DIAG E1_MAKESA('D', 'I', 'A', 'G') |
328 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | 447 | #define E1_SA_INFO E1_MAKESA('I', 'N', 'F', 'O') |
329 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | 448 | #define E1_SA_OPTN E1_MAKESA('O', 'P', 'T', 'N') |
330 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | 449 | #define E1_SA_RATE E1_MAKESA('R', 'A', 'T', 'E') |
450 | #define E1_SA_STAT E1_MAKESA('S', 'T', 'A', 'T') | ||
451 | |||
452 | #define E4_SA_CNTL 1 | ||
453 | #define E4_SA_STAT 2 | ||
454 | #define E4_SA_INFO 3 | ||
455 | #define E4_SA_TEST 4 | ||
456 | #define E4_SA_OPTN 5 | ||
457 | #define E4_SA_RATE 6 | ||
458 | #define E4_SA_DIAG 7 | ||
459 | #define E4_SA_CNFG 8 | ||
460 | |||
461 | /* structures representing a CMV (Configuration and Management Variable) */ | ||
462 | struct cmv_e1 { | ||
463 | __le16 wPreamble; | ||
464 | __u8 bDirection; | ||
465 | __u8 bFunction; | ||
466 | __le16 wIndex; | ||
467 | __le32 dwSymbolicAddress; | ||
331 | __le16 wOffsetAddress; | 468 | __le16 wOffsetAddress; |
332 | __le32 dwData; | 469 | __le32 dwData; |
333 | } __attribute__ ((packed)); | 470 | } __attribute__ ((packed)); |
334 | #define CMV_SIZE 16 | ||
335 | 471 | ||
336 | /* structure representing swap information */ | 472 | struct cmv_e4 { |
337 | struct swap_info { | 473 | __be16 wGroup; |
474 | __be16 wFunction; | ||
475 | __be16 wOffset; | ||
476 | __be16 wAddress; | ||
477 | __be32 dwData [6]; | ||
478 | } __attribute__ ((packed)); | ||
479 | |||
480 | /* structures representing swap information */ | ||
481 | struct swap_info_e1 { | ||
338 | __u8 bSwapPageNo; | 482 | __u8 bSwapPageNo; |
339 | __u8 bOvl; /* overlay */ | 483 | __u8 bOvl; /* overlay */ |
340 | } __attribute__ ((packed)); | 484 | } __attribute__ ((packed)); |
341 | 485 | ||
342 | /* structure representing interrupt data */ | 486 | struct swap_info_e4 { |
487 | __u8 bSwapPageNo; | ||
488 | } __attribute__ ((packed)); | ||
489 | |||
490 | /* structures representing interrupt data */ | ||
491 | #define e1_bSwapPageNo u.e1.s1.swapinfo.bSwapPageNo | ||
492 | #define e1_bOvl u.e1.s1.swapinfo.bOvl | ||
493 | #define e4_bSwapPageNo u.e4.s1.swapinfo.bSwapPageNo | ||
494 | |||
495 | #define INT_LOADSWAPPAGE 0x0001 | ||
496 | #define INT_INCOMINGCMV 0x0002 | ||
497 | |||
498 | union intr_data_e1 { | ||
499 | struct { | ||
500 | struct swap_info_e1 swapinfo; | ||
501 | __le16 wDataSize; | ||
502 | } __attribute__ ((packed)) s1; | ||
503 | struct { | ||
504 | struct cmv_e1 cmv; | ||
505 | __le16 wDataSize; | ||
506 | } __attribute__ ((packed)) s2; | ||
507 | } __attribute__ ((packed)); | ||
508 | |||
509 | union intr_data_e4 { | ||
510 | struct { | ||
511 | struct swap_info_e4 swapinfo; | ||
512 | __le16 wDataSize; | ||
513 | } __attribute__ ((packed)) s1; | ||
514 | struct { | ||
515 | struct cmv_e4 cmv; | ||
516 | __le16 wDataSize; | ||
517 | } __attribute__ ((packed)) s2; | ||
518 | } __attribute__ ((packed)); | ||
519 | |||
343 | struct intr_pkt { | 520 | struct intr_pkt { |
344 | __u8 bType; | 521 | __u8 bType; |
345 | __u8 bNotification; | 522 | __u8 bNotification; |
@@ -347,43 +524,48 @@ struct intr_pkt { | |||
347 | __le16 wIndex; | 524 | __le16 wIndex; |
348 | __le16 wLength; | 525 | __le16 wLength; |
349 | __le16 wInterrupt; | 526 | __le16 wInterrupt; |
350 | #define INT_LOADSWAPPAGE 0x0001 | ||
351 | #define INT_INCOMINGCMV 0x0002 | ||
352 | union { | 527 | union { |
353 | struct { | 528 | union intr_data_e1 e1; |
354 | struct swap_info swapinfo; | 529 | union intr_data_e4 e4; |
355 | __le16 wDataSize; | 530 | } u; |
356 | } __attribute__ ((packed)) s1; | ||
357 | |||
358 | struct { | ||
359 | struct cmv cmv; | ||
360 | __le16 wDataSize; | ||
361 | } __attribute__ ((packed)) s2; | ||
362 | } __attribute__ ((packed)) u; | ||
363 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
364 | #define bOvl u.s1.swapinfo.bOvl | ||
365 | } __attribute__ ((packed)); | 531 | } __attribute__ ((packed)); |
366 | #define INTR_PKT_SIZE 28 | 532 | |
533 | #define E1_INTR_PKT_SIZE 28 | ||
534 | #define E4_INTR_PKT_SIZE 64 | ||
367 | 535 | ||
368 | static struct usb_driver uea_driver; | 536 | static struct usb_driver uea_driver; |
369 | static DEFINE_MUTEX(uea_mutex); | 537 | static DEFINE_MUTEX(uea_mutex); |
370 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | 538 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III", "Eagle IV"}; |
371 | 539 | ||
372 | static int modem_index; | 540 | static int modem_index; |
373 | static unsigned int debug; | 541 | static unsigned int debug; |
374 | static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1}; | 542 | static unsigned int altsetting[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF}; |
375 | static int sync_wait[NB_MODEM]; | 543 | static int sync_wait[NB_MODEM]; |
376 | static char *cmv_file[NB_MODEM]; | 544 | static char *cmv_file[NB_MODEM]; |
545 | static int annex[NB_MODEM]; | ||
377 | 546 | ||
378 | module_param(debug, uint, 0644); | 547 | module_param(debug, uint, 0644); |
379 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | 548 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); |
380 | module_param_array(use_iso, bool, NULL, 0644); | 549 | module_param_array(altsetting, uint, NULL, 0644); |
381 | MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic"); | 550 | MODULE_PARM_DESC(altsetting, "alternate setting for incoming traffic: 0=bulk, " |
551 | "1=isoc slowest, ... , 8=isoc fastest (default)"); | ||
382 | module_param_array(sync_wait, bool, NULL, 0644); | 552 | module_param_array(sync_wait, bool, NULL, 0644); |
383 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | 553 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); |
384 | module_param_array(cmv_file, charp, NULL, 0644); | 554 | module_param_array(cmv_file, charp, NULL, 0644); |
385 | MODULE_PARM_DESC(cmv_file, | 555 | MODULE_PARM_DESC(cmv_file, |
386 | "file name with configuration and management variables"); | 556 | "file name with configuration and management variables"); |
557 | module_param_array(annex, uint, NULL, 0644); | ||
558 | MODULE_PARM_DESC(annex, | ||
559 | "manually set annex a/b (0=auto, 1=annex a, 2=annex b)"); | ||
560 | |||
561 | #define uea_wait(sc, cond, timeo) \ | ||
562 | ({ \ | ||
563 | int _r = wait_event_interruptible_timeout(sc->sync_q, \ | ||
564 | (cond) || kthread_should_stop(), timeo); \ | ||
565 | if (kthread_should_stop()) \ | ||
566 | _r = -ENODEV; \ | ||
567 | _r; \ | ||
568 | }) | ||
387 | 569 | ||
388 | #define UPDATE_ATM_STAT(type, val) \ | 570 | #define UPDATE_ATM_STAT(type, val) \ |
389 | do { \ | 571 | do { \ |
@@ -519,6 +701,9 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
519 | case EAGLE_III: | 701 | case EAGLE_III: |
520 | fw_name = FW_DIR "eagleIII.fw"; | 702 | fw_name = FW_DIR "eagleIII.fw"; |
521 | break; | 703 | break; |
704 | case EAGLE_IV: | ||
705 | fw_name = FW_DIR "eagleIV.fw"; | ||
706 | break; | ||
522 | } | 707 | } |
523 | 708 | ||
524 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | 709 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); |
@@ -537,7 +722,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
537 | /* | 722 | /* |
538 | * Make sure that the DSP code provided is safe to use. | 723 | * Make sure that the DSP code provided is safe to use. |
539 | */ | 724 | */ |
540 | static int check_dsp(u8 *dsp, unsigned int len) | 725 | static int check_dsp_e1(u8 *dsp, unsigned int len) |
541 | { | 726 | { |
542 | u8 pagecount, blockcount; | 727 | u8 pagecount, blockcount; |
543 | u16 blocksize; | 728 | u16 blocksize; |
@@ -588,6 +773,51 @@ static int check_dsp(u8 *dsp, unsigned int len) | |||
588 | return 0; | 773 | return 0; |
589 | } | 774 | } |
590 | 775 | ||
776 | static int check_dsp_e4(u8 *dsp, int len) | ||
777 | { | ||
778 | int i; | ||
779 | struct l1_code *p = (struct l1_code *) dsp; | ||
780 | unsigned int sum = p->code - dsp; | ||
781 | |||
782 | if (len < sum) | ||
783 | return 1; | ||
784 | |||
785 | if (strcmp("STRATIPHY ANEXA", p->string_header) != 0 && | ||
786 | strcmp("STRATIPHY ANEXB", p->string_header) != 0) | ||
787 | return 1; | ||
788 | |||
789 | for (i = 0; i < E4_MAX_PAGE_NUMBER; i++) { | ||
790 | struct block_index *blockidx; | ||
791 | u8 blockno = p->page_number_to_block_index[i]; | ||
792 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
793 | continue; | ||
794 | |||
795 | do { | ||
796 | u64 l; | ||
797 | |||
798 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
799 | return 1; | ||
800 | |||
801 | blockidx = &p->page_header[blockno++]; | ||
802 | if ((u8 *)(blockidx + 1) - dsp >= len) | ||
803 | return 1; | ||
804 | |||
805 | if (le16_to_cpu(blockidx->PageNumber) != i) | ||
806 | return 1; | ||
807 | |||
808 | l = E4_PAGE_BYTES(blockidx->PageSize); | ||
809 | sum += l; | ||
810 | l += le32_to_cpu(blockidx->PageOffset); | ||
811 | if (l > len) | ||
812 | return 1; | ||
813 | |||
814 | /* zero is zero regardless endianes */ | ||
815 | } while (blockidx->NotLastBlock); | ||
816 | } | ||
817 | |||
818 | return (sum == len) ? 0 : 1; | ||
819 | } | ||
820 | |||
591 | /* | 821 | /* |
592 | * send data to the idma pipe | 822 | * send data to the idma pipe |
593 | * */ | 823 | * */ |
@@ -624,13 +854,18 @@ static int request_dsp(struct uea_softc *sc) | |||
624 | int ret; | 854 | int ret; |
625 | char *dsp_name; | 855 | char *dsp_name; |
626 | 856 | ||
627 | if (UEA_CHIP_VERSION(sc) == ADI930) { | 857 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
628 | if (IS_ISDN(sc->usb_dev)) | 858 | if (IS_ISDN(sc)) |
859 | dsp_name = FW_DIR "DSP4i.bin"; | ||
860 | else | ||
861 | dsp_name = FW_DIR "DSP4p.bin"; | ||
862 | } else if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
863 | if (IS_ISDN(sc)) | ||
629 | dsp_name = FW_DIR "DSP9i.bin"; | 864 | dsp_name = FW_DIR "DSP9i.bin"; |
630 | else | 865 | else |
631 | dsp_name = FW_DIR "DSP9p.bin"; | 866 | dsp_name = FW_DIR "DSP9p.bin"; |
632 | } else { | 867 | } else { |
633 | if (IS_ISDN(sc->usb_dev)) | 868 | if (IS_ISDN(sc)) |
634 | dsp_name = FW_DIR "DSPei.bin"; | 869 | dsp_name = FW_DIR "DSPei.bin"; |
635 | else | 870 | else |
636 | dsp_name = FW_DIR "DSPep.bin"; | 871 | dsp_name = FW_DIR "DSPep.bin"; |
@@ -640,11 +875,16 @@ static int request_dsp(struct uea_softc *sc) | |||
640 | if (ret < 0) { | 875 | if (ret < 0) { |
641 | uea_err(INS_TO_USBDEV(sc), | 876 | uea_err(INS_TO_USBDEV(sc), |
642 | "requesting firmware %s failed with error %d\n", | 877 | "requesting firmware %s failed with error %d\n", |
643 | dsp_name, ret); | 878 | dsp_name, ret); |
644 | return ret; | 879 | return ret; |
645 | } | 880 | } |
646 | 881 | ||
647 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | 882 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) |
883 | ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); | ||
884 | else | ||
885 | ret = check_dsp_e1(sc->dsp_firm->data, sc->dsp_firm->size); | ||
886 | |||
887 | if (ret) { | ||
648 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 888 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", |
649 | dsp_name); | 889 | dsp_name); |
650 | release_firmware(sc->dsp_firm); | 890 | release_firmware(sc->dsp_firm); |
@@ -658,12 +898,12 @@ static int request_dsp(struct uea_softc *sc) | |||
658 | /* | 898 | /* |
659 | * The uea_load_page() function must be called within a process context | 899 | * The uea_load_page() function must be called within a process context |
660 | */ | 900 | */ |
661 | static void uea_load_page(struct work_struct *work) | 901 | static void uea_load_page_e1(struct work_struct *work) |
662 | { | 902 | { |
663 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | 903 | struct uea_softc *sc = container_of(work, struct uea_softc, task); |
664 | u16 pageno = sc->pageno; | 904 | u16 pageno = sc->pageno; |
665 | u16 ovl = sc->ovl; | 905 | u16 ovl = sc->ovl; |
666 | struct block_info bi; | 906 | struct block_info_e1 bi; |
667 | 907 | ||
668 | u8 *p; | 908 | u8 *p; |
669 | u8 pagecount, blockcount; | 909 | u8 pagecount, blockcount; |
@@ -716,7 +956,7 @@ static void uea_load_page(struct work_struct *work) | |||
716 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | 956 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); |
717 | 957 | ||
718 | /* send block info through the IDMA pipe */ | 958 | /* send block info through the IDMA pipe */ |
719 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | 959 | if (uea_idma_write(sc, &bi, E1_BLOCK_INFO_SIZE)) |
720 | goto bad2; | 960 | goto bad2; |
721 | 961 | ||
722 | /* send block data through the IDMA pipe */ | 962 | /* send block data through the IDMA pipe */ |
@@ -735,17 +975,114 @@ bad1: | |||
735 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | 975 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); |
736 | } | 976 | } |
737 | 977 | ||
978 | static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot) | ||
979 | { | ||
980 | struct block_info_e4 bi; | ||
981 | struct block_index *blockidx; | ||
982 | struct l1_code *p = (struct l1_code *) sc->dsp_firm->data; | ||
983 | u8 blockno = p->page_number_to_block_index[pageno]; | ||
984 | |||
985 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
986 | bi.bBootPage = boot; | ||
987 | bi.bPageNumber = pageno; | ||
988 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
989 | |||
990 | do { | ||
991 | u8 *blockoffset; | ||
992 | unsigned int blocksize; | ||
993 | |||
994 | blockidx = &p->page_header[blockno]; | ||
995 | blocksize = E4_PAGE_BYTES(blockidx->PageSize); | ||
996 | blockoffset = sc->dsp_firm->data + le32_to_cpu(blockidx->PageOffset); | ||
997 | |||
998 | bi.dwSize = cpu_to_be32(blocksize); | ||
999 | bi.dwAddress = swab32(blockidx->PageAddress); | ||
1000 | |||
1001 | uea_dbg(INS_TO_USBDEV(sc), | ||
1002 | "sending block %u for DSP page %u size %u adress %x\n", | ||
1003 | blockno, pageno, blocksize, le32_to_cpu(blockidx->PageAddress)); | ||
1004 | |||
1005 | /* send block info through the IDMA pipe */ | ||
1006 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1007 | goto bad; | ||
1008 | |||
1009 | /* send block data through the IDMA pipe */ | ||
1010 | if (uea_idma_write(sc, blockoffset, blocksize)) | ||
1011 | goto bad; | ||
1012 | |||
1013 | blockno++; | ||
1014 | } while (blockidx->NotLastBlock); | ||
1015 | |||
1016 | return; | ||
1017 | |||
1018 | bad: | ||
1019 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", blockno); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | static void uea_load_page_e4(struct work_struct *work) | ||
1024 | { | ||
1025 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | ||
1026 | u8 pageno = sc->pageno; | ||
1027 | int i; | ||
1028 | struct block_info_e4 bi; | ||
1029 | struct l1_code *p; | ||
1030 | |||
1031 | uea_dbg(INS_TO_USBDEV(sc), "sending DSP page %u\n", pageno); | ||
1032 | |||
1033 | /* reload firmware when reboot start and it's loaded already */ | ||
1034 | if (pageno == 0 && sc->dsp_firm) { | ||
1035 | release_firmware(sc->dsp_firm); | ||
1036 | sc->dsp_firm = NULL; | ||
1037 | } | ||
1038 | |||
1039 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
1040 | return; | ||
1041 | |||
1042 | p = (struct l1_code *) sc->dsp_firm->data; | ||
1043 | if (pageno >= p->page_header[0].PageNumber) { | ||
1044 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | if (pageno != 0) { | ||
1049 | __uea_load_page_e4(sc, pageno, 0); | ||
1050 | return; | ||
1051 | } | ||
1052 | |||
1053 | uea_dbg(INS_TO_USBDEV(sc), | ||
1054 | "sending Main DSP page %u\n", p->page_header[0].PageNumber); | ||
1055 | |||
1056 | for (i = 0; i < le16_to_cpu(p->page_header[0].PageNumber); i++) { | ||
1057 | if (E4_IS_BOOT_PAGE(p->page_header[i].PageSize)) | ||
1058 | __uea_load_page_e4(sc, i, 1); | ||
1059 | } | ||
1060 | |||
1061 | uea_dbg(INS_TO_USBDEV(sc),"sending start bi\n"); | ||
1062 | |||
1063 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
1064 | bi.bBootPage = 0; | ||
1065 | bi.bPageNumber = 0xff; | ||
1066 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
1067 | bi.dwSize = cpu_to_be32(E4_PAGE_BYTES(p->page_header[0].PageSize)); | ||
1068 | bi.dwAddress = swab32(p->page_header[0].PageAddress); | ||
1069 | |||
1070 | /* send block info through the IDMA pipe */ | ||
1071 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1072 | uea_err(INS_TO_USBDEV(sc), "sending DSP start bi failed\n"); | ||
1073 | } | ||
1074 | |||
738 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | 1075 | static inline void wake_up_cmv_ack(struct uea_softc *sc) |
739 | { | 1076 | { |
740 | BUG_ON(sc->cmv_ack); | 1077 | BUG_ON(sc->cmv_ack); |
741 | sc->cmv_ack = 1; | 1078 | sc->cmv_ack = 1; |
742 | wake_up(&sc->cmv_ack_wait); | 1079 | wake_up(&sc->sync_q); |
743 | } | 1080 | } |
744 | 1081 | ||
745 | static inline int wait_cmv_ack(struct uea_softc *sc) | 1082 | static inline int wait_cmv_ack(struct uea_softc *sc) |
746 | { | 1083 | { |
747 | int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait, | 1084 | int ret = uea_wait(sc, sc->cmv_ack , ACK_TIMEOUT); |
748 | sc->cmv_ack, ACK_TIMEOUT); | 1085 | |
749 | sc->cmv_ack = 0; | 1086 | sc->cmv_ack = 0; |
750 | 1087 | ||
751 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", | 1088 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", |
@@ -792,33 +1129,34 @@ static int uea_request(struct uea_softc *sc, | |||
792 | return 0; | 1129 | return 0; |
793 | } | 1130 | } |
794 | 1131 | ||
795 | static int uea_cmv(struct uea_softc *sc, | 1132 | static int uea_cmv_e1(struct uea_softc *sc, |
796 | u8 function, u32 address, u16 offset, u32 data) | 1133 | u8 function, u32 address, u16 offset, u32 data) |
797 | { | 1134 | { |
798 | struct cmv cmv; | 1135 | struct cmv_e1 cmv; |
799 | int ret; | 1136 | int ret; |
800 | 1137 | ||
801 | uea_enters(INS_TO_USBDEV(sc)); | 1138 | uea_enters(INS_TO_USBDEV(sc)); |
802 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " | 1139 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " |
803 | "offset : 0x%04x, data : 0x%08x\n", | 1140 | "offset : 0x%04x, data : 0x%08x\n", |
804 | FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), | 1141 | E1_FUNCTION_TYPE(function), E1_FUNCTION_SUBTYPE(function), |
805 | GETSA1(address), GETSA2(address), GETSA3(address), | 1142 | E1_GETSA1(address), E1_GETSA2(address), E1_GETSA3(address), |
806 | GETSA4(address), offset, data); | 1143 | E1_GETSA4(address), offset, data); |
1144 | |||
807 | /* we send a request, but we expect a reply */ | 1145 | /* we send a request, but we expect a reply */ |
808 | sc->cmv_function = function | 0x2; | 1146 | sc->cmv_dsc.e1.function = function | 0x2; |
809 | sc->cmv_idx++; | 1147 | sc->cmv_dsc.e1.idx++; |
810 | sc->cmv_address = address; | 1148 | sc->cmv_dsc.e1.address = address; |
811 | sc->cmv_offset = offset; | 1149 | sc->cmv_dsc.e1.offset = offset; |
812 | 1150 | ||
813 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | 1151 | cmv.wPreamble = cpu_to_le16(E1_PREAMBLE); |
814 | cmv.bDirection = HOSTTOMODEM; | 1152 | cmv.bDirection = E1_HOSTTOMODEM; |
815 | cmv.bFunction = function; | 1153 | cmv.bFunction = function; |
816 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | 1154 | cmv.wIndex = cpu_to_le16(sc->cmv_dsc.e1.idx); |
817 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | 1155 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); |
818 | cmv.wOffsetAddress = cpu_to_le16(offset); | 1156 | cmv.wOffsetAddress = cpu_to_le16(offset); |
819 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | 1157 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); |
820 | 1158 | ||
821 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | 1159 | ret = uea_request(sc, UEA_E1_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); |
822 | if (ret < 0) | 1160 | if (ret < 0) |
823 | return ret; | 1161 | return ret; |
824 | ret = wait_cmv_ack(sc); | 1162 | ret = wait_cmv_ack(sc); |
@@ -826,10 +1164,44 @@ static int uea_cmv(struct uea_softc *sc, | |||
826 | return ret; | 1164 | return ret; |
827 | } | 1165 | } |
828 | 1166 | ||
829 | static inline int uea_read_cmv(struct uea_softc *sc, | 1167 | static int uea_cmv_e4(struct uea_softc *sc, |
1168 | u16 function, u16 group, u16 address, u16 offset, u32 data) | ||
1169 | { | ||
1170 | struct cmv_e4 cmv; | ||
1171 | int ret; | ||
1172 | |||
1173 | uea_enters(INS_TO_USBDEV(sc)); | ||
1174 | memset(&cmv, 0, sizeof(cmv)); | ||
1175 | |||
1176 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, " | ||
1177 | "Address : 0x%04x, offset : 0x%04x, data : 0x%08x\n", | ||
1178 | E4_FUNCTION_TYPE(function), E4_FUNCTION_SUBTYPE(function), | ||
1179 | group, address, offset, data); | ||
1180 | |||
1181 | /* we send a request, but we expect a reply */ | ||
1182 | sc->cmv_dsc.e4.function = function | (0x1 << 4); | ||
1183 | sc->cmv_dsc.e4.offset = offset; | ||
1184 | sc->cmv_dsc.e4.address = address; | ||
1185 | sc->cmv_dsc.e4.group = group; | ||
1186 | |||
1187 | cmv.wFunction = cpu_to_be16(function); | ||
1188 | cmv.wGroup = cpu_to_be16(group); | ||
1189 | cmv.wAddress = cpu_to_be16(address); | ||
1190 | cmv.wOffset = cpu_to_be16(offset); | ||
1191 | cmv.dwData[0] = cpu_to_be32(data); | ||
1192 | |||
1193 | ret = uea_request(sc, UEA_E4_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); | ||
1194 | if (ret < 0) | ||
1195 | return ret; | ||
1196 | ret = wait_cmv_ack(sc); | ||
1197 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1198 | return ret; | ||
1199 | } | ||
1200 | |||
1201 | static inline int uea_read_cmv_e1(struct uea_softc *sc, | ||
830 | u32 address, u16 offset, u32 *data) | 1202 | u32 address, u16 offset, u32 *data) |
831 | { | 1203 | { |
832 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | 1204 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTREAD), |
833 | address, offset, 0); | 1205 | address, offset, 0); |
834 | if (ret < 0) | 1206 | if (ret < 0) |
835 | uea_err(INS_TO_USBDEV(sc), | 1207 | uea_err(INS_TO_USBDEV(sc), |
@@ -840,10 +1212,27 @@ static inline int uea_read_cmv(struct uea_softc *sc, | |||
840 | return ret; | 1212 | return ret; |
841 | } | 1213 | } |
842 | 1214 | ||
843 | static inline int uea_write_cmv(struct uea_softc *sc, | 1215 | static inline int uea_read_cmv_e4(struct uea_softc *sc, |
1216 | u8 size, u16 group, u16 address, u16 offset, u32 *data) | ||
1217 | { | ||
1218 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTREAD, size), | ||
1219 | group, address, offset, 0); | ||
1220 | if (ret < 0) | ||
1221 | uea_err(INS_TO_USBDEV(sc), | ||
1222 | "reading cmv failed with error %d\n", ret); | ||
1223 | else { | ||
1224 | *data = sc->data; | ||
1225 | /* size is in 16-bit word quantities */ | ||
1226 | if (size > 2) | ||
1227 | *(data + 1) = sc->data1; | ||
1228 | } | ||
1229 | return ret; | ||
1230 | } | ||
1231 | |||
1232 | static inline int uea_write_cmv_e1(struct uea_softc *sc, | ||
844 | u32 address, u16 offset, u32 data) | 1233 | u32 address, u16 offset, u32 data) |
845 | { | 1234 | { |
846 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | 1235 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTWRITE), |
847 | address, offset, data); | 1236 | address, offset, data); |
848 | if (ret < 0) | 1237 | if (ret < 0) |
849 | uea_err(INS_TO_USBDEV(sc), | 1238 | uea_err(INS_TO_USBDEV(sc), |
@@ -852,12 +1241,48 @@ static inline int uea_write_cmv(struct uea_softc *sc, | |||
852 | return ret; | 1241 | return ret; |
853 | } | 1242 | } |
854 | 1243 | ||
1244 | static inline int uea_write_cmv_e4(struct uea_softc *sc, | ||
1245 | u8 size, u16 group, u16 address, u16 offset, u32 data) | ||
1246 | { | ||
1247 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTWRITE, size), | ||
1248 | group, address, offset, data); | ||
1249 | if (ret < 0) | ||
1250 | uea_err(INS_TO_USBDEV(sc), | ||
1251 | "writing cmv failed with error %d\n", ret); | ||
1252 | |||
1253 | return ret; | ||
1254 | } | ||
1255 | |||
1256 | static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate) | ||
1257 | { | ||
1258 | int ret; | ||
1259 | u16 timeout; | ||
1260 | |||
1261 | /* in bulk mode the modem have problem with high rate | ||
1262 | * changing internal timing could improve things, but the | ||
1263 | * value is misterious. | ||
1264 | * ADI930 don't support it (-EPIPE error). | ||
1265 | */ | ||
1266 | |||
1267 | if (UEA_CHIP_VERSION(sc) == ADI930 || | ||
1268 | altsetting[sc->modem_index] > 0 || | ||
1269 | sc->stats.phy.dsrate == dsrate) | ||
1270 | return; | ||
1271 | |||
1272 | /* Original timming (1Mbit/s) from ADI (used in windows driver) */ | ||
1273 | timeout = (dsrate <= 1024*1024) ? 0 : 1; | ||
1274 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
1275 | uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n", | ||
1276 | timeout, ret < 0 ? " failed" : ""); | ||
1277 | |||
1278 | } | ||
1279 | |||
855 | /* | 1280 | /* |
856 | * Monitor the modem and update the stat | 1281 | * Monitor the modem and update the stat |
857 | * return 0 if everything is ok | 1282 | * return 0 if everything is ok |
858 | * return < 0 if an error occurs (-EAGAIN reboot needed) | 1283 | * return < 0 if an error occurs (-EAGAIN reboot needed) |
859 | */ | 1284 | */ |
860 | static int uea_stat(struct uea_softc *sc) | 1285 | static int uea_stat_e1(struct uea_softc *sc) |
861 | { | 1286 | { |
862 | u32 data; | 1287 | u32 data; |
863 | int ret; | 1288 | int ret; |
@@ -865,7 +1290,7 @@ static int uea_stat(struct uea_softc *sc) | |||
865 | uea_enters(INS_TO_USBDEV(sc)); | 1290 | uea_enters(INS_TO_USBDEV(sc)); |
866 | data = sc->stats.phy.state; | 1291 | data = sc->stats.phy.state; |
867 | 1292 | ||
868 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | 1293 | ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state); |
869 | if (ret < 0) | 1294 | if (ret < 0) |
870 | return ret; | 1295 | return ret; |
871 | 1296 | ||
@@ -885,7 +1310,7 @@ static int uea_stat(struct uea_softc *sc) | |||
885 | 1310 | ||
886 | case 3: /* fail ... */ | 1311 | case 3: /* fail ... */ |
887 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | 1312 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" |
888 | " (may be try other cmv/dsp)\n"); | 1313 | " (may be try other cmv/dsp)\n"); |
889 | return -EAGAIN; | 1314 | return -EAGAIN; |
890 | 1315 | ||
891 | case 4 ... 6: /* test state */ | 1316 | case 4 ... 6: /* test state */ |
@@ -923,7 +1348,7 @@ static int uea_stat(struct uea_softc *sc) | |||
923 | /* wake up processes waiting for synchronization */ | 1348 | /* wake up processes waiting for synchronization */ |
924 | wake_up(&sc->sync_q); | 1349 | wake_up(&sc->sync_q); |
925 | 1350 | ||
926 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | 1351 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 2, &sc->stats.phy.flags); |
927 | if (ret < 0) | 1352 | if (ret < 0) |
928 | return ret; | 1353 | return ret; |
929 | sc->stats.phy.mflags |= sc->stats.phy.flags; | 1354 | sc->stats.phy.mflags |= sc->stats.phy.flags; |
@@ -937,105 +1362,223 @@ static int uea_stat(struct uea_softc *sc) | |||
937 | return 0; | 1362 | return 0; |
938 | } | 1363 | } |
939 | 1364 | ||
940 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | 1365 | ret = uea_read_cmv_e1(sc, E1_SA_RATE, 0, &data); |
941 | if (ret < 0) | 1366 | if (ret < 0) |
942 | return ret; | 1367 | return ret; |
943 | 1368 | ||
944 | /* in bulk mode the modem have problem with high rate | 1369 | uea_set_bulk_timeout(sc, (data >> 16) * 32); |
945 | * changing internal timing could improve things, but the | ||
946 | * value is misterious. | ||
947 | * ADI930 don't support it (-EPIPE error). | ||
948 | */ | ||
949 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
950 | && !use_iso[sc->modem_index] | ||
951 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
952 | /* Original timming from ADI(used in windows driver) | ||
953 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
954 | */ | ||
955 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
956 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
957 | uea_info(INS_TO_USBDEV(sc), | ||
958 | "setting new timeout %d%s\n", timeout, | ||
959 | ret < 0?" failed":""); | ||
960 | } | ||
961 | sc->stats.phy.dsrate = (data >> 16) * 32; | 1370 | sc->stats.phy.dsrate = (data >> 16) * 32; |
962 | sc->stats.phy.usrate = (data & 0xffff) * 32; | 1371 | sc->stats.phy.usrate = (data & 0xffff) * 32; |
963 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | 1372 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); |
964 | 1373 | ||
965 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | 1374 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 23, &data); |
966 | if (ret < 0) | 1375 | if (ret < 0) |
967 | return ret; | 1376 | return ret; |
968 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | 1377 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; |
969 | 1378 | ||
970 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | 1379 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 47, &data); |
971 | if (ret < 0) | 1380 | if (ret < 0) |
972 | return ret; | 1381 | return ret; |
973 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | 1382 | sc->stats.phy.usattenuation = (data & 0xff) / 2; |
974 | 1383 | ||
975 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | 1384 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 25, &sc->stats.phy.dsmargin); |
976 | if (ret < 0) | 1385 | if (ret < 0) |
977 | return ret; | 1386 | return ret; |
978 | 1387 | ||
979 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | 1388 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 49, &sc->stats.phy.usmargin); |
980 | if (ret < 0) | 1389 | if (ret < 0) |
981 | return ret; | 1390 | return ret; |
982 | 1391 | ||
983 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | 1392 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 51, &sc->stats.phy.rxflow); |
984 | if (ret < 0) | 1393 | if (ret < 0) |
985 | return ret; | 1394 | return ret; |
986 | 1395 | ||
987 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | 1396 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 52, &sc->stats.phy.txflow); |
988 | if (ret < 0) | 1397 | if (ret < 0) |
989 | return ret; | 1398 | return ret; |
990 | 1399 | ||
991 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | 1400 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 54, &sc->stats.phy.dsunc); |
992 | if (ret < 0) | 1401 | if (ret < 0) |
993 | return ret; | 1402 | return ret; |
994 | 1403 | ||
995 | /* only for atu-c */ | 1404 | /* only for atu-c */ |
996 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | 1405 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 58, &sc->stats.phy.usunc); |
997 | if (ret < 0) | 1406 | if (ret < 0) |
998 | return ret; | 1407 | return ret; |
999 | 1408 | ||
1000 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | 1409 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 53, &sc->stats.phy.dscorr); |
1001 | if (ret < 0) | 1410 | if (ret < 0) |
1002 | return ret; | 1411 | return ret; |
1003 | 1412 | ||
1004 | /* only for atu-c */ | 1413 | /* only for atu-c */ |
1005 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | 1414 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 57, &sc->stats.phy.uscorr); |
1006 | if (ret < 0) | 1415 | if (ret < 0) |
1007 | return ret; | 1416 | return ret; |
1008 | 1417 | ||
1009 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | 1418 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 8, &sc->stats.phy.vidco); |
1010 | if (ret < 0) | 1419 | if (ret < 0) |
1011 | return ret; | 1420 | return ret; |
1012 | 1421 | ||
1013 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | 1422 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 13, &sc->stats.phy.vidcpe); |
1014 | if (ret < 0) | 1423 | if (ret < 0) |
1015 | return ret; | 1424 | return ret; |
1016 | 1425 | ||
1017 | return 0; | 1426 | return 0; |
1018 | } | 1427 | } |
1019 | 1428 | ||
1020 | static int request_cmvs(struct uea_softc *sc, | 1429 | static int uea_stat_e4(struct uea_softc *sc) |
1021 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
1022 | { | 1430 | { |
1023 | int ret, size; | 1431 | u32 data; |
1024 | u8 *data; | 1432 | u32 tmp_arr[2]; |
1433 | int ret; | ||
1434 | |||
1435 | uea_enters(INS_TO_USBDEV(sc)); | ||
1436 | data = sc->stats.phy.state; | ||
1437 | |||
1438 | /* XXX only need to be done before operationnal... */ | ||
1439 | ret = uea_read_cmv_e4(sc, 1, E4_SA_STAT, 0, 0, &sc->stats.phy.state); | ||
1440 | if (ret < 0) | ||
1441 | return ret; | ||
1442 | |||
1443 | switch (sc->stats.phy.state) { | ||
1444 | case 0x0: /* not yet synchronized */ | ||
1445 | case 0x1: | ||
1446 | case 0x3: | ||
1447 | case 0x4: | ||
1448 | uea_dbg(INS_TO_USBDEV(sc), "modem not yet synchronized\n"); | ||
1449 | return 0; | ||
1450 | case 0x5: /* initialization */ | ||
1451 | case 0x6: | ||
1452 | case 0x9: | ||
1453 | case 0xa: | ||
1454 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
1455 | return 0; | ||
1456 | case 0x2: /* fail ... */ | ||
1457 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | ||
1458 | " (may be try other cmv/dsp)\n"); | ||
1459 | return -EAGAIN; | ||
1460 | case 0x7: /* operational */ | ||
1461 | break; | ||
1462 | default: | ||
1463 | uea_warn(INS_TO_USBDEV(sc), "unknown state: %x\n", sc->stats.phy.state); | ||
1464 | return 0; | ||
1465 | } | ||
1466 | |||
1467 | if (data != 7) { | ||
1468 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
1469 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
1470 | |||
1471 | /* release the dsp firmware as it is not needed until | ||
1472 | * the next failure | ||
1473 | */ | ||
1474 | if (sc->dsp_firm) { | ||
1475 | release_firmware(sc->dsp_firm); | ||
1476 | sc->dsp_firm = NULL; | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | /* always update it as atm layer could not be init when we switch to | ||
1481 | * operational state | ||
1482 | */ | ||
1483 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
1484 | |||
1485 | /* wake up processes waiting for synchronization */ | ||
1486 | wake_up(&sc->sync_q); | ||
1487 | |||
1488 | /* TODO improve this state machine : | ||
1489 | * we need some CMV info : what they do and their unit | ||
1490 | * we should find the equivalent of eagle3- CMV | ||
1491 | */ | ||
1492 | /* check flags */ | ||
1493 | ret = uea_read_cmv_e4(sc, 1, E4_SA_DIAG, 0, 0, &sc->stats.phy.flags); | ||
1494 | if (ret < 0) | ||
1495 | return ret; | ||
1496 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
1497 | |||
1498 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
1499 | * we check the status again in order to detect the failure earlier | ||
1500 | */ | ||
1501 | if (sc->stats.phy.flags) { | ||
1502 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", | ||
1503 | sc->stats.phy.flags); | ||
1504 | if (sc->stats.phy.flags & 1) //delineation LOSS | ||
1505 | return -EAGAIN; | ||
1506 | if (sc->stats.phy.flags & 0x4000) //Reset Flag | ||
1507 | return -EAGAIN; | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | /* rate data may be in upper or lower half of 64 bit word, strange */ | ||
1512 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 0, 0, tmp_arr); | ||
1513 | if (ret < 0) | ||
1514 | return ret; | ||
1515 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1516 | sc->stats.phy.usrate = data / 1000; | ||
1517 | |||
1518 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 1, 0, tmp_arr); | ||
1519 | if (ret < 0) | ||
1520 | return ret; | ||
1521 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1522 | uea_set_bulk_timeout(sc, data / 1000); | ||
1523 | sc->stats.phy.dsrate = data / 1000; | ||
1524 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
1525 | |||
1526 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 1, &data); | ||
1527 | if (ret < 0) | ||
1528 | return ret; | ||
1529 | sc->stats.phy.dsattenuation = data / 10; | ||
1530 | |||
1531 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 1, &data); | ||
1532 | if (ret < 0) | ||
1533 | return ret; | ||
1534 | sc->stats.phy.usattenuation = data / 10; | ||
1535 | |||
1536 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 3, &data); | ||
1537 | if (ret < 0) | ||
1538 | return ret; | ||
1539 | sc->stats.phy.dsmargin = data / 2; | ||
1540 | |||
1541 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 3, &data); | ||
1542 | if (ret < 0) | ||
1543 | return ret; | ||
1544 | sc->stats.phy.usmargin = data / 10; | ||
1545 | |||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) | ||
1550 | { | ||
1551 | char file_arr[] = "CMVxy.bin"; | ||
1025 | char *file; | 1552 | char *file; |
1026 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1027 | 1553 | ||
1554 | /* set proper name corresponding modem version and line type */ | ||
1028 | if (cmv_file[sc->modem_index] == NULL) { | 1555 | if (cmv_file[sc->modem_index] == NULL) { |
1029 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1556 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1030 | file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin"; | 1557 | file_arr[3] = '9'; |
1558 | else if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1559 | file_arr[3] = '4'; | ||
1031 | else | 1560 | else |
1032 | file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin"; | 1561 | file_arr[3] = 'e'; |
1562 | |||
1563 | file_arr[4] = IS_ISDN(sc) ? 'i' : 'p'; | ||
1564 | file = file_arr; | ||
1033 | } else | 1565 | } else |
1034 | file = cmv_file[sc->modem_index]; | 1566 | file = cmv_file[sc->modem_index]; |
1035 | 1567 | ||
1036 | strcpy(cmv_name, FW_DIR); | 1568 | strcpy(cmv_name, FW_DIR); |
1037 | strlcat(cmv_name, file, sizeof(cmv_name)); | 1569 | strlcat(cmv_name, file, FIRMWARE_NAME_MAX); |
1570 | if (ver == 2) | ||
1571 | strlcat(cmv_name, ".v2", FIRMWARE_NAME_MAX); | ||
1572 | } | ||
1573 | |||
1574 | static int request_cmvs_old(struct uea_softc *sc, | ||
1575 | void **cmvs, const struct firmware **fw) | ||
1576 | { | ||
1577 | int ret, size; | ||
1578 | u8 *data; | ||
1579 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1038 | 1580 | ||
1581 | cmvs_file_name(sc, cmv_name, 1); | ||
1039 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | 1582 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); |
1040 | if (ret < 0) { | 1583 | if (ret < 0) { |
1041 | uea_err(INS_TO_USBDEV(sc), | 1584 | uea_err(INS_TO_USBDEV(sc), |
@@ -1045,16 +1588,197 @@ static int request_cmvs(struct uea_softc *sc, | |||
1045 | } | 1588 | } |
1046 | 1589 | ||
1047 | data = (u8 *) (*fw)->data; | 1590 | data = (u8 *) (*fw)->data; |
1048 | size = *data * sizeof(struct uea_cmvs) + 1; | 1591 | size = (*fw)->size; |
1049 | if (size != (*fw)->size) { | 1592 | if (size < 1) |
1050 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 1593 | goto err_fw_corrupted; |
1051 | cmv_name); | 1594 | |
1052 | release_firmware(*fw); | 1595 | if (size != *data * sizeof(struct uea_cmvs_v1) + 1) |
1053 | return -EILSEQ; | 1596 | goto err_fw_corrupted; |
1597 | |||
1598 | *cmvs = (void *)(data + 1); | ||
1599 | return *data; | ||
1600 | |||
1601 | err_fw_corrupted: | ||
1602 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1603 | release_firmware(*fw); | ||
1604 | return -EILSEQ; | ||
1605 | } | ||
1606 | |||
1607 | static int request_cmvs(struct uea_softc *sc, | ||
1608 | void **cmvs, const struct firmware **fw, int *ver) | ||
1609 | { | ||
1610 | int ret, size; | ||
1611 | u32 crc; | ||
1612 | u8 *data; | ||
1613 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1614 | |||
1615 | cmvs_file_name(sc, cmv_name, 2); | ||
1616 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
1617 | if (ret < 0) { | ||
1618 | /* if caller can handle old version, try to provide it */ | ||
1619 | if (*ver == 1) { | ||
1620 | uea_warn(INS_TO_USBDEV(sc), "requesting firmware %s failed, " | ||
1621 | "try to get older cmvs\n", cmv_name); | ||
1622 | return request_cmvs_old(sc, cmvs, fw); | ||
1623 | } | ||
1624 | uea_err(INS_TO_USBDEV(sc), | ||
1625 | "requesting firmware %s failed with error %d\n", | ||
1626 | cmv_name, ret); | ||
1627 | return ret; | ||
1054 | } | 1628 | } |
1055 | 1629 | ||
1056 | *cmvs = (struct uea_cmvs *)(data + 1); | 1630 | size = (*fw)->size; |
1631 | data = (u8 *) (*fw)->data; | ||
1632 | if (size < 4 || strncmp(data, "cmv2", 4) != 0) { | ||
1633 | if (*ver == 1) { | ||
1634 | uea_warn(INS_TO_USBDEV(sc), "firmware %s is corrupted, " | ||
1635 | "try to get older cmvs\n", cmv_name); | ||
1636 | release_firmware(*fw); | ||
1637 | return request_cmvs_old(sc, cmvs, fw); | ||
1638 | } | ||
1639 | goto err_fw_corrupted; | ||
1640 | } | ||
1641 | |||
1642 | *ver = 2; | ||
1643 | |||
1644 | data += 4; | ||
1645 | size -= 4; | ||
1646 | if (size < 5) | ||
1647 | goto err_fw_corrupted; | ||
1648 | |||
1649 | crc = FW_GET_LONG(data); | ||
1650 | data += 4; | ||
1651 | size -= 4; | ||
1652 | if (crc32_be(0, data, size) != crc) | ||
1653 | goto err_fw_corrupted; | ||
1654 | |||
1655 | if (size != *data * sizeof(struct uea_cmvs_v2) + 1) | ||
1656 | goto err_fw_corrupted; | ||
1657 | |||
1658 | *cmvs = (void *) (data + 1); | ||
1057 | return *data; | 1659 | return *data; |
1660 | |||
1661 | err_fw_corrupted: | ||
1662 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1663 | release_firmware(*fw); | ||
1664 | return -EILSEQ; | ||
1665 | } | ||
1666 | |||
1667 | static int uea_send_cmvs_e1(struct uea_softc *sc) | ||
1668 | { | ||
1669 | int i, ret, len; | ||
1670 | void *cmvs_ptr; | ||
1671 | const struct firmware *cmvs_fw; | ||
1672 | int ver = 1; // we can handle v1 cmv firmware version; | ||
1673 | |||
1674 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1675 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 1); | ||
1676 | if (ret < 0) | ||
1677 | return ret; | ||
1678 | |||
1679 | /* Dump firmware version */ | ||
1680 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 10, &sc->stats.phy.firmid); | ||
1681 | if (ret < 0) | ||
1682 | return ret; | ||
1683 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1684 | sc->stats.phy.firmid); | ||
1685 | |||
1686 | /* get options */ | ||
1687 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1688 | if (ret < 0) | ||
1689 | return ret; | ||
1690 | |||
1691 | /* send options */ | ||
1692 | if (ver == 1) { | ||
1693 | struct uea_cmvs_v1 *cmvs_v1 = cmvs_ptr; | ||
1694 | |||
1695 | uea_warn(INS_TO_USBDEV(sc), "use deprecated cmvs version, " | ||
1696 | "please update your firmware\n"); | ||
1697 | |||
1698 | for (i = 0; i < len; i++) { | ||
1699 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v1[i].address), | ||
1700 | FW_GET_WORD(&cmvs_v1[i].offset), | ||
1701 | FW_GET_LONG(&cmvs_v1[i].data)); | ||
1702 | if (ret < 0) | ||
1703 | goto out; | ||
1704 | } | ||
1705 | } else if (ver == 2) { | ||
1706 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1707 | |||
1708 | for (i = 0; i < len; i++) { | ||
1709 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v2[i].address), | ||
1710 | (u16) FW_GET_LONG(&cmvs_v2[i].offset), | ||
1711 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1712 | if (ret < 0) | ||
1713 | goto out; | ||
1714 | } | ||
1715 | } else { | ||
1716 | /* This realy should not happen */ | ||
1717 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1718 | goto out; | ||
1719 | } | ||
1720 | |||
1721 | /* Enter in R-ACT-REQ */ | ||
1722 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 2); | ||
1723 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1724 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1725 | out: | ||
1726 | release_firmware(cmvs_fw); | ||
1727 | return ret; | ||
1728 | } | ||
1729 | |||
1730 | static int uea_send_cmvs_e4(struct uea_softc *sc) | ||
1731 | { | ||
1732 | int i, ret, len; | ||
1733 | void *cmvs_ptr; | ||
1734 | const struct firmware *cmvs_fw; | ||
1735 | int ver = 2; // we can only handle v2 cmv firmware version; | ||
1736 | |||
1737 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1738 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 1); | ||
1739 | if (ret < 0) | ||
1740 | return ret; | ||
1741 | |||
1742 | /* Dump firmware version */ | ||
1743 | /* XXX don't read the 3th byte as it is always 6 */ | ||
1744 | ret = uea_read_cmv_e4(sc, 2, E4_SA_INFO, 55, 0, &sc->stats.phy.firmid); | ||
1745 | if (ret < 0) | ||
1746 | return ret; | ||
1747 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1748 | sc->stats.phy.firmid); | ||
1749 | |||
1750 | |||
1751 | /* get options */ | ||
1752 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1753 | if (ret < 0) | ||
1754 | return ret; | ||
1755 | |||
1756 | /* send options */ | ||
1757 | if (ver == 2) { | ||
1758 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1759 | |||
1760 | for (i = 0; i < len; i++) { | ||
1761 | ret = uea_write_cmv_e4(sc, 1, | ||
1762 | FW_GET_LONG(&cmvs_v2[i].group), | ||
1763 | FW_GET_LONG(&cmvs_v2[i].address), | ||
1764 | FW_GET_LONG(&cmvs_v2[i].offset), | ||
1765 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1766 | if (ret < 0) | ||
1767 | goto out; | ||
1768 | } | ||
1769 | } else { | ||
1770 | /* This realy should not happen */ | ||
1771 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1772 | goto out; | ||
1773 | } | ||
1774 | |||
1775 | /* Enter in R-ACT-REQ */ | ||
1776 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 2); | ||
1777 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1778 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1779 | out: | ||
1780 | release_firmware(cmvs_fw); | ||
1781 | return ret; | ||
1058 | } | 1782 | } |
1059 | 1783 | ||
1060 | /* Start boot post firmware modem: | 1784 | /* Start boot post firmware modem: |
@@ -1066,9 +1790,7 @@ static int request_cmvs(struct uea_softc *sc, | |||
1066 | static int uea_start_reset(struct uea_softc *sc) | 1790 | static int uea_start_reset(struct uea_softc *sc) |
1067 | { | 1791 | { |
1068 | u16 zero = 0; /* ;-) */ | 1792 | u16 zero = 0; /* ;-) */ |
1069 | int i, len, ret; | 1793 | int ret; |
1070 | struct uea_cmvs *cmvs; | ||
1071 | const struct firmware *cmvs_fw; | ||
1072 | 1794 | ||
1073 | uea_enters(INS_TO_USBDEV(sc)); | 1795 | uea_enters(INS_TO_USBDEV(sc)); |
1074 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | 1796 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); |
@@ -1093,25 +1815,36 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1093 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | 1815 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); |
1094 | 1816 | ||
1095 | /* original driver use 200ms, but windows driver use 100ms */ | 1817 | /* original driver use 200ms, but windows driver use 100ms */ |
1096 | msleep(100); | 1818 | ret = uea_wait(sc, 0, msecs_to_jiffies(100)); |
1819 | if (ret < 0) | ||
1820 | return ret; | ||
1097 | 1821 | ||
1098 | /* leave reset mode */ | 1822 | /* leave reset mode */ |
1099 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | 1823 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); |
1100 | 1824 | ||
1101 | /* clear tx and rx mailboxes */ | 1825 | if (UEA_CHIP_VERSION(sc) != EAGLE_IV) { |
1102 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | 1826 | /* clear tx and rx mailboxes */ |
1103 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | 1827 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); |
1104 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | 1828 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); |
1829 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
1830 | } | ||
1831 | |||
1832 | ret = uea_wait(sc, 0, msecs_to_jiffies(1000)); | ||
1833 | if (ret < 0) | ||
1834 | return ret; | ||
1835 | |||
1836 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1837 | sc->cmv_dsc.e4.function = E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1); | ||
1838 | else | ||
1839 | sc->cmv_dsc.e1.function = E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY); | ||
1105 | 1840 | ||
1106 | msleep(1000); | ||
1107 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
1108 | /* demask interrupt */ | 1841 | /* demask interrupt */ |
1109 | sc->booting = 0; | 1842 | sc->booting = 0; |
1110 | 1843 | ||
1111 | /* start loading DSP */ | 1844 | /* start loading DSP */ |
1112 | sc->pageno = 0; | 1845 | sc->pageno = 0; |
1113 | sc->ovl = 0; | 1846 | sc->ovl = 0; |
1114 | schedule_work(&sc->task); | 1847 | queue_work(sc->work_q, &sc->task); |
1115 | 1848 | ||
1116 | /* wait for modem ready CMV */ | 1849 | /* wait for modem ready CMV */ |
1117 | ret = wait_cmv_ack(sc); | 1850 | ret = wait_cmv_ack(sc); |
@@ -1120,38 +1853,10 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1120 | 1853 | ||
1121 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); | 1854 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); |
1122 | 1855 | ||
1123 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | 1856 | ret = sc->send_cmvs(sc); |
1124 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
1125 | if (ret < 0) | 1857 | if (ret < 0) |
1126 | return ret; | 1858 | return ret; |
1127 | 1859 | ||
1128 | /* Dump firmware version */ | ||
1129 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
1130 | if (ret < 0) | ||
1131 | return ret; | ||
1132 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1133 | sc->stats.phy.firmid); | ||
1134 | |||
1135 | /* get options */ | ||
1136 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
1137 | if (ret < 0) | ||
1138 | return ret; | ||
1139 | |||
1140 | /* send options */ | ||
1141 | for (i = 0; i < len; i++) { | ||
1142 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
1143 | FW_GET_WORD(&cmvs[i].offset), | ||
1144 | FW_GET_LONG(&cmvs[i].data)); | ||
1145 | if (ret < 0) | ||
1146 | goto out; | ||
1147 | } | ||
1148 | /* Enter in R-ACT-REQ */ | ||
1149 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
1150 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1151 | uea_info(INS_TO_USBDEV(sc), "Modem started, " | ||
1152 | "waiting synchronization\n"); | ||
1153 | out: | ||
1154 | release_firmware(cmvs_fw); | ||
1155 | sc->reset = 0; | 1860 | sc->reset = 0; |
1156 | uea_leaves(INS_TO_USBDEV(sc)); | 1861 | uea_leaves(INS_TO_USBDEV(sc)); |
1157 | return ret; | 1862 | return ret; |
@@ -1174,12 +1879,10 @@ static int uea_kthread(void *data) | |||
1174 | if (ret < 0 || sc->reset) | 1879 | if (ret < 0 || sc->reset) |
1175 | ret = uea_start_reset(sc); | 1880 | ret = uea_start_reset(sc); |
1176 | if (!ret) | 1881 | if (!ret) |
1177 | ret = uea_stat(sc); | 1882 | ret = sc->stat(sc); |
1178 | if (ret != -EAGAIN) | 1883 | if (ret != -EAGAIN) |
1179 | msleep_interruptible(1000); | 1884 | uea_wait(sc, 0, msecs_to_jiffies(1000)); |
1180 | if (try_to_freeze()) | 1885 | try_to_freeze(); |
1181 | uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, " | ||
1182 | "please unplug/replug your modem\n"); | ||
1183 | } | 1886 | } |
1184 | uea_leaves(INS_TO_USBDEV(sc)); | 1887 | uea_leaves(INS_TO_USBDEV(sc)); |
1185 | return ret; | 1888 | return ret; |
@@ -1234,7 +1937,6 @@ static int load_XILINX_firmware(struct uea_softc *sc) | |||
1234 | if (ret < 0) | 1937 | if (ret < 0) |
1235 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | 1938 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); |
1236 | 1939 | ||
1237 | |||
1238 | err1: | 1940 | err1: |
1239 | release_firmware(fw_entry); | 1941 | release_firmware(fw_entry); |
1240 | err0: | 1942 | err0: |
@@ -1243,40 +1945,41 @@ err0: | |||
1243 | } | 1945 | } |
1244 | 1946 | ||
1245 | /* The modem send us an ack. First with check if it right */ | 1947 | /* The modem send us an ack. First with check if it right */ |
1246 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | 1948 | static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) |
1247 | { | 1949 | { |
1950 | struct cmv_dsc_e1 *dsc = &sc->cmv_dsc.e1; | ||
1951 | struct cmv_e1 *cmv = &intr->u.e1.s2.cmv; | ||
1952 | |||
1248 | uea_enters(INS_TO_USBDEV(sc)); | 1953 | uea_enters(INS_TO_USBDEV(sc)); |
1249 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | 1954 | if (le16_to_cpu(cmv->wPreamble) != E1_PREAMBLE) |
1250 | goto bad1; | 1955 | goto bad1; |
1251 | 1956 | ||
1252 | if (cmv->bDirection != MODEMTOHOST) | 1957 | if (cmv->bDirection != E1_MODEMTOHOST) |
1253 | goto bad1; | 1958 | goto bad1; |
1254 | 1959 | ||
1255 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | 1960 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to |
1256 | * the first MEMACESS cmv. Ignore it... | 1961 | * the first MEMACESS cmv. Ignore it... |
1257 | */ | 1962 | */ |
1258 | if (cmv->bFunction != sc->cmv_function) { | 1963 | if (cmv->bFunction != dsc->function) { |
1259 | if (UEA_CHIP_VERSION(sc) == ADI930 | 1964 | if (UEA_CHIP_VERSION(sc) == ADI930 |
1260 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | 1965 | && cmv->bFunction == E1_MAKEFUNCTION(2, 2)) { |
1261 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | 1966 | cmv->wIndex = cpu_to_le16(dsc->idx); |
1262 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | 1967 | put_unaligned(cpu_to_le32(dsc->address), &cmv->dwSymbolicAddress); |
1263 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | 1968 | cmv->wOffsetAddress = cpu_to_le16(dsc->offset); |
1264 | } | 1969 | } else |
1265 | else | ||
1266 | goto bad2; | 1970 | goto bad2; |
1267 | } | 1971 | } |
1268 | 1972 | ||
1269 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | 1973 | if (cmv->bFunction == E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY)) { |
1270 | wake_up_cmv_ack(sc); | 1974 | wake_up_cmv_ack(sc); |
1271 | uea_leaves(INS_TO_USBDEV(sc)); | 1975 | uea_leaves(INS_TO_USBDEV(sc)); |
1272 | return; | 1976 | return; |
1273 | } | 1977 | } |
1274 | 1978 | ||
1275 | /* in case of MEMACCESS */ | 1979 | /* in case of MEMACCESS */ |
1276 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | 1980 | if (le16_to_cpu(cmv->wIndex) != dsc->idx || |
1277 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | 1981 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != dsc->address || |
1278 | sc->cmv_address | 1982 | le16_to_cpu(cmv->wOffsetAddress) != dsc->offset) |
1279 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
1280 | goto bad2; | 1983 | goto bad2; |
1281 | 1984 | ||
1282 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | 1985 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); |
@@ -1289,8 +1992,8 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | |||
1289 | bad2: | 1992 | bad2: |
1290 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | 1993 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," |
1291 | "Function : %d, Subfunction : %d\n", | 1994 | "Function : %d, Subfunction : %d\n", |
1292 | FUNCTION_TYPE(cmv->bFunction), | 1995 | E1_FUNCTION_TYPE(cmv->bFunction), |
1293 | FUNCTION_SUBTYPE(cmv->bFunction)); | 1996 | E1_FUNCTION_SUBTYPE(cmv->bFunction)); |
1294 | uea_leaves(INS_TO_USBDEV(sc)); | 1997 | uea_leaves(INS_TO_USBDEV(sc)); |
1295 | return; | 1998 | return; |
1296 | 1999 | ||
@@ -1301,6 +2004,61 @@ bad1: | |||
1301 | uea_leaves(INS_TO_USBDEV(sc)); | 2004 | uea_leaves(INS_TO_USBDEV(sc)); |
1302 | } | 2005 | } |
1303 | 2006 | ||
2007 | /* The modem send us an ack. First with check if it right */ | ||
2008 | static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2009 | { | ||
2010 | struct cmv_dsc_e4 *dsc = &sc->cmv_dsc.e4; | ||
2011 | struct cmv_e4 *cmv = &intr->u.e4.s2.cmv; | ||
2012 | |||
2013 | uea_enters(INS_TO_USBDEV(sc)); | ||
2014 | uea_dbg(INS_TO_USBDEV(sc), "cmv %x %x %x %x %x %x\n", | ||
2015 | be16_to_cpu(cmv->wGroup), be16_to_cpu(cmv->wFunction), | ||
2016 | be16_to_cpu(cmv->wOffset), be16_to_cpu(cmv->wAddress), | ||
2017 | be32_to_cpu(cmv->dwData[0]), be32_to_cpu(cmv->dwData[1])); | ||
2018 | |||
2019 | if (be16_to_cpu(cmv->wFunction) != dsc->function) | ||
2020 | goto bad2; | ||
2021 | |||
2022 | if (be16_to_cpu(cmv->wFunction) == E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1)) { | ||
2023 | wake_up_cmv_ack(sc); | ||
2024 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2025 | return; | ||
2026 | } | ||
2027 | |||
2028 | /* in case of MEMACCESS */ | ||
2029 | if (be16_to_cpu(cmv->wOffset) != dsc->offset || | ||
2030 | be16_to_cpu(cmv->wGroup) != dsc->group || | ||
2031 | be16_to_cpu(cmv->wAddress) != dsc->address) | ||
2032 | goto bad2; | ||
2033 | |||
2034 | sc->data = be32_to_cpu(cmv->dwData[0]); | ||
2035 | sc->data1 = be32_to_cpu(cmv->dwData[1]); | ||
2036 | wake_up_cmv_ack(sc); | ||
2037 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2038 | return; | ||
2039 | |||
2040 | bad2: | ||
2041 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
2042 | "Function : %d, Subfunction : %d\n", | ||
2043 | E4_FUNCTION_TYPE(cmv->wFunction), | ||
2044 | E4_FUNCTION_SUBTYPE(cmv->wFunction)); | ||
2045 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2046 | return; | ||
2047 | } | ||
2048 | |||
2049 | static void uea_schedule_load_page_e1(struct uea_softc *sc, struct intr_pkt *intr) | ||
2050 | { | ||
2051 | sc->pageno = intr->e1_bSwapPageNo; | ||
2052 | sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4; | ||
2053 | queue_work(sc->work_q, &sc->task); | ||
2054 | } | ||
2055 | |||
2056 | static void uea_schedule_load_page_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2057 | { | ||
2058 | sc->pageno = intr->e4_bSwapPageNo; | ||
2059 | queue_work(sc->work_q, &sc->task); | ||
2060 | } | ||
2061 | |||
1304 | /* | 2062 | /* |
1305 | * interrupt handler | 2063 | * interrupt handler |
1306 | */ | 2064 | */ |
@@ -1308,11 +2066,13 @@ static void uea_intr(struct urb *urb) | |||
1308 | { | 2066 | { |
1309 | struct uea_softc *sc = urb->context; | 2067 | struct uea_softc *sc = urb->context; |
1310 | struct intr_pkt *intr = urb->transfer_buffer; | 2068 | struct intr_pkt *intr = urb->transfer_buffer; |
2069 | int status = urb->status; | ||
2070 | |||
1311 | uea_enters(INS_TO_USBDEV(sc)); | 2071 | uea_enters(INS_TO_USBDEV(sc)); |
1312 | 2072 | ||
1313 | if (unlikely(urb->status < 0)) { | 2073 | if (unlikely(status < 0)) { |
1314 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | 2074 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", |
1315 | urb->status); | 2075 | status); |
1316 | return; | 2076 | return; |
1317 | } | 2077 | } |
1318 | 2078 | ||
@@ -1324,13 +2084,11 @@ static void uea_intr(struct urb *urb) | |||
1324 | 2084 | ||
1325 | switch (le16_to_cpu(intr->wInterrupt)) { | 2085 | switch (le16_to_cpu(intr->wInterrupt)) { |
1326 | case INT_LOADSWAPPAGE: | 2086 | case INT_LOADSWAPPAGE: |
1327 | sc->pageno = intr->bSwapPageNo; | 2087 | sc->schedule_load_page(sc, intr); |
1328 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
1329 | schedule_work(&sc->task); | ||
1330 | break; | 2088 | break; |
1331 | 2089 | ||
1332 | case INT_INCOMINGCMV: | 2090 | case INT_INCOMINGCMV: |
1333 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | 2091 | sc->dispatch_cmv(sc, intr); |
1334 | break; | 2092 | break; |
1335 | 2093 | ||
1336 | default: | 2094 | default: |
@@ -1347,35 +2105,55 @@ resubmit: | |||
1347 | */ | 2105 | */ |
1348 | static int uea_boot(struct uea_softc *sc) | 2106 | static int uea_boot(struct uea_softc *sc) |
1349 | { | 2107 | { |
1350 | int ret; | 2108 | int ret, size; |
1351 | struct intr_pkt *intr; | 2109 | struct intr_pkt *intr; |
1352 | 2110 | ||
1353 | uea_enters(INS_TO_USBDEV(sc)); | 2111 | uea_enters(INS_TO_USBDEV(sc)); |
1354 | 2112 | ||
1355 | INIT_WORK(&sc->task, uea_load_page); | 2113 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2114 | size = E4_INTR_PKT_SIZE; | ||
2115 | sc->dispatch_cmv = uea_dispatch_cmv_e4; | ||
2116 | sc->schedule_load_page = uea_schedule_load_page_e4; | ||
2117 | sc->stat = uea_stat_e4; | ||
2118 | sc->send_cmvs = uea_send_cmvs_e4; | ||
2119 | INIT_WORK(&sc->task, uea_load_page_e4); | ||
2120 | } else { | ||
2121 | size = E1_INTR_PKT_SIZE; | ||
2122 | sc->dispatch_cmv = uea_dispatch_cmv_e1; | ||
2123 | sc->schedule_load_page = uea_schedule_load_page_e1; | ||
2124 | sc->stat = uea_stat_e1; | ||
2125 | sc->send_cmvs = uea_send_cmvs_e1; | ||
2126 | INIT_WORK(&sc->task, uea_load_page_e1); | ||
2127 | } | ||
2128 | |||
1356 | init_waitqueue_head(&sc->sync_q); | 2129 | init_waitqueue_head(&sc->sync_q); |
1357 | init_waitqueue_head(&sc->cmv_ack_wait); | 2130 | |
2131 | sc->work_q = create_workqueue("ueagle-dsp"); | ||
2132 | if (!sc->work_q) { | ||
2133 | uea_err(INS_TO_USBDEV(sc), "cannot allocate workqueue\n"); | ||
2134 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2135 | return -ENOMEM; | ||
2136 | } | ||
1358 | 2137 | ||
1359 | if (UEA_CHIP_VERSION(sc) == ADI930) | 2138 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1360 | load_XILINX_firmware(sc); | 2139 | load_XILINX_firmware(sc); |
1361 | 2140 | ||
1362 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | 2141 | intr = kmalloc(size, GFP_KERNEL); |
1363 | if (!intr) { | 2142 | if (!intr) { |
1364 | uea_err(INS_TO_USBDEV(sc), | 2143 | uea_err(INS_TO_USBDEV(sc), |
1365 | "cannot allocate interrupt package\n"); | 2144 | "cannot allocate interrupt package\n"); |
1366 | uea_leaves(INS_TO_USBDEV(sc)); | 2145 | goto err0; |
1367 | return -ENOMEM; | ||
1368 | } | 2146 | } |
1369 | 2147 | ||
1370 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | 2148 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); |
1371 | if (!sc->urb_int) { | 2149 | if (!sc->urb_int) { |
1372 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | 2150 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); |
1373 | goto err; | 2151 | goto err1; |
1374 | } | 2152 | } |
1375 | 2153 | ||
1376 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | 2154 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, |
1377 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | 2155 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), |
1378 | intr, INTR_PKT_SIZE, uea_intr, sc, | 2156 | intr, size, uea_intr, sc, |
1379 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | 2157 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. |
1380 | endpoint[0].desc.bInterval); | 2158 | endpoint[0].desc.bInterval); |
1381 | 2159 | ||
@@ -1383,7 +2161,7 @@ static int uea_boot(struct uea_softc *sc) | |||
1383 | if (ret < 0) { | 2161 | if (ret < 0) { |
1384 | uea_err(INS_TO_USBDEV(sc), | 2162 | uea_err(INS_TO_USBDEV(sc), |
1385 | "urb submition failed with error %d\n", ret); | 2163 | "urb submition failed with error %d\n", ret); |
1386 | goto err; | 2164 | goto err1; |
1387 | } | 2165 | } |
1388 | 2166 | ||
1389 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | 2167 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); |
@@ -1397,10 +2175,12 @@ static int uea_boot(struct uea_softc *sc) | |||
1397 | 2175 | ||
1398 | err2: | 2176 | err2: |
1399 | usb_kill_urb(sc->urb_int); | 2177 | usb_kill_urb(sc->urb_int); |
1400 | err: | 2178 | err1: |
1401 | usb_free_urb(sc->urb_int); | 2179 | usb_free_urb(sc->urb_int); |
1402 | sc->urb_int = NULL; | 2180 | sc->urb_int = NULL; |
1403 | kfree(intr); | 2181 | kfree(intr); |
2182 | err0: | ||
2183 | destroy_workqueue(sc->work_q); | ||
1404 | uea_leaves(INS_TO_USBDEV(sc)); | 2184 | uea_leaves(INS_TO_USBDEV(sc)); |
1405 | return -ENOMEM; | 2185 | return -ENOMEM; |
1406 | } | 2186 | } |
@@ -1415,15 +2195,15 @@ static void uea_stop(struct uea_softc *sc) | |||
1415 | ret = kthread_stop(sc->kthread); | 2195 | ret = kthread_stop(sc->kthread); |
1416 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | 2196 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); |
1417 | 2197 | ||
1418 | /* stop any pending boot process */ | ||
1419 | flush_scheduled_work(); | ||
1420 | |||
1421 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | 2198 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); |
1422 | 2199 | ||
1423 | usb_kill_urb(sc->urb_int); | 2200 | usb_kill_urb(sc->urb_int); |
1424 | kfree(sc->urb_int->transfer_buffer); | 2201 | kfree(sc->urb_int->transfer_buffer); |
1425 | usb_free_urb(sc->urb_int); | 2202 | usb_free_urb(sc->urb_int); |
1426 | 2203 | ||
2204 | /* stop any pending boot process, when no one can schedule work */ | ||
2205 | destroy_workqueue(sc->work_q); | ||
2206 | |||
1427 | if (sc->dsp_firm) | 2207 | if (sc->dsp_firm) |
1428 | release_firmware(sc->dsp_firm); | 2208 | release_firmware(sc->dsp_firm); |
1429 | uea_leaves(INS_TO_USBDEV(sc)); | 2209 | uea_leaves(INS_TO_USBDEV(sc)); |
@@ -1485,6 +2265,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1485 | char *buf) | 2265 | char *buf) |
1486 | { | 2266 | { |
1487 | int ret = -ENODEV; | 2267 | int ret = -ENODEV; |
2268 | int modem_state; | ||
1488 | struct uea_softc *sc; | 2269 | struct uea_softc *sc; |
1489 | 2270 | ||
1490 | mutex_lock(&uea_mutex); | 2271 | mutex_lock(&uea_mutex); |
@@ -1492,7 +2273,34 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1492 | if (!sc) | 2273 | if (!sc) |
1493 | goto out; | 2274 | goto out; |
1494 | 2275 | ||
1495 | switch (GET_STATUS(sc->stats.phy.state)) { | 2276 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2277 | switch (sc->stats.phy.state) { | ||
2278 | case 0x0: /* not yet synchronized */ | ||
2279 | case 0x1: | ||
2280 | case 0x3: | ||
2281 | case 0x4: | ||
2282 | modem_state = 0; | ||
2283 | break; | ||
2284 | case 0x5: /* initialization */ | ||
2285 | case 0x6: | ||
2286 | case 0x9: | ||
2287 | case 0xa: | ||
2288 | modem_state = 1; | ||
2289 | break; | ||
2290 | case 0x7: /* operational */ | ||
2291 | modem_state = 2; | ||
2292 | break; | ||
2293 | case 0x2: /* fail ... */ | ||
2294 | modem_state = 3; | ||
2295 | break; | ||
2296 | default: /* unknown */ | ||
2297 | modem_state = 4; | ||
2298 | break; | ||
2299 | } | ||
2300 | } else | ||
2301 | modem_state = GET_STATUS(sc->stats.phy.state); | ||
2302 | |||
2303 | switch (modem_state) { | ||
1496 | case 0: | 2304 | case 0: |
1497 | ret = sprintf(buf, "Modem is booting\n"); | 2305 | ret = sprintf(buf, "Modem is booting\n"); |
1498 | break; | 2306 | break; |
@@ -1502,9 +2310,12 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1502 | case 2: | 2310 | case 2: |
1503 | ret = sprintf(buf, "Modem is operational\n"); | 2311 | ret = sprintf(buf, "Modem is operational\n"); |
1504 | break; | 2312 | break; |
1505 | default: | 2313 | case 3: |
1506 | ret = sprintf(buf, "Modem synchronization failed\n"); | 2314 | ret = sprintf(buf, "Modem synchronization failed\n"); |
1507 | break; | 2315 | break; |
2316 | default: | ||
2317 | ret = sprintf(buf, "Modem state is unknown\n"); | ||
2318 | break; | ||
1508 | } | 2319 | } |
1509 | out: | 2320 | out: |
1510 | mutex_unlock(&uea_mutex); | 2321 | mutex_unlock(&uea_mutex); |
@@ -1518,18 +2329,26 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | |||
1518 | { | 2329 | { |
1519 | int ret = -ENODEV; | 2330 | int ret = -ENODEV; |
1520 | struct uea_softc *sc; | 2331 | struct uea_softc *sc; |
2332 | char *delin = "GOOD"; | ||
1521 | 2333 | ||
1522 | mutex_lock(&uea_mutex); | 2334 | mutex_lock(&uea_mutex); |
1523 | sc = dev_to_uea(dev); | 2335 | sc = dev_to_uea(dev); |
1524 | if (!sc) | 2336 | if (!sc) |
1525 | goto out; | 2337 | goto out; |
1526 | 2338 | ||
1527 | if (sc->stats.phy.flags & 0x0C00) | 2339 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
1528 | ret = sprintf(buf, "ERROR\n"); | 2340 | if (sc->stats.phy.flags & 0x4000) |
1529 | else if (sc->stats.phy.flags & 0x0030) | 2341 | delin = "RESET"; |
1530 | ret = sprintf(buf, "LOSS\n"); | 2342 | else if (sc->stats.phy.flags & 0x0001) |
1531 | else | 2343 | delin = "LOSS"; |
1532 | ret = sprintf(buf, "GOOD\n"); | 2344 | } else { |
2345 | if (sc->stats.phy.flags & 0x0C00) | ||
2346 | delin = "ERROR"; | ||
2347 | else if (sc->stats.phy.flags & 0x0030) | ||
2348 | delin = "LOSS"; | ||
2349 | } | ||
2350 | |||
2351 | ret = sprintf(buf, "%s\n", delin); | ||
1533 | out: | 2352 | out: |
1534 | mutex_unlock(&uea_mutex); | 2353 | mutex_unlock(&uea_mutex); |
1535 | return ret; | 2354 | return ret; |
@@ -1660,6 +2479,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1660 | struct usb_device *usb = interface_to_usbdev(intf); | 2479 | struct usb_device *usb = interface_to_usbdev(intf); |
1661 | struct uea_softc *sc; | 2480 | struct uea_softc *sc; |
1662 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | 2481 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; |
2482 | unsigned int alt; | ||
1663 | 2483 | ||
1664 | uea_enters(usb); | 2484 | uea_enters(usb); |
1665 | 2485 | ||
@@ -1694,22 +2514,29 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1694 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | 2514 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; |
1695 | sc->driver_info = id->driver_info; | 2515 | sc->driver_info = id->driver_info; |
1696 | 2516 | ||
1697 | /* ADI930 don't support iso */ | 2517 | /* first try to use module parameter */ |
1698 | if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) { | 2518 | if (annex[sc->modem_index] == 1) |
1699 | int i; | 2519 | sc->annex = ANNEXA; |
1700 | 2520 | else if (annex[sc->modem_index] == 2) | |
1701 | /* try set fastest alternate for inbound traffic interface */ | 2521 | sc->annex = ANNEXB; |
1702 | for (i = FASTEST_ISO_INTF; i > 0; i--) | 2522 | /* try to autodetect annex */ |
1703 | if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0) | 2523 | else if (sc->driver_info & AUTO_ANNEX_A) |
1704 | break; | 2524 | sc->annex = ANNEXA; |
2525 | else if (sc->driver_info & AUTO_ANNEX_B) | ||
2526 | sc->annex = ANNEXB; | ||
2527 | else | ||
2528 | sc->annex = (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)?ANNEXB:ANNEXA; | ||
1705 | 2529 | ||
1706 | if (i > 0) { | 2530 | alt = altsetting[sc->modem_index]; |
1707 | uea_dbg(usb, "set alternate %d for 2 interface\n", i); | 2531 | /* ADI930 don't support iso */ |
2532 | if (UEA_CHIP_VERSION(id) != ADI930 && alt > 0) { | ||
2533 | if (alt <= 8 && usb_set_interface(usb, UEA_DS_IFACE_NO, alt) == 0) { | ||
2534 | uea_dbg(usb, "set alternate %u for 2 interface\n", alt); | ||
1708 | uea_info(usb, "using iso mode\n"); | 2535 | uea_info(usb, "using iso mode\n"); |
1709 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; | 2536 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; |
1710 | } else { | 2537 | } else { |
1711 | uea_err(usb, "setting any alternate failed for " | 2538 | uea_err(usb, "setting alternate %u failed for " |
1712 | "2 interface, using bulk mode\n"); | 2539 | "2 interface, using bulk mode\n", alt); |
1713 | } | 2540 | } |
1714 | } | 2541 | } |
1715 | 2542 | ||
@@ -1719,9 +2546,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1719 | 2546 | ||
1720 | ret = uea_boot(sc); | 2547 | ret = uea_boot(sc); |
1721 | if (ret < 0) | 2548 | if (ret < 0) |
1722 | goto error; | 2549 | goto error_rm_grp; |
1723 | 2550 | ||
1724 | return 0; | 2551 | return 0; |
2552 | |||
2553 | error_rm_grp: | ||
2554 | sysfs_remove_group(&intf->dev.kobj, &attr_grp); | ||
1725 | error: | 2555 | error: |
1726 | kfree(sc); | 2556 | kfree(sc); |
1727 | return ret; | 2557 | return ret; |
@@ -1752,10 +2582,11 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1752 | struct usb_device *usb = interface_to_usbdev(intf); | 2582 | struct usb_device *usb = interface_to_usbdev(intf); |
1753 | 2583 | ||
1754 | uea_enters(usb); | 2584 | uea_enters(usb); |
1755 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n", | 2585 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", |
1756 | le16_to_cpu(usb->descriptor.idVendor), | 2586 | le16_to_cpu(usb->descriptor.idVendor), |
1757 | le16_to_cpu(usb->descriptor.idProduct), | 2587 | le16_to_cpu(usb->descriptor.idProduct), |
1758 | chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots"); | 2588 | le16_to_cpu(usb->descriptor.bcdDevice), |
2589 | chip_name[UEA_CHIP_VERSION(id)]); | ||
1759 | 2590 | ||
1760 | usb_reset_device(usb); | 2591 | usb_reset_device(usb); |
1761 | 2592 | ||
@@ -1788,24 +2619,40 @@ static void uea_disconnect(struct usb_interface *intf) | |||
1788 | * List of supported VID/PID | 2619 | * List of supported VID/PID |
1789 | */ | 2620 | */ |
1790 | static const struct usb_device_id uea_ids[] = { | 2621 | static const struct usb_device_id uea_ids[] = { |
2622 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
2623 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
2624 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2625 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
2626 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2627 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2628 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2629 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2630 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
2631 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
2632 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PREFIRM), .driver_info = EAGLE_IV | PREFIRM}, | ||
2633 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PSTFIRM), .driver_info = EAGLE_IV | PSTFIRM}, | ||
2634 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2635 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, | ||
2636 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2637 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, | ||
2638 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2639 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_A}, | ||
2640 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2641 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_B}, | ||
1791 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | 2642 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1792 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | 2643 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, |
1793 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2644 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1794 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2645 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_A}, |
1795 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | 2646 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1796 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | 2647 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_B}, |
1797 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1798 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1799 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
1800 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
1801 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2648 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1802 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2649 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1803 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2650 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1804 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2651 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1805 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2652 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1806 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2653 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1807 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2654 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1808 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2655 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1809 | {} | 2656 | {} |
1810 | }; | 2657 | }; |
1811 | 2658 | ||