aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/Kconfig10
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/aircable.c16
-rw-r--r--drivers/usb/serial/airprime.c10
-rw-r--r--drivers/usb/serial/ark3116.c61
-rw-r--r--drivers/usb/serial/belkin_sa.c78
-rw-r--r--drivers/usb/serial/cyberjack.c17
-rw-r--r--drivers/usb/serial/cypress_m8.c18
-rw-r--r--drivers/usb/serial/digi_acceleport.c99
-rw-r--r--drivers/usb/serial/empeg.c14
-rw-r--r--drivers/usb/serial/ftdi_sio.c119
-rw-r--r--drivers/usb/serial/garmin_gps.c47
-rw-r--r--drivers/usb/serial/generic.c97
-rw-r--r--drivers/usb/serial/io_edgeport.c40
-rw-r--r--drivers/usb/serial/io_fw_down3.h1460
-rw-r--r--drivers/usb/serial/io_ti.c124
-rw-r--r--drivers/usb/serial/io_usbvend.h12
-rw-r--r--drivers/usb/serial/ipaq.c14
-rw-r--r--drivers/usb/serial/ipw.c12
-rw-r--r--drivers/usb/serial/ir-usb.c154
-rw-r--r--drivers/usb/serial/keyspan.c456
-rw-r--r--drivers/usb/serial/keyspan.h74
-rw-r--r--drivers/usb/serial/keyspan_pda.c17
-rw-r--r--drivers/usb/serial/keyspan_usa67msg.h254
-rw-r--r--drivers/usb/serial/kl5kusb105.c22
-rw-r--r--drivers/usb/serial/kobil_sct.c26
-rw-r--r--drivers/usb/serial/mct_u232.c149
-rw-r--r--drivers/usb/serial/mct_u232.h15
-rw-r--r--drivers/usb/serial/mos7720.c43
-rw-r--r--drivers/usb/serial/mos7840.c106
-rw-r--r--drivers/usb/serial/navman.c7
-rw-r--r--drivers/usb/serial/omninet.c20
-rw-r--r--drivers/usb/serial/option.c34
-rw-r--r--drivers/usb/serial/oti6858.c1342
-rw-r--r--drivers/usb/serial/oti6858.h15
-rw-r--r--drivers/usb/serial/pl2303.c90
-rw-r--r--drivers/usb/serial/safe_serial.c6
-rw-r--r--drivers/usb/serial/sierra.c371
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c46
-rw-r--r--drivers/usb/serial/usb-serial.c35
-rw-r--r--drivers/usb/serial/visor.c64
-rw-r--r--drivers/usb/serial/whiteheat.c122
42 files changed, 3905 insertions, 1812 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 3efe67092f15..43d6db696f90 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -464,6 +464,16 @@ config USB_SERIAL_PL2303
464 To compile this driver as a module, choose M here: the 464 To compile this driver as a module, choose M here: the
465 module will be called pl2303. 465 module will be called pl2303.
466 466
467config USB_SERIAL_OTI6858
468 tristate "USB Ours Technology Inc. OTi-6858 USB To RS232 Bridge Controller (EXPERIMENTAL)"
469 depends on USB_SERIAL
470 help
471 Say Y here if you want to use the OTi-6858 single port USB to serial
472 converter device.
473
474 To compile this driver as a module, choose M here: the
475 module will be called oti6858.
476
467config USB_SERIAL_HP4X 477config USB_SERIAL_HP4X
468 tristate "USB HP4x Calculators support" 478 tristate "USB HP4x Calculators support"
469 depends on USB_SERIAL 479 depends on USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 61166ad450e6..07a976eca6b7 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o
40obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o 40obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o
41obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o 41obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
42obj-$(CONFIG_USB_SERIAL_OPTION) += option.o 42obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
43obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o
43obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o 44obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
44obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o 45obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
45obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o 46obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index fbc8c27d5d99..1cd29cd6bd00 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -411,12 +411,13 @@ static int aircable_write(struct usb_serial_port *port,
411static void aircable_write_bulk_callback(struct urb *urb) 411static void aircable_write_bulk_callback(struct urb *urb)
412{ 412{
413 struct usb_serial_port *port = urb->context; 413 struct usb_serial_port *port = urb->context;
414 int status = urb->status;
414 int result; 415 int result;
415 416
416 dbg("%s - urb->status: %d", __FUNCTION__ , urb->status); 417 dbg("%s - urb status: %d", __FUNCTION__ , status);
417 418
418 /* This has been taken from cypress_m8.c cypress_write_int_callback */ 419 /* This has been taken from cypress_m8.c cypress_write_int_callback */
419 switch (urb->status) { 420 switch (status) {
420 case 0: 421 case 0:
421 /* success */ 422 /* success */
422 break; 423 break;
@@ -425,14 +426,14 @@ static void aircable_write_bulk_callback(struct urb *urb)
425 case -ESHUTDOWN: 426 case -ESHUTDOWN:
426 /* this urb is terminated, clean up */ 427 /* this urb is terminated, clean up */
427 dbg("%s - urb shutting down with status: %d", 428 dbg("%s - urb shutting down with status: %d",
428 __FUNCTION__, urb->status); 429 __FUNCTION__, status);
429 port->write_urb_busy = 0; 430 port->write_urb_busy = 0;
430 return; 431 return;
431 default: 432 default:
432 /* error in the urb, so we have to resubmit it */ 433 /* error in the urb, so we have to resubmit it */
433 dbg("%s - Overflow in write", __FUNCTION__); 434 dbg("%s - Overflow in write", __FUNCTION__);
434 dbg("%s - nonzero write bulk status received: %d", 435 dbg("%s - nonzero write bulk status received: %d",
435 __FUNCTION__, urb->status); 436 __FUNCTION__, status);
436 port->write_urb->transfer_buffer_length = 1; 437 port->write_urb->transfer_buffer_length = 1;
437 port->write_urb->dev = port->serial->dev; 438 port->write_urb->dev = port->serial->dev;
438 result = usb_submit_urb(port->write_urb, GFP_ATOMIC); 439 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
@@ -457,16 +458,17 @@ static void aircable_read_bulk_callback(struct urb *urb)
457 unsigned long no_packages, remaining, package_length, i; 458 unsigned long no_packages, remaining, package_length, i;
458 int result, shift = 0; 459 int result, shift = 0;
459 unsigned char *temp; 460 unsigned char *temp;
461 int status = urb->status;
460 462
461 dbg("%s - port %d", __FUNCTION__, port->number); 463 dbg("%s - port %d", __FUNCTION__, port->number);
462 464
463 if (urb->status) { 465 if (status) {
464 dbg("%s - urb->status = %d", __FUNCTION__, urb->status); 466 dbg("%s - urb status = %d", __FUNCTION__, status);
465 if (!port->open_count) { 467 if (!port->open_count) {
466 dbg("%s - port is closed, exiting.", __FUNCTION__); 468 dbg("%s - port is closed, exiting.", __FUNCTION__);
467 return; 469 return;
468 } 470 }
469 if (urb->status == -EPROTO) { 471 if (status == -EPROTO) {
470 dbg("%s - caught -EPROTO, resubmitting the urb", 472 dbg("%s - caught -EPROTO, resubmitting the urb",
471 __FUNCTION__); 473 __FUNCTION__);
472 usb_fill_bulk_urb(port->read_urb, port->serial->dev, 474 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 39a498362594..cff6fd190a28 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -82,12 +82,13 @@ static void airprime_read_bulk_callback(struct urb *urb)
82 unsigned char *data = urb->transfer_buffer; 82 unsigned char *data = urb->transfer_buffer;
83 struct tty_struct *tty; 83 struct tty_struct *tty;
84 int result; 84 int result;
85 int status = urb->status;
85 86
86 dbg("%s - port %d", __FUNCTION__, port->number); 87 dbg("%s - port %d", __FUNCTION__, port->number);
87 88
88 if (urb->status) { 89 if (status) {
89 dbg("%s - nonzero read bulk status received: %d", 90 dbg("%s - nonzero read bulk status received: %d",
90 __FUNCTION__, urb->status); 91 __FUNCTION__, status);
91 return; 92 return;
92 } 93 }
93 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 94 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -109,6 +110,7 @@ static void airprime_write_bulk_callback(struct urb *urb)
109{ 110{
110 struct usb_serial_port *port = urb->context; 111 struct usb_serial_port *port = urb->context;
111 struct airprime_private *priv = usb_get_serial_port_data(port); 112 struct airprime_private *priv = usb_get_serial_port_data(port);
113 int status = urb->status;
112 unsigned long flags; 114 unsigned long flags;
113 115
114 dbg("%s - port %d", __FUNCTION__, port->number); 116 dbg("%s - port %d", __FUNCTION__, port->number);
@@ -116,9 +118,9 @@ static void airprime_write_bulk_callback(struct urb *urb)
116 /* free up the transfer buffer, as usb_free_urb() does not do this */ 118 /* free up the transfer buffer, as usb_free_urb() does not do this */
117 kfree (urb->transfer_buffer); 119 kfree (urb->transfer_buffer);
118 120
119 if (urb->status) 121 if (status)
120 dbg("%s - nonzero write bulk status received: %d", 122 dbg("%s - nonzero write bulk status received: %d",
121 __FUNCTION__, urb->status); 123 __FUNCTION__, status);
122 spin_lock_irqsave(&priv->lock, flags); 124 spin_lock_irqsave(&priv->lock, flags);
123 --priv->outstanding_urbs; 125 --priv->outstanding_urbs;
124 spin_unlock_irqrestore(&priv->lock, flags); 126 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index fe437125f14b..c9fd486c1c7d 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -172,7 +172,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
172 172
173 dbg("%s - port %d", __FUNCTION__, port->number); 173 dbg("%s - port %d", __FUNCTION__, port->number);
174 174
175 if ((!port->tty) || (!port->tty->termios)) { 175 if (!port->tty || !port->tty->termios) {
176 dbg("%s - no tty structures", __FUNCTION__); 176 dbg("%s - no tty structures", __FUNCTION__);
177 return; 177 return;
178 } 178 }
@@ -188,16 +188,6 @@ static void ark3116_set_termios(struct usb_serial_port *port,
188 188
189 cflag = port->tty->termios->c_cflag; 189 cflag = port->tty->termios->c_cflag;
190 190
191 /* check that they really want us to change something: */
192 if (old_termios) {
193 if ((cflag == old_termios->c_cflag) &&
194 (RELEVANT_IFLAG(port->tty->termios->c_iflag) ==
195 RELEVANT_IFLAG(old_termios->c_iflag))) {
196 dbg("%s - nothing to change...", __FUNCTION__);
197 return;
198 }
199 }
200
201 buf = kmalloc(1, GFP_KERNEL); 191 buf = kmalloc(1, GFP_KERNEL);
202 if (!buf) { 192 if (!buf) {
203 dbg("error kmalloc"); 193 dbg("error kmalloc");
@@ -220,7 +210,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
220 dbg("setting CS7"); 210 dbg("setting CS7");
221 break; 211 break;
222 default: 212 default:
223 err("CSIZE was set but not CS5-CS8, using CS8!"); 213 dbg("CSIZE was set but not CS5-CS8, using CS8!");
224 /* fall through */ 214 /* fall through */
225 case CS8: 215 case CS8:
226 config |= 0x03; 216 config |= 0x03;
@@ -251,38 +241,33 @@ static void ark3116_set_termios(struct usb_serial_port *port,
251 } 241 }
252 242
253 /* set baudrate */ 243 /* set baudrate */
254 baud = 0; 244 baud = tty_get_baud_rate(port->tty);
255 switch (cflag & CBAUD) { 245
256 case B0: 246 switch (baud) {
257 err("can't set 0 baud, using 9600 instead"); 247 case 75:
248 case 150:
249 case 300:
250 case 600:
251 case 1200:
252 case 1800:
253 case 2400:
254 case 4800:
255 case 9600:
256 case 19200:
257 case 38400:
258 case 57600:
259 case 115200:
260 case 230400:
261 case 460800:
258 break; 262 break;
259 case B75: baud = 75; break; 263 /* set 9600 as default (if given baudrate is invalid for example) */
260 case B150: baud = 150; break;
261 case B300: baud = 300; break;
262 case B600: baud = 600; break;
263 case B1200: baud = 1200; break;
264 case B1800: baud = 1800; break;
265 case B2400: baud = 2400; break;
266 case B4800: baud = 4800; break;
267 case B9600: baud = 9600; break;
268 case B19200: baud = 19200; break;
269 case B38400: baud = 38400; break;
270 case B57600: baud = 57600; break;
271 case B115200: baud = 115200; break;
272 case B230400: baud = 230400; break;
273 case B460800: baud = 460800; break;
274 default: 264 default:
275 dbg("does not support the baudrate requested (fix it)"); 265 baud = 9600;
276 break;
277 } 266 }
278 267
279 /* set 9600 as default (if given baudrate is invalid for example) */
280 if (baud == 0)
281 baud = 9600;
282
283 /* 268 /*
284 * found by try'n'error, be careful, maybe there are other options 269 * found by try'n'error, be careful, maybe there are other options
285 * for multiplicator etc! 270 * for multiplicator etc! (3.5 for example)
286 */ 271 */
287 if (baud == 460800) 272 if (baud == 460800)
288 /* strange, for 460800 the formula is wrong 273 /* strange, for 460800 the formula is wrong
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 3b800d277c4b..e67ce25f7512 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -255,9 +255,10 @@ static void belkin_sa_read_int_callback (struct urb *urb)
255 struct belkin_sa_private *priv; 255 struct belkin_sa_private *priv;
256 unsigned char *data = urb->transfer_buffer; 256 unsigned char *data = urb->transfer_buffer;
257 int retval; 257 int retval;
258 int status = urb->status;
258 unsigned long flags; 259 unsigned long flags;
259 260
260 switch (urb->status) { 261 switch (status) {
261 case 0: 262 case 0:
262 /* success */ 263 /* success */
263 break; 264 break;
@@ -265,10 +266,12 @@ static void belkin_sa_read_int_callback (struct urb *urb)
265 case -ENOENT: 266 case -ENOENT:
266 case -ESHUTDOWN: 267 case -ESHUTDOWN:
267 /* this urb is terminated, clean up */ 268 /* this urb is terminated, clean up */
268 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 269 dbg("%s - urb shutting down with status: %d",
270 __FUNCTION__, status);
269 return; 271 return;
270 default: 272 default:
271 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 273 dbg("%s - nonzero urb status received: %d",
274 __FUNCTION__, status);
272 goto exit; 275 goto exit;
273 } 276 }
274 277
@@ -346,6 +349,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
346 unsigned long flags; 349 unsigned long flags;
347 unsigned long control_state; 350 unsigned long control_state;
348 int bad_flow_control; 351 int bad_flow_control;
352 speed_t baud;
349 353
350 if ((!port->tty) || (!port->tty->termios)) { 354 if ((!port->tty) || (!port->tty->termios)) {
351 dbg ("%s - no tty or termios structure", __FUNCTION__); 355 dbg ("%s - no tty or termios structure", __FUNCTION__);
@@ -361,16 +365,8 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
361 bad_flow_control = priv->bad_flow_control; 365 bad_flow_control = priv->bad_flow_control;
362 spin_unlock_irqrestore(&priv->lock, flags); 366 spin_unlock_irqrestore(&priv->lock, flags);
363 367
364 /* check that they really want us to change something */ 368 old_iflag = old_termios->c_iflag;
365 if (old_termios) { 369 old_cflag = old_termios->c_cflag;
366 if ((cflag == old_termios->c_cflag) &&
367 (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
368 dbg("%s - nothing to change...", __FUNCTION__);
369 return;
370 }
371 old_iflag = old_termios->c_iflag;
372 old_cflag = old_termios->c_cflag;
373 }
374 370
375 /* Set the baud rate */ 371 /* Set the baud rate */
376 if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { 372 if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
@@ -384,38 +380,30 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
384 if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0) 380 if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
385 err("Set RTS error"); 381 err("Set RTS error");
386 } 382 }
383 }
387 384
388 switch(cflag & CBAUD) { 385 baud = tty_get_baud_rate(port->tty);
389 case B0: /* handled below */ break; 386 urb_value = BELKIN_SA_BAUD(baud);
390 case B300: urb_value = BELKIN_SA_BAUD(300); break; 387 /* Clip to maximum speed */
391 case B600: urb_value = BELKIN_SA_BAUD(600); break; 388 if (urb_value == 0)
392 case B1200: urb_value = BELKIN_SA_BAUD(1200); break; 389 urb_value = 1;
393 case B2400: urb_value = BELKIN_SA_BAUD(2400); break; 390 /* Turn it back into a resulting real baud rate */
394 case B4800: urb_value = BELKIN_SA_BAUD(4800); break; 391 baud = BELKIN_SA_BAUD(urb_value);
395 case B9600: urb_value = BELKIN_SA_BAUD(9600); break; 392 /* FIXME: Once the tty updates are done then push this back to the tty */
396 case B19200: urb_value = BELKIN_SA_BAUD(19200); break; 393
397 case B38400: urb_value = BELKIN_SA_BAUD(38400); break; 394 if ((cflag & CBAUD) != B0 ) {
398 case B57600: urb_value = BELKIN_SA_BAUD(57600); break; 395 if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
399 case B115200: urb_value = BELKIN_SA_BAUD(115200); break; 396 err("Set baudrate error");
400 case B230400: urb_value = BELKIN_SA_BAUD(230400); break; 397 } else {
401 default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600"); 398 /* Disable flow control */
402 urb_value = BELKIN_SA_BAUD(9600); break; 399 if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
403 } 400 err("Disable flowcontrol error");
404 if ((cflag & CBAUD) != B0 ) { 401 /* Drop RTS and DTR */
405 if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0) 402 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
406 err("Set baudrate error"); 403 if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
407 } else { 404 err("DTR LOW error");
408 /* Disable flow control */ 405 if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
409 if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0) 406 err("RTS LOW error");
410 err("Disable flowcontrol error");
411
412 /* Drop RTS and DTR */
413 control_state &= ~(TIOCM_DTR | TIOCM_RTS);
414 if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
415 err("DTR LOW error");
416 if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
417 err("RTS LOW error");
418 }
419 } 407 }
420 408
421 /* set the parity */ 409 /* set the parity */
@@ -435,7 +423,7 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
435 case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break; 423 case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
436 case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break; 424 case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
437 case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break; 425 case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
438 default: err("CSIZE was not CS5-CS8, using default of 8"); 426 default: dbg("CSIZE was not CS5-CS8, using default of 8");
439 urb_value = BELKIN_SA_DATA_BITS(8); 427 urb_value = BELKIN_SA_DATA_BITS(8);
440 break; 428 break;
441 } 429 }
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 4167753ed31f..4353df92487f 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -305,12 +305,13 @@ static void cyberjack_read_int_callback( struct urb *urb )
305 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 305 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
306 struct cyberjack_private *priv = usb_get_serial_port_data(port); 306 struct cyberjack_private *priv = usb_get_serial_port_data(port);
307 unsigned char *data = urb->transfer_buffer; 307 unsigned char *data = urb->transfer_buffer;
308 int status = urb->status;
308 int result; 309 int result;
309 310
310 dbg("%s - port %d", __FUNCTION__, port->number); 311 dbg("%s - port %d", __FUNCTION__, port->number);
311 312
312 /* the urb might have been killed. */ 313 /* the urb might have been killed. */
313 if (urb->status) 314 if (status)
314 return; 315 return;
315 316
316 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 317 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -365,12 +366,14 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
365 unsigned char *data = urb->transfer_buffer; 366 unsigned char *data = urb->transfer_buffer;
366 short todo; 367 short todo;
367 int result; 368 int result;
369 int status = urb->status;
368 370
369 dbg("%s - port %d", __FUNCTION__, port->number); 371 dbg("%s - port %d", __FUNCTION__, port->number);
370 372
371 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 373 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
372 if (urb->status) { 374 if (status) {
373 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 375 dbg("%s - nonzero read bulk status received: %d",
376 __FUNCTION__, status);
374 return; 377 return;
375 } 378 }
376 379
@@ -411,12 +414,14 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
411{ 414{
412 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 415 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
413 struct cyberjack_private *priv = usb_get_serial_port_data(port); 416 struct cyberjack_private *priv = usb_get_serial_port_data(port);
417 int status = urb->status;
414 418
415 dbg("%s - port %d", __FUNCTION__, port->number); 419 dbg("%s - port %d", __FUNCTION__, port->number);
416 420
417 port->write_urb_busy = 0; 421 port->write_urb_busy = 0;
418 if (urb->status) { 422 if (status) {
419 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 423 dbg("%s - nonzero write bulk status received: %d",
424 __FUNCTION__, status);
420 return; 425 return;
421 } 426 }
422 427
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 57b8e27285fc..163386336a5d 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1275,10 +1275,11 @@ static void cypress_read_int_callback(struct urb *urb)
1275 int bytes = 0; 1275 int bytes = 0;
1276 int result; 1276 int result;
1277 int i = 0; 1277 int i = 0;
1278 int status = urb->status;
1278 1279
1279 dbg("%s - port %d", __FUNCTION__, port->number); 1280 dbg("%s - port %d", __FUNCTION__, port->number);
1280 1281
1281 switch (urb->status) { 1282 switch (status) {
1282 case 0: /* success */ 1283 case 0: /* success */
1283 break; 1284 break;
1284 case -ECONNRESET: 1285 case -ECONNRESET:
@@ -1292,7 +1293,7 @@ static void cypress_read_int_callback(struct urb *urb)
1292 default: 1293 default:
1293 /* something ugly is going on... */ 1294 /* something ugly is going on... */
1294 dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n", 1295 dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
1295 __FUNCTION__,urb->status); 1296 __FUNCTION__, status);
1296 cypress_set_dead(port); 1297 cypress_set_dead(port);
1297 return; 1298 return;
1298 } 1299 }
@@ -1419,10 +1420,11 @@ static void cypress_write_int_callback(struct urb *urb)
1419 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1420 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1420 struct cypress_private *priv = usb_get_serial_port_data(port); 1421 struct cypress_private *priv = usb_get_serial_port_data(port);
1421 int result; 1422 int result;
1423 int status = urb->status;
1422 1424
1423 dbg("%s - port %d", __FUNCTION__, port->number); 1425 dbg("%s - port %d", __FUNCTION__, port->number);
1424 1426
1425 switch (urb->status) { 1427 switch (status) {
1426 case 0: 1428 case 0:
1427 /* success */ 1429 /* success */
1428 break; 1430 break;
@@ -1430,7 +1432,8 @@ static void cypress_write_int_callback(struct urb *urb)
1430 case -ENOENT: 1432 case -ENOENT:
1431 case -ESHUTDOWN: 1433 case -ESHUTDOWN:
1432 /* this urb is terminated, clean up */ 1434 /* this urb is terminated, clean up */
1433 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 1435 dbg("%s - urb shutting down with status: %d",
1436 __FUNCTION__, status);
1434 priv->write_urb_in_use = 0; 1437 priv->write_urb_in_use = 0;
1435 return; 1438 return;
1436 case -EPIPE: /* no break needed; clear halt and resubmit */ 1439 case -EPIPE: /* no break needed; clear halt and resubmit */
@@ -1438,7 +1441,8 @@ static void cypress_write_int_callback(struct urb *urb)
1438 break; 1441 break;
1439 usb_clear_halt(port->serial->dev, 0x02); 1442 usb_clear_halt(port->serial->dev, 0x02);
1440 /* error in the urb, so we have to resubmit it */ 1443 /* error in the urb, so we have to resubmit it */
1441 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 1444 dbg("%s - nonzero write bulk status received: %d",
1445 __FUNCTION__, status);
1442 port->interrupt_out_urb->transfer_buffer_length = 1; 1446 port->interrupt_out_urb->transfer_buffer_length = 1;
1443 port->interrupt_out_urb->dev = port->serial->dev; 1447 port->interrupt_out_urb->dev = port->serial->dev;
1444 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 1448 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
@@ -1450,7 +1454,7 @@ static void cypress_write_int_callback(struct urb *urb)
1450 break; 1454 break;
1451 default: 1455 default:
1452 dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n", 1456 dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
1453 __FUNCTION__,urb->status); 1457 __FUNCTION__, status);
1454 cypress_set_dead(port); 1458 cypress_set_dead(port);
1455 break; 1459 break;
1456 } 1460 }
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index d78692c01cfa..976f54ec26e6 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -416,9 +416,6 @@ struct digi_port {
416 int dp_port_num; 416 int dp_port_num;
417 int dp_out_buf_len; 417 int dp_out_buf_len;
418 unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE]; 418 unsigned char dp_out_buf[DIGI_OUT_BUF_SIZE];
419 int dp_in_buf_len;
420 unsigned char dp_in_buf[DIGI_IN_BUF_SIZE];
421 unsigned char dp_in_flag_buf[DIGI_IN_BUF_SIZE];
422 int dp_write_urb_in_use; 419 int dp_write_urb_in_use;
423 unsigned int dp_modem_signals; 420 unsigned int dp_modem_signals;
424 wait_queue_head_t dp_modem_change_wait; 421 wait_queue_head_t dp_modem_change_wait;
@@ -920,7 +917,6 @@ dbg( "digi_rx_throttle: TOP: port=%d", priv->dp_port_num );
920 spin_lock_irqsave( &priv->dp_port_lock, flags ); 917 spin_lock_irqsave( &priv->dp_port_lock, flags );
921 priv->dp_throttled = 1; 918 priv->dp_throttled = 1;
922 priv->dp_throttle_restart = 0; 919 priv->dp_throttle_restart = 0;
923 priv->dp_in_buf_len = 0;
924 spin_unlock_irqrestore( &priv->dp_port_lock, flags ); 920 spin_unlock_irqrestore( &priv->dp_port_lock, flags );
925 921
926} 922}
@@ -930,23 +926,16 @@ static void digi_rx_unthrottle( struct usb_serial_port *port )
930{ 926{
931 927
932 int ret = 0; 928 int ret = 0;
933 int len;
934 unsigned long flags; 929 unsigned long flags;
935 struct digi_port *priv = usb_get_serial_port_data(port); 930 struct digi_port *priv = usb_get_serial_port_data(port);
936 struct tty_struct *tty = port->tty;
937
938 931
939dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); 932dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
940 933
941 spin_lock_irqsave( &priv->dp_port_lock, flags ); 934 spin_lock_irqsave( &priv->dp_port_lock, flags );
942 935
943 /* send any buffered chars from throttle time on to tty subsystem */ 936 /* turn throttle off */
944 937 priv->dp_throttled = 0;
945 len = tty_buffer_request_room(tty, priv->dp_in_buf_len); 938 priv->dp_throttle_restart = 0;
946 if( len > 0 ) {
947 tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len);
948 tty_flip_buffer_push( tty );
949 }
950 939
951 /* restart read chain */ 940 /* restart read chain */
952 if( priv->dp_throttle_restart ) { 941 if( priv->dp_throttle_restart ) {
@@ -954,11 +943,6 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
954 ret = usb_submit_urb( port->read_urb, GFP_ATOMIC ); 943 ret = usb_submit_urb( port->read_urb, GFP_ATOMIC );
955 } 944 }
956 945
957 /* turn throttle off */
958 priv->dp_throttled = 0;
959 priv->dp_in_buf_len = 0;
960 priv->dp_throttle_restart = 0;
961
962 spin_unlock_irqrestore( &priv->dp_port_lock, flags ); 946 spin_unlock_irqrestore( &priv->dp_port_lock, flags );
963 947
964 if( ret ) { 948 if( ret ) {
@@ -1340,19 +1324,21 @@ static void digi_write_bulk_callback( struct urb *urb )
1340 struct digi_port *priv; 1324 struct digi_port *priv;
1341 struct digi_serial *serial_priv; 1325 struct digi_serial *serial_priv;
1342 int ret = 0; 1326 int ret = 0;
1327 int status = urb->status;
1343 1328
1344 1329
1345dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); 1330 dbg("digi_write_bulk_callback: TOP, urb status=%d", status);
1346 1331
1347 /* port and serial sanity check */ 1332 /* port and serial sanity check */
1348 if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { 1333 if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) {
1349 err("%s: port or port->private is NULL, status=%d", __FUNCTION__, 1334 err("%s: port or port->private is NULL, status=%d",
1350 urb->status ); 1335 __FUNCTION__, status);
1351 return; 1336 return;
1352 } 1337 }
1353 serial = port->serial; 1338 serial = port->serial;
1354 if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) { 1339 if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) {
1355 err("%s: serial or serial->private is NULL, status=%d", __FUNCTION__, urb->status ); 1340 err("%s: serial or serial->private is NULL, status=%d",
1341 __FUNCTION__, status);
1356 return; 1342 return;
1357 } 1343 }
1358 1344
@@ -1687,7 +1673,6 @@ dbg( "digi_startup: TOP" );
1687 spin_lock_init( &priv->dp_port_lock ); 1673 spin_lock_init( &priv->dp_port_lock );
1688 priv->dp_port_num = i; 1674 priv->dp_port_num = i;
1689 priv->dp_out_buf_len = 0; 1675 priv->dp_out_buf_len = 0;
1690 priv->dp_in_buf_len = 0;
1691 priv->dp_write_urb_in_use = 0; 1676 priv->dp_write_urb_in_use = 0;
1692 priv->dp_modem_signals = 0; 1677 priv->dp_modem_signals = 0;
1693 init_waitqueue_head( &priv->dp_modem_change_wait ); 1678 init_waitqueue_head( &priv->dp_modem_change_wait );
@@ -1757,25 +1742,28 @@ static void digi_read_bulk_callback( struct urb *urb )
1757 struct digi_port *priv; 1742 struct digi_port *priv;
1758 struct digi_serial *serial_priv; 1743 struct digi_serial *serial_priv;
1759 int ret; 1744 int ret;
1745 int status = urb->status;
1760 1746
1761 1747
1762dbg( "digi_read_bulk_callback: TOP" ); 1748dbg( "digi_read_bulk_callback: TOP" );
1763 1749
1764 /* port sanity check, do not resubmit if port is not valid */ 1750 /* port sanity check, do not resubmit if port is not valid */
1765 if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { 1751 if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) {
1766 err("%s: port or port->private is NULL, status=%d", __FUNCTION__, 1752 err("%s: port or port->private is NULL, status=%d",
1767 urb->status ); 1753 __FUNCTION__, status);
1768 return; 1754 return;
1769 } 1755 }
1770 if( port->serial == NULL 1756 if( port->serial == NULL
1771 || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) { 1757 || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) {
1772 err("%s: serial is bad or serial->private is NULL, status=%d", __FUNCTION__, urb->status ); 1758 err("%s: serial is bad or serial->private is NULL, status=%d",
1759 __FUNCTION__, status);
1773 return; 1760 return;
1774 } 1761 }
1775 1762
1776 /* do not resubmit urb if it has any status error */ 1763 /* do not resubmit urb if it has any status error */
1777 if( urb->status ) { 1764 if (status) {
1778 err("%s: nonzero read bulk status: status=%d, port=%d", __FUNCTION__, urb->status, priv->dp_port_num ); 1765 err("%s: nonzero read bulk status: status=%d, port=%d",
1766 __FUNCTION__, status, priv->dp_port_num);
1779 return; 1767 return;
1780 } 1768 }
1781 1769
@@ -1816,10 +1804,11 @@ static int digi_read_inb_callback( struct urb *urb )
1816 struct digi_port *priv = usb_get_serial_port_data(port); 1804 struct digi_port *priv = usb_get_serial_port_data(port);
1817 int opcode = ((unsigned char *)urb->transfer_buffer)[0]; 1805 int opcode = ((unsigned char *)urb->transfer_buffer)[0];
1818 int len = ((unsigned char *)urb->transfer_buffer)[1]; 1806 int len = ((unsigned char *)urb->transfer_buffer)[1];
1819 int status = ((unsigned char *)urb->transfer_buffer)[2]; 1807 int port_status = ((unsigned char *)urb->transfer_buffer)[2];
1820 unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3; 1808 unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3;
1821 int flag,throttled; 1809 int flag,throttled;
1822 int i; 1810 int i;
1811 int status = urb->status;
1823 1812
1824 /* do not process callbacks on closed ports */ 1813 /* do not process callbacks on closed ports */
1825 /* but do continue the read chain */ 1814 /* but do continue the read chain */
@@ -1828,7 +1817,10 @@ static int digi_read_inb_callback( struct urb *urb )
1828 1817
1829 /* short/multiple packet check */ 1818 /* short/multiple packet check */
1830 if( urb->actual_length != len + 2 ) { 1819 if( urb->actual_length != len + 2 ) {
1831 err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, port=%d, opcode=%d, len=%d, actual_length=%d, status=%d", __FUNCTION__, urb->status, priv->dp_port_num, opcode, len, urb->actual_length, status ); 1820 err("%s: INCOMPLETE OR MULTIPLE PACKET, urb status=%d, "
1821 "port=%d, opcode=%d, len=%d, actual_length=%d, "
1822 "port_status=%d", __FUNCTION__, status, priv->dp_port_num,
1823 opcode, len, urb->actual_length, port_status);
1832 return( -1 ); 1824 return( -1 );
1833 } 1825 }
1834 1826
@@ -1843,52 +1835,37 @@ static int digi_read_inb_callback( struct urb *urb )
1843 /* receive data */ 1835 /* receive data */
1844 if( opcode == DIGI_CMD_RECEIVE_DATA ) { 1836 if( opcode == DIGI_CMD_RECEIVE_DATA ) {
1845 1837
1846 /* get flag from status */ 1838 /* get flag from port_status */
1847 flag = 0; 1839 flag = 0;
1848 1840
1849 /* overrun is special, not associated with a char */ 1841 /* overrun is special, not associated with a char */
1850 if( status & DIGI_OVERRUN_ERROR ) { 1842 if (port_status & DIGI_OVERRUN_ERROR) {
1851 tty_insert_flip_char( tty, 0, TTY_OVERRUN ); 1843 tty_insert_flip_char( tty, 0, TTY_OVERRUN );
1852 } 1844 }
1853 1845
1854 /* break takes precedence over parity, */ 1846 /* break takes precedence over parity, */
1855 /* which takes precedence over framing errors */ 1847 /* which takes precedence over framing errors */
1856 if( status & DIGI_BREAK_ERROR ) { 1848 if (port_status & DIGI_BREAK_ERROR) {
1857 flag = TTY_BREAK; 1849 flag = TTY_BREAK;
1858 } else if( status & DIGI_PARITY_ERROR ) { 1850 } else if (port_status & DIGI_PARITY_ERROR) {
1859 flag = TTY_PARITY; 1851 flag = TTY_PARITY;
1860 } else if( status & DIGI_FRAMING_ERROR ) { 1852 } else if (port_status & DIGI_FRAMING_ERROR) {
1861 flag = TTY_FRAME; 1853 flag = TTY_FRAME;
1862 } 1854 }
1863 1855
1864 /* data length is len-1 (one byte of len is status) */ 1856 /* data length is len-1 (one byte of len is port_status) */
1865 --len; 1857 --len;
1866 1858
1867 if( throttled ) { 1859 len = tty_buffer_request_room(tty, len);
1868 1860 if( len > 0 ) {
1869 len = min( len, 1861 /* Hot path */
1870 DIGI_IN_BUF_SIZE - priv->dp_in_buf_len ); 1862 if(flag == TTY_NORMAL)
1871 1863 tty_insert_flip_string(tty, data, len);
1872 if( len > 0 ) { 1864 else {
1873 memcpy( priv->dp_in_buf + priv->dp_in_buf_len, 1865 for(i = 0; i < len; i++)
1874 data, len ); 1866 tty_insert_flip_char(tty, data[i], flag);
1875 memset( priv->dp_in_flag_buf
1876 + priv->dp_in_buf_len, flag, len );
1877 priv->dp_in_buf_len += len;
1878 }
1879
1880 } else {
1881 len = tty_buffer_request_room(tty, len);
1882 if( len > 0 ) {
1883 /* Hot path */
1884 if(flag == TTY_NORMAL)
1885 tty_insert_flip_string(tty, data, len);
1886 else {
1887 for(i = 0; i < len; i++)
1888 tty_insert_flip_char(tty, data[i], flag);
1889 }
1890 tty_flip_buffer_push( tty );
1891 } 1867 }
1868 tty_flip_buffer_push( tty );
1892 } 1869 }
1893 } 1870 }
1894 1871
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 4703c8f85383..050fcc996f56 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -326,12 +326,14 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port)
326 326
327static void empeg_write_bulk_callback (struct urb *urb) 327static void empeg_write_bulk_callback (struct urb *urb)
328{ 328{
329 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 329 struct usb_serial_port *port = urb->context;
330 int status = urb->status;
330 331
331 dbg("%s - port %d", __FUNCTION__, port->number); 332 dbg("%s - port %d", __FUNCTION__, port->number);
332 333
333 if (urb->status) { 334 if (status) {
334 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 335 dbg("%s - nonzero write bulk status received: %d",
336 __FUNCTION__, status);
335 return; 337 return;
336 } 338 }
337 339
@@ -345,11 +347,13 @@ static void empeg_read_bulk_callback (struct urb *urb)
345 struct tty_struct *tty; 347 struct tty_struct *tty;
346 unsigned char *data = urb->transfer_buffer; 348 unsigned char *data = urb->transfer_buffer;
347 int result; 349 int result;
350 int status = urb->status;
348 351
349 dbg("%s - port %d", __FUNCTION__, port->number); 352 dbg("%s - port %d", __FUNCTION__, port->number);
350 353
351 if (urb->status) { 354 if (status) {
352 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 355 dbg("%s - nonzero read bulk status received: %d",
356 __FUNCTION__, status);
353 return; 357 return;
354 } 358 }
355 359
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index da1c6f7f82b8..7b1673a44077 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -271,26 +271,58 @@ static int debug;
271static __u16 vendor = FTDI_VID; 271static __u16 vendor = FTDI_VID;
272static __u16 product; 272static __u16 product;
273 273
274struct ftdi_private {
275 ftdi_chip_type_t chip_type;
276 /* type of the device, either SIO or FT8U232AM */
277 int baud_base; /* baud base clock for divisor setting */
278 int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
279 __u16 last_set_data_urb_value ;
280 /* the last data state set - needed for doing a break */
281 int write_offset; /* This is the offset in the usb data block to write the serial data -
282 * it is different between devices
283 */
284 int flags; /* some ASYNC_xxxx flags are supported */
285 unsigned long last_dtr_rts; /* saved modem control outputs */
286 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
287 char prev_status, diff_status; /* Used for TIOCMIWAIT */
288 __u8 rx_flags; /* receive state flags (throttling) */
289 spinlock_t rx_lock; /* spinlock for receive state */
290 struct delayed_work rx_work;
291 struct usb_serial_port *port;
292 int rx_processed;
293 unsigned long rx_bytes;
294
295 __u16 interface; /* FT2232C port interface (0 for FT232/245) */
296
297 int force_baud; /* if non-zero, force the baud rate to this value */
298 int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
299
300 spinlock_t tx_lock; /* spinlock for transmit state */
301 unsigned long tx_bytes;
302 unsigned long tx_outstanding_bytes;
303 unsigned long tx_outstanding_urbs;
304};
305
274/* struct ftdi_sio_quirk is used by devices requiring special attention. */ 306/* struct ftdi_sio_quirk is used by devices requiring special attention. */
275struct ftdi_sio_quirk { 307struct ftdi_sio_quirk {
276 int (*probe)(struct usb_serial *); 308 int (*probe)(struct usb_serial *);
277 void (*setup)(struct usb_serial *); /* Special settings during startup. */ 309 void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
278}; 310};
279 311
280static int ftdi_olimex_probe (struct usb_serial *serial); 312static int ftdi_olimex_probe (struct usb_serial *serial);
281static void ftdi_USB_UIRT_setup (struct usb_serial *serial); 313static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
282static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); 314static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
283 315
284static struct ftdi_sio_quirk ftdi_olimex_quirk = { 316static struct ftdi_sio_quirk ftdi_olimex_quirk = {
285 .probe = ftdi_olimex_probe, 317 .probe = ftdi_olimex_probe,
286}; 318};
287 319
288static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { 320static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
289 .setup = ftdi_USB_UIRT_setup, 321 .port_probe = ftdi_USB_UIRT_setup,
290}; 322};
291 323
292static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { 324static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
293 .setup = ftdi_HE_TIRA1_setup, 325 .port_probe = ftdi_HE_TIRA1_setup,
294}; 326};
295 327
296/* 328/*
@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = {
567#define THROTTLED 0x01 599#define THROTTLED 0x01
568#define ACTUALLY_THROTTLED 0x02 600#define ACTUALLY_THROTTLED 0x02
569 601
570struct ftdi_private {
571 ftdi_chip_type_t chip_type;
572 /* type of the device, either SIO or FT8U232AM */
573 int baud_base; /* baud base clock for divisor setting */
574 int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
575 __u16 last_set_data_urb_value ;
576 /* the last data state set - needed for doing a break */
577 int write_offset; /* This is the offset in the usb data block to write the serial data -
578 * it is different between devices
579 */
580 int flags; /* some ASYNC_xxxx flags are supported */
581 unsigned long last_dtr_rts; /* saved modem control outputs */
582 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
583 char prev_status, diff_status; /* Used for TIOCMIWAIT */
584 __u8 rx_flags; /* receive state flags (throttling) */
585 spinlock_t rx_lock; /* spinlock for receive state */
586 struct delayed_work rx_work;
587 struct usb_serial_port *port;
588 int rx_processed;
589 unsigned long rx_bytes;
590
591 __u16 interface; /* FT2232C port interface (0 for FT232/245) */
592
593 int force_baud; /* if non-zero, force the baud rate to this value */
594 int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
595
596 spinlock_t tx_lock; /* spinlock for transmit state */
597 unsigned long tx_bytes;
598 unsigned long tx_outstanding_bytes;
599 unsigned long tx_outstanding_urbs;
600};
601
602/* Used for TIOCMIWAIT */ 602/* Used for TIOCMIWAIT */
603#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) 603#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
604#define FTDI_STATUS_B1_MASK (FTDI_RS_BI) 604#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
@@ -609,7 +609,6 @@ struct ftdi_private {
609 609
610/* function prototypes for a FTDI serial converter */ 610/* function prototypes for a FTDI serial converter */
611static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); 611static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
612static int ftdi_sio_attach (struct usb_serial *serial);
613static void ftdi_shutdown (struct usb_serial *serial); 612static void ftdi_shutdown (struct usb_serial *serial);
614static int ftdi_sio_port_probe (struct usb_serial_port *port); 613static int ftdi_sio_port_probe (struct usb_serial_port *port);
615static int ftdi_sio_port_remove (struct usb_serial_port *port); 614static int ftdi_sio_port_remove (struct usb_serial_port *port);
@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = {
663 .ioctl = ftdi_ioctl, 662 .ioctl = ftdi_ioctl,
664 .set_termios = ftdi_set_termios, 663 .set_termios = ftdi_set_termios,
665 .break_ctl = ftdi_break_ctl, 664 .break_ctl = ftdi_break_ctl,
666 .attach = ftdi_sio_attach,
667 .shutdown = ftdi_shutdown, 665 .shutdown = ftdi_shutdown,
668}; 666};
669 667
@@ -1149,7 +1147,9 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
1149 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); 1147 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]);
1150 retval = device_create_file(&port->dev, &dev_attr_event_char); 1148 retval = device_create_file(&port->dev, &dev_attr_event_char);
1151 if ((!retval) && 1149 if ((!retval) &&
1152 (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { 1150 (priv->chip_type == FT232BM ||
1151 priv->chip_type == FT2232C ||
1152 priv->chip_type == FT232RL)) {
1153 retval = device_create_file(&port->dev, 1153 retval = device_create_file(&port->dev,
1154 &dev_attr_latency_timer); 1154 &dev_attr_latency_timer);
1155 } 1155 }
@@ -1198,6 +1198,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
1198static int ftdi_sio_port_probe(struct usb_serial_port *port) 1198static int ftdi_sio_port_probe(struct usb_serial_port *port)
1199{ 1199{
1200 struct ftdi_private *priv; 1200 struct ftdi_private *priv;
1201 struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
1202
1201 1203
1202 dbg("%s",__FUNCTION__); 1204 dbg("%s",__FUNCTION__);
1203 1205
@@ -1214,6 +1216,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1214 than queue a task to deliver them */ 1216 than queue a task to deliver them */
1215 priv->flags = ASYNC_LOW_LATENCY; 1217 priv->flags = ASYNC_LOW_LATENCY;
1216 1218
1219 if (quirk && quirk->port_probe)
1220 quirk->port_probe(priv);
1221
1217 /* Increase the size of read buffers */ 1222 /* Increase the size of read buffers */
1218 kfree(port->bulk_in_buffer); 1223 kfree(port->bulk_in_buffer);
1219 port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL); 1224 port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
@@ -1244,29 +1249,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1244 return 0; 1249 return 0;
1245} 1250}
1246 1251
1247/* attach subroutine */
1248static int ftdi_sio_attach (struct usb_serial *serial)
1249{
1250 /* Check for device requiring special set up. */
1251 struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
1252
1253 if (quirk && quirk->setup)
1254 quirk->setup(serial);
1255
1256 return 0;
1257} /* ftdi_sio_attach */
1258
1259
1260/* Setup for the USB-UIRT device, which requires hardwired 1252/* Setup for the USB-UIRT device, which requires hardwired
1261 * baudrate (38400 gets mapped to 312500) */ 1253 * baudrate (38400 gets mapped to 312500) */
1262/* Called from usbserial:serial_probe */ 1254/* Called from usbserial:serial_probe */
1263static void ftdi_USB_UIRT_setup (struct usb_serial *serial) 1255static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
1264{ 1256{
1265 struct ftdi_private *priv;
1266
1267 dbg("%s",__FUNCTION__); 1257 dbg("%s",__FUNCTION__);
1268 1258
1269 priv = usb_get_serial_port_data(serial->port[0]);
1270 priv->flags |= ASYNC_SPD_CUST; 1259 priv->flags |= ASYNC_SPD_CUST;
1271 priv->custom_divisor = 77; 1260 priv->custom_divisor = 77;
1272 priv->force_baud = B38400; 1261 priv->force_baud = B38400;
@@ -1274,13 +1263,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
1274 1263
1275/* Setup for the HE-TIRA1 device, which requires hardwired 1264/* Setup for the HE-TIRA1 device, which requires hardwired
1276 * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ 1265 * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */
1277static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) 1266static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
1278{ 1267{
1279 struct ftdi_private *priv;
1280
1281 dbg("%s",__FUNCTION__); 1268 dbg("%s",__FUNCTION__);
1282 1269
1283 priv = usb_get_serial_port_data(serial->port[0]);
1284 priv->flags |= ASYNC_SPD_CUST; 1270 priv->flags |= ASYNC_SPD_CUST;
1285 priv->custom_divisor = 240; 1271 priv->custom_divisor = 240;
1286 priv->force_baud = B38400; 1272 priv->force_baud = B38400;
@@ -1574,14 +1560,15 @@ static void ftdi_write_bulk_callback (struct urb *urb)
1574 struct ftdi_private *priv; 1560 struct ftdi_private *priv;
1575 int data_offset; /* will be 1 for the SIO and 0 otherwise */ 1561 int data_offset; /* will be 1 for the SIO and 0 otherwise */
1576 unsigned long countback; 1562 unsigned long countback;
1563 int status = urb->status;
1577 1564
1578 /* free up the transfer buffer, as usb_free_urb() does not do this */ 1565 /* free up the transfer buffer, as usb_free_urb() does not do this */
1579 kfree (urb->transfer_buffer); 1566 kfree (urb->transfer_buffer);
1580 1567
1581 dbg("%s - port %d", __FUNCTION__, port->number); 1568 dbg("%s - port %d", __FUNCTION__, port->number);
1582 1569
1583 if (urb->status) { 1570 if (status) {
1584 dbg("nonzero write bulk status received: %d", urb->status); 1571 dbg("nonzero write bulk status received: %d", status);
1585 return; 1572 return;
1586 } 1573 }
1587 1574
@@ -1657,6 +1644,7 @@ static void ftdi_read_bulk_callback (struct urb *urb)
1657 struct ftdi_private *priv; 1644 struct ftdi_private *priv;
1658 unsigned long countread; 1645 unsigned long countread;
1659 unsigned long flags; 1646 unsigned long flags;
1647 int status = urb->status;
1660 1648
1661 if (urb->number_of_packets > 0) { 1649 if (urb->number_of_packets > 0) {
1662 err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__, 1650 err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
@@ -1685,9 +1673,10 @@ static void ftdi_read_bulk_callback (struct urb *urb)
1685 err("%s - Not my urb!", __FUNCTION__); 1673 err("%s - Not my urb!", __FUNCTION__);
1686 } 1674 }
1687 1675
1688 if (urb->status) { 1676 if (status) {
1689 /* This will happen at close every time so it is a dbg not an err */ 1677 /* This will happen at close every time so it is a dbg not an err */
1690 dbg("(this is ok on close) nonzero read bulk status received: %d", urb->status); 1678 dbg("(this is ok on close) nonzero read bulk status received: "
1679 "%d", status);
1691 return; 1680 return;
1692 } 1681 }
1693 1682
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 74660a3aa670..04bd3b7a2985 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1036,15 +1036,16 @@ static void garmin_write_bulk_callback (struct urb *urb)
1036 unsigned long flags; 1036 unsigned long flags;
1037 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1037 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1038 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); 1038 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1039 int status = urb->status;
1039 1040
1040 /* free up the transfer buffer, as usb_free_urb() does not do this */ 1041 /* free up the transfer buffer, as usb_free_urb() does not do this */
1041 kfree (urb->transfer_buffer); 1042 kfree (urb->transfer_buffer);
1042 1043
1043 dbg("%s - port %d", __FUNCTION__, port->number); 1044 dbg("%s - port %d", __FUNCTION__, port->number);
1044 1045
1045 if (urb->status) { 1046 if (status) {
1046 dbg("%s - nonzero write bulk status received: %d", 1047 dbg("%s - nonzero write bulk status received: %d",
1047 __FUNCTION__, urb->status); 1048 __FUNCTION__, status);
1048 spin_lock_irqsave(&garmin_data_p->lock, flags); 1049 spin_lock_irqsave(&garmin_data_p->lock, flags);
1049 garmin_data_p->flags |= CLEAR_HALT_REQUIRED; 1050 garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
1050 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 1051 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
@@ -1281,7 +1282,8 @@ static void garmin_read_bulk_callback (struct urb *urb)
1281 struct usb_serial *serial = port->serial; 1282 struct usb_serial *serial = port->serial;
1282 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); 1283 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1283 unsigned char *data = urb->transfer_buffer; 1284 unsigned char *data = urb->transfer_buffer;
1284 int status; 1285 int status = urb->status;
1286 int retval;
1285 1287
1286 dbg("%s - port %d", __FUNCTION__, port->number); 1288 dbg("%s - port %d", __FUNCTION__, port->number);
1287 1289
@@ -1290,9 +1292,9 @@ static void garmin_read_bulk_callback (struct urb *urb)
1290 return; 1292 return;
1291 } 1293 }
1292 1294
1293 if (urb->status) { 1295 if (status) {
1294 dbg("%s - nonzero read bulk status received: %d", 1296 dbg("%s - nonzero read bulk status received: %d",
1295 __FUNCTION__, urb->status); 1297 __FUNCTION__, status);
1296 return; 1298 return;
1297 } 1299 }
1298 1300
@@ -1306,19 +1308,19 @@ static void garmin_read_bulk_callback (struct urb *urb)
1306 spin_lock_irqsave(&garmin_data_p->lock, flags); 1308 spin_lock_irqsave(&garmin_data_p->lock, flags);
1307 garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART; 1309 garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART;
1308 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 1310 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
1309 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1311 retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1310 if (status) 1312 if (retval)
1311 dev_err(&port->dev, 1313 dev_err(&port->dev,
1312 "%s - failed resubmitting read urb, error %d\n", 1314 "%s - failed resubmitting read urb, error %d\n",
1313 __FUNCTION__, status); 1315 __FUNCTION__, retval);
1314 } else if (urb->actual_length > 0) { 1316 } else if (urb->actual_length > 0) {
1315 /* Continue trying to read until nothing more is received */ 1317 /* Continue trying to read until nothing more is received */
1316 if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) { 1318 if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) {
1317 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1319 retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1318 if (status) 1320 if (retval)
1319 dev_err(&port->dev, 1321 dev_err(&port->dev,
1320 "%s - failed resubmitting read urb, error %d\n", 1322 "%s - failed resubmitting read urb, "
1321 __FUNCTION__, status); 1323 "error %d\n", __FUNCTION__, retval);
1322 } 1324 }
1323 } else { 1325 } else {
1324 dbg("%s - end of bulk data", __FUNCTION__); 1326 dbg("%s - end of bulk data", __FUNCTION__);
@@ -1333,13 +1335,14 @@ static void garmin_read_bulk_callback (struct urb *urb)
1333static void garmin_read_int_callback (struct urb *urb) 1335static void garmin_read_int_callback (struct urb *urb)
1334{ 1336{
1335 unsigned long flags; 1337 unsigned long flags;
1336 int status; 1338 int retval;
1337 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1339 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1338 struct usb_serial *serial = port->serial; 1340 struct usb_serial *serial = port->serial;
1339 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); 1341 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1340 unsigned char *data = urb->transfer_buffer; 1342 unsigned char *data = urb->transfer_buffer;
1343 int status = urb->status;
1341 1344
1342 switch (urb->status) { 1345 switch (status) {
1343 case 0: 1346 case 0:
1344 /* success */ 1347 /* success */
1345 break; 1348 break;
@@ -1348,11 +1351,11 @@ static void garmin_read_int_callback (struct urb *urb)
1348 case -ESHUTDOWN: 1351 case -ESHUTDOWN:
1349 /* this urb is terminated, clean up */ 1352 /* this urb is terminated, clean up */
1350 dbg("%s - urb shutting down with status: %d", 1353 dbg("%s - urb shutting down with status: %d",
1351 __FUNCTION__, urb->status); 1354 __FUNCTION__, status);
1352 return; 1355 return;
1353 default: 1356 default:
1354 dbg("%s - nonzero urb status received: %d", 1357 dbg("%s - nonzero urb status received: %d",
1355 __FUNCTION__, urb->status); 1358 __FUNCTION__, status);
1356 return; 1359 return;
1357 } 1360 }
1358 1361
@@ -1374,11 +1377,11 @@ static void garmin_read_int_callback (struct urb *urb)
1374 port->read_urb->transfer_buffer, 1377 port->read_urb->transfer_buffer,
1375 port->read_urb->transfer_buffer_length, 1378 port->read_urb->transfer_buffer_length,
1376 garmin_read_bulk_callback, port); 1379 garmin_read_bulk_callback, port);
1377 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1380 retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
1378 if (status) { 1381 if (retval) {
1379 dev_err(&port->dev, 1382 dev_err(&port->dev,
1380 "%s - failed submitting read urb, error %d\n", 1383 "%s - failed submitting read urb, error %d\n",
1381 __FUNCTION__, status); 1384 __FUNCTION__, retval);
1382 } else { 1385 } else {
1383 spin_lock_irqsave(&garmin_data_p->lock, flags); 1386 spin_lock_irqsave(&garmin_data_p->lock, flags);
1384 garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; 1387 garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE;
@@ -1422,11 +1425,11 @@ static void garmin_read_int_callback (struct urb *urb)
1422 } 1425 }
1423 1426
1424 port->interrupt_in_urb->dev = port->serial->dev; 1427 port->interrupt_in_urb->dev = port->serial->dev;
1425 status = usb_submit_urb (urb, GFP_ATOMIC); 1428 retval = usb_submit_urb (urb, GFP_ATOMIC);
1426 if (status) 1429 if (retval)
1427 dev_err(&urb->dev->dev, 1430 dev_err(&urb->dev->dev,
1428 "%s - Error %d submitting interrupt urb\n", 1431 "%s - Error %d submitting interrupt urb\n",
1429 __FUNCTION__, status); 1432 __FUNCTION__, retval);
1430} 1433}
1431 1434
1432 1435
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 4f8282ad7720..88a2c7dce335 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -69,6 +69,7 @@ struct usb_serial_driver usb_serial_generic_device = {
69 .shutdown = usb_serial_generic_shutdown, 69 .shutdown = usb_serial_generic_shutdown,
70 .throttle = usb_serial_generic_throttle, 70 .throttle = usb_serial_generic_throttle,
71 .unthrottle = usb_serial_generic_unthrottle, 71 .unthrottle = usb_serial_generic_unthrottle,
72 .resume = usb_serial_generic_resume,
72}; 73};
73 74
74static int generic_probe(struct usb_interface *interface, 75static int generic_probe(struct usb_interface *interface,
@@ -169,6 +170,23 @@ static void generic_cleanup (struct usb_serial_port *port)
169 } 170 }
170} 171}
171 172
173int usb_serial_generic_resume(struct usb_serial *serial)
174{
175 struct usb_serial_port *port;
176 int i, c = 0, r;
177
178 for (i = 0; i < serial->num_ports; i++) {
179 port = serial->port[i];
180 if (port->open_count && port->read_urb) {
181 r = usb_submit_urb(port->read_urb, GFP_NOIO);
182 if (r < 0)
183 c++;
184 }
185 }
186
187 return c ? -EIO : 0;
188}
189
172void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp) 190void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
173{ 191{
174 dbg("%s - port %d", __FUNCTION__, port->number); 192 dbg("%s - port %d", __FUNCTION__, port->number);
@@ -263,79 +281,82 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
263 return (chars); 281 return (chars);
264} 282}
265 283
266/* Push data to tty layer and resubmit the bulk read URB */ 284
267static void flush_and_resubmit_read_urb (struct usb_serial_port *port) 285static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
268{ 286{
269 struct usb_serial *serial = port->serial;
270 struct urb *urb = port->read_urb; 287 struct urb *urb = port->read_urb;
271 struct tty_struct *tty = port->tty; 288 struct usb_serial *serial = port->serial;
272 int result; 289 int result;
273 290
274 /* Push data to tty */
275 if (tty && urb->actual_length) {
276 tty_buffer_request_room(tty, urb->actual_length);
277 tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
278 tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
279 }
280
281 /* Continue reading from device */ 291 /* Continue reading from device */
282 usb_fill_bulk_urb (port->read_urb, serial->dev, 292 usb_fill_bulk_urb (urb, serial->dev,
283 usb_rcvbulkpipe (serial->dev, 293 usb_rcvbulkpipe (serial->dev,
284 port->bulk_in_endpointAddress), 294 port->bulk_in_endpointAddress),
285 port->read_urb->transfer_buffer, 295 urb->transfer_buffer,
286 port->read_urb->transfer_buffer_length, 296 urb->transfer_buffer_length,
287 ((serial->type->read_bulk_callback) ? 297 ((serial->type->read_bulk_callback) ?
288 serial->type->read_bulk_callback : 298 serial->type->read_bulk_callback :
289 usb_serial_generic_read_bulk_callback), port); 299 usb_serial_generic_read_bulk_callback), port);
290 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 300 result = usb_submit_urb(urb, mem_flags);
291 if (result) 301 if (result)
292 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 302 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
293} 303}
294 304
305/* Push data to tty layer and resubmit the bulk read URB */
306static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
307{
308 struct urb *urb = port->read_urb;
309 struct tty_struct *tty = port->tty;
310 int room;
311
312 /* Push data to tty */
313 if (tty && urb->actual_length) {
314 room = tty_buffer_request_room(tty, urb->actual_length);
315 if (room) {
316 tty_insert_flip_string(tty, urb->transfer_buffer, room);
317 tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
318 }
319 }
320
321 resubmit_read_urb(port, GFP_ATOMIC);
322}
323
295void usb_serial_generic_read_bulk_callback (struct urb *urb) 324void usb_serial_generic_read_bulk_callback (struct urb *urb)
296{ 325{
297 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 326 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
298 unsigned char *data = urb->transfer_buffer; 327 unsigned char *data = urb->transfer_buffer;
299 int is_throttled; 328 int status = urb->status;
300 unsigned long flags;
301 329
302 dbg("%s - port %d", __FUNCTION__, port->number); 330 dbg("%s - port %d", __FUNCTION__, port->number);
303 331
304 if (urb->status) { 332 if (unlikely(status != 0)) {
305 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 333 dbg("%s - nonzero read bulk status received: %d",
334 __FUNCTION__, status);
306 return; 335 return;
307 } 336 }
308 337
309 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 338 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
310 339
311 /* Throttle the device if requested by tty */ 340 /* Throttle the device if requested by tty */
312 if (urb->actual_length) { 341 spin_lock(&port->lock);
313 spin_lock_irqsave(&port->lock, flags); 342 if (!(port->throttled = port->throttle_req))
314 is_throttled = port->throttled = port->throttle_req; 343 /* Handle data and continue reading from device */
315 spin_unlock_irqrestore(&port->lock, flags); 344 flush_and_resubmit_read_urb(port);
316 if (is_throttled) { 345 spin_unlock(&port->lock);
317 /* Let the received data linger in the read URB;
318 * usb_serial_generic_unthrottle() will pick it
319 * up later. */
320 dbg("%s - throttling device", __FUNCTION__);
321 return;
322 }
323 }
324
325 /* Handle data and continue reading from device */
326 flush_and_resubmit_read_urb(port);
327} 346}
328EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 347EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
329 348
330void usb_serial_generic_write_bulk_callback (struct urb *urb) 349void usb_serial_generic_write_bulk_callback (struct urb *urb)
331{ 350{
332 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 351 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
352 int status = urb->status;
333 353
334 dbg("%s - port %d", __FUNCTION__, port->number); 354 dbg("%s - port %d", __FUNCTION__, port->number);
335 355
336 port->write_urb_busy = 0; 356 port->write_urb_busy = 0;
337 if (urb->status) { 357 if (status) {
338 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 358 dbg("%s - nonzero write bulk status received: %d",
359 __FUNCTION__, status);
339 return; 360 return;
340 } 361 }
341 362
@@ -370,8 +391,8 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port)
370 spin_unlock_irqrestore(&port->lock, flags); 391 spin_unlock_irqrestore(&port->lock, flags);
371 392
372 if (was_throttled) { 393 if (was_throttled) {
373 /* Handle pending data and resume reading from device */ 394 /* Resume reading from device */
374 flush_and_resubmit_read_urb(port); 395 resubmit_read_urb(port, GFP_KERNEL);
375 } 396 }
376} 397}
377 398
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 056e1923c4de..dd42f57089ff 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -599,10 +599,11 @@ static void edge_interrupt_callback (struct urb *urb)
599 int txCredits; 599 int txCredits;
600 int portNumber; 600 int portNumber;
601 int result; 601 int result;
602 int status = urb->status;
602 603
603 dbg("%s", __FUNCTION__); 604 dbg("%s", __FUNCTION__);
604 605
605 switch (urb->status) { 606 switch (status) {
606 case 0: 607 case 0:
607 /* success */ 608 /* success */
608 break; 609 break;
@@ -610,10 +611,12 @@ static void edge_interrupt_callback (struct urb *urb)
610 case -ENOENT: 611 case -ENOENT:
611 case -ESHUTDOWN: 612 case -ESHUTDOWN:
612 /* this urb is terminated, clean up */ 613 /* this urb is terminated, clean up */
613 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 614 dbg("%s - urb shutting down with status: %d",
615 __FUNCTION__, status);
614 return; 616 return;
615 default: 617 default:
616 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 618 dbg("%s - nonzero urb status received: %d",
619 __FUNCTION__, status);
617 goto exit; 620 goto exit;
618 } 621 }
619 622
@@ -688,13 +691,15 @@ static void edge_bulk_in_callback (struct urb *urb)
688{ 691{
689 struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context; 692 struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context;
690 unsigned char *data = urb->transfer_buffer; 693 unsigned char *data = urb->transfer_buffer;
691 int status; 694 int retval;
692 __u16 raw_data_length; 695 __u16 raw_data_length;
696 int status = urb->status;
693 697
694 dbg("%s", __FUNCTION__); 698 dbg("%s", __FUNCTION__);
695 699
696 if (urb->status) { 700 if (status) {
697 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 701 dbg("%s - nonzero read bulk status received: %d",
702 __FUNCTION__, status);
698 edge_serial->read_in_progress = false; 703 edge_serial->read_in_progress = false;
699 return; 704 return;
700 } 705 }
@@ -722,9 +727,11 @@ static void edge_bulk_in_callback (struct urb *urb)
722 if (edge_serial->rxBytesAvail > 0) { 727 if (edge_serial->rxBytesAvail > 0) {
723 dbg("%s - posting a read", __FUNCTION__); 728 dbg("%s - posting a read", __FUNCTION__);
724 edge_serial->read_urb->dev = edge_serial->serial->dev; 729 edge_serial->read_urb->dev = edge_serial->serial->dev;
725 status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); 730 retval = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);
726 if (status) { 731 if (retval) {
727 dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status); 732 dev_err(&urb->dev->dev,
733 "%s - usb_submit_urb(read bulk) failed, "
734 "retval = %d\n", __FUNCTION__, retval);
728 edge_serial->read_in_progress = false; 735 edge_serial->read_in_progress = false;
729 } 736 }
730 } else { 737 } else {
@@ -744,11 +751,13 @@ static void edge_bulk_out_data_callback (struct urb *urb)
744{ 751{
745 struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; 752 struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
746 struct tty_struct *tty; 753 struct tty_struct *tty;
754 int status = urb->status;
747 755
748 dbg("%s", __FUNCTION__); 756 dbg("%s", __FUNCTION__);
749 757
750 if (urb->status) { 758 if (status) {
751 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 759 dbg("%s - nonzero write bulk status received: %d",
760 __FUNCTION__, status);
752 } 761 }
753 762
754 tty = edge_port->port->tty; 763 tty = edge_port->port->tty;
@@ -1504,15 +1513,6 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
1504 } 1513 }
1505 1514
1506 cflag = tty->termios->c_cflag; 1515 cflag = tty->termios->c_cflag;
1507 /* check that they really want us to change something */
1508 if (old_termios) {
1509 if (cflag == old_termios->c_cflag &&
1510 tty->termios->c_iflag == old_termios->c_iflag) {
1511 dbg("%s - nothing to change", __FUNCTION__);
1512 return;
1513 }
1514 }
1515
1516 dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 1516 dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
1517 tty->termios->c_cflag, tty->termios->c_iflag); 1517 tty->termios->c_cflag, tty->termios->c_iflag);
1518 if (old_termios) { 1518 if (old_termios) {
diff --git a/drivers/usb/serial/io_fw_down3.h b/drivers/usb/serial/io_fw_down3.h
index 93b56d68a27b..4496b068c50f 100644
--- a/drivers/usb/serial/io_fw_down3.h
+++ b/drivers/usb/serial/io_fw_down3.h
@@ -5,7 +5,7 @@
5//************************************************************** 5//**************************************************************
6 6
7 7
8static int IMAGE_SIZE = 12749; 8static int IMAGE_SIZE = 12938;
9 9
10struct EDGE_FIRMWARE_VERSION_INFO 10struct EDGE_FIRMWARE_VERSION_INFO
11{ 11{
@@ -16,7 +16,7 @@ struct EDGE_FIRMWARE_VERSION_INFO
16 16
17static struct EDGE_FIRMWARE_VERSION_INFO IMAGE_VERSION_NAME = 17static struct EDGE_FIRMWARE_VERSION_INFO IMAGE_VERSION_NAME =
18{ 18{
19 4, 10, 0 // Major, Minor, Build 19 4, 80, 0 // Major, Minor, Build
20 20
21}; 21};
22 22
@@ -27,16 +27,16 @@ static unsigned char IMAGE_ARRAY_NAME[] =
27// WORD Length; 27// WORD Length;
28// BYTE CheckSum; 28// BYTE CheckSum;
29// }; 29// };
300xca, 0x31, 300x87, 0x32,
310xa8, 310x9a,
32 32
330x02, 0x26, 0xfe, 0x02, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 330x02, 0x27, 0xbf, 0x02, 0x21, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00,
340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1a, 0x85, 0x3f, 340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1a, 0x85, 0x3f,
350x8c, 0x85, 0x40, 0x8a, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 350x8c, 0x85, 0x40, 0x8a, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00,
360xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x3e, 360xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x3e,
370x24, 0x08, 0xf8, 0xe6, 0x60, 0x2b, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0xa6, 0x81, 0xe5, 0x3e, 0x75, 370x24, 0x08, 0xf8, 0xe6, 0x60, 0x2b, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0xa6, 0x81, 0xe5, 0x3e, 0x75,
380xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0x78, 0x8c, 0xe5, 0x81, 380xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0x78, 0x8c, 0xe5, 0x81,
390x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0x94, 0xe6, 0xf0, 0x08, 0xa3, 0xd9, 390x04, 0xc3, 0x98, 0xf9, 0x94, 0x22, 0x40, 0x03, 0x02, 0x11, 0xdc, 0xe6, 0xf0, 0x08, 0xa3, 0xd9,
400xfa, 0x74, 0x08, 0x25, 0x3e, 0xf8, 0x05, 0x3e, 0x08, 0xe6, 0x54, 0x80, 0x70, 0x0c, 0xe5, 0x3e, 400xfa, 0x74, 0x08, 0x25, 0x3e, 0xf8, 0x05, 0x3e, 0x08, 0xe6, 0x54, 0x80, 0x70, 0x0c, 0xe5, 0x3e,
410xb4, 0x07, 0xf3, 0x78, 0x08, 0x75, 0x3e, 0x00, 0x80, 0xef, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0x86, 410xb4, 0x07, 0xf3, 0x78, 0x08, 0x75, 0x3e, 0x00, 0x80, 0xef, 0xe5, 0x3e, 0x24, 0x10, 0xf8, 0x86,
420x81, 0xe5, 0x3e, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 420x81, 0xe5, 0x3e, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83,
@@ -49,387 +49,398 @@ static unsigned char IMAGE_ARRAY_NAME[] =
490xc9, 0xf0, 0x69, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, 0xca, 0xf0, 0x6a, 0x60, 0x02, 0x7e, 0x04, 490xc9, 0xf0, 0x69, 0x60, 0x02, 0x7e, 0x04, 0xa3, 0xe0, 0xca, 0xf0, 0x6a, 0x60, 0x02, 0x7e, 0x04,
500xa3, 0xe0, 0xcb, 0xf0, 0x6b, 0x60, 0x02, 0x7e, 0x04, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0, 500xa3, 0xe0, 0xcb, 0xf0, 0x6b, 0x60, 0x02, 0x7e, 0x04, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc0, 0xf0,
510xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 510xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05,
520xc0, 0x06, 0xc0, 0x07, 0x90, 0xff, 0x93, 0x74, 0x01, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, 520xc0, 0x06, 0xc0, 0x07, 0x74, 0x15, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x23, 0x74,
530x02, 0x11, 0x94, 0x85, 0x41, 0x8d, 0x85, 0x42, 0x8b, 0x74, 0xaf, 0xf5, 0x82, 0x74, 0xfa, 0xf5, 530x66, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x16, 0x74, 0xff, 0xf0, 0x74,
540x83, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, 540x1c, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x60, 0x04, 0x14, 0xf0, 0x70, 0x04, 0xc2, 0x90,
550x90, 0xff, 0x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, 550x80, 0xfc, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0xe5, 0x81, 0x94, 0xfd, 0x40, 0x03, 0x02, 0x11,
560xb4, 0x02, 0x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x27, 560xdc, 0x85, 0x41, 0x8d, 0x85, 0x42, 0x8b, 0x74, 0xb2, 0xf5, 0x82, 0x74, 0xfa, 0xf5, 0x83, 0xe0,
570x8d, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, 570xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x4a, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff,
580xa3, 0xe0, 0xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, 580x4e, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x20, 0xb4, 0x02,
590x90, 0xff, 0x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x25, 590x1d, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80,
600xb4, 0x02, 0x22, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x27, 600x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x04, 0xd0, 0x83, 0xd0, 0x82, 0xa3, 0xe0,
610x8d, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 610xb4, 0x01, 0x1b, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x52, 0xe0, 0x30, 0xe7, 0x2c, 0x90, 0xff,
620x80, 0x03, 0x02, 0x02, 0x62, 0x74, 0x15, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x20, 0x04, 620x56, 0xe0, 0x30, 0xe7, 0x25, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x02, 0xf0, 0x80, 0x25, 0xb4, 0x02,
630xf1, 0x20, 0x02, 0x03, 0x30, 0x01, 0xeb, 0x74, 0x18, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 630x22, 0xc0, 0x82, 0xc0, 0x83, 0x90, 0xff, 0x7a, 0xe0, 0x30, 0xe7, 0x05, 0x12, 0x28, 0x4e, 0x80,
640x14, 0xfc, 0xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 640x09, 0xd0, 0x83, 0xd0, 0x82, 0x74, 0x03, 0xf0, 0x80, 0x09, 0xd0, 0x83, 0xd0, 0x82, 0x80, 0x03,
650x7e, 0x01, 0x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x33, 0x12, 0x00, 0xc9, 0xee, 650x02, 0x02, 0x90, 0x74, 0x16, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x20, 0x04, 0xf1, 0x20,
660x64, 0x04, 0x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 660x02, 0x03, 0x30, 0x01, 0xeb, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xe0, 0x14, 0xfc,
670x02, 0x60, 0x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x33, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 670xf0, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0x64, 0x04, 0x70, 0x0f, 0xec, 0x70, 0x62, 0x7e, 0x01,
680x33, 0x7c, 0x0a, 0x74, 0x18, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 680x12, 0x00, 0xc9, 0x7c, 0x0a, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x12, 0x00, 0xc9, 0xee, 0x64, 0x04,
690xa3, 0xee, 0xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 690x60, 0x1d, 0xec, 0x70, 0x4b, 0x7c, 0x0a, 0xed, 0x14, 0xfd, 0x70, 0x15, 0xee, 0x64, 0x02, 0x60,
700x80, 0x10, 0xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 700x07, 0x7e, 0x02, 0x7d, 0x32, 0x02, 0x02, 0x61, 0x7e, 0x01, 0x7d, 0xfa, 0x02, 0x02, 0x61, 0x7c,
710xd2, 0xb1, 0x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 710x0a, 0x74, 0x19, 0xf5, 0x82, 0x74, 0xf9, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee,
720x60, 0x08, 0x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x3d, 720xf0, 0x14, 0x60, 0x18, 0x20, 0xe1, 0x0f, 0x20, 0x01, 0x06, 0xd2, 0xb1, 0xc2, 0xb0, 0x80, 0x10,
730x60, 0x13, 0x14, 0xf5, 0x3d, 0x70, 0x0e, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 730xc2, 0xb1, 0xd2, 0xb0, 0x80, 0x0a, 0xc2, 0xb1, 0xc2, 0xb0, 0x80, 0x04, 0xd2, 0xb0, 0xd2, 0xb1,
740x0f, 0xd2, 0x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 740x78, 0x19, 0x79, 0x09, 0x7a, 0x07, 0xe7, 0x70, 0x04, 0xa6, 0x00, 0x80, 0x0b, 0xe6, 0x60, 0x08,
750x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 750x16, 0xe6, 0x70, 0x04, 0xe7, 0x44, 0x80, 0xf7, 0x08, 0x09, 0xda, 0xea, 0xe5, 0x3d, 0x60, 0x13,
760x90, 0xff, 0x04, 0xe0, 0x90, 0xfa, 0xb6, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 760x14, 0xf5, 0x3d, 0x70, 0x0e, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0x57, 0xd2,
770xec, 0xff, 0xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 770x8c, 0xd2, 0x8d, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0,
780x01, 0x7f, 0x08, 0x8e, 0x3b, 0x8f, 0x3c, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 780x01, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, 0x90, 0xff,
790xff, 0xea, 0x90, 0xfa, 0xba, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x1c, 0x30, 0xe4, 0xf5, 0x4d, 0xe5, 790x04, 0xe0, 0x90, 0xfa, 0xb9, 0xf0, 0x90, 0xff, 0x06, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff,
800x4d, 0xc3, 0x94, 0x02, 0x50, 0x0f, 0x12, 0x1c, 0x11, 0xe4, 0x12, 0x1a, 0x38, 0x05, 0x4d, 0x04, 800xea, 0xfe, 0xef, 0xc3, 0x94, 0x08, 0xee, 0x94, 0x01, 0x50, 0x02, 0x80, 0x04, 0x7e, 0x01, 0x7f,
810x12, 0x1c, 0x02, 0x80, 0xea, 0x12, 0x1c, 0x30, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 810x08, 0x8e, 0x3b, 0x8f, 0x3c, 0x90, 0xff, 0x02, 0xe0, 0xfc, 0xa3, 0xe0, 0xfa, 0xec, 0xff, 0xea,
820xc0, 0x70, 0x03, 0x02, 0x08, 0xc5, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 820x90, 0xfa, 0xbd, 0xf0, 0xef, 0xa3, 0xf0, 0x12, 0x1c, 0xe0, 0xe4, 0xf5, 0x4d, 0xe5, 0x4d, 0xc3,
830xe0, 0xfe, 0x54, 0x0f, 0xf5, 0x4d, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 830x94, 0x02, 0x50, 0x0f, 0x12, 0x1c, 0xc1, 0xe4, 0x12, 0x1a, 0xe8, 0x05, 0x4d, 0x04, 0x12, 0x1c,
840x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 0x4c, 0x03, 0x56, 0x00, 0x04, 0x29, 0x01, 0x05, 0x3c, 0x03, 840xb2, 0x80, 0xea, 0x12, 0x1c, 0xe0, 0x90, 0xff, 0x00, 0xe0, 0xff, 0x54, 0x60, 0x24, 0xc0, 0x70,
850x06, 0x03, 0x05, 0x06, 0x45, 0x06, 0x07, 0xa7, 0x08, 0x07, 0xef, 0x09, 0x08, 0x4b, 0x0a, 0x08, 850x03, 0x02, 0x08, 0xf3, 0x24, 0x40, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xfe,
860x8b, 0x0b, 0x00, 0x00, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 860x54, 0x0f, 0xf5, 0x4d, 0xee, 0x30, 0xe7, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0a, 0x90, 0xff,
870xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x64, 0x02, 0x45, 870x01, 0xe0, 0x12, 0x1b, 0xfc, 0x03, 0x84, 0x00, 0x04, 0x57, 0x01, 0x05, 0x6a, 0x03, 0x06, 0x31,
880x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 880x05, 0x06, 0x73, 0x06, 0x07, 0xd5, 0x08, 0x08, 0x1d, 0x09, 0x08, 0x79, 0x0a, 0x08, 0xb9, 0x0b,
890x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xee, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0x11, 0x74, 890x00, 0x00, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0,
900x01, 0x12, 0x1a, 0x38, 0x78, 0x67, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x1c, 0x11, 0x74, 0x02, 0x12, 900x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64, 0x02, 0x45, 0x3b, 0x60,
910x1a, 0x38, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb6, 0xe0, 910x03, 0x02, 0x0f, 0x6e, 0xef, 0x54, 0x1f, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x47, 0x24, 0x02, 0x60,
920x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 920x03, 0x02, 0x0f, 0x6e, 0xee, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xc1, 0x74, 0x01, 0x12,
930x26, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 930x1a, 0xe8, 0x78, 0x67, 0xe6, 0x30, 0xe0, 0x08, 0x12, 0x1c, 0xc1, 0x74, 0x02, 0x12, 0x1a, 0xe8,
940x60, 0x07, 0x64, 0x80, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0xb2, 0x40, 0x03, 0x02, 0x0f, 940x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03,
950x26, 0xe5, 0x4d, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x1c, 0x0e, 0x12, 0x1a, 950x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x7f,
960x38, 0x80, 0x24, 0x90, 0xff, 0x82, 0x12, 0x1c, 0x0e, 0x12, 0x1a, 0x38, 0x80, 0x19, 0x15, 0x4d, 960x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x0e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x60, 0x07,
970x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0x12, 0x1c, 0x0c, 0x12, 0x1a, 0x38, 0x80, 0x09, 0x12, 0x1c, 970x64, 0x80, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
980xb3, 0x12, 0x1c, 0x0c, 0x12, 0x1a, 0x38, 0x12, 0x1c, 0x11, 0x12, 0x19, 0xf2, 0x60, 0x05, 0x74, 980x4d, 0x70, 0x19, 0x30, 0x0a, 0x0b, 0x90, 0xff, 0x80, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80,
990x01, 0x12, 0x1a, 0x38, 0x7f, 0x02, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 990x24, 0x90, 0xff, 0x82, 0x12, 0x1c, 0xbe, 0x12, 0x1a, 0xe8, 0x80, 0x19, 0x15, 0x4d, 0x30, 0x0a,
1000x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x14, 0x60, 0x2d, 1000x0b, 0x12, 0x1d, 0x55, 0x12, 0x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x80, 0x09, 0x12, 0x1d, 0x63, 0x12,
1010x14, 0x60, 0x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x04, 1010x1c, 0xbc, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xa2, 0x60, 0x05, 0x74, 0x01, 0x12,
1020xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 1020x1a, 0xe8, 0x7f, 0x02, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
1030x0f, 0x26, 0x78, 0x67, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 1030x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60, 0x2d, 0x14, 0x60,
1040xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb6, 1040x59, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x04, 0xa3, 0xe0,
1050xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb6, 0xe0, 0xd3, 1050x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e,
1060x94, 0x01, 0x40, 0x03, 0x02, 0x0f, 0x26, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xfa, 0xba, 0xe0, 1060x78, 0x67, 0xe6, 0x54, 0xfe, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06,
1070x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0xb2, 0x40, 0x03, 0x02, 0x0f, 1070x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x09, 0x90, 0xfa, 0xb9, 0xe0, 0x60,
1080x26, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 1080x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0c, 0x90, 0xfa, 0xb9, 0xe0, 0xd3, 0x94, 0x01,
1090x07, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x4d, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 1090x40, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02,
1100x54, 0xf7, 0xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x4d, 0x24, 0xfe, 0x60, 1100xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0xfa, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0xe5,
1110x20, 0x24, 0xfb, 0x60, 0x34, 0x24, 0x06, 0x70, 0x35, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 1110x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5,
1120xfd, 0x7f, 0x03, 0x12, 0x2d, 0xa8, 0x80, 0x26, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2d, 0xa8, 0x80, 1120x4d, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d, 0x70, 0x0f, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7,
1130x1d, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2d, 0xa8, 0x80, 0x0e, 1130xf0, 0x90, 0xff, 0x80, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0xe5, 0x4d, 0x24, 0xfe, 0x60, 0x20, 0x24,
1140xe4, 0xfd, 0x7f, 0x04, 0x12, 0x2d, 0xa8, 0x80, 0x05, 0x7f, 0x87, 0x12, 0x31, 0x32, 0x15, 0x4d, 1140xfb, 0x60, 0x34, 0x24, 0x06, 0x70, 0x35, 0x30, 0x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f,
1150x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, 0x09, 0x12, 0x1c, 1150x03, 0x12, 0x2e, 0x79, 0x80, 0x26, 0xe4, 0xfd, 0x7f, 0x03, 0x12, 0x2e, 0x79, 0x80, 0x1d, 0x30,
1160xb3, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 1160x0a, 0x0c, 0xa2, 0x0a, 0xe4, 0x33, 0xfd, 0x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x0e, 0xe4, 0xfd,
1170x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 1170x7f, 0x04, 0x12, 0x2e, 0x79, 0x80, 0x05, 0x7f, 0x87, 0x12, 0x31, 0xef, 0x15, 0x4d, 0x30, 0x0a,
1180x14, 0x60, 0x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 1180x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5,
1190xe0, 0x70, 0x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 1190x83, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02,
1200x60, 0x03, 0x02, 0x0f, 0x26, 0x78, 0x67, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, 0x02, 0x31, 0xb1, 1200x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x14, 0x60,
1210xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe0, 0x07, 1210x2d, 0x14, 0x60, 0x55, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70,
1220xe5, 0x4d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x0a, 0xe5, 0x4d, 0xd3, 0x94, 1220x04, 0xa3, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03,
1230x01, 0x40, 0x03, 0x02, 0x0f, 0x26, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xfa, 0xba, 0xe0, 0x70, 1230x02, 0x0f, 0x6e, 0x78, 0x67, 0xe6, 0x44, 0x01, 0xf6, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35,
1240x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x12, 0x31, 0x82, 1240x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe0, 0x07, 0xe5, 0x4d,
1250x40, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x26, 1250x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x0a, 0xe5, 0x4d, 0xd3, 0x94, 0x01, 0x40,
1260xe5, 0x4d, 0x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x1d, 0x64, 0x02, 0x1d, 0x2f, 0xe5, 0x35, 0x20, 1260x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3,
1270xe1, 0x03, 0x02, 0x0f, 0x26, 0x15, 0x4d, 0x30, 0x0a, 0x0b, 0x12, 0x1c, 0xa5, 0xf5, 0x83, 0xe0, 1270xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x12, 0x32, 0x3f, 0x40, 0x03,
1280x44, 0x08, 0xf0, 0x80, 0x09, 0x12, 0x1c, 0xb3, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0xe4, 0xff, 1280x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x06, 0x20, 0xe0, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x4d,
1290x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 1290x70, 0x09, 0x30, 0x0a, 0x03, 0x02, 0x1e, 0x14, 0x02, 0x1d, 0xdf, 0xe5, 0x35, 0x20, 0xe1, 0x03,
1300x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 1300x02, 0x0f, 0x6e, 0x15, 0x4d, 0x30, 0x0a, 0x0b, 0x12, 0x1d, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x08,
1310x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x30, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xbb, 1310xf0, 0x80, 0x09, 0x12, 0x1d, 0x63, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0xe4, 0xff, 0x02, 0x32,
1320xe0, 0x90, 0xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x35, 0x01, 0x80, 0x03, 0x53, 0x35, 0xfe, 1320x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02,
1330xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 1330x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03,
1340x3b, 0x70, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 1340x02, 0x0f, 0x6e, 0xe5, 0x35, 0x30, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0, 0x90,
1350xba, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, 0x75, 0x24, 0x02, 1350xff, 0xff, 0xf0, 0xe0, 0x60, 0x05, 0x43, 0x35, 0x01, 0x80, 0x03, 0x53, 0x35, 0xfe, 0xe4, 0xff,
1360x60, 0x03, 0x02, 0x0f, 0x26, 0xed, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0x30, 0x12, 0x1d, 1360x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x70,
1370x5d, 0x7d, 0x03, 0x12, 0x0f, 0x6d, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0x2a, 0x90, 0xfa, 1370x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0,
1380xb3, 0xe0, 0xfd, 0xa3, 0x12, 0x1c, 0x7b, 0x12, 0x0f, 0x89, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 1380xfc, 0xa3, 0xe0, 0xfd, 0xec, 0x24, 0xfe, 0x60, 0x3a, 0x14, 0x60, 0x75, 0x24, 0x02, 0x60, 0x03,
1390xaf, 0x3c, 0x02, 0x0f, 0xba, 0x12, 0x1c, 0x30, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe4, 0x0d, 0x12, 1390x02, 0x0f, 0x6e, 0xed, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1c, 0xe0, 0x12, 0x1e, 0x0d, 0x7d,
1400x1d, 0x5d, 0x7d, 0x14, 0x12, 0x0f, 0x6d, 0x60, 0x10, 0x02, 0x0f, 0x26, 0x12, 0x1d, 0x5d, 0x7d, 1400x03, 0x12, 0x0f, 0xb5, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0,
1410x04, 0x12, 0x0f, 0xc1, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x0f, 0x2a, 0x90, 0xfa, 0xb3, 0xe0, 1410xfd, 0xa3, 0x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c,
1420xfd, 0xa3, 0x12, 0x1c, 0x7b, 0x12, 0x0f, 0x89, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 1420x02, 0x10, 0x02, 0x12, 0x1c, 0xe0, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x0d, 0x12, 0x1e, 0x0d,
1430x02, 0x0f, 0xba, 0x12, 0x1d, 0x5d, 0x7d, 0x05, 0x12, 0x0f, 0xc1, 0x60, 0x03, 0x02, 0x0f, 0x26, 1430x7d, 0x14, 0x12, 0x0f, 0xb5, 0x60, 0x10, 0x02, 0x0f, 0x6e, 0x12, 0x1e, 0x0d, 0x7d, 0x04, 0x12,
1440x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb3, 0x12, 0x1c, 0x78, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 1440x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x0f, 0x72, 0x90, 0xfa, 0xb6, 0xe0, 0xfd, 0xa3,
1450xb4, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xbb, 0xe0, 0x90, 0xfa, 0xb2, 0xf0, 1450x12, 0x1d, 0x2b, 0x12, 0x0f, 0xd1, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x02, 0x10,
1460xe4, 0xf5, 0x4c, 0x90, 0xfa, 0xb2, 0xe0, 0xff, 0xe5, 0x4c, 0xc3, 0x9f, 0x50, 0x24, 0x12, 0x1c, 1460x02, 0x12, 0x1e, 0x0d, 0x7d, 0x05, 0x12, 0x10, 0x09, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x7b, 0x01,
1470x72, 0x12, 0x0f, 0xcc, 0xff, 0xfd, 0x90, 0xfa, 0xb4, 0xe4, 0x8d, 0xf0, 0x12, 0x1a, 0x6c, 0x90, 1470x7a, 0xfa, 0x79, 0xb6, 0x12, 0x1d, 0x28, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4,
1480xfa, 0xb3, 0xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0f, 0x26, 0x05, 0x4c, 1480x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xb5, 0xf0, 0xe4, 0xf5,
1490x80, 0xd1, 0x12, 0x1c, 0x72, 0x12, 0x0f, 0xcc, 0x24, 0xfe, 0xff, 0x90, 0xfa, 0xb3, 0xf0, 0xfd, 1490x4c, 0x90, 0xfa, 0xb5, 0xe0, 0xff, 0xe5, 0x4c, 0xc3, 0x9f, 0x50, 0x24, 0x12, 0x1d, 0x22, 0x12,
1500xa3, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1a, 0x6c, 0x7a, 0xf9, 0x79, 0x6f, 0x7b, 0x01, 0x8b, 0x36, 1500x10, 0x14, 0xff, 0xfd, 0x90, 0xfa, 0xb7, 0xe4, 0x8d, 0xf0, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xb6,
1510x8a, 0x37, 0x89, 0x38, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x1c, 0x78, 0x12, 0x25, 1510xe0, 0xc3, 0x9f, 0xf0, 0xd3, 0x94, 0x00, 0x50, 0x03, 0x02, 0x0f, 0x6e, 0x05, 0x4c, 0x80, 0xd1,
1520xd7, 0x8f, 0x4c, 0x05, 0x4c, 0x05, 0x4c, 0x12, 0x1c, 0x11, 0xe5, 0x4c, 0x12, 0x1a, 0x38, 0x12, 1520x12, 0x1d, 0x22, 0x12, 0x10, 0x14, 0x24, 0xfe, 0xff, 0x90, 0xfa, 0xb6, 0xf0, 0xfd, 0xa3, 0xe4,
1530x1c, 0x11, 0x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x1a, 0x4a, 0xaf, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 1530x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0x7a, 0xf9, 0x79, 0x72, 0x7b, 0x01, 0x8b, 0x36, 0x8a, 0x37,
1540x95, 0x3c, 0xee, 0x95, 0x3b, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x8e, 0x39, 0x8f, 1540x89, 0x38, 0xe9, 0x24, 0x02, 0xf9, 0xe4, 0x3a, 0xfa, 0x12, 0x1d, 0x28, 0x12, 0x26, 0x98, 0x8f,
1550x3a, 0x02, 0x2c, 0x07, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 1550x4c, 0x05, 0x4c, 0x05, 0x4c, 0x12, 0x1c, 0xc1, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x12, 0x1c, 0xc1,
1560x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 1560x90, 0x00, 0x01, 0x74, 0x03, 0x12, 0x1a, 0xfa, 0xaf, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c,
1570x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 1570xee, 0x95, 0x3b, 0x50, 0x02, 0x80, 0x04, 0xae, 0x3b, 0xaf, 0x3c, 0x8e, 0x39, 0x8f, 0x3a, 0x02,
1580x12, 0x1c, 0xc9, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 1580x2c, 0xd8, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x64,
1590x02, 0x0f, 0x26, 0x75, 0x36, 0x00, 0x75, 0x37, 0x00, 0x75, 0x38, 0x32, 0x02, 0x0f, 0xa9, 0xe5, 1590x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f,
1600x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 1600x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d,
1610x90, 0xfa, 0xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xd3, 0x90, 0xfa, 0xbb, 0xe0, 0x94, 0x01, 1610x79, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f,
1620x90, 0xfa, 0xba, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x60, 0x03, 1620x6e, 0x75, 0x36, 0x00, 0x75, 0x37, 0x00, 0x75, 0x38, 0x32, 0x02, 0x0f, 0xf1, 0xe5, 0x35, 0x30,
1630x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 1630xe7, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa,
1640xbb, 0xe0, 0xf5, 0x32, 0xe5, 0x32, 0x70, 0x08, 0x43, 0x35, 0x01, 0x53, 0x35, 0xfd, 0x80, 0x06, 1640xb9, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94, 0x01, 0x90, 0xfa,
1650x53, 0x35, 0xfe, 0x43, 0x35, 0x02, 0xe4, 0xff, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x20, 0xe7, 0x03, 1650xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x60, 0x03, 0x02, 0x0f,
1660x02, 0x0f, 0x26, 0xe5, 0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 1660x6e, 0xe5, 0x35, 0x20, 0xe0, 0x06, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbe, 0xe0,
1670xb6, 0xe0, 0x60, 0x03, 0x02, 0x0f, 0x26, 0x90, 0xfa, 0xba, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 1670xf5, 0x32, 0xe5, 0x32, 0x70, 0x08, 0x43, 0x35, 0x01, 0x53, 0x35, 0xfd, 0x80, 0x06, 0x53, 0x35,
1680x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 0xc9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 1680xfe, 0x43, 0x35, 0x02, 0xe4, 0xff, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x20, 0xe7, 0x03, 0x02, 0x0f,
1690x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 0x7f, 0x01, 0x02, 0x31, 0xb1, 0xe5, 0x35, 0x30, 0xe7, 0x03, 1690x6e, 0xe5, 0x3c, 0x64, 0x01, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xb9, 0xe0,
1700x02, 0x0f, 0x26, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xd3, 0x90, 0xfa, 0xbb, 1700x60, 0x03, 0x02, 0x0f, 0x6e, 0x90, 0xfa, 0xbd, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x03, 0x02,
1710xe0, 0x94, 0x00, 0x90, 0xfa, 0xba, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x26, 0x12, 0x1c, 1710x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1,
1720xc9, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0f, 0x26, 0xe5, 0x35, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x26, 1720x03, 0x02, 0x0f, 0x6e, 0x7f, 0x01, 0x02, 0x32, 0x6e, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f,
1730xe4, 0xff, 0x02, 0x31, 0xb1, 0x90, 0xff, 0x01, 0x12, 0x1d, 0x74, 0xef, 0x12, 0x1a, 0x38, 0x90, 1730x6e, 0xe5, 0x3c, 0x45, 0x3b, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xd3, 0x90, 0xfa, 0xbe, 0xe0, 0x94,
1740xfa, 0xb6, 0x12, 0x1d, 0x74, 0x90, 0x00, 0x01, 0xef, 0x12, 0x1a, 0x4a, 0x90, 0x00, 0x02, 0xe4, 1740x00, 0x90, 0xfa, 0xbd, 0xe0, 0x94, 0x00, 0x40, 0x03, 0x02, 0x0f, 0x6e, 0x12, 0x1d, 0x79, 0x64,
1750x12, 0x1a, 0x4a, 0x74, 0x03, 0x12, 0x1c, 0x02, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0xa3, 0xe0, 0x85, 1750x01, 0x60, 0x03, 0x02, 0x0f, 0x6e, 0xe5, 0x35, 0x20, 0xe1, 0x03, 0x02, 0x0f, 0x6e, 0xe4, 0xff,
1760x38, 0x82, 0x85, 0x37, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 1760x02, 0x32, 0x6e, 0x90, 0xff, 0x01, 0x12, 0x1e, 0x24, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa, 0xb9,
1770x4c, 0x09, 0x4a, 0x02, 0x09, 0x6c, 0x04, 0x09, 0x8e, 0x05, 0x09, 0xba, 0x06, 0x09, 0xd8, 0x07, 1770x12, 0x1e, 0x24, 0x90, 0x00, 0x01, 0xef, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x02, 0xe4, 0x12, 0x1a,
1780x09, 0xf6, 0x08, 0x0a, 0x14, 0x09, 0x0a, 0x32, 0x0b, 0x0a, 0xe7, 0x80, 0x0d, 0x6f, 0x81, 0x0d, 1780xfa, 0x74, 0x03, 0x12, 0x1c, 0xb2, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0xa3, 0xe0, 0x85, 0x38, 0x82,
1790xa0, 0x82, 0x0b, 0x2e, 0x83, 0x0b, 0x77, 0x84, 0x0b, 0x96, 0x85, 0x0b, 0xdb, 0x86, 0x0c, 0x26, 1790x85, 0x37, 0x83, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x01, 0xe0, 0x12, 0x1b, 0xfc, 0x09,
1800x87, 0x0c, 0xb7, 0x88, 0x0d, 0x42, 0x89, 0x0a, 0x50, 0x92, 0x0a, 0x50, 0x93, 0x0e, 0x53, 0xc0, 1800x7b, 0x02, 0x09, 0x9d, 0x04, 0x09, 0xbf, 0x05, 0x09, 0xeb, 0x06, 0x0a, 0x09, 0x07, 0x0a, 0x27,
1810x0e, 0x7f, 0xc1, 0x0e, 0x90, 0xc2, 0x00, 0x00, 0x0f, 0x15, 0xe5, 0x35, 0x20, 0xe7, 0x05, 0x7f, 1810x08, 0x0a, 0x45, 0x09, 0x0a, 0x63, 0x0b, 0x0b, 0x18, 0x80, 0x0d, 0xb7, 0x81, 0x0d, 0xe8, 0x82,
1820x05, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 1820x0b, 0x5f, 0x83, 0x0b, 0xa8, 0x84, 0x0b, 0xc7, 0x85, 0x0c, 0x0c, 0x86, 0x0c, 0x57, 0x87, 0x0c,
1830x7f, 0x07, 0x02, 0x11, 0x16, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0x18, 0xe5, 0x35, 0x20, 0xe7, 1830xe8, 0x88, 0x0d, 0x73, 0x89, 0x0a, 0x81, 0x92, 0x0a, 0x81, 0x93, 0x0d, 0xa0, 0xb0, 0x0e, 0x9b,
1840x05, 0x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 1840xc0, 0x0e, 0xc7, 0xc1, 0x0e, 0xd8, 0xc2, 0x00, 0x00, 0x0f, 0x5d, 0xe5, 0x35, 0x20, 0xe7, 0x05,
1850x7c, 0x00, 0x7f, 0x0c, 0x02, 0x11, 0x16, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0x18, 0xe5, 0x35, 1850x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c,
1860x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1d, 0x92, 0x50, 0x06, 0xe5, 0x3c, 0x45, 0x3b, 0x70, 1860x00, 0x7f, 0x07, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5, 0x35, 0x20,
1870x05, 0x7f, 0x02, 0x02, 0x30, 0xec, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfe, 0x24, 0xfd, 0x50, 0x02, 1870xe7, 0x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef,
1880x80, 0x03, 0x02, 0x31, 0x6f, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 1880xfd, 0x7c, 0x00, 0x7f, 0x0c, 0x02, 0x11, 0x5e, 0xe4, 0xfd, 0x7f, 0x07, 0x02, 0x2f, 0xb4, 0xe5,
1890x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x08, 1890x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1e, 0x42, 0x50, 0x06, 0xe5, 0x3c, 0x45, 0x3b,
1900x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 1900x70, 0x05, 0x7f, 0x02, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfe, 0x24, 0xfd, 0x50,
1910x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x09, 0x02, 0x11, 1910x02, 0x80, 0x03, 0x02, 0x32, 0x2c, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03,
1920x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 1920x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f,
1930xc1, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, 0x11, 0x16, 0x7f, 1930x08, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f,
1940x07, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 1940x71, 0x12, 0x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x09, 0x02,
1950x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 1950x11, 0x5e, 0x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12,
1960x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x29, 0x12, 0x1c, 0xc1, 0x60, 0x03, 0x04, 1960x1d, 0x71, 0x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0a, 0x02, 0x11, 0x5e,
1970x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x11, 0x16, 0x7f, 0x07, 0x02, 0x30, 0xec, 1970x7f, 0x07, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71,
1980xe5, 0x35, 0x30, 0xe7, 0x56, 0x12, 0x1c, 0xc9, 0x70, 0x4a, 0x90, 0xff, 0x02, 0xe0, 0xf5, 0x4c, 1980x60, 0x03, 0x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0b, 0x02, 0x11, 0x5e, 0x7f, 0x07,
1990xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 0x4c, 0xb4, 0x83, 0x05, 0x75, 1990x02, 0x31, 0xa9, 0xe5, 0x35, 0x30, 0xe7, 0x03, 0x02, 0x0f, 0x71, 0x12, 0x1d, 0x71, 0x60, 0x03,
2000x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x4c, 0x12, 0x1b, 0x72, 0x12, 2000x04, 0x70, 0x09, 0xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0e, 0x02, 0x11, 0x5e, 0x7f, 0x07, 0x02, 0x31,
2010x1d, 0x8b, 0x12, 0x25, 0x39, 0x12, 0x1c, 0xd9, 0x12, 0x1a, 0x0b, 0x60, 0x05, 0x12, 0x31, 0xbd, 2010xa9, 0xe5, 0x35, 0x30, 0xe7, 0x56, 0x12, 0x1d, 0x79, 0x70, 0x4a, 0x90, 0xff, 0x02, 0xe0, 0xf5,
2020x80, 0x06, 0x85, 0x33, 0x39, 0x85, 0x34, 0x3a, 0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 2020x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 0x4c, 0xb4, 0x83, 0x05,
2030x72, 0x02, 0x2c, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0x18, 0x12, 0x1c, 0xc9, 0x60, 0x05, 2030x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 0x4c, 0x12, 0x1c, 0x22,
2040x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x1d, 0x92, 0x40, 0x05, 0x7f, 0x03, 0x02, 0x30, 0xec, 0x90, 2040x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12, 0x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x05, 0x12, 0x32,
2050xff, 0x02, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12, 0xe5, 2050x7a, 0x80, 0x06, 0x85, 0x33, 0x39, 0x85, 0x34, 0x3a, 0x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75,
2060x4c, 0xb4, 0x83, 0x05, 0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04, 0xf5, 2060x38, 0x75, 0x02, 0x2c, 0xd8, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x12, 0x1d, 0x79, 0x60,
2070x4c, 0x12, 0x1b, 0x72, 0x02, 0x31, 0x6f, 0x12, 0x1d, 0x9c, 0x12, 0x2a, 0x06, 0x12, 0x1c, 0x83, 2070x05, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x42, 0x40, 0x05, 0x7f, 0x03, 0x02, 0x31, 0xa9,
2080xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x78, 0x68, 0x12, 0x1b, 2080x90, 0xff, 0x02, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xb4, 0x82, 0x05, 0x75, 0x4c, 0x61, 0x80, 0x12,
2090x28, 0x90, 0x00, 0x02, 0x12, 0x1a, 0x0b, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, 0xe4, 0x12, 0x1a, 2090xe5, 0x4c, 0xb4, 0x83, 0x05, 0x75, 0x4c, 0x62, 0x80, 0x08, 0xe5, 0x4c, 0xc4, 0x54, 0xf0, 0x04,
2100x4a, 0x90, 0xfa, 0xb7, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x7c, 0xe6, 0xfc, 0x08, 0xe6, 0x8c, 2100xf5, 0x4c, 0x12, 0x1c, 0x22, 0x02, 0x32, 0x2c, 0x12, 0x1e, 0x4c, 0x12, 0x2a, 0xc7, 0x12, 0x1d,
2110x83, 0x12, 0x1c, 0x8b, 0xef, 0xf0, 0x12, 0x31, 0xc7, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x90, 0xfa, 2110x33, 0xe0, 0x54, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x78, 0x68, 0x12,
2120xb6, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3, 2120x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0xf2, 0x90, 0x00, 0x02, 0xe4, 0x12,
2130xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, 0xbb, 0xe0, 0x42, 2130x1a, 0xfa, 0x90, 0xfa, 0xba, 0xe0, 0x44, 0x80, 0xff, 0xf0, 0x78, 0x7c, 0xe6, 0xfc, 0x08, 0xe6,
2140x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xba, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3, 0xe0, 2140x8c, 0x83, 0x12, 0x1d, 0x3b, 0xef, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90,
2150xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xbb, 0xe0, 0x42, 0xb0, 2150xfa, 0xb9, 0xe0, 0x64, 0x01, 0x70, 0x1f, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06,
2160xd2, 0xaf, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0x30, 0x90, 0xfa, 0xb6, 0xe0, 0xb4, 0x01, 2160xa3, 0xe0, 0xf5, 0x90, 0x80, 0x2d, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0x90, 0x90, 0xfa, 0xbe, 0xe0,
2170x0a, 0x12, 0x1c, 0x11, 0xe5, 0x90, 0x12, 0x1a, 0x38, 0x80, 0x08, 0x12, 0x1c, 0x11, 0xe5, 0xb0, 2170x42, 0x90, 0xd2, 0xaf, 0x80, 0x1d, 0x90, 0xfa, 0xbd, 0xe0, 0xff, 0x7e, 0x00, 0x70, 0x06, 0xa3,
2180x12, 0x1a, 0x38, 0x02, 0x0f, 0xa9, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x24, 0x12, 0x12, 0x1c, 0x41, 2180xe0, 0xf5, 0xb0, 0x80, 0x0e, 0xc2, 0xaf, 0xef, 0xf4, 0x52, 0xb0, 0x90, 0xfa, 0xbe, 0xe0, 0x42,
2190x20, 0xe1, 0x33, 0x12, 0x1c, 0xd0, 0xef, 0x24, 0xfc, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90, 0xfa, 2190xb0, 0xd2, 0xaf, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0xb4,
2200xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x1d, 0xa6, 2200x01, 0x0a, 0x12, 0x1c, 0xc1, 0xe5, 0x90, 0x12, 0x1a, 0xe8, 0x80, 0x08, 0x12, 0x1c, 0xc1, 0xe5,
2210xf0, 0x80, 0x13, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0xf0, 2210xb0, 0x12, 0x1a, 0xe8, 0x02, 0x0f, 0xf1, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0x13, 0x12, 0x1c,
2220x80, 0x04, 0x12, 0x1d, 0xad, 0xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 2220xf1, 0x20, 0xe1, 0x33, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60, 0x18, 0x04, 0x70, 0x28, 0x90,
2230x24, 0x12, 0x12, 0x1c, 0x41, 0x20, 0xe1, 0x39, 0x12, 0x1c, 0xd0, 0xef, 0x24, 0xfc, 0x60, 0x1b, 2230xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x19, 0x12, 0x1e,
2240x04, 0x70, 0x2e, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, 0xf0, 2240x56, 0xf0, 0x80, 0x13, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10,
2250x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 2250xf0, 0x80, 0x04, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x90, 0xfa, 0xb9, 0xe0,
2260x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 2260xff, 0x24, 0x13, 0x12, 0x1c, 0xf1, 0x20, 0xe1, 0x39, 0x12, 0x1d, 0x80, 0xef, 0x24, 0xfc, 0x60,
2270xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x12, 0x1c, 0xc1, 0x60, 0x4d, 0x04, 0x60, 2270x1b, 0x04, 0x70, 0x2e, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20,
2280x03, 0x02, 0x0c, 0xb2, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x0f, 0x90, 0xff, 0xa4, 0x12, 0x1c, 0x3a, 2280xf0, 0x80, 0x1f, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x16, 0x90, 0xfa, 0xba, 0xe0,
2290x30, 0xe1, 0x6f, 0x12, 0x1d, 0x7c, 0x02, 0x0c, 0xb2, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfb, 0x12, 2290x60, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54,
2300x1c, 0x3d, 0xfe, 0x30, 0xe1, 0x5c, 0x30, 0xe2, 0x11, 0x30, 0xb4, 0x05, 0x12, 0x1d, 0x7c, 0x80, 2300xdf, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x12, 0x1d, 0x71, 0x60, 0x4d, 0x04,
2310x51, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x48, 0x30, 0x95, 0x05, 0x12, 0x1d, 0x7c, 2310x60, 0x03, 0x02, 0x0c, 0xe3, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x0f, 0x90, 0xff, 0xa4, 0x12, 0x1c,
2320x80, 0x40, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x37, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 2320xea, 0x30, 0xe1, 0x6f, 0x12, 0x1e, 0x2c, 0x02, 0x0c, 0xe3, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfb,
2330x12, 0x90, 0xff, 0xb4, 0x12, 0x1c, 0x3a, 0x30, 0xe1, 0x28, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 2330x12, 0x1c, 0xed, 0xfe, 0x30, 0xe1, 0x5c, 0x30, 0xe2, 0x11, 0x30, 0xb4, 0x05, 0x12, 0x1e, 0x2c,
2340xf0, 0x80, 0x1f, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfb, 0x12, 0x1c, 0x3d, 0x30, 0xe1, 0x13, 0x30, 2340x80, 0x51, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x48, 0x30, 0x95, 0x05, 0x12, 0x1e,
2350x93, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 2350x2c, 0x80, 0x40, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xfd, 0xf0, 0x80, 0x37, 0x90, 0xfa, 0xba, 0xe0,
2360xfd, 0xf0, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfc, 2360x60, 0x12, 0x90, 0xff, 0xb4, 0x12, 0x1c, 0xea, 0x30, 0xe1, 0x28, 0x90, 0xff, 0xb4, 0xe0, 0x44,
2370x60, 0x40, 0x04, 0x70, 0x78, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xa2, 0xe0, 0x44, 2370x02, 0xf0, 0x80, 0x1f, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xfb, 0x12, 0x1c, 0xed, 0x30, 0xe1, 0x13,
2380x40, 0xf0, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x65, 0xd2, 0x03, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 2380x30, 0x93, 0x09, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0,
2390xff, 0xa3, 0xef, 0x54, 0x7f, 0xf0, 0x80, 0x55, 0x30, 0x03, 0x0e, 0x90, 0xff, 0xa3, 0xe0, 0x44, 2390x54, 0xfd, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x90, 0xfa, 0xb9, 0xe0, 0x24,
2400x80, 0xf0, 0xc2, 0x03, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 2400xfc, 0x60, 0x40, 0x04, 0x70, 0x78, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xa2, 0xe0,
2410x80, 0x3b, 0x90, 0xfa, 0xb7, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xb2, 0xe0, 0x44, 0x40, 0xf0, 0xa3, 2410x44, 0x40, 0xf0, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x65, 0xd2, 0x03, 0xa3, 0xe0, 0x54, 0xdf, 0xf0,
2420xe0, 0xff, 0x30, 0xe7, 0x28, 0xd2, 0x04, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0xff, 0xb3, 0xef, 2420x90, 0xff, 0xa3, 0xef, 0x54, 0x7f, 0xf0, 0x80, 0x55, 0x30, 0x03, 0x0e, 0x90, 0xff, 0xa3, 0xe0,
2430x54, 0x7f, 0xf0, 0x80, 0x18, 0x30, 0x04, 0x0e, 0x90, 0xff, 0xb3, 0xe0, 0x44, 0x80, 0xf0, 0xc2, 2430x44, 0x80, 0xf0, 0xc2, 0x03, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x54, 0xbf,
2440x04, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff, 0x02, 2440xf0, 0x80, 0x3b, 0x90, 0xfa, 0xba, 0xe0, 0x60, 0x1d, 0x90, 0xff, 0xb2, 0xe0, 0x44, 0x40, 0xf0,
2450x30, 0xec, 0x12, 0x1c, 0x30, 0x90, 0xfa, 0xb6, 0xe0, 0x24, 0xfc, 0x60, 0x0f, 0x04, 0x70, 0x16, 2450xa3, 0xe0, 0xff, 0x30, 0xe7, 0x28, 0xd2, 0x04, 0xa3, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0xff, 0xb3,
2460x90, 0xff, 0xa6, 0xe0, 0x12, 0x1c, 0x11, 0x12, 0x1a, 0x38, 0x80, 0x0a, 0x90, 0xff, 0xb6, 0xe0, 2460xef, 0x54, 0x7f, 0xf0, 0x80, 0x18, 0x30, 0x04, 0x0e, 0x90, 0xff, 0xb3, 0xe0, 0x44, 0x80, 0xf0,
2470x12, 0x1c, 0x11, 0x12, 0x1a, 0x38, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0x07, 0xe4, 2470xc2, 0x04, 0xa3, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x54, 0xbf, 0xf0, 0xe4, 0xff,
2480xff, 0x12, 0x30, 0xec, 0x12, 0x1d, 0x37, 0x7f, 0x03, 0x12, 0x12, 0x19, 0x90, 0xf9, 0x15, 0xe0, 2480x02, 0x31, 0xa9, 0x12, 0x1c, 0xe0, 0x90, 0xfa, 0xb9, 0xe0, 0x24, 0xfc, 0x60, 0x0f, 0x04, 0x70,
2490x30, 0xe4, 0x08, 0x90, 0xff, 0x93, 0x74, 0x80, 0xf0, 0x80, 0x10, 0x90, 0xff, 0xfc, 0xe0, 0x54, 2490x16, 0x90, 0xff, 0xa6, 0xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x80, 0x0a, 0x90, 0xff, 0xb6,
2500x7f, 0xf0, 0x7f, 0xff, 0x7e, 0x00, 0x12, 0x30, 0x16, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 2500xe0, 0x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8,
2510xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x90, 0xfa, 0xbc, 0x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 2510x90, 0xf9, 0x15, 0x74, 0x01, 0xf0, 0x90, 0xf9, 0x1c, 0x74, 0x19, 0xf0, 0x90, 0xf9, 0x66, 0x74,
2520xb4, 0xf0, 0xa3, 0x74, 0x15, 0xf0, 0xe0, 0x54, 0x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 2520xff, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x12, 0x1d, 0xe7, 0x7f,
2530xb9, 0xf0, 0xd3, 0x94, 0x00, 0xe4, 0x94, 0x3e, 0x40, 0x08, 0x90, 0xfa, 0xbd, 0xe0, 0x90, 0xfa, 2530x03, 0x12, 0x12, 0x61, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe4, 0x08, 0x90, 0xff, 0x93, 0x74, 0x80,
2540xb9, 0xf0, 0x12, 0x0f, 0x50, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x73, 0x12, 0x1c, 0x4a, 0x90, 0xfa, 2540xf0, 0x80, 0x10, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0xff, 0x7e, 0x00, 0x12, 0x30,
2550xbc, 0x12, 0x1d, 0x56, 0x60, 0x27, 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 2550xd3, 0xc2, 0x90, 0xc2, 0xaf, 0x00, 0x80, 0xfd, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x90, 0xfa, 0xbf,
2560xfa, 0xb9, 0x74, 0x40, 0xf0, 0x80, 0x08, 0x90, 0xfa, 0xbd, 0xe0, 0x90, 0xfa, 0xb9, 0xf0, 0x12, 2560x74, 0x3e, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0xfa, 0xb7, 0xf0, 0xa3, 0x74, 0x15, 0xf0, 0xe0, 0x54,
2570x0f, 0x50, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x46, 0x12, 0x1c, 0x4a, 0x80, 0xd1, 0x75, 0x4c, 0x02, 2570x3f, 0xff, 0xc3, 0x74, 0x40, 0x9f, 0x90, 0xfa, 0xbc, 0xf0, 0xd3, 0x94, 0x00, 0xe4, 0x94, 0x3e,
2580x90, 0xfa, 0xbc, 0xe4, 0xf0, 0xa3, 0x04, 0xf0, 0x90, 0xfa, 0xb4, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 2580x40, 0x08, 0x90, 0xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45,
2590xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0x90, 0xfa, 0xbd, 0xe0, 0xf5, 0x4a, 0x7d, 0x0f, 0x7c, 2590x30, 0x70, 0x73, 0x12, 0x1c, 0xfa, 0x90, 0xfa, 0xbf, 0x12, 0x1e, 0x06, 0x60, 0x27, 0xd3, 0xef,
2600x00, 0x12, 0x28, 0x9f, 0x75, 0x30, 0x00, 0x8f, 0x31, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0xe4, 2600x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x08, 0x90, 0xfa, 0xbc, 0x74, 0x40, 0xf0, 0x80, 0x08, 0x90,
2610xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xaf, 0x31, 2610xfa, 0xc0, 0xe0, 0x90, 0xfa, 0xbc, 0xf0, 0x12, 0x0f, 0x98, 0xe5, 0x31, 0x45, 0x30, 0x70, 0x46,
2620x02, 0x30, 0xec, 0x12, 0x1c, 0xd0, 0x30, 0xe7, 0x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x64, 0xf0, 2620x12, 0x1c, 0xfa, 0x80, 0xd1, 0x75, 0x4c, 0x02, 0x90, 0xfa, 0xbf, 0xe4, 0xf0, 0xa3, 0x04, 0xf0,
2630xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80, 0x11, 0x90, 0xfa, 0xb7, 0xe0, 0x54, 0x0f, 0x90, 2630x90, 0xfa, 0xb7, 0xe4, 0xf0, 0xa3, 0x74, 0x0f, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0x90,
2640xf9, 0x63, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02, 0xc2, 0x94, 0xe4, 0xff, 0x02, 0x30, 0xec, 0x12, 2640xfa, 0xc0, 0xe0, 0xf5, 0x4a, 0x7d, 0x0f, 0x7c, 0x00, 0x12, 0x29, 0x60, 0x75, 0x30, 0x00, 0x8f,
2650x1d, 0x9c, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80, 0x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x30, 0xec, 2650x31, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x4c, 0xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26,
2660x12, 0x1c, 0xd0, 0x54, 0x03, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 2660x98, 0xe4, 0xf5, 0x30, 0xf5, 0x31, 0xaf, 0x31, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x30, 0xe7,
2670x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91, 0x80, 0x23, 0x12, 0x1d, 0xa6, 0x12, 0x0f, 0x78, 2670x10, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x67, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x15, 0xc2, 0x95, 0x80,
2680x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0x78, 0xff, 2680x11, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0f, 0x90, 0xf9, 0x65, 0xf0, 0xd3, 0x94, 0x00, 0x40, 0x02,
2690xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2, 0x91, 0x12, 0x1d, 0xa6, 0xf0, 0x90, 0xfa, 0xb7, 2690xc2, 0x94, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1e, 0x4c, 0xbf, 0x01, 0x04, 0xd2, 0x93, 0x80,
2700xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 2700x02, 0xc2, 0x93, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0x12, 0x1d, 0x80, 0x54, 0x03, 0x14, 0x60, 0x0a,
2710x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80, 0x27, 0xc2, 0x92, 0x80, 0x23, 0x12, 0x1d, 0xad, 2710x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x91, 0x80, 0x27, 0xc2, 0x91,
2720x12, 0x0f, 0x98, 0x60, 0x04, 0xd2, 0x92, 0x80, 0x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 2720x80, 0x23, 0x12, 0x1e, 0x56, 0x12, 0x0f, 0xc0, 0x60, 0x04, 0xd2, 0x91, 0x80, 0x17, 0x90, 0xff,
2730x0f, 0x98, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92, 0x80, 0x02, 0xd2, 0x92, 0x12, 0x1d, 0xad, 0xf0, 2730xa4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xc0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x91, 0x80, 0x02, 0xd2,
2740xe4, 0xff, 0x02, 0x30, 0xec, 0xe5, 0x35, 0x30, 0xe7, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 2740x91, 0x12, 0x1e, 0x56, 0xf0, 0x90, 0xfa, 0xba, 0xe0, 0x54, 0x0c, 0xff, 0x13, 0x13, 0x54, 0x3f,
2750x18, 0x7f, 0x05, 0x02, 0x30, 0xec, 0x12, 0x31, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb3, 2750x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x08, 0x24, 0x03, 0x70, 0x2b, 0xd2, 0x92, 0x80,
2760x90, 0xfa, 0xb4, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 2760x27, 0xc2, 0x92, 0x80, 0x23, 0x12, 0x1e, 0x5d, 0x12, 0x0f, 0xe0, 0x60, 0x04, 0xd2, 0x92, 0x80,
2770xfa, 0xb4, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 2770x17, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x10, 0x12, 0x0f, 0xe0, 0xff, 0xbf, 0xa0, 0x04, 0xc2, 0x92,
2780xaa, 0x4e, 0xa9, 0x4f, 0x7b, 0xff, 0x90, 0xfa, 0xb4, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 2780x80, 0x02, 0xd2, 0x92, 0x12, 0x1e, 0x5d, 0xf0, 0xe4, 0xff, 0x02, 0x31, 0xa9, 0xe5, 0x35, 0x30,
2790xb9, 0xe0, 0xf5, 0x4a, 0x12, 0x28, 0x9f, 0x75, 0x30, 0x00, 0x8f, 0x31, 0x22, 0x12, 0x22, 0xa0, 2790xe7, 0x07, 0xe4, 0xfd, 0x7f, 0x05, 0x02, 0x2f, 0xb4, 0x7f, 0x05, 0x02, 0x31, 0xa9, 0x12, 0x32,
2800x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22, 0xf0, 0x7f, 0x01, 0x12, 0x12, 0x19, 0x90, 0xff, 2800x7a, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb6, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
2810xa6, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x54, 0xa0, 0x22, 0x12, 0x25, 0xd7, 0x8f, 0x4c, 0x7e, 0x00, 2810xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb7, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b,
2820xc3, 0xef, 0x95, 0x3c, 0xee, 0x95, 0x3b, 0x22, 0xf0, 0x7f, 0x01, 0x12, 0x12, 0x19, 0x90, 0xff, 2820x1c, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xaa, 0x4e, 0xa9, 0x4f, 0x7b, 0xff, 0x90, 0xfa,
2830xb6, 0xe0, 0x90, 0xfa, 0xb8, 0xf0, 0x54, 0xa0, 0x22, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 2830xb7, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xbc, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60, 0x75,
2840x2c, 0x07, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x02, 0x31, 0x82, 0x8e, 0x39, 0x8f, 0x3a, 0x02, 0x2c, 2840x30, 0x00, 0x8f, 0x31, 0x22, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22,
2850x07, 0x12, 0x22, 0xa0, 0x7e, 0x00, 0x8e, 0x30, 0x8f, 0x31, 0xef, 0x22, 0x7d, 0x01, 0x12, 0x25, 2850xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0,
2860xd7, 0x90, 0xfa, 0xb1, 0xe0, 0x22, 0xef, 0x90, 0xf8, 0x04, 0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 2860x22, 0x12, 0x26, 0x98, 0x8f, 0x4c, 0x7e, 0x00, 0xc3, 0xef, 0x95, 0x3c, 0xee, 0x95, 0x3b, 0x22,
2870xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd, 0xfe, 0xde, 0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 2870xf0, 0x7f, 0x01, 0x12, 0x12, 0x61, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xbb, 0xf0, 0x54, 0xa0,
2880x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70, 0x03, 0xd0, 0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 2880x22, 0x75, 0x39, 0x00, 0x75, 0x3a, 0x01, 0x02, 0x2c, 0xd8, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x02,
2890xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x04, 0xc0, 0x05, 0xe5, 0x3e, 0x24, 2890x32, 0x3f, 0x8e, 0x39, 0x8f, 0x3a, 0x02, 0x2c, 0xd8, 0x12, 0x23, 0x61, 0x7e, 0x00, 0x8e, 0x30,
2900x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c, 0xff, 0x12, 0x10, 0x78, 0x7f, 0x00, 0x7e, 0x00, 2900x8f, 0x31, 0xef, 0x22, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xb4, 0xe0, 0x22, 0xef, 0x90,
2910xe5, 0x43, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 2910xf8, 0x04, 0xf0, 0x22, 0xc0, 0xa8, 0xc2, 0xaf, 0xee, 0x60, 0x0a, 0xc0, 0x05, 0x7d, 0x7f, 0xdd,
2920xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 2920xfe, 0xde, 0xfa, 0xd0, 0x05, 0xef, 0xc3, 0x94, 0x15, 0x50, 0x03, 0xd0, 0xa8, 0x22, 0x13, 0x70,
2930xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 2930x03, 0xd0, 0xa8, 0x22, 0xff, 0xd5, 0x07, 0xfd, 0xd0, 0xa8, 0x22, 0xc0, 0x00, 0xc0, 0x01, 0xc0,
2940xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 2940x02, 0xc0, 0x04, 0xc0, 0x05, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x86, 0x05, 0x53, 0x05, 0x7f, 0x7c,
2950xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x12, 0x11, 0x0f, 0xd0, 0x05, 0xd0, 2950xff, 0x12, 0x10, 0xc0, 0x7f, 0x00, 0x7e, 0x00, 0xe5, 0x43, 0x60, 0x46, 0xfc, 0x90, 0xf9, 0x1d,
2960x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x85, 0xa8, 0x44, 0x75, 0xa8, 0x88, 0xec, 0x70, 2960xe0, 0x54, 0x7f, 0x6d, 0x70, 0x0f, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
2970x02, 0x7c, 0x3f, 0x8c, 0x3d, 0x22, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0x66, 2970xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xdc, 0xe6, 0x80, 0x26, 0xdc, 0x06, 0xd0, 0x82,
2980x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x04, 0xc0, 0x06, 0x7c, 0xff, 0x12, 0x10, 2980xd0, 0x83, 0x80, 0x1e, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83,
2990x78, 0xe5, 0x43, 0x60, 0x42, 0xfe, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 2990xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3,
3000x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x43, 0x80, 0x07, 0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 3000x80, 0xda, 0x12, 0x11, 0x57, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22,
3010x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80, 0xd8, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 3010x85, 0xa8, 0x44, 0x75, 0xa8, 0x88, 0xec, 0x70, 0x02, 0x7c, 0x3f, 0x8c, 0x3d, 0x22, 0xe5, 0x3e,
3020xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3, 0xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 3020x24, 0x08, 0xf8, 0x76, 0x00, 0x12, 0x11, 0xae, 0x80, 0xfb, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02,
3030xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78, 0x08, 0x08, 0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 3030xc0, 0x04, 0xc0, 0x06, 0x7c, 0xff, 0x12, 0x10, 0xc0, 0xe5, 0x43, 0x60, 0x42, 0xfe, 0x90, 0xf9,
3040x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77, 0x00, 0x80, 0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 3040x1d, 0xe0, 0x54, 0x7f, 0x6f, 0x70, 0x0b, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x15, 0x43,
3050xee, 0x12, 0x11, 0x0f, 0xd0, 0x06, 0xd0, 0x04, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 3050x80, 0x07, 0xa3, 0xa3, 0xa3, 0xde, 0xea, 0x80, 0x26, 0xde, 0x06, 0xd0, 0x82, 0xd0, 0x83, 0x80,
3060x3d, 0x00, 0x85, 0x44, 0xa8, 0x22, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc3, 0xe5, 0x43, 0x24, 3060xd8, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xd0, 0x82, 0xd0, 0x83, 0xe8, 0xf0, 0xa3,
3070xe8, 0x50, 0x05, 0x12, 0x11, 0x66, 0x80, 0xf4, 0xef, 0x60, 0x31, 0x90, 0x30, 0x54, 0xe4, 0x93, 3070xe9, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0x80, 0xda, 0x78,
3080xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff, 0x12, 0x10, 0x78, 0xd0, 0x04, 0x43, 0x07, 0x80, 3080x08, 0x08, 0x79, 0x18, 0x09, 0x7c, 0x01, 0xe6, 0x54, 0x7f, 0x6f, 0x70, 0x06, 0x76, 0x00, 0x77,
3090xe5, 0x43, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 3090x00, 0x80, 0x06, 0x08, 0x09, 0x0c, 0xbc, 0x08, 0xee, 0x12, 0x11, 0x57, 0xd0, 0x06, 0xd0, 0x04,
3100xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05, 0x43, 0x12, 0x11, 0x0f, 0xd0, 0x83, 0xd0, 0x82, 3100xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0x22, 0x75, 0x3d, 0x00, 0x85, 0x44, 0xa8, 0x22, 0xc0, 0xf0,
3110xd0, 0xf0, 0x22, 0x02, 0x11, 0x94, 0xc0, 0x04, 0x7c, 0x20, 0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 3110xc0, 0x82, 0xc0, 0x83, 0xc3, 0xe5, 0x43, 0x24, 0xe8, 0x50, 0x05, 0x12, 0x11, 0xae, 0x80, 0xf4,
3120xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75, 0x88, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 3120xef, 0x60, 0x31, 0x90, 0x31, 0x11, 0xe4, 0x93, 0xc3, 0x9f, 0x40, 0x2f, 0xc0, 0x04, 0x7c, 0xff,
3130x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04, 0xf0, 0x90, 0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 3130x12, 0x10, 0xc0, 0xd0, 0x04, 0x43, 0x07, 0x80, 0xe5, 0x43, 0x75, 0xf0, 0x03, 0xa4, 0x24, 0x1d,
3140xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90, 0xff, 0x48, 0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 3140xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xef, 0xf0, 0xec, 0xa3, 0xf0, 0xed, 0xa3, 0xf0, 0x05,
3150xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 3150x43, 0x12, 0x11, 0x57, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x02, 0x11, 0xdc, 0xc0, 0x04,
3160xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 3160x7c, 0x20, 0xd2, 0x8c, 0xd2, 0x8d, 0xd5, 0x04, 0xfd, 0xd0, 0x04, 0x22, 0x75, 0xa8, 0x00, 0x75,
3170x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0xd2, 0xb0, 0xd2, 0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 3170x88, 0x00, 0x75, 0xb8, 0x00, 0x75, 0xf0, 0x00, 0x75, 0xd0, 0x00, 0xe4, 0xf8, 0x90, 0xf8, 0x04,
3180x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x0f, 0xdc, 3180xf0, 0x90, 0x00, 0x00, 0xf6, 0x08, 0xb8, 0x00, 0xfb, 0x02, 0x00, 0x00, 0xc2, 0xaf, 0xe4, 0x90,
3190x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x03, 0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 3190xff, 0x48, 0xf0, 0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x08, 0xf0, 0x90, 0xff, 0x10, 0xf0, 0x90,
3200xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x42, 0x8e, 0x41, 0x22, 0xc3, 0xef, 0x94, 0xbc, 3200xff, 0x80, 0xf0, 0xa3, 0xa3, 0xf0, 0xd2, 0xb1, 0xc2, 0xb0, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10,
3210xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f, 0xd0, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 3210x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0xd2,
3220xbf, 0x00, 0x01, 0x0e, 0x8f, 0x40, 0x8e, 0x3f, 0x22, 0xef, 0x70, 0x01, 0x22, 0xc0, 0x00, 0xc0, 3220xb0, 0xd2, 0xb1, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10,
3230xa8, 0xc2, 0xaf, 0xe5, 0x3e, 0x24, 0x18, 0xf8, 0xa6, 0x07, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0xc6, 3230x24, 0x7e, 0xff, 0x7f, 0xff, 0x12, 0x10, 0x24, 0x80, 0xcc, 0xc3, 0xee, 0x94, 0x02, 0x50, 0x04,
3240x54, 0x7f, 0xf6, 0xd0, 0xa8, 0xe6, 0x30, 0xe7, 0x03, 0xd0, 0x00, 0x22, 0x12, 0x11, 0x66, 0x80, 3240x7e, 0x03, 0x7f, 0xe8, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f,
3250xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08, 0xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, 3250x42, 0x8e, 0x41, 0x22, 0xc3, 0xef, 0x94, 0xbc, 0xee, 0x94, 0x02, 0x50, 0x04, 0x7e, 0x07, 0x7f,
3260x12, 0x11, 0x66, 0x80, 0xee, 0xd0, 0x00, 0x22, 0xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 3260xd0, 0xef, 0xf4, 0xff, 0xee, 0xf4, 0xfe, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0x8f, 0x40, 0x8e, 0x3f,
3270xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8, 0x76, 0x9a, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, 3270x22, 0xef, 0x70, 0x01, 0x22, 0xc0, 0x00, 0xc0, 0xa8, 0xc2, 0xaf, 0xe5, 0x3e, 0x24, 0x18, 0xf8,
3280x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83, 0xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, 3280xa6, 0x07, 0xe5, 0x3e, 0x24, 0x08, 0xf8, 0xc6, 0x54, 0x7f, 0xf6, 0xd0, 0xa8, 0xe6, 0x30, 0xe7,
3290x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f, 0x75, 0xf0, 0x02, 0xa4, 0x24, 0x36, 0xf5, 0x82, 3290x03, 0xd0, 0x00, 0x22, 0x12, 0x11, 0xae, 0x80, 0xf4, 0xc0, 0x00, 0x7f, 0x01, 0xef, 0x24, 0x08,
3300xe5, 0xf0, 0x34, 0x30, 0xf5, 0x83, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, 3300xf8, 0xe6, 0x60, 0x09, 0x0f, 0xbf, 0x08, 0xf5, 0x12, 0x11, 0xae, 0x80, 0xee, 0xd0, 0x00, 0x22,
3310x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24, 0x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, 3310xc0, 0xf0, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x00, 0xc0, 0x06, 0xc0, 0x04, 0xed, 0x24, 0x10, 0xf8,
3320xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0xf0, 0x22, 0x75, 0x3e, 0x00, 0x75, 0x43, 3320x76, 0x9a, 0xed, 0x75, 0xf0, 0x21, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0xf8, 0xf5, 0x83,
3330x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76, 0x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, 3330xc0, 0x82, 0xc0, 0x83, 0xa3, 0xa3, 0xe4, 0x78, 0x0d, 0xf0, 0xa3, 0xd8, 0xfc, 0xef, 0x54, 0x7f,
3340xf8, 0x04, 0xe0, 0xfc, 0x90, 0x30, 0x54, 0xe4, 0x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, 3340x75, 0xf0, 0x02, 0xa4, 0x24, 0xf3, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x30, 0xf5, 0x83, 0xe4, 0x93,
3350x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f, 0xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, 3350xfe, 0x74, 0x01, 0x93, 0xfc, 0xd0, 0x83, 0xd0, 0x82, 0xec, 0xf0, 0xa3, 0xee, 0xf0, 0xed, 0x24,
3360xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75, 0x81, 0x8b, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, 3360x08, 0xf8, 0xef, 0x44, 0x80, 0xf6, 0xd0, 0x04, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0x83, 0xd0, 0x82,
3370xe5, 0x43, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x1b, 0xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, 3370xd0, 0xf0, 0x22, 0x75, 0x3e, 0x00, 0x75, 0x43, 0x00, 0x7a, 0x08, 0x79, 0x18, 0x78, 0x08, 0x76,
3380x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6, 0x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, 3380x00, 0x77, 0x00, 0x08, 0x09, 0xda, 0xf8, 0x90, 0xf8, 0x04, 0xe0, 0xfc, 0x90, 0x31, 0x11, 0xe4,
3390xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0, 0x07, 0x12, 0x12, 0x41, 0xad, 0x07, 0xaf, 0x02, 3390x93, 0xc3, 0x9c, 0x50, 0x05, 0xe4, 0x90, 0xf8, 0x04, 0xf0, 0x78, 0x08, 0x74, 0x80, 0x44, 0x7f,
3400x12, 0x12, 0x58, 0xd0, 0x07, 0xa3, 0xa3, 0xa3, 0xdf, 0xce, 0x12, 0x11, 0x66, 0x80, 0xc1, 0x8f, 3400xf6, 0x74, 0x01, 0x44, 0x10, 0xf5, 0x89, 0x75, 0xb8, 0x00, 0xd2, 0xab, 0xd2, 0xa9, 0x22, 0x75,
3410x24, 0x12, 0x2a, 0x06, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 3410x81, 0x8b, 0xd2, 0x8e, 0xd2, 0x8c, 0xd2, 0xaf, 0xe5, 0x43, 0x60, 0x36, 0xff, 0x90, 0xf9, 0x1d,
3420x21, 0xf3, 0xe0, 0xfd, 0x12, 0x22, 0x8a, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x21, 0xf3, 0xed, 0xf0, 3420xe0, 0x54, 0x80, 0x60, 0x28, 0x78, 0x08, 0x79, 0x08, 0xe0, 0x54, 0x7f, 0xfa, 0x7b, 0x00, 0xe6,
3430x12, 0x22, 0x56, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xe0, 0xff, 0x12, 0x22, 0x99, 0x24, 0x09, 0x12, 3430x54, 0x7f, 0xb5, 0x02, 0x02, 0x7b, 0xff, 0x08, 0xd9, 0xf5, 0xeb, 0x70, 0x10, 0xea, 0xf0, 0xc0,
3440x21, 0xf3, 0xef, 0xf0, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x22, 0x09, 0xc0, 3440x07, 0x12, 0x12, 0x89, 0xad, 0x07, 0xaf, 0x02, 0x12, 0x12, 0xa0, 0xd0, 0x07, 0xa3, 0xa3, 0xa3,
3450x83, 0xc0, 0x82, 0xa3, 0xe0, 0x25, 0xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 3450xdf, 0xce, 0x12, 0x11, 0xae, 0x80, 0xc1, 0x8f, 0x24, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xb5, 0xa3,
3460x82, 0xe0, 0x33, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x78, 0x80, 0x12, 0x22, 0x09, 3460xa3, 0xe0, 0xa3, 0x30, 0xe7, 0x28, 0x78, 0x7e, 0x12, 0x22, 0x99, 0xe0, 0x44, 0x01, 0xf0, 0x12,
3470xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0xff, 0x12, 0x22, 0x8a, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x21, 3470x22, 0xfa, 0x12, 0x22, 0x9d, 0xe0, 0x20, 0xe0, 0xf6, 0x12, 0x23, 0x50, 0x74, 0x02, 0xf0, 0x12,
3480xf3, 0xef, 0xf0, 0xed, 0x12, 0x22, 0x99, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xed, 0xf0, 0x12, 0x21, 3480x22, 0xda, 0xe0, 0xa3, 0x30, 0xe5, 0x07, 0x12, 0x23, 0x50, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x80,
3490xfb, 0xe0, 0xff, 0x30, 0xe7, 0x19, 0x12, 0x22, 0x6e, 0x12, 0x21, 0xf3, 0xe0, 0x60, 0x09, 0x12, 3490xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x23,
3500x21, 0xfb, 0xef, 0x44, 0x02, 0xf0, 0x80, 0x07, 0x12, 0x21, 0xfb, 0xef, 0x54, 0xfd, 0xf0, 0x78, 3500x39, 0x8a, 0x83, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x23, 0x06, 0x24, 0x07, 0x12,
3510x7e, 0x12, 0x22, 0x09, 0xa3, 0xa3, 0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 3510x22, 0xa1, 0xe0, 0xff, 0x12, 0x23, 0x5a, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x90, 0xf9,
3520xfd, 0x12, 0x22, 0x43, 0xa3, 0xe0, 0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 3520x16, 0xe0, 0x30, 0xe4, 0x20, 0x08, 0x12, 0x22, 0xb7, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xe0, 0x25,
3530x05, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x31, 0x94, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x78, 0x80, 3530xe0, 0xff, 0x05, 0x82, 0xd5, 0x82, 0x02, 0x15, 0x83, 0x15, 0x82, 0xe0, 0x33, 0xd0, 0x82, 0xd0,
3540xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x24, 0x06, 0x12, 0x21, 0xf3, 0xe0, 0x60, 0x03, 0x43, 0x07, 3540x83, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x22, 0xb5, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xec, 0xff, 0x12,
3550x04, 0x53, 0x07, 0xfc, 0x78, 0x80, 0x12, 0x22, 0x7a, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0x42, 3550x23, 0x39, 0x8a, 0x83, 0x24, 0x08, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0xed, 0x12, 0x23, 0x5a, 0x24,
3560x07, 0x43, 0x07, 0x80, 0x12, 0x22, 0x8a, 0xf5, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xef, 0xf0, 0x12, 3560x07, 0x12, 0x22, 0xa1, 0xed, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0x30, 0xe6, 0x0a, 0x12, 0x23, 0x41,
3570x22, 0x99, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0xff, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xe0, 3570x24, 0x09, 0x12, 0x22, 0xa1, 0xe4, 0xf0, 0x12, 0x22, 0xa9, 0xe0, 0xff, 0x30, 0xe7, 0x1b, 0x12,
3580xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf, 0x80, 0x03, 0x43, 0x07, 0x20, 0xec, 3580x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x60, 0x09, 0x12, 0x22, 0xa9, 0xef, 0x44, 0x02,
3590x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07, 0x10, 0x12, 0x21, 0xfb, 0xe0, 0xfe, 3590xf0, 0x80, 0x07, 0x12, 0x22, 0xa9, 0xef, 0x54, 0xfd, 0xf0, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3,
3600x54, 0x03, 0x60, 0x73, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1, 0x69, 0x78, 0x80, 0x12, 0x22, 0x6f, 3600xa3, 0xe0, 0xff, 0x53, 0x07, 0xc7, 0x08, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x12, 0x22, 0xe0, 0xa3,
3610x12, 0x21, 0xf3, 0xe0, 0x12, 0x1b, 0x4c, 0x14, 0xa6, 0x00, 0x14, 0xda, 0x01, 0x14, 0xdf, 0x03, 3610xe0, 0x30, 0xe3, 0x12, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0x12, 0x22, 0xa1, 0xe0,
3620x14, 0xda, 0x05, 0x14, 0xdf, 0x07, 0x14, 0xda, 0x09, 0x14, 0xdf, 0x0b, 0x14, 0xda, 0x0d, 0x14, 3620x90, 0x32, 0x51, 0x93, 0x42, 0x07, 0x53, 0x07, 0xfb, 0x12, 0x23, 0x1e, 0x24, 0x06, 0x12, 0x22,
3630xdf, 0x0f, 0x00, 0x00, 0x14, 0xe7, 0xe5, 0x24, 0x64, 0x03, 0x70, 0x21, 0x90, 0xf9, 0x15, 0xe0, 3630xa1, 0xe0, 0x60, 0x03, 0x43, 0x07, 0x04, 0x53, 0x07, 0xfc, 0x78, 0x80, 0x12, 0x23, 0x29, 0x24,
3640x30, 0xe2, 0x0d, 0x30, 0xb4, 0x05, 0x43, 0x07, 0x02, 0x80, 0x2c, 0x53, 0x07, 0xfd, 0x80, 0x27, 3640x04, 0x12, 0x22, 0xa1, 0xe0, 0x42, 0x07, 0x43, 0x07, 0x80, 0x12, 0x23, 0x39, 0xf5, 0x82, 0x8a,
3650x30, 0x95, 0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07, 0xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 3650x83, 0xa3, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0x5a, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0xff, 0x8d,
3660x43, 0x07, 0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d, 0x43, 0x07, 0x02, 0x80, 0x08, 0x53, 3660x82, 0x8c, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe1, 0x05, 0x53, 0x07, 0xdf,
3670x07, 0xfd, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x22, 0x78, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xef, 3670x80, 0x03, 0x43, 0x07, 0x20, 0xec, 0x30, 0xe4, 0x05, 0x53, 0x07, 0xef, 0x80, 0x03, 0x43, 0x07,
3680xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff, 0x12, 0x21, 0xfb, 0xe0, 0xfe, 0x54, 3680x10, 0x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x60, 0x73, 0x53, 0x07, 0xdf, 0xee, 0x30, 0xe1,
3690x03, 0x70, 0x03, 0x02, 0x15, 0xd7, 0xee, 0x20, 0xe1, 0x03, 0x02, 0x15, 0xd4, 0x12, 0x22, 0x6e, 3690x69, 0x12, 0x23, 0x1e, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc, 0x15, 0x2c, 0x00,
3700x12, 0x21, 0xf3, 0xe0, 0x12, 0x1b, 0x4c, 0x15, 0x36, 0x00, 0x15, 0x6c, 0x01, 0x15, 0x6c, 0x03, 3700x15, 0x60, 0x01, 0x15, 0x65, 0x03, 0x15, 0x60, 0x05, 0x15, 0x65, 0x07, 0x15, 0x60, 0x09, 0x15,
3710x15, 0xa0, 0x05, 0x15, 0xa0, 0x07, 0x15, 0x86, 0x09, 0x15, 0x86, 0x0b, 0x15, 0xba, 0x0d, 0x15, 3710x65, 0x0b, 0x15, 0x60, 0x0d, 0x15, 0x65, 0x0f, 0x00, 0x00, 0x15, 0x6d, 0xe5, 0x24, 0x64, 0x03,
3720xba, 0x0f, 0x00, 0x00, 0x15, 0xd7, 0xe5, 0x24, 0x64, 0x03, 0x70, 0x23, 0x90, 0xf9, 0x15, 0xe0, 3720x70, 0x21, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0d, 0x30, 0xb4, 0x05, 0x43, 0x07, 0x02, 0x80,
3730x30, 0xe2, 0x0f, 0x30, 0xb1, 0x06, 0x53, 0x07, 0x7f, 0x02, 0x15, 0xd7, 0x43, 0x07, 0x80, 0x02, 3730x2c, 0x53, 0x07, 0xfd, 0x80, 0x27, 0x30, 0x95, 0x05, 0x43, 0x07, 0x02, 0x80, 0x1f, 0x53, 0x07,
3740x15, 0xd7, 0x30, 0x94, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x7d, 0x43, 0x07, 0x80, 0x80, 0x78, 0x30, 3740xfd, 0x80, 0x1a, 0x30, 0x93, 0x05, 0x43, 0x07, 0x02, 0x80, 0x12, 0x53, 0x07, 0xfd, 0x80, 0x0d,
3750x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x70, 0x43, 0x07, 0x80, 0x80, 0x6b, 0xe5, 0x24, 0xb4, 0x03, 3750x43, 0x07, 0x02, 0x80, 0x08, 0x53, 0x07, 0xfd, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x12, 0x23, 0x27,
3760x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 3760x24, 0x04, 0x12, 0x22, 0xa1, 0xef, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xff,
3770xf0, 0x53, 0x07, 0x7f, 0x80, 0x51, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 3770x12, 0x22, 0xa9, 0xe0, 0xfe, 0x54, 0x03, 0x70, 0x03, 0x02, 0x16, 0x60, 0xee, 0x20, 0xe1, 0x03,
3780x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x37, 3780x02, 0x16, 0x5d, 0x08, 0x12, 0x23, 0x20, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0x12, 0x1b, 0xfc,
3790xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 3790x15, 0xbf, 0x00, 0x15, 0xf5, 0x01, 0x15, 0xf5, 0x03, 0x16, 0x29, 0x05, 0x16, 0x29, 0x07, 0x16,
3800x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x43, 0x07, 0x80, 0x80, 0x1d, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 3800x0f, 0x09, 0x16, 0x0f, 0x0b, 0x16, 0x43, 0x0d, 0x16, 0x43, 0x0f, 0x00, 0x00, 0x16, 0x60, 0xe5,
3810xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x43, 3810x24, 0x64, 0x03, 0x70, 0x23, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe2, 0x0f, 0x30, 0xb1, 0x06, 0x53,
3820x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f, 0x78, 0x80, 0x12, 0x22, 0x3f, 0xe0, 0xfc, 0xa3, 0xe0, 3820x07, 0x7f, 0x02, 0x16, 0x60, 0x43, 0x07, 0x80, 0x02, 0x16, 0x60, 0x30, 0x94, 0x05, 0x53, 0x07,
3830xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03, 0x53, 0x07, 0xdf, 0xec, 0x30, 0xe3, 0x05, 3830x7f, 0x80, 0x7d, 0x43, 0x07, 0x80, 0x80, 0x78, 0x30, 0x92, 0x05, 0x53, 0x07, 0x7f, 0x80, 0x70,
3840x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x10, 0x80, 3840x43, 0x07, 0x80, 0x80, 0x6b, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xef,
3850x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43, 0x07, 0x08, 0x80, 0x03, 0x53, 0x07, 0xf7, 3850xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x51, 0xe5,
3860xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03, 0x53, 0x07, 0xfb, 0xed, 0x30, 0xe6, 0x05, 3860x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e,
3870x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed, 0x30, 0xe7, 0x05, 0x43, 0x07, 0x02, 0x80, 3870xe0, 0x44, 0x20, 0xf0, 0x53, 0x07, 0x7f, 0x80, 0x37, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff,
3880x03, 0x53, 0x07, 0xfd, 0x78, 0x7e, 0x12, 0x22, 0x3f, 0xa3, 0xef, 0xf0, 0x12, 0x31, 0xc7, 0x7f, 3880x9e, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xdf, 0xf0, 0x43, 0x07,
3890x00, 0x22, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x16, 0xf0, 0x90, 0xff, 0xf9, 0x74, 3890x80, 0x80, 0x1d, 0xe5, 0x24, 0xb4, 0x03, 0x09, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x10, 0xf0, 0x80,
3900x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcc, 0xe4, 0xfd, 0x12, 0x22, 0xa0, 0x90, 0xfa, 0xcc, 3900x07, 0x90, 0xff, 0x9e, 0xe0, 0x44, 0x20, 0xf0, 0x43, 0x07, 0x80, 0x80, 0x03, 0x53, 0x07, 0x7f,
3910xe4, 0x75, 0xf0, 0x03, 0x12, 0x1a, 0x6c, 0x12, 0x18, 0xe2, 0xe5, 0x23, 0x30, 0xe7, 0x02, 0xd2, 3910x12, 0x22, 0xda, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x30, 0xe0, 0x05, 0x43, 0x07, 0x20, 0x80, 0x03,
3920x02, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x24, 0x90, 0xfa, 0xcc, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 3920x53, 0x07, 0xdf, 0xec, 0x30, 0xe3, 0x05, 0x43, 0x07, 0x40, 0x80, 0x03, 0x53, 0x07, 0xbf, 0xec,
3930x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 3930x30, 0xe0, 0x05, 0x43, 0x07, 0x10, 0x80, 0x03, 0x53, 0x07, 0xef, 0xed, 0x30, 0xe4, 0x05, 0x43,
3940x00, 0x7a, 0x00, 0x79, 0x23, 0x75, 0x2d, 0x00, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0xe5, 3940x07, 0x08, 0x80, 0x03, 0x53, 0x07, 0xf7, 0xed, 0x30, 0xe5, 0x05, 0x43, 0x07, 0x04, 0x80, 0x03,
3950x23, 0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x23, 0x64, 0x07, 0x60, 0x1e, 0xe5, 0x23, 0x64, 3950x53, 0x07, 0xfb, 0xed, 0x30, 0xe6, 0x05, 0x43, 0x07, 0x01, 0x80, 0x03, 0x53, 0x07, 0xfe, 0xed,
3960x06, 0x60, 0x18, 0xe5, 0x23, 0x64, 0x14, 0x60, 0x12, 0xe5, 0x23, 0x64, 0x41, 0x60, 0x0c, 0xe5, 3960x30, 0xe7, 0x05, 0x43, 0x07, 0x02, 0x80, 0x03, 0x53, 0x07, 0xfd, 0x78, 0x7e, 0x12, 0x22, 0xdc,
3970x23, 0x64, 0x1a, 0x70, 0x46, 0xe5, 0x24, 0x64, 0x02, 0x70, 0x40, 0xe5, 0x23, 0xb4, 0x07, 0x16, 3970xa3, 0xef, 0xf0, 0x12, 0x32, 0x84, 0x7f, 0x00, 0x22, 0x90, 0xff, 0xfa, 0x74, 0x08, 0xf0, 0xa3,
3980xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 3980x74, 0x16, 0xf0, 0x90, 0xff, 0xf9, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf, 0xe4,
3990xe0, 0x44, 0x02, 0xf0, 0x80, 0x1e, 0xe5, 0x23, 0xb4, 0x41, 0x12, 0x90, 0xf9, 0x15, 0xe0, 0x44, 3990xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x1b, 0x1c, 0x12, 0x19,
4000x06, 0xf0, 0xa3, 0xe0, 0x44, 0x06, 0xf0, 0xd2, 0xb1, 0xd2, 0xb4, 0x80, 0x07, 0x90, 0xf9, 0x15, 4000x92, 0xe5, 0x23, 0x30, 0xe7, 0x02, 0xd2, 0x02, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x24, 0x90, 0xfa,
4010xe0, 0x44, 0x01, 0xf0, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x23, 0x64, 0x42, 0x60, 4010xcf, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xcf,
4020x05, 0xe5, 0x23, 0xb4, 0x43, 0x0c, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x80, 0xf0, 0xa3, 0xe0, 0x44, 4020xe4, 0xf0, 0xa3, 0x74, 0x0b, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x75, 0x2d, 0x00, 0xf5,
4030x80, 0xf0, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x18, 0xe2, 0x90, 0xff, 4030x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0xe5, 0x23, 0x24, 0x80, 0x90, 0xff, 0xf8, 0xf0, 0xe5, 0x23,
4040xf5, 0xe5, 0x23, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x33, 0xf5, 0x34, 0xf5, 0x32, 0x12, 0x1d, 0x84, 4040x64, 0x07, 0x60, 0x1e, 0xe5, 0x23, 0x64, 0x06, 0x60, 0x18, 0xe5, 0x23, 0x64, 0x14, 0x60, 0x12,
4050x12, 0x1c, 0x30, 0x12, 0x1d, 0x8b, 0x90, 0xf9, 0x67, 0x12, 0x1b, 0x43, 0x90, 0xf9, 0x6c, 0x12, 4050xe5, 0x23, 0x64, 0x41, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x1a, 0x70, 0x46, 0xe5, 0x24, 0x64, 0x02,
4060x1b, 0x43, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81, 4060x70, 0x40, 0xe5, 0x23, 0xb4, 0x07, 0x16, 0xd2, 0x94, 0xd2, 0x95, 0xd2, 0x92, 0xd2, 0x93, 0x90,
4070xf9, 0x16, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1e, 0xe5, 0x23, 0xb4,
4080x41, 0x12, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x06, 0xf0, 0xa3, 0xe0, 0x44, 0x06, 0xf0, 0xd2, 0xb1,
4090xd2, 0xb4, 0x80, 0x07, 0x90, 0xf9, 0x16, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x44,
4100x01, 0xf0, 0xe5, 0x23, 0x64, 0x42, 0x60, 0x0c, 0xe5, 0x23, 0x64, 0x43, 0x60, 0x06, 0xe5, 0x23,
4110x64, 0x44, 0x70, 0x2e, 0x90, 0xf9, 0x16, 0xe0, 0xff, 0xe5, 0x23, 0xb4, 0x44, 0x04, 0x7e, 0x40,
4120x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9, 0x16, 0xf0, 0xa3, 0xe0, 0xff, 0xe5,
4130x23, 0xb4, 0x44, 0x04, 0x7e, 0x40, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x24, 0x80, 0x4f, 0x90, 0xf9,
4140x17, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, 0xa3, 0x74, 0x0d, 0xf0, 0x12, 0x19, 0x92, 0x90, 0xff,
4150xf5, 0xe5, 0x23, 0xf0, 0xe4, 0xf5, 0x35, 0xf5, 0x33, 0xf5, 0x34, 0xf5, 0x32, 0x12, 0x1e, 0x34,
4160x12, 0x1c, 0xe0, 0x12, 0x1e, 0x3b, 0x90, 0xf9, 0x6a, 0x12, 0x1b, 0xf3, 0x90, 0xf9, 0x6f, 0x12,
4170x1b, 0xf3, 0x90, 0xff, 0xff, 0xe4, 0xf0, 0x90, 0xff, 0x83, 0xe0, 0xe4, 0xf0, 0x90, 0xff, 0x81,
4070x74, 0x80, 0xf0, 0xa3, 0x74, 0x84, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xe4, 0xf5, 0x23, 0xe5, 0x23, 4180x74, 0x80, 0xf0, 0xa3, 0x74, 0x84, 0xf0, 0x90, 0xff, 0x80, 0xf0, 0xe4, 0xf5, 0x23, 0xe5, 0x23,
4080x12, 0x1c, 0xa7, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x23, 0x12, 0x1c, 0xb5, 0xf5, 0x83, 0xe4, 0xf0, 4190x12, 0x1d, 0x57, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x23, 0x12, 0x1d, 0x65, 0xf5, 0x83, 0xe4, 0xf0,
4090x05, 0x23, 0xe5, 0x23, 0xb4, 0x07, 0xe7, 0x78, 0x7a, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x31, 4200x05, 0x23, 0xe5, 0x23, 0xb4, 0x07, 0xe7, 0x78, 0x7a, 0x76, 0xfe, 0x08, 0x76, 0xf0, 0x90, 0x32,
4100x4d, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x31, 0x5a, 0xe4, 0x93, 0xff, 4210x0a, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xad, 0x07, 0x90, 0x32, 0x17, 0xe4, 0x93, 0xff,
4110x08, 0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x1c, 0x97, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0, 4220x08, 0xf6, 0xff, 0xed, 0x54, 0x0f, 0xfd, 0x12, 0x1d, 0x47, 0x74, 0x84, 0xf0, 0xed, 0x75, 0xf0,
4120x08, 0xa4, 0x24, 0x47, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xc3, 0x74, 0xf0, 4230x08, 0xa4, 0x24, 0x47, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xc3, 0x74, 0xf0,
4130x9f, 0x78, 0x7b, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x1c, 0x28, 0xce, 0xc3, 0x13, 0xce, 4240x9f, 0x78, 0x7b, 0xf6, 0x74, 0xfe, 0x94, 0x00, 0x18, 0x12, 0x1c, 0xd8, 0xce, 0xc3, 0x13, 0xce,
4140x13, 0xd8, 0xf9, 0xff, 0xed, 0x12, 0x1c, 0xf8, 0xef, 0xf0, 0xed, 0x12, 0x1d, 0x1e, 0xe4, 0xf5, 4250x13, 0xd8, 0xf9, 0xff, 0xed, 0x12, 0x1d, 0xa8, 0xef, 0xf0, 0xed, 0x12, 0x1d, 0xce, 0xe4, 0xf5,
4150x23, 0xe5, 0x23, 0x90, 0x31, 0x47, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xe5, 0x23, 0x25, 0xe0, 4260x23, 0xe5, 0x23, 0x90, 0x32, 0x04, 0x93, 0xff, 0x78, 0x78, 0xf6, 0xfd, 0xe5, 0x23, 0x25, 0xe0,
4160x24, 0x4e, 0xf5, 0x82, 0xe4, 0x34, 0x31, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7, 4270x24, 0x0b, 0xf5, 0x82, 0xe4, 0x34, 0x32, 0xf5, 0x83, 0xe4, 0x93, 0x08, 0xf6, 0xed, 0x30, 0xe7,
4170x53, 0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1c, 0x97, 0x12, 0x1d, 0x06, 0x24, 0x47, 0xf5, 0x82, 4280x53, 0x18, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x47, 0x12, 0x1d, 0xb6, 0x24, 0x47, 0xf5, 0x82,
4180xe4, 0x34, 0xff, 0x12, 0x1c, 0x18, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12, 4290xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe9, 0x12,
4190x1c, 0xf8, 0xef, 0xf0, 0x12, 0x1c, 0x1f, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 4300x1d, 0xa8, 0xef, 0xf0, 0x12, 0x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d,
4200x0b, 0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x1d, 0x1e, 4310xbb, 0x24, 0x45, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x12, 0x1d, 0xce,
4210xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x46, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 4320xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x46, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80,
4220xf0, 0x02, 0x18, 0xb7, 0x78, 0x78, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1c, 0xea, 0x12, 0x1d, 0x06, 4330xf0, 0x02, 0x19, 0x67, 0x78, 0x78, 0xe6, 0x54, 0x0f, 0xf9, 0x12, 0x1d, 0x9a, 0x12, 0x1d, 0xb6,
4230x24, 0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x1c, 0x18, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 4340x24, 0x07, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0x12, 0x1c, 0xc8, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8,
4240xf9, 0x12, 0x1d, 0x0b, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12, 4350xf9, 0x12, 0x1d, 0xbb, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0x12,
4250x1c, 0x1f, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 0x0b, 0x24, 0x05, 0xf5, 0x82, 4360x1c, 0xcf, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x12, 0x1d, 0xbb, 0x24, 0x05, 0xf5, 0x82,
4260xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 4370xe4, 0x34, 0xff, 0xf5, 0x83, 0xef, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82,
4270xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 4380xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0xe9, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82,
4280xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x23, 0xe5, 0x23, 0x64, 0x04, 0x60, 0x03, 0x02, 4390xe4, 0x34, 0xff, 0xf5, 0x83, 0xe4, 0xf0, 0x05, 0x23, 0xe5, 0x23, 0x64, 0x04, 0x60, 0x03, 0x02,
4290x17, 0xe1, 0x90, 0x31, 0x4c, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0x12, 0x1c, 0xe8, 0xe4, 0xf0, 4400x18, 0x91, 0x90, 0x32, 0x09, 0xe4, 0x93, 0xff, 0x78, 0x78, 0xf6, 0x12, 0x1d, 0x98, 0xe4, 0xf0,
4300x90, 0x31, 0x4b, 0x93, 0xff, 0xf6, 0x12, 0x1c, 0x95, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05, 4410x90, 0x32, 0x08, 0x93, 0xff, 0xf6, 0x12, 0x1d, 0x45, 0xe4, 0xf0, 0x90, 0xff, 0xfd, 0x74, 0x05,
4310xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 4420xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12,
4320x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x25, 0xd7, 0xe7, 0x09, 0xf6, 0x08, 4430x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0xe7, 0x09, 0xf6, 0x08,
4330xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e, 0x88, 0x82, 0x8c, 0x83, 4440xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e, 0x88, 0x82, 0x8c, 0x83,
4340xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x78, 4450xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x78,
4350xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83, 0xe3, 0x09, 0xf0, 0xa3, 4460xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83, 0xe3, 0x09, 0xf0, 0xa3,
@@ -445,7 +456,7 @@ static unsigned char IMAGE_ARRAY_NAME[] =
4450x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc, 0x88, 0xf0, 0xef, 0x60, 4560x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc, 0x88, 0xf0, 0xef, 0x60,
4460x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xb9, 0xf5, 4570x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xb9, 0xf5,
4470x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 0x23, 0x45, 0x82, 0x23, 0x90, 0x19, 4580x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 0x23, 0x45, 0x82, 0x23, 0x90, 0x19,
4480x4c, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 4590xfc, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb,
4490xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 4600xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82,
4500x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 4610x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8,
4510xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 4620xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82,
@@ -469,364 +480,365 @@ static unsigned char IMAGE_ARRAY_NAME[] =
4690xe0, 0xf9, 0x22, 0xeb, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xe9, 0xf0, 0x22, 0xd0, 0x83, 0xd0, 0x82, 4800xe0, 0xf9, 0x22, 0xeb, 0xf0, 0xa3, 0xea, 0xf0, 0xa3, 0xe9, 0xf0, 0x22, 0xd0, 0x83, 0xd0, 0x82,
4700xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 4810xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01,
4710x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 4820x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3,
4720x80, 0xdf, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0xe5, 0x4c, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 4830x80, 0xdf, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0xe5, 0x4c, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25,
4730x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0x74, 0x11, 0x12, 4840x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0x74, 0x11, 0x12,
4740x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x06, 4850x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x06,
4750xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 4860xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38,
4760xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 0x38, 0x04, 0x25, 4870xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 0xe8, 0x04, 0x25,
4770x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a, 4880x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0xab, 0x36, 0xfa, 0xa9, 0x38, 0xe4, 0x12, 0x1a,
4780x38, 0x04, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x04, 0xe0, 0xab, 4890xe8, 0x04, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x90, 0xff, 0x04, 0xe0, 0xab,
4790x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 4900x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8, 0x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35,
4800x37, 0xf5, 0x37, 0x90, 0xff, 0x05, 0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0x38, 4910x37, 0xf5, 0x37, 0x90, 0xff, 0x05, 0xe0, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x12, 0x1a, 0xe8,
4810x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x22, 0xf5, 0x83, 0xe0, 0x54, 4920x74, 0x01, 0x25, 0x38, 0xf5, 0x38, 0xe4, 0x35, 0x37, 0xf5, 0x37, 0x22, 0xf5, 0x83, 0xe0, 0x54,
4820x08, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xf5, 0x83, 0xef, 0xf0, 0xfd, 0x7c, 0x00, 0xc3, 4930x08, 0xab, 0x36, 0xaa, 0x37, 0xa9, 0x38, 0x22, 0xf5, 0x83, 0xef, 0xf0, 0xfd, 0x7c, 0x00, 0xc3,
4830x78, 0x7b, 0xe6, 0x9d, 0xf6, 0x18, 0xe6, 0x9c, 0xf6, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x03, 0x22, 4940x78, 0x7b, 0xe6, 0x9d, 0xf6, 0x18, 0xe6, 0x9c, 0xf6, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x03, 0x22,
4840x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 0x6f, 0x22, 0xe0, 0x44, 0x04, 0xf0, 0x74, 0x12, 4950x75, 0x36, 0x01, 0x75, 0x37, 0xf9, 0x75, 0x38, 0x72, 0x22, 0xe0, 0x44, 0x04, 0xf0, 0x74, 0x13,
4850x2f, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xe0, 0x22, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x7e, 4960x2f, 0xf5, 0x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0xe0, 0x22, 0x90, 0xfa, 0xbc, 0xe0, 0xff, 0x7e,
4860x00, 0xc3, 0x90, 0xfa, 0xbd, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xbc, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 4970x00, 0xc3, 0x90, 0xfa, 0xc0, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xbf, 0xe0, 0x9e, 0xf0, 0x90, 0xfa,
4870xb4, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0xef, 0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5, 4980xb7, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x4f, 0xf5, 0x4f, 0xee, 0x35, 0x4e, 0xf5,
4880x4e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb1, 0x90, 0xfa, 0xb4, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 4990x4e, 0x22, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xb4, 0x90, 0xfa, 0xb7, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
4890xf5, 0x2e, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x04, 0xf5, 0x82, 0xe4, 5000xf5, 0x2e, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x04, 0xf5, 0x82, 0xe4,
4900x35, 0x83, 0xf5, 0x83, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe4, 5010x35, 0x83, 0xf5, 0x83, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe4,
4910x34, 0xff, 0xf5, 0x83, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x48, 0xf5, 0x82, 0xe4, 5020x34, 0xff, 0xf5, 0x83, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x48, 0xf5, 0x82, 0xe4,
4920x34, 0xff, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x34, 0xff, 5030x34, 0xff, 0x22, 0xe5, 0x4d, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x34, 0xff,
4930x22, 0x90, 0xfa, 0xb6, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22, 5040x22, 0x90, 0xfa, 0xb9, 0xe0, 0xff, 0x24, 0xfc, 0x22, 0x90, 0xff, 0x00, 0xe0, 0x54, 0x1f, 0x22,
4940x90, 0xfa, 0xbb, 0xe0, 0x90, 0xfa, 0xb7, 0xf0, 0x22, 0x75, 0x33, 0x00, 0x8f, 0x34, 0x90, 0xf9, 5050x90, 0xfa, 0xbe, 0xe0, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x75, 0x33, 0x00, 0x8f, 0x34, 0x90, 0xf9,
4950x6c, 0x12, 0x1b, 0x3a, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 5060x6f, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x02, 0x22, 0x54, 0x0f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00,
4960xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x41, 0xf5, 0x82, 5070xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x41, 0xf5, 0x82,
4970xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x74, 0x80, 0xf0, 0x08, 0xe6, 0xff, 0xe9, 0x75, 0xf0, 0x08, 5080xe4, 0x34, 0xff, 0xf5, 0x83, 0x22, 0x74, 0x80, 0xf0, 0x08, 0xe6, 0xff, 0xe9, 0x75, 0xf0, 0x08,
4980xa4, 0x22, 0x74, 0xaf, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0, 5090xa4, 0x22, 0x74, 0xb2, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0x22, 0x75, 0xf0,
4990x08, 0xa4, 0x24, 0x42, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x22, 0x90, 5100x08, 0xa4, 0x24, 0x42, 0xf5, 0x82, 0xe4, 0x34, 0xff, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x22, 0x90,
5000xff, 0x82, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x03, 0xf0, 0x90, 0xff, 5110xff, 0x82, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x03, 0xf0, 0x90, 0xff,
5010xfc, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x78, 0x67, 0xe6, 0x54, 0xfd, 0xf6, 0x90, 0xff, 0xfd, 0x74, 5120xfc, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x78, 0x67, 0xe6, 0x54, 0xfd, 0xf6, 0x90, 0xff, 0xfd, 0x74,
5020x65, 0xf0, 0x22, 0x12, 0x1b, 0x1c, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a, 5130x65, 0xf0, 0x22, 0x12, 0x1b, 0xcc, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x22, 0x7b, 0x01, 0x7a,
5030xfa, 0x79, 0xb4, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0, 5140xfa, 0x79, 0xb7, 0x22, 0x90, 0xff, 0x80, 0xe0, 0x44, 0x08, 0xf0, 0x22, 0x90, 0xff, 0x83, 0xe0,
5040x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x67, 0x02, 0x1b, 0x3a, 0x90, 0xff, 0xa4, 0xe0, 5150x54, 0x7f, 0xf0, 0x22, 0xe0, 0xff, 0x90, 0xf9, 0x6a, 0x02, 0x1b, 0xea, 0x90, 0xff, 0xa4, 0xe0,
5050x44, 0x02, 0xf0, 0x22, 0x75, 0x39, 0x01, 0x75, 0x3a, 0x09, 0x22, 0x7b, 0x01, 0x7a, 0xf9, 0x79, 5160x44, 0x02, 0xf0, 0x22, 0x75, 0x39, 0x01, 0x75, 0x3a, 0x09, 0x22, 0x7b, 0x01, 0x7a, 0xf9, 0x79,
5060x6f, 0x22, 0xd3, 0xe5, 0x3c, 0x94, 0x08, 0xe5, 0x3b, 0x94, 0x01, 0x22, 0x90, 0xfa, 0xbb, 0xe0, 5170x72, 0x22, 0xd3, 0xe5, 0x3c, 0x94, 0x08, 0xe5, 0x3b, 0x94, 0x01, 0x22, 0x90, 0xfa, 0xbe, 0xe0,
5070xff, 0x90, 0xfa, 0xb7, 0xf0, 0x22, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4, 5180xff, 0x90, 0xfa, 0xba, 0xf0, 0x22, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xef, 0x22, 0x90, 0xff, 0xb4,
5080xe0, 0x54, 0xef, 0x22, 0x12, 0x10, 0x03, 0x78, 0x88, 0xef, 0xf6, 0x12, 0x2a, 0x06, 0x12, 0x22, 5190xe0, 0x54, 0xef, 0x22, 0x12, 0x10, 0x4b, 0x78, 0x88, 0xef, 0xf6, 0x12, 0x2a, 0xc7, 0x12, 0x22,
5090x4a, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x21, 0xf3, 0xe0, 0xfd, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x0a, 5200xfa, 0x8e, 0x83, 0x24, 0x09, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x0a,
5100x12, 0x22, 0x52, 0x24, 0x0a, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x1a, 0x4a, 0x12, 5210x12, 0x23, 0x02, 0x24, 0x0a, 0x12, 0x22, 0xa1, 0xe0, 0x90, 0x00, 0x0b, 0x12, 0x1a, 0xfa, 0x12,
5110x22, 0x4a, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x53, 0x12, 0x22, 0x56, 0x24, 5220x22, 0xfa, 0xf5, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x53, 0x12, 0x23, 0x06, 0x24,
5120x04, 0x12, 0x21, 0xf3, 0xe0, 0xf5, 0x54, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x55, 5230x04, 0x12, 0x22, 0xa1, 0xe0, 0xf5, 0x54, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x55,
5130xe5, 0x53, 0xc4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x78, 0x88, 0xf6, 0xd3, 0x94, 0x00, 0x40, 0x06, 5240xe5, 0x53, 0xc4, 0x13, 0x13, 0x13, 0x54, 0x01, 0x78, 0x88, 0xf6, 0xd3, 0x94, 0x00, 0x40, 0x06,
5140xe5, 0x54, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x88, 0xe6, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x0c, 0xef, 5250xe5, 0x54, 0x30, 0xe1, 0x01, 0x06, 0x78, 0x88, 0xe6, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x0c, 0xef,
5150x12, 0x1a, 0x4a, 0x78, 0x80, 0x12, 0x22, 0x09, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x53, 5260x12, 0x1a, 0xfa, 0x12, 0x22, 0xb5, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x53, 0x07, 0x0c,
5160x07, 0x0c, 0x53, 0x06, 0xe6, 0xe5, 0x53, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, 0x54, 0x20, 5270x53, 0x06, 0xe6, 0xe5, 0x53, 0x30, 0xe5, 0x03, 0x43, 0x07, 0x01, 0xe5, 0x54, 0x20, 0xe5, 0x0e,
5170xe5, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, 0x07, 0x02, 5280xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43, 0x07, 0x02, 0xe5, 0x53,
5180xe5, 0x53, 0x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x53, 0x30, 0xe2, 0x03, 0x43, 0x07, 0x20, 5290x30, 0xe3, 0x03, 0x43, 0x07, 0x10, 0xe5, 0x53, 0x30, 0xe2, 0x03, 0x43, 0x07, 0x20, 0xe5, 0x53,
5190xe5, 0x53, 0x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x53, 0x30, 0xe1, 0x03, 0x43, 0x07, 5300x54, 0x03, 0x60, 0x03, 0x43, 0x07, 0x40, 0xe5, 0x53, 0x30, 0xe1, 0x03, 0x43, 0x07, 0x80, 0xe5,
5200x80, 0xe5, 0x53, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x53, 0x30, 0xe6, 0x03, 0x43, 0x06, 5310x53, 0x30, 0xe4, 0x03, 0x43, 0x06, 0x01, 0xe5, 0x53, 0x30, 0xe6, 0x03, 0x43, 0x06, 0x08, 0xe5,
5210x08, 0xe5, 0x54, 0x20, 0xe4, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 5320x54, 0x20, 0xe4, 0x0e, 0xe5, 0x53, 0x54, 0x7f, 0x70, 0x08, 0xe5, 0x53, 0x20, 0xe7, 0x03, 0x43,
5220x03, 0x43, 0x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, 0x8f, 0xf0, 5330x06, 0x10, 0x53, 0x07, 0xfb, 0x53, 0x06, 0x79, 0x90, 0x00, 0x05, 0xee, 0x8f, 0xf0, 0x12, 0x1b,
5230x12, 0x1a, 0xef, 0xe5, 0x55, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, 0x12, 0x22, 5340x9f, 0xe5, 0x55, 0x30, 0xe3, 0x12, 0x54, 0x30, 0xff, 0xc4, 0x54, 0x0f, 0x12, 0x22, 0xe7, 0x90,
5240x2c, 0x90, 0x00, 0x08, 0xef, 0x12, 0x1a, 0x4a, 0x80, 0x0a, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x08, 5350x00, 0x08, 0xef, 0x12, 0x1a, 0xfa, 0x80, 0x0a, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x08, 0xe4, 0x12,
5250xe4, 0x12, 0x1a, 0x4a, 0xe5, 0x55, 0x54, 0x03, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x07, 0xef, 0x12, 5360x1a, 0xfa, 0xe5, 0x55, 0x54, 0x03, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x07, 0xef, 0x12, 0x1a, 0xfa,
5260x1a, 0x4a, 0xe5, 0x55, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x1a, 0x4a, 0x90, 5370xe5, 0x55, 0x54, 0x04, 0xff, 0xc3, 0x13, 0x90, 0x00, 0x09, 0x12, 0x1a, 0xfa, 0x90, 0x00, 0x07,
5270x00, 0x07, 0x12, 0x1a, 0x0b, 0x70, 0x13, 0x12, 0x22, 0x2d, 0xe9, 0x24, 0x09, 0xf9, 0xe4, 0x3a, 5380x12, 0x1a, 0xbb, 0x70, 0x13, 0x12, 0x22, 0xe8, 0xe9, 0x24, 0x09, 0xf9, 0xe4, 0x3a, 0xfa, 0x12,
5280xfa, 0x12, 0x19, 0xf2, 0xff, 0xc3, 0x13, 0x12, 0x1a, 0x38, 0x12, 0x22, 0x78, 0x24, 0x08, 0x12, 5390x1a, 0xa2, 0xff, 0xc3, 0x13, 0x12, 0x1a, 0xe8, 0x12, 0x23, 0x27, 0x24, 0x08, 0x12, 0x22, 0xa1,
5290x21, 0xf3, 0xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x21, 0xf3, 0xe0, 5400xe0, 0xfe, 0x8d, 0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x07, 0x12, 0x22, 0xa1, 0xe0, 0xfd, 0xee,
5300xfd, 0xee, 0xed, 0x12, 0x22, 0x2c, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0xef, 0x12, 5410xed, 0x12, 0x22, 0xe7, 0x90, 0x00, 0x03, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x9f, 0x12, 0x32, 0x84,
5310x31, 0xc7, 0x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2f, 0x18, 0x02, 0x10, 0x86, 0x90, 0xfa, 0xe3, 0xe0, 5420x7d, 0x0a, 0xe4, 0xff, 0x12, 0x2f, 0xb4, 0x02, 0x10, 0xce, 0x90, 0xfa, 0xe6, 0xe0, 0xb4, 0x03,
5320xb4, 0x03, 0x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, 0xfa, 0xd7, 5430x06, 0x7e, 0x00, 0x7f, 0x40, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x08, 0x90, 0xfa, 0xda, 0xee, 0xf0,
5330xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0xff, 0x7e, 0x00, 0x90, 0xfa, 5440xa3, 0xef, 0xf0, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0xff, 0x7e, 0x00, 0x90, 0xfa, 0xd6, 0xee,
5340xd3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, 0x12, 0x1a, 5450xf0, 0xa3, 0xef, 0xf0, 0x70, 0x03, 0x7f, 0x08, 0x22, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xff,
5350x98, 0xff, 0x90, 0xfa, 0xd5, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, 0x01, 0x8e, 5460x90, 0xfa, 0xd8, 0xe5, 0xf0, 0xf0, 0xa3, 0xef, 0xf0, 0xae, 0x02, 0xaf, 0x01, 0x8e, 0x50, 0x8f,
5360x50, 0x8f, 0x51, 0x74, 0x0a, 0x25, 0x51, 0xf5, 0x51, 0xe4, 0x35, 0x50, 0xf5, 0x50, 0x90, 0xfa, 5470x51, 0x74, 0x0a, 0x25, 0x51, 0xf5, 0x51, 0xe4, 0x35, 0x50, 0xf5, 0x50, 0x90, 0xfa, 0xdb, 0xe0,
5370xd8, 0xe0, 0xff, 0x14, 0xfe, 0x90, 0xfa, 0xd6, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, 0xff, 0x90, 5480xff, 0x14, 0xfe, 0x90, 0xfa, 0xd9, 0xe0, 0x5e, 0xfe, 0xc3, 0xef, 0x9e, 0xff, 0x90, 0xfa, 0xdd,
5380xfa, 0xda, 0xf0, 0xc3, 0x90, 0xfa, 0xd4, 0xe0, 0x9f, 0x90, 0xfa, 0xd3, 0xe0, 0x94, 0x00, 0x50, 5490xf0, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0x90, 0xfa, 0xd6, 0xe0, 0x94, 0x00, 0x50, 0x06, 0xa3,
5390x06, 0xa3, 0xe0, 0x90, 0xfa, 0xda, 0xf0, 0x12, 0x1f, 0xfb, 0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 5500xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff, 0x22, 0x12, 0x2e, 0x2b,
5400x2d, 0x5a, 0x90, 0xfa, 0xd3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, 0xfa, 0xd7, 5510x90, 0xfa, 0xd6, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x4e, 0x60, 0x2b, 0x90, 0xfa, 0xda, 0xe0, 0xfc,
5410xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, 0xfa, 0xda, 5520xa3, 0xe0, 0xfd, 0xd3, 0xef, 0x9d, 0xee, 0x9c, 0x40, 0x07, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x80,
5420xf0, 0x80, 0x08, 0x90, 0xfa, 0xd4, 0xe0, 0x90, 0xfa, 0xda, 0xf0, 0x12, 0x1f, 0xfb, 0x60, 0x03, 5530x08, 0x90, 0xfa, 0xd7, 0xe0, 0x90, 0xfa, 0xdd, 0xf0, 0x12, 0x20, 0xa9, 0x60, 0x03, 0xe0, 0xff,
5430xe0, 0xff, 0x22, 0x12, 0x2d, 0x5a, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 5540x22, 0x12, 0x2e, 0x2b, 0x80, 0xca, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x52, 0xe4, 0xf5, 0x2d, 0xf5,
5440x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x7f, 0x00, 0x22, 0xaa, 0x50, 0xa9, 0x51, 0x7b, 5550x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7f, 0x00, 0x22, 0xaa, 0x50, 0xa9, 0x51, 0x7b, 0x01, 0x90,
5450x01, 0x90, 0xfa, 0xd5, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xda, 0xe0, 0xf5, 0x4a, 0x12, 5560xfa, 0xd8, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x90, 0xfa, 0xdd, 0xe0, 0xf5, 0x4a, 0x12, 0x29, 0x60,
5460x28, 0x9f, 0x90, 0xfa, 0xd9, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, 0xfe, 0x60, 5570x90, 0xfa, 0xdc, 0xef, 0xf0, 0x22, 0xef, 0x24, 0xae, 0x60, 0x52, 0x24, 0xfe, 0x60, 0x2e, 0x24,
5470x2e, 0x24, 0xfe, 0x70, 0x03, 0x02, 0x20, 0xbb, 0x24, 0x06, 0x60, 0x03, 0x02, 0x21, 0x03, 0x78, 5580xfe, 0x70, 0x03, 0x02, 0x21, 0x69, 0x24, 0x06, 0x60, 0x03, 0x02, 0x21, 0xb1, 0x78, 0x71, 0xe6,
5480x71, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x33, 5590x54, 0xfb, 0xf6, 0x90, 0xff, 0xa5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x33, 0x90, 0xfa,
5490x90, 0xfa, 0x91, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xaf, 0x74, 0x01, 0xf0, 0x22, 0x78, 5600x94, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb2, 0x74, 0x01, 0xf0, 0x22, 0x78, 0x72, 0xe6,
5500x72, 0xe6, 0x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x43, 5610x54, 0xfb, 0xf6, 0x90, 0xff, 0xb5, 0xe0, 0xf5, 0x22, 0x44, 0x0f, 0xf0, 0x74, 0x43, 0x90, 0xfa,
5510x90, 0xfa, 0x93, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb0, 0x74, 0x01, 0xf0, 0x22, 0x90, 5620x96, 0xf0, 0xe5, 0x22, 0xa3, 0xf0, 0x90, 0xfa, 0xb3, 0x74, 0x01, 0xf0, 0x22, 0x90, 0xfa, 0xa0,
5520xfa, 0x9d, 0xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x21, 0x03, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 5630xe0, 0xa3, 0x20, 0xe5, 0x03, 0x02, 0x21, 0xb1, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0,
5530xca, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xca, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 5640xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xa6, 0x12,
5540xa6, 0x12, 0x22, 0x5d, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xca, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 5650x23, 0x0d, 0x90, 0xff, 0xa6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0,
5550xcb, 0xe0, 0xff, 0x74, 0x34, 0xfe, 0x12, 0x2c, 0xb4, 0xef, 0x70, 0x57, 0x90, 0xfa, 0xcb, 0xe0, 5660xff, 0x74, 0x34, 0xfe, 0x12, 0x2d, 0x85, 0xef, 0x70, 0x57, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74,
5560xff, 0x74, 0x34, 0x90, 0xfa, 0x95, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xa7, 0xe0, 0xa3, 5670x34, 0x90, 0xfa, 0x98, 0xf0, 0xef, 0xa3, 0xf0, 0x22, 0x90, 0xfa, 0xaa, 0xe0, 0xa3, 0x30, 0xe5,
5570x30, 0xe5, 0x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xca, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xca, 5680x40, 0x90, 0xff, 0xb6, 0xe0, 0x90, 0xfa, 0xcd, 0xf0, 0xa3, 0xf0, 0x90, 0xfa, 0xcd, 0xe0, 0xff,
5580xe0, 0xff, 0x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x22, 0x5d, 0x90, 0xff, 0xb6, 5690x54, 0x0f, 0xfe, 0x60, 0x10, 0x90, 0xff, 0xb6, 0x12, 0x23, 0x0d, 0x90, 0xff, 0xb6, 0xe0, 0x90,
5590xe0, 0x90, 0xfa, 0xca, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xcb, 0xe0, 0xff, 0x74, 0x44, 0xfe, 0x12, 5700xfa, 0xcd, 0xf0, 0x80, 0xe6, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0xfe, 0x12, 0x2d, 0x85,
5600x2c, 0xb4, 0xef, 0x70, 0x0e, 0x90, 0xfa, 0xcb, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, 0x97, 0xf0, 5710xef, 0x70, 0x0e, 0x90, 0xfa, 0xce, 0xe0, 0xff, 0x74, 0x44, 0x90, 0xfa, 0x9a, 0xf0, 0xef, 0xa3,
5610xef, 0xa3, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 5720xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0,
5620x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 5730x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x90,
5630x07, 0x90, 0xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xc9, 0xf0, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0xef, 5740xff, 0x92, 0xe0, 0xff, 0x90, 0xfa, 0xcc, 0xf0, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0xef, 0x12, 0x1b,
5640x12, 0x1b, 0x4c, 0x21, 0xbb, 0x26, 0x21, 0xbb, 0x2e, 0x21, 0x5e, 0x30, 0x21, 0x5e, 0x32, 0x21, 5750xfc, 0x22, 0x69, 0x26, 0x22, 0x69, 0x2e, 0x22, 0x0c, 0x30, 0x22, 0x0c, 0x32, 0x22, 0x1a, 0x38,
5650x6c, 0x38, 0x21, 0x7e, 0x3a, 0x21, 0xb0, 0x3e, 0x21, 0x9b, 0x44, 0x21, 0x90, 0x46, 0x21, 0xa6, 5760x22, 0x2c, 0x3a, 0x22, 0x5e, 0x3e, 0x22, 0x49, 0x44, 0x22, 0x3e, 0x46, 0x22, 0x54, 0x50, 0x22,
5660x50, 0x21, 0xa6, 0x52, 0x21, 0xa6, 0x54, 0x21, 0xa6, 0x56, 0x00, 0x00, 0x21, 0xc0, 0x90, 0xfa, 5770x54, 0x52, 0x22, 0x54, 0x54, 0x22, 0x54, 0x56, 0x00, 0x00, 0x22, 0x6e, 0x90, 0xfa, 0xcc, 0xe0,
5670xc9, 0xe0, 0xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x11, 0x16, 0x80, 0x62, 0x7c, 0x00, 0x7d, 0x01, 5780xfd, 0x7c, 0x00, 0x7f, 0x01, 0x12, 0x11, 0x5e, 0x80, 0x62, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x03,
5680x7f, 0x03, 0x12, 0x11, 0x16, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, 0x7c, 0x00, 5790x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x50, 0x7c, 0x00, 0x7d, 0x01,
5690x7d, 0x01, 0x7f, 0x02, 0x12, 0x11, 0x16, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x3e, 5800x7f, 0x02, 0x12, 0x11, 0x5e, 0x90, 0xff, 0xfe, 0xe0, 0x44, 0x40, 0xf0, 0x80, 0x3e, 0x7c, 0x00,
5700x7c, 0x00, 0x7d, 0x01, 0x7f, 0x05, 0x12, 0x11, 0x16, 0x80, 0x33, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 5810x7d, 0x01, 0x7f, 0x05, 0x12, 0x11, 0x5e, 0x80, 0x33, 0x7c, 0x00, 0x7d, 0x01, 0x7f, 0x06, 0x12,
5710x06, 0x12, 0x11, 0x16, 0x80, 0x28, 0x90, 0xfa, 0xc9, 0xe0, 0xff, 0x12, 0x20, 0x18, 0x80, 0x1e, 5820x11, 0x5e, 0x80, 0x28, 0x90, 0xfa, 0xcc, 0xe0, 0xff, 0x12, 0x20, 0xc6, 0x80, 0x1e, 0x7c, 0x00,
5720x7c, 0x00, 0x7d, 0x01, 0x7f, 0x04, 0x12, 0x11, 0x16, 0x80, 0x13, 0x12, 0x27, 0x8d, 0x80, 0x0e, 5830x7d, 0x01, 0x7f, 0x04, 0x12, 0x11, 0x5e, 0x80, 0x13, 0x12, 0x28, 0x4e, 0x80, 0x0e, 0x90, 0xfa,
5730x90, 0xfa, 0xc9, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x2c, 0xb4, 0xd0, 0x07, 5840xcc, 0xe0, 0x24, 0x00, 0xff, 0xe4, 0x34, 0xff, 0xfe, 0x12, 0x2d, 0x85, 0xd0, 0x07, 0xd0, 0x06,
5740xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 5850xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82,
5750xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x24, 5860xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0x24, 0x04, 0x8e,
5760x04, 0x8e, 0x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x74, 0x12, 0x25, 0x24, 0xf5, 5870x83, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 0x74, 0x13, 0x25, 0x24, 0xf5, 0x82, 0xe4,
5770x82, 0xe4, 0x34, 0xf9, 0xf5, 0x83, 0x22, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 5880x34, 0xf9, 0xf5, 0x83, 0x22, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0x22,
5780x83, 0x22, 0x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 5890x78, 0x80, 0xe6, 0xfe, 0x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0x7b, 0xff, 0x7a,
5790xff, 0x7a, 0x31, 0x79, 0x99, 0x7e, 0x00, 0x7f, 0x0a, 0x02, 0x19, 0xcc, 0xff, 0x90, 0xf9, 0x6c, 5900x32, 0x79, 0x56, 0x7e, 0x00, 0x7f, 0x0a, 0x02, 0x1a, 0x7c, 0x78, 0x80, 0xe6, 0xfc, 0x08, 0xe6,
5800x02, 0x1b, 0x3a, 0x90, 0xf9, 0x67, 0x12, 0x1b, 0x3a, 0x90, 0x00, 0x04, 0x02, 0x1a, 0x0b, 0xe6, 5910xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, 0xff, 0x90, 0xf9, 0x6f, 0x02, 0x1b, 0xea, 0x90, 0xf9,
5810xfc, 0x08, 0xe6, 0xf5, 0x82, 0x8c, 0x83, 0xa3, 0xa3, 0x22, 0x78, 0x7e, 0xe6, 0xfe, 0x08, 0xe6, 5920x6a, 0x12, 0x1b, 0xea, 0x90, 0x00, 0x04, 0x02, 0x1a, 0xbb, 0x78, 0x7e, 0xe6, 0xfe, 0x08, 0xe6,
5820xff, 0x22, 0xed, 0x12, 0x1a, 0x4a, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90, 5930xff, 0x22, 0xed, 0x12, 0x1a, 0xfa, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x22, 0xef, 0xf0, 0x90,
5830xfa, 0xcb, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, 0xf0, 0x4e, 0xf0, 0x22, 0x08, 0xe6, 5940xfa, 0xce, 0xe0, 0x54, 0x0f, 0x4e, 0xfe, 0xf0, 0xef, 0x54, 0xf0, 0x4e, 0xf0, 0x22, 0x78, 0x80,
5840xfc, 0x08, 0xe6, 0x8c, 0x83, 0x24, 0x09, 0x22, 0x78, 0x7e, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 5950xe6, 0xfc, 0x08, 0xe6, 0x8c, 0x83, 0x22, 0x78, 0x7e, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x8c, 0x83,
5850x83, 0x22, 0xa6, 0x07, 0xe6, 0x24, 0x6e, 0xf8, 0xe6, 0x22, 0x78, 0x7e, 0xe6, 0xfa, 0x08, 0xe6, 5960x22, 0xa6, 0x07, 0xe6, 0x24, 0x6e, 0xf8, 0xe6, 0x22, 0x78, 0x7e, 0xe6, 0xfa, 0x08, 0xe6, 0xfb,
5860xfb, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22, 0x8b, 0x82, 0x8a, 0x83, 0xe5, 0x82, 0x22, 5970x22, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x22, 0x26, 0xf6, 0x18, 0xee, 0x36, 0xf6, 0x22,
5870x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0x8d, 0x28, 0x90, 0xfa, 0xcf, 0xe4, 0xf0, 0xa3, 0x74, 0x02, 5980xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0x22, 0x8b, 0x82, 0x8a, 0x83, 0xe5, 0x82,
5880xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xce, 0x90, 0xfa, 0xcf, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0, 0xf5, 5990x22, 0x8b, 0x25, 0x8a, 0x26, 0x89, 0x27, 0x8d, 0x28, 0x90, 0xfa, 0xd2, 0xe4, 0xf0, 0xa3, 0x74,
5890x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xce, 0xe0, 0x65, 0x28, 0x60, 0x46, 0xa3, 0xe0, 6000x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe0, 0xf5, 0x2d, 0xa3, 0xe0,
5900xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0x2f, 0x90, 0xfa, 0xce, 0xe0, 6010xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xd1, 0xe0, 0x65, 0x28, 0x60, 0x46, 0xa3,
5910xff, 0x90, 0xfa, 0xd1, 0xe4, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0x12, 0x23, 0x2f, 0x90, 0xfa, 0xd1, 6020xe0, 0xff, 0xa3, 0xe0, 0xa3, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x23, 0xf0, 0x90, 0xfa, 0xd1,
5920xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xcf, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xfa, 0xce, 0xe0, 6030xe0, 0xff, 0x90, 0xfa, 0xd4, 0xe4, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0x12, 0x23, 0xf0, 0x90, 0xfa,
5930xa3, 0x75, 0xf0, 0x00, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x04, 0x12, 0x1a, 6040xd4, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0xfa, 0xd2, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xfa, 0xd1,
5940x6c, 0x02, 0x22, 0xb1, 0x90, 0xfa, 0xd0, 0xe0, 0x24, 0x01, 0xff, 0x90, 0xfa, 0xcf, 0xe0, 0x34, 6050xe0, 0xa3, 0x75, 0xf0, 0x00, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x04, 0x12,
5950x00, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x8f, 0xf0, 0x12, 0x1a, 0xd0, 0x7f, 0x00, 0x22, 0x7b, 6060x1b, 0x1c, 0x02, 0x23, 0x72, 0x90, 0xfa, 0xd3, 0xe0, 0x24, 0x01, 0xff, 0x90, 0xfa, 0xd2, 0xe0,
5960x01, 0x7a, 0xfa, 0x79, 0xce, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1a, 0x6c, 0x85, 6070x34, 0x00, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x8f, 0xf0, 0x12, 0x1b, 0x80, 0x7f, 0x00, 0x22,
5970xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x25, 0xd7, 0x8f, 0x62, 0x12, 0x2a, 0x06, 0x12, 0x22, 6080x7b, 0x01, 0x7a, 0xfa, 0x79, 0xd1, 0x90, 0xfa, 0xd2, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x1c,
5980x4a, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x21, 0xf3, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x02, 0xf0, 0x08, 6090x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x02, 0x26, 0x98, 0x8f, 0x62, 0x12, 0x2a, 0xc7, 0x12,
5990x12, 0x22, 0x3f, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x22, 0x56, 0x24, 0x0b, 0x12, 0x21, 0xf3, 6100x22, 0xfa, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x02, 0xf0,
6000xe0, 0x44, 0x01, 0xf0, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 6110x08, 0x12, 0x22, 0xdc, 0xe0, 0xa3, 0x30, 0xe5, 0x0c, 0x12, 0x23, 0x06, 0x24, 0x0b, 0x12, 0x22,
6010x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x62, 0x24, 0xfe, 0x44, 0x20, 0xfc, 0x4d, 0xf0, 0xe5, 0x82, 0x24, 6120xa1, 0xe0, 0x44, 0x01, 0xf0, 0x78, 0x7c, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xf5, 0x82, 0x8e, 0x83,
6020x04, 0x12, 0x21, 0xf3, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0x74, 6130xe0, 0x54, 0xb8, 0xfd, 0xf0, 0xe5, 0x62, 0x24, 0xfe, 0x44, 0x20, 0xfc, 0x4d, 0xf0, 0xe5, 0x82,
6030x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x05, 0x12, 0x21, 0xf3, 0xc0, 6140x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xb8, 0xf0, 0x4c, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3,
6040x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x96, 0x25, 0x62, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 6150x74, 0x03, 0xf0, 0x18, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x8e, 0x83, 0x24, 0x05, 0x12, 0x22, 0xa1,
6050xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 6160xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x74, 0x99, 0x25, 0x62, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5,
6060x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x21, 0xf3, 0xe0, 0x44, 0x80, 0xf0, 6170x83, 0xe0, 0x54, 0xfc, 0x44, 0x03, 0xfc, 0xed, 0x4c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82,
6070x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x62, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 6180x8e, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0, 0x44, 0x80,
6080x10, 0x03, 0x7f, 0x02, 0x12, 0x12, 0x19, 0x78, 0x67, 0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0, 0xd2, 6190xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x62, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22,
6090xb1, 0x90, 0xf9, 0x15, 0xe0, 0x30, 0xe7, 0x07, 0x90, 0xff, 0x9e, 0xe4, 0xf0, 0x80, 0x36, 0xd2, 6200x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x12, 0x61, 0x78, 0x67, 0xe6, 0x44, 0x02, 0xf6, 0xd2, 0xb0,
6100xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, 0x7b, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa, 0x7c, 6210xd2, 0xb1, 0x90, 0xf9, 0x16, 0xe0, 0x30, 0xe7, 0x07, 0x90, 0xff, 0x9e, 0xe4, 0xf0, 0x80, 0x36,
6110xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, 0x79, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa, 0x7a, 6220xd2, 0xb3, 0x90, 0xff, 0xa4, 0xe0, 0x90, 0xfa, 0x7e, 0xf0, 0x90, 0xff, 0xb4, 0xe0, 0x90, 0xfa,
6120xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74, 0x40, 6230x7f, 0xf0, 0x90, 0xff, 0xa2, 0xe0, 0x90, 0xfa, 0x7c, 0xf0, 0x90, 0xff, 0xb2, 0xe0, 0x90, 0xfa,
6130xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, 0xe4, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90, 0xff, 6240x7d, 0xf0, 0x90, 0xff, 0xa4, 0x74, 0x30, 0xf0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xff, 0xa2, 0x74,
6140x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43, 0x87, 6250x40, 0xf0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xfa, 0xe7, 0xe5, 0xa8, 0xf0, 0x75, 0xa8, 0x81, 0x90,
6150x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7b, 0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7c, 0xe0, 6260xff, 0x92, 0xe0, 0x60, 0x04, 0xe4, 0xf0, 0x80, 0xf6, 0x90, 0xff, 0xfd, 0x74, 0x3a, 0xf0, 0x43,
6160x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x79, 0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x7a, 0xe0, 6270x87, 0x01, 0x00, 0x00, 0x00, 0x90, 0xfa, 0x7e, 0xe0, 0x90, 0xff, 0xa4, 0xf0, 0x90, 0xfa, 0x7f,
6170x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe4, 0xe0, 6280xe0, 0x90, 0xff, 0xb4, 0xf0, 0x90, 0xfa, 0x7c, 0xe0, 0x90, 0xff, 0xa2, 0xf0, 0x90, 0xfa, 0x7d,
6180xf5, 0xa8, 0x02, 0x10, 0x86, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x12, 0x2d, 0x3c, 0x90, 0xfa, 6290xe0, 0x90, 0xff, 0xb2, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x60, 0x02, 0xc2, 0xb3, 0x90, 0xfa, 0xe7,
6190xc0, 0x12, 0x1b, 0x43, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0x43, 0x90, 0xfa, 6300xe0, 0xf5, 0xa8, 0x02, 0x10, 0xce, 0x8b, 0x5c, 0x8a, 0x5d, 0x89, 0x5e, 0x12, 0x2e, 0x0d, 0x90,
6200xc4, 0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x1a, 0x6c, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0x3a, 0xe9, 0x24, 6310xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xaa, 0x5d, 0xa9, 0x5e, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xf3, 0x90,
6210x01, 0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x43, 0xab, 0x5c, 0xaa, 0x5d, 0xa9, 6320xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x0a, 0x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0xea, 0xe9,
6220x5e, 0x12, 0x2d, 0x48, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x82, 0xf6, 0x90, 0xfa, 0xbe, 6330x24, 0x01, 0xf9, 0xe4, 0x3a, 0xfa, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xab, 0x5c, 0xaa, 0x5d,
6230xe0, 0xff, 0x78, 0x82, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xc0, 0x12, 0x2d, 0x1d, 0xff, 6340xa9, 0x5e, 0x12, 0x2e, 0x19, 0xe0, 0xff, 0xc3, 0x13, 0xf0, 0xe4, 0x78, 0x82, 0xf6, 0x90, 0xfa,
6240x78, 0x83, 0xf6, 0x90, 0xfa, 0xc3, 0x12, 0x2d, 0x1d, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x83, 0xf6, 6350xc1, 0xe0, 0xff, 0x78, 0x82, 0xe6, 0xc3, 0x9f, 0x50, 0x4a, 0x90, 0xfa, 0xc3, 0x12, 0x2d, 0xee,
6250x12, 0x2d, 0x1a, 0x5e, 0x4f, 0xff, 0x78, 0x83, 0xf6, 0x12, 0x2d, 0x23, 0x75, 0xf0, 0x02, 0x12, 6360xff, 0x78, 0x83, 0xf6, 0x90, 0xfa, 0xc6, 0x12, 0x2d, 0xee, 0xfe, 0xf4, 0x5f, 0xff, 0x78, 0x83,
6260x1a, 0x6c, 0x90, 0xfa, 0xc4, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1a, 0x6c, 0xab, 0x5c, 0xaa, 0x5d, 6370xf6, 0x12, 0x2d, 0xeb, 0x5e, 0x4f, 0xff, 0x78, 0x83, 0xf6, 0x12, 0x2d, 0xf4, 0x75, 0xf0, 0x02,
6270xa9, 0x5e, 0x90, 0x00, 0x04, 0x12, 0x1a, 0x0b, 0x30, 0xe4, 0x03, 0x12, 0x2d, 0x32, 0x78, 0x82, 6380x12, 0x1b, 0x1c, 0x90, 0xfa, 0xc7, 0xe4, 0x75, 0xf0, 0x02, 0x12, 0x1b, 0x1c, 0xab, 0x5c, 0xaa,
6280x06, 0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xbf, 0xf0, 0x22, 0x8b, 0x56, 0x8a, 0x57, 0x89, 0x58, 0x90, 6390x5d, 0xa9, 0x5e, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xbb, 0x30, 0xe4, 0x03, 0x12, 0x2e, 0x03, 0x78,
6290xfa, 0xbf, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xbe, 0xf0, 0x12, 0x19, 0xf2, 0x24, 0x6e, 0x60, 6400x82, 0x06, 0x80, 0xaa, 0xe4, 0x90, 0xfa, 0xc2, 0xf0, 0x22, 0x8b, 0x56, 0x8a, 0x57, 0x89, 0x58,
6300x26, 0x14, 0x70, 0x70, 0x12, 0x2d, 0x09, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x24, 0x95, 6410x90, 0xfa, 0xc2, 0x74, 0x06, 0xf0, 0xe4, 0x90, 0xfa, 0xc1, 0xf0, 0x12, 0x1a, 0xa2, 0x24, 0x6e,
6310x80, 0x62, 0x12, 0x2d, 0x53, 0x12, 0x1f, 0x2c, 0x90, 0xfa, 0xbf, 0xef, 0xf0, 0x80, 0x55, 0x90, 6420x60, 0x26, 0x14, 0x70, 0x70, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70, 0x12, 0x12, 0x25,
6320xfa, 0xbf, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2d, 0x09, 0x60, 0x09, 0x24, 0x30, 0x70, 0x3e, 6430x56, 0x80, 0x62, 0x12, 0x2e, 0x24, 0x12, 0x1f, 0xda, 0x90, 0xfa, 0xc2, 0xef, 0xf0, 0x80, 0x55,
6330x12, 0x2c, 0x5f, 0x80, 0x3f, 0xe5, 0x58, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x57, 0xfa, 0x7b, 0x01, 6440x90, 0xfa, 0xc2, 0x74, 0x81, 0xf0, 0x80, 0x4d, 0x12, 0x2d, 0xda, 0x60, 0x09, 0x24, 0x30, 0x70,
6340xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2d, 0x53, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0xfd, 6450x3e, 0x12, 0x2d, 0x30, 0x80, 0x3f, 0xe5, 0x58, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x57, 0xfa, 0x7b,
6350x90, 0x00, 0x08, 0x12, 0x1a, 0x98, 0xf5, 0x2e, 0x85, 0xf0, 0x2d, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 6460x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb,
6360x03, 0x12, 0x25, 0xd7, 0x90, 0xfa, 0xbe, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90, 0xfa, 6470xfd, 0x90, 0x00, 0x08, 0x12, 0x1b, 0x48, 0xf5, 0x2e, 0x85, 0xf0, 0x2d, 0xd0, 0x01, 0xd0, 0x02,
6370xbf, 0x74, 0x81, 0xf0, 0x90, 0xfa, 0xbf, 0xe0, 0x12, 0x2d, 0x53, 0x90, 0x00, 0x02, 0x12, 0x1a, 6480xd0, 0x03, 0x12, 0x26, 0x98, 0x90, 0xfa, 0xc1, 0xef, 0xf0, 0xe4, 0xa3, 0xf0, 0x80, 0x06, 0x90,
6380x4a, 0x90, 0xfa, 0xbe, 0xe0, 0xff, 0x22, 0x8b, 0x29, 0x8a, 0x2a, 0x89, 0x2b, 0x8d, 0x2c, 0xe5, 6490xfa, 0xc2, 0x74, 0x81, 0xf0, 0x90, 0xfa, 0xc2, 0xe0, 0x12, 0x2e, 0x24, 0x90, 0x00, 0x02, 0x12,
6390x2c, 0x70, 0x03, 0xaf, 0x2c, 0x22, 0x12, 0x2d, 0x82, 0x70, 0x16, 0x12, 0x2d, 0xa1, 0xe5, 0x2d, 6500x1a, 0xfa, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x22, 0x8b, 0x29, 0x8a, 0x2a, 0x89, 0x2b, 0x8d, 0x2c,
6400x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0x1b, 0x50, 0xf2, 0x12, 0x26, 0x64, 0x40, 0x0b, 0x7f, 0x00, 6510xe5, 0x2c, 0x70, 0x03, 0xaf, 0x2c, 0x22, 0x12, 0x2e, 0x53, 0x70, 0x16, 0x12, 0x2e, 0x72, 0xe5,
6410x22, 0x12, 0x2d, 0xa1, 0x12, 0x26, 0x64, 0x50, 0xf8, 0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0, 0xe5, 6520x2d, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12, 0x27, 0x25, 0x40, 0x0b, 0x7f,
6420x2c, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4, 0xf0, 6530x00, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x27, 0x25, 0x50, 0xf8, 0x90, 0xff, 0xf3, 0x74, 0xa1, 0xf0,
6430xf5, 0x2f, 0xe5, 0x2c, 0x14, 0xff, 0xe5, 0x2f, 0xc3, 0x9f, 0x50, 0x2a, 0x12, 0x31, 0x04, 0x40, 6540xe5, 0x2c, 0xb4, 0x01, 0x07, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0xf1, 0xe4,
6440x03, 0xaf, 0x2f, 0x22, 0xc3, 0xe5, 0x2c, 0x95, 0x2f, 0xff, 0xbf, 0x02, 0x07, 0x90, 0xff, 0xf0, 6550xf0, 0xf5, 0x2f, 0xe5, 0x2c, 0x14, 0xff, 0xe5, 0x2f, 0xc3, 0x9f, 0x50, 0x2a, 0x12, 0x31, 0xc1,
6450xe0, 0x44, 0x02, 0xf0, 0x12, 0x2d, 0x94, 0x05, 0x2f, 0x74, 0x01, 0x25, 0x2b, 0xf5, 0x2b, 0xe4, 6560x40, 0x03, 0xaf, 0x2f, 0x22, 0xc3, 0xe5, 0x2c, 0x95, 0x2f, 0xff, 0xbf, 0x02, 0x07, 0x90, 0xff,
6460x35, 0x2a, 0xf5, 0x2a, 0x80, 0xcc, 0x12, 0x31, 0x04, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x12, 0x2d, 6570xf0, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x2e, 0x65, 0x05, 0x2f, 0x74, 0x01, 0x25, 0x2b, 0xf5, 0x2b,
6470x94, 0xaf, 0x2c, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x2e, 0xf0, 0x02, 0x31, 0x1b, 0x12, 0x10, 0x03, 6580xe4, 0x35, 0x2a, 0xf5, 0x2a, 0x80, 0xcc, 0x12, 0x31, 0xc1, 0x40, 0x03, 0x7f, 0x18, 0x22, 0x12,
6480x78, 0x84, 0x12, 0x22, 0x82, 0x30, 0xe1, 0x08, 0x7f, 0x13, 0x12, 0x30, 0xec, 0x02, 0x26, 0xfb, 6590x2e, 0x65, 0xaf, 0x2c, 0x22, 0x90, 0xff, 0xf1, 0xe5, 0x2e, 0xf0, 0x02, 0x31, 0xd8, 0x12, 0x10,
6490x78, 0x84, 0xe6, 0xf9, 0x24, 0x12, 0x12, 0x21, 0xff, 0xe0, 0xff, 0x30, 0xe7, 0x40, 0x54, 0x03, 6600x4b, 0x78, 0x84, 0x12, 0x23, 0x31, 0x30, 0xe1, 0x08, 0x7f, 0x13, 0x12, 0x31, 0xa9, 0x02, 0x27,
6500x60, 0x1e, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x44, 0x04, 6610xbc, 0x78, 0x84, 0xe6, 0xf9, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xff, 0x30, 0xe7, 0x40, 0x54,
6510xf0, 0x80, 0x46, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x80, 0x39, 6620x03, 0x60, 0x1e, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x44,
6520xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x80, 6630x04, 0xf0, 0x80, 0x46, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x80,
6530x28, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1b, 0xef, 0x54, 6640x39, 0xe9, 0xb4, 0x03, 0x0d, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x01, 0xf0,
6540x03, 0x60, 0x14, 0xe9, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80, 0x07, 6650x80, 0x28, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x1b, 0xef,
6550x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x17, 0xe0, 0x04, 0xf0, 0xaf, 6660x54, 0x03, 0x60, 0x14, 0xe9, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x54, 0xdf, 0xf0, 0x80,
6560x01, 0x12, 0x22, 0x33, 0xfd, 0x12, 0x2f, 0x49, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x75, 0xa8, 6670x07, 0x90, 0xff, 0xb4, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0xb3, 0x90, 0xf9, 0x18, 0xe0, 0x04, 0xf0,
6570x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x8b, 0x02, 0x27, 0x48, 0x02, 0x30, 0xcf, 6680xaf, 0x01, 0x12, 0x22, 0xee, 0xfd, 0x12, 0x2f, 0xe5, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x75,
6580xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 6690xa8, 0x40, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x8b, 0x02, 0x28, 0x09, 0x02, 0x31,
6590x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 6700x8c, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf,
6600x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 6710xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54,
6610x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x2b, 0x4c, 0xe4, 0x7e, 0x01, 0x93, 0x60, 6720x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80,
6620xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 6730x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x2b, 0xa9, 0xe4, 0x7e, 0x01, 0x93,
6630x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 6740x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60,
6640xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 6750x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4,
6650xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xe4, 0xf5, 0x22, 6760x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3,
6660x12, 0x1d, 0x12, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x22, 0x24, 0x03, 0xff, 0x12, 0x2f, 0x77, 0x12, 6770xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0xe4, 0xf5,
6670x1d, 0x12, 0xe4, 0xf0, 0x05, 0x22, 0xe5, 0x22, 0xc3, 0x94, 0x02, 0x40, 0xe3, 0xe4, 0xf5, 0x22, 6780x22, 0x12, 0x1d, 0xc2, 0xe0, 0xb4, 0x04, 0x0d, 0xe5, 0x22, 0x24, 0x03, 0xff, 0x12, 0x30, 0x13,
6680x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x91, 0x12, 0x1d, 0x53, 0x60, 0x2c, 0x12, 0x2c, 0xb4, 6790x12, 0x1d, 0xc2, 0xe4, 0xf0, 0x05, 0x22, 0xe5, 0x22, 0xc3, 0x94, 0x02, 0x40, 0xe3, 0xe4, 0xf5,
6690xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x91, 0x12, 0x1b, 0x1c, 0xe4, 0xf0, 6800x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1e, 0x03, 0x60, 0x2c, 0x12, 0x2d,
6700xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x22, 0x90, 0xfa, 0x9d, 0x12, 0x1b, 0x1c, 0xe0, 0xa3, 0x30, 6810x85, 0xef, 0x60, 0x52, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 0x94, 0x12, 0x1b, 0xcc, 0xe4,
6710xe6, 0x33, 0x12, 0x1d, 0x12, 0x74, 0x04, 0xf0, 0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90, 0xfa, 6820xf0, 0xa3, 0xf0, 0x75, 0xf0, 0x0a, 0xe5, 0x22, 0x90, 0xfa, 0xa0, 0x12, 0x1b, 0xcc, 0xe0, 0xa3,
6720x95, 0x12, 0x1d, 0x53, 0x60, 0x16, 0x12, 0x2c, 0xb4, 0xef, 0x60, 0x19, 0x75, 0xf0, 0x02, 0xe5, 6830x30, 0xe6, 0x33, 0x12, 0x1d, 0xc2, 0x74, 0x04, 0xf0, 0x22, 0x75, 0xf0, 0x02, 0xe5, 0x22, 0x90,
6730x22, 0x90, 0xfa, 0x95, 0x12, 0x1b, 0x1c, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x05, 0x22, 0xe5, 0x22, 6840xfa, 0x98, 0x12, 0x1e, 0x03, 0x60, 0x16, 0x12, 0x2d, 0x85, 0xef, 0x60, 0x19, 0x75, 0xf0, 0x02,
6740xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xfe, 0xef, 6850xe5, 0x22, 0x90, 0xfa, 0x98, 0x12, 0x1b, 0xcc, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x05, 0x22, 0xe5,
6750xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xe0, 0x12, 6860x22, 0xc3, 0x94, 0x02, 0x40, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xfe,
6760x1c, 0x11, 0x12, 0x1a, 0x38, 0x0f, 0x12, 0x1c, 0x00, 0x80, 0xdd, 0xef, 0xfd, 0xc3, 0xe5, 0x3a, 6870xef, 0xc3, 0x9e, 0x50, 0x17, 0x74, 0xf0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xe0,
6770x9d, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 0xd3, 0xe5, 0x3a, 0x94, 0x00, 0xe5, 0x39, 6880x12, 0x1c, 0xc1, 0x12, 0x1a, 0xe8, 0x0f, 0x12, 0x1c, 0xb0, 0x80, 0xdd, 0xef, 0xfd, 0xc3, 0xe5,
6780x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, 0x12, 0x1d, 0x2f, 0x12, 0x1d, 0x84, 6890x3a, 0x9d, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 0xd3, 0xe5, 0x3a, 0x94, 0x00, 0xe5,
6790x12, 0x1d, 0x76, 0x12, 0x19, 0xf2, 0x24, 0x6e, 0x60, 0x1e, 0x14, 0x60, 0x1b, 0x24, 0x8e, 0x70, 6900x39, 0x94, 0x00, 0x40, 0x06, 0xe4, 0x90, 0xff, 0x83, 0xf0, 0x22, 0x12, 0x1d, 0xdf, 0x12, 0x1e,
6800x2d, 0x90, 0x00, 0x01, 0x12, 0x1a, 0x0b, 0xff, 0x24, 0xfc, 0x60, 0x03, 0x04, 0x70, 0x1f, 0xef, 6910x34, 0x12, 0x1e, 0x26, 0x12, 0x1a, 0xa2, 0x24, 0x6e, 0x60, 0x1e, 0x14, 0x60, 0x1b, 0x24, 0x8e,
6810xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x11, 0x16, 0x12, 0x1d, 0x8b, 0x12, 0x25, 0x39, 0x12, 0x1c, 6920x70, 0x2d, 0x90, 0x00, 0x01, 0x12, 0x1a, 0xbb, 0xff, 0x24, 0xfc, 0x60, 0x03, 0x04, 0x70, 0x1f,
6820xd9, 0x12, 0x1a, 0x0b, 0x60, 0x03, 0x02, 0x31, 0xbd, 0xe4, 0xff, 0x12, 0x31, 0xb1, 0x22, 0x8b, 6930xef, 0xfd, 0x7c, 0x00, 0x7f, 0x0d, 0x02, 0x11, 0x5e, 0x12, 0x1e, 0x3b, 0x12, 0x25, 0xfa, 0x12,
6830x45, 0x8a, 0x46, 0x89, 0x47, 0x8c, 0x48, 0x8d, 0x49, 0xd2, 0x00, 0x12, 0x2d, 0x82, 0x70, 0x16, 6940x1d, 0x89, 0x12, 0x1a, 0xbb, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e, 0x22,
6840x12, 0x2d, 0xa1, 0xe5, 0x48, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0x1b, 0x50, 0xf2, 0x12, 0x29, 6950x8b, 0x45, 0x8a, 0x46, 0x89, 0x47, 0x8c, 0x48, 0x8d, 0x49, 0xd2, 0x00, 0x12, 0x2e, 0x53, 0x70,
6850x14, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2d, 0xa1, 0x12, 0x29, 0x14, 0x50, 0xf8, 0xe4, 0xf5, 6960x16, 0x12, 0x2e, 0x72, 0xe5, 0x48, 0x90, 0xff, 0xf1, 0xf0, 0x12, 0x31, 0xd8, 0x50, 0xf2, 0x12,
6860x4b, 0xe5, 0x4a, 0x14, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, 0x17, 0x12, 0x29, 0x04, 0x40, 0x03, 6970x29, 0xd5, 0x40, 0x0b, 0x7f, 0x18, 0x22, 0x12, 0x2e, 0x72, 0x12, 0x29, 0xd5, 0x50, 0xf8, 0xe4,
6870x7f, 0x18, 0x22, 0x05, 0x4b, 0x74, 0x01, 0x25, 0x47, 0xf5, 0x47, 0xe4, 0x35, 0x46, 0xf5, 0x46, 6980xf5, 0x4b, 0xe5, 0x4a, 0x14, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, 0x17, 0x12, 0x29, 0xc5, 0x40,
6880x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x29, 0x04, 0x40, 0x03, 0x7f, 0x18, 6990x03, 0x7f, 0x18, 0x22, 0x05, 0x4b, 0x74, 0x01, 0x25, 0x47, 0xf5, 0x47, 0xe4, 0x35, 0x46, 0xf5,
6890x22, 0x7f, 0x00, 0x22, 0xab, 0x45, 0xaa, 0x46, 0xa9, 0x47, 0x12, 0x19, 0xf2, 0x90, 0xff, 0xf1, 7000x46, 0x80, 0xdf, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x29, 0xc5, 0x40, 0x03, 0x7f,
6900xf0, 0x02, 0x31, 0x1b, 0x90, 0xff, 0xf1, 0xe5, 0x49, 0xf0, 0x02, 0x31, 0x1b, 0x7b, 0x01, 0x7a, 7010x18, 0x22, 0x7f, 0x00, 0x22, 0xab, 0x45, 0xaa, 0x46, 0xa9, 0x47, 0x12, 0x1a, 0xa2, 0x90, 0xff,
6910xfa, 0x79, 0xcc, 0xe4, 0xfd, 0x12, 0x22, 0xa0, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x09, 0x12, 7020xf1, 0xf0, 0x02, 0x31, 0xd8, 0x90, 0xff, 0xf1, 0xe5, 0x49, 0xf0, 0x02, 0x31, 0xd8, 0x7b, 0x01,
6920x1a, 0x6c, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 7030x7a, 0xfa, 0x79, 0xcf, 0xe4, 0xfd, 0x12, 0x23, 0x61, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x09,
6930x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x90, 0xff, 0xf7, 0xe5, 7040x12, 0x1b, 0x1c, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01,
6940x23, 0x12, 0x29, 0x78, 0x90, 0xff, 0xf6, 0xe5, 0x23, 0xf0, 0x90, 0xfa, 0xcc, 0xe4, 0xf0, 0xa3, 7050x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x90, 0xff, 0xf7,
6950x74, 0x06, 0x12, 0x29, 0x78, 0xe5, 0x23, 0x30, 0xe0, 0x07, 0x90, 0xff, 0xfc, 0x74, 0x94, 0xf0, 7060xe5, 0x23, 0x12, 0x2a, 0x39, 0x90, 0xff, 0xf6, 0xe5, 0x23, 0xf0, 0x90, 0xfa, 0xcf, 0xe4, 0xf0,
6960x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23, 0x90, 7070xa3, 0x74, 0x06, 0x12, 0x2a, 0x39, 0xe5, 0x23, 0x30, 0xe0, 0x07, 0x90, 0xff, 0xfc, 0x74, 0x94,
6970xfa, 0xcc, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1a, 0x82, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d, 0x01, 7080xf0, 0x22, 0x90, 0xff, 0xfc, 0x74, 0x90, 0xf0, 0x22, 0xf0, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x23,
6980x02, 0x25, 0xd7, 0x90, 0xff, 0x93, 0x74, 0x2a, 0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06, 0x90, 7090x90, 0xfa, 0xcf, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x1b, 0x32, 0x85, 0xf0, 0x2e, 0xf5, 0x2d, 0x7d,
6990xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, 0xe0, 0x44, 0x90, 0xf0, 0xe4, 0x90, 0xf9, 0x15, 7100x01, 0x02, 0x26, 0x98, 0x90, 0xff, 0x93, 0x74, 0x81, 0xf0, 0x90, 0xff, 0xff, 0xe0, 0x60, 0x06,
7000xf0, 0xa3, 0xf0, 0x12, 0x2a, 0x78, 0x12, 0x16, 0x42, 0x12, 0x2f, 0xcd, 0x7e, 0x07, 0x7f, 0xd0, 7110x90, 0xff, 0xfc, 0x74, 0x10, 0xf0, 0x90, 0xff, 0x91, 0xe0, 0x44, 0x90, 0xf0, 0xe4, 0x90, 0xf9,
7010x12, 0x11, 0xe2, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x11, 0xfc, 0xe4, 0x78, 0x77, 0xf6, 0x78, 0x77, 7120x16, 0xf0, 0xa3, 0xf0, 0x12, 0x2b, 0x39, 0x12, 0x16, 0xc9, 0x12, 0x30, 0x69, 0x7e, 0x07, 0x7f,
7020xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x6e, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x77, 0x06, 7130xd0, 0x12, 0x12, 0x2a, 0x7e, 0x0f, 0x7f, 0xa0, 0x12, 0x12, 0x44, 0xe4, 0x78, 0x77, 0xf6, 0x78,
7030x80, 0xec, 0x7f, 0x03, 0x12, 0x2e, 0xb3, 0x90, 0xf9, 0x15, 0xe0, 0x20, 0xe4, 0x05, 0x7f, 0x04, 7140x77, 0xe6, 0xff, 0xc3, 0x94, 0x06, 0x50, 0x0b, 0x74, 0x6e, 0x2f, 0xf8, 0xe4, 0xf6, 0x78, 0x77,
7040x12, 0x2e, 0xb3, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8, 0xe0, 7150x06, 0x80, 0xec, 0x7f, 0x03, 0x12, 0x30, 0xb2, 0x90, 0xf9, 0x16, 0xe0, 0x20, 0xe4, 0x05, 0x7f,
7050x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x15, 0x65, 0xa8, 0x65, 0xa6, 0x07, 0x30, 0x08, 0x05, 0x12, 7160x04, 0x12, 0x30, 0xb2, 0x90, 0xff, 0x9b, 0xe4, 0xf0, 0x90, 0xff, 0x9a, 0xf0, 0x90, 0xff, 0xe8,
7060x11, 0x66, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x65, 0xe6, 0xff, 0xb4, 0x03, 0x0f, 0x78, 0x7c, 0x76, 7170xe0, 0x54, 0x1f, 0xf0, 0xd2, 0xa8, 0x22, 0x15, 0x65, 0xa8, 0x65, 0xa6, 0x07, 0x30, 0x08, 0x05,
7070xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, 0x7c, 0x76, 0xff, 7180x12, 0x11, 0xae, 0x80, 0xf8, 0xd2, 0x08, 0xa8, 0x65, 0xe6, 0xff, 0xb4, 0x03, 0x0f, 0x78, 0x7c,
7080x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x80, 0x76, 0xfa, 0x08, 0x76, 0x9b, 7190x76, 0xff, 0x08, 0x76, 0xe0, 0x08, 0x76, 0xff, 0x08, 0x76, 0xa0, 0x80, 0x0d, 0x78, 0x7c, 0x76,
7090xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x22, 0x92, 0x7b, 0x01, 0x7a, 0xff, 7200xff, 0x08, 0x76, 0xe2, 0x08, 0x76, 0xff, 0x08, 0x76, 0xb0, 0x78, 0x80, 0x76, 0xfa, 0x08, 0x76,
7100x79, 0x48, 0x78, 0x68, 0x12, 0x1b, 0x31, 0xa8, 0x65, 0xe6, 0x24, 0xfd, 0x75, 0xf0, 0x08, 0xa4, 7210x9e, 0xef, 0x24, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0xae, 0xf0, 0x12, 0x23, 0x49, 0x7b, 0x01, 0x7a,
7110xff, 0xae, 0xf0, 0x78, 0x6a, 0x12, 0x22, 0x92, 0x79, 0x08, 0x78, 0x6b, 0x12, 0x1b, 0x31, 0x78, 7220xff, 0x79, 0x48, 0x78, 0x68, 0x12, 0x1b, 0xe1, 0xa8, 0x65, 0xe6, 0x24, 0xfd, 0x75, 0xf0, 0x08,
7120x6d, 0xef, 0x12, 0x22, 0x92, 0x05, 0x65, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xab, 0xf0, 0xe0, 7230xa4, 0xff, 0xae, 0xf0, 0x78, 0x6a, 0x12, 0x23, 0x49, 0x79, 0x08, 0x78, 0x6b, 0x12, 0x1b, 0xe1,
7130x44, 0x20, 0xf0, 0x90, 0xfa, 0xe3, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcc, 0xe4, 7240x78, 0x6d, 0xef, 0x12, 0x23, 0x49, 0x05, 0x65, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xab, 0xf0,
7140xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x25, 0xd7, 0x7e, 0x00, 0x90, 0xfa, 0xe1, 0xee, 0xf0, 7250xe0, 0x44, 0x20, 0xf0, 0x90, 0xfa, 0xe6, 0x74, 0x02, 0xf0, 0x7b, 0x01, 0x7a, 0xfa, 0x79, 0xcf,
7150xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcc, 0xe0, 0xb4, 0x52, 0x09, 0x90, 0xf9, 7260xe4, 0xf5, 0x2d, 0xf5, 0x2e, 0x7d, 0x01, 0x12, 0x26, 0x98, 0x7e, 0x00, 0x90, 0xfa, 0xe4, 0xee,
7160x15, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe1, 0xe0, 0x70, 0x04, 0xa3, 0xe0, 0x64, 7270xf0, 0xa3, 0xef, 0xf0, 0x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x52, 0x09, 0x90,
7170x01, 0x70, 0x10, 0x90, 0xfa, 0xcc, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x15, 0xe0, 0x44, 0x10, 7280xf9, 0x16, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x29, 0x90, 0xfa, 0xe4, 0xe0, 0x70, 0x04, 0xa3, 0xe0,
7180xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe3, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x15, 0xe0, 0x54, 0xef, 0xf0, 7290x64, 0x01, 0x70, 0x10, 0x90, 0xfa, 0xcf, 0xe0, 0xb4, 0x10, 0x09, 0x90, 0xf9, 0x16, 0xe0, 0x44,
7190x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x12, 0x10, 0x03, 0x78, 0x8a, 0xef, 0xf6, 0x12, 7300x10, 0xf0, 0x80, 0x0d, 0x90, 0xfa, 0xe6, 0x74, 0x03, 0xf0, 0x90, 0xf9, 0x16, 0xe0, 0x54, 0xef,
7200x2a, 0x06, 0x12, 0x22, 0x33, 0x30, 0xe0, 0x25, 0x12, 0x22, 0x07, 0xe0, 0x54, 0x7f, 0xf0, 0x78, 7310xf0, 0x90, 0xff, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x03, 0x68, 0x01, 0xff, 0x48, 0x03, 0x6b,
7210x6b, 0x12, 0x1b, 0x28, 0x90, 0x00, 0x02, 0x12, 0x1a, 0x0b, 0x30, 0xe7, 0x09, 0x90, 0x00, 0x02, 7320x01, 0xff, 0x08, 0x02, 0x66, 0x00, 0x00, 0x44, 0xfa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfa,
7220xe4, 0x12, 0x1a, 0x4a, 0x80, 0xe9, 0x12, 0x22, 0x07, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x22, 0x33, 7330x94, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xb2, 0x00, 0x00, 0x42, 0xfa, 0x7e, 0x00, 0x00, 0x42,
7230x30, 0xe1, 0x1e, 0x12, 0x21, 0xe9, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x31, 0x5c, 0x78, 0x68, 0x12, 7340xfa, 0x7c, 0x00, 0x00, 0x42, 0xf9, 0x6d, 0xff, 0xff, 0x42, 0xfa, 0x7a, 0x00, 0x00, 0x41, 0xf9,
7240x1b, 0x28, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x1a, 0x4a, 0x12, 0x21, 0xe9, 0xe0, 0x44, 0x80, 7350x66, 0xff, 0x41, 0xf9, 0x1c, 0x19, 0x41, 0xf9, 0x15, 0x00, 0x43, 0xf9, 0x19, 0x0a, 0x32, 0x02,
7250xf0, 0x12, 0x31, 0xc7, 0xe4, 0xff, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x03, 0x68, 0x01, 0xff, 7360x41, 0xf9, 0x68, 0x20, 0x41, 0xf9, 0x69, 0x20, 0x41, 0xf9, 0x65, 0x00, 0x41, 0xf9, 0x67, 0x00,
7260x48, 0x03, 0x6b, 0x01, 0xff, 0x08, 0x02, 0x66, 0x00, 0x00, 0x44, 0xfa, 0x95, 0x00, 0x00, 0x00, 7370x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf9, 0x16, 0x00, 0x00, 0x41, 0xf9, 0x18, 0x00,
7270x00, 0x44, 0xfa, 0x91, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfa, 0xaf, 0x00, 0x00, 0x42, 0xfa, 0x7b, 7380x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 0x10, 0x4b, 0x78, 0x8a, 0xef, 0xf6, 0x12,
7280x00, 0x00, 0x42, 0xfa, 0x79, 0x00, 0x00, 0x42, 0xf9, 0x6a, 0xff, 0xff, 0x42, 0xfa, 0x77, 0x00, 7390x2a, 0xc7, 0x12, 0x22, 0xee, 0x30, 0xe0, 0x29, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x7f,
7290x00, 0x43, 0xf9, 0x18, 0x0a, 0x32, 0x02, 0x41, 0xf9, 0x65, 0x20, 0x41, 0xf9, 0x66, 0x20, 0x41, 7400xf0, 0x78, 0x6b, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x12, 0x1a, 0xbb, 0x30, 0xe7, 0x09, 0x90,
7300xf9, 0x63, 0x00, 0x41, 0xf9, 0x64, 0x00, 0x44, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf9, 7410x00, 0x02, 0xe4, 0x12, 0x1a, 0xfa, 0x80, 0xe9, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x44, 0x80,
7310x15, 0x00, 0x00, 0x41, 0xf9, 0x17, 0x00, 0x01, 0x20, 0x00, 0x41, 0xf8, 0x04, 0x00, 0x00, 0x12, 7420xf0, 0x12, 0x22, 0xee, 0x30, 0xe1, 0x1e, 0x12, 0x22, 0x97, 0xe0, 0x54, 0x7f, 0xf0, 0x12, 0x32,
7320x10, 0x03, 0x78, 0x85, 0xef, 0xf6, 0x12, 0x30, 0x93, 0x12, 0x30, 0xec, 0x78, 0x85, 0xe6, 0xff, 7430x19, 0x78, 0x68, 0x12, 0x1b, 0xd8, 0x90, 0x00, 0x02, 0x74, 0x80, 0x12, 0x1a, 0xfa, 0x12, 0x22,
7330x24, 0x12, 0x12, 0x21, 0xff, 0xe0, 0xfe, 0x30, 0xe7, 0x16, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 7440x97, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0xe4, 0xff, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce,
7340x9e, 0xe0, 0x54, 0xfa, 0xf0, 0x80, 0x22, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf5, 0xf0, 0x80, 0x19, 7450x12, 0x10, 0x4b, 0x78, 0x85, 0xef, 0xf6, 0x12, 0x31, 0x50, 0x12, 0x31, 0xa9, 0x78, 0x85, 0xe6,
7350xee, 0x54, 0x03, 0x60, 0x14, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20, 0xf0, 7460xff, 0x24, 0x13, 0x12, 0x22, 0xad, 0xe0, 0xfe, 0x30, 0xe7, 0x16, 0xef, 0xb4, 0x03, 0x09, 0x90,
7360x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x17, 0xe0, 0x14, 0xf0, 0xe0, 7470xff, 0x9e, 0xe0, 0x54, 0xfa, 0xf0, 0x80, 0x22, 0x90, 0xff, 0x9e, 0xe0, 0x54, 0xf5, 0xf0, 0x80,
7370x70, 0x02, 0xd2, 0xb3, 0x02, 0x10, 0x86, 0x12, 0x1d, 0x6c, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 7480x19, 0xee, 0x54, 0x03, 0x60, 0x14, 0xef, 0xb4, 0x03, 0x09, 0x90, 0xff, 0xa4, 0xe0, 0x44, 0x20,
7380xe5, 0x39, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x3a, 0x94, 0x08, 0xe5, 0x39, 0x94, 0x00, 0x40, 7490xf0, 0x80, 0x07, 0x90, 0xff, 0xb4, 0xe0, 0x44, 0x20, 0xf0, 0x90, 0xf9, 0x18, 0xe0, 0x14, 0xf0,
7390x11, 0x7f, 0x08, 0xef, 0xe5, 0x3a, 0x94, 0x08, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5, 0x39, 7500xe0, 0x70, 0x02, 0xd2, 0xb3, 0x02, 0x10, 0xce, 0x12, 0x1e, 0x1c, 0xe5, 0x3a, 0x64, 0x09, 0x70,
7400x80, 0x05, 0xaf, 0x3a, 0x12, 0x1d, 0x84, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x19, 0x12, 0x1c, 7510x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x48, 0xc3, 0xe5, 0x3a, 0x94, 0x08, 0xe5, 0x39, 0x94, 0x00,
7410x11, 0x12, 0x19, 0xf2, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83, 0xed, 7520x40, 0x11, 0x7f, 0x08, 0xef, 0xe5, 0x3a, 0x94, 0x08, 0xf5, 0x3a, 0xe5, 0x39, 0x94, 0x00, 0xf5,
7420xf0, 0x0e, 0x12, 0x1c, 0x00, 0x80, 0xe2, 0xef, 0x54, 0x7f, 0x90, 0xff, 0x81, 0xf0, 0x22, 0x8b, 7530x39, 0x80, 0x05, 0xaf, 0x3a, 0x12, 0x1e, 0x34, 0xe4, 0xfe, 0xee, 0xc3, 0x9f, 0x50, 0x19, 0x12,
7430x59, 0x8a, 0x5a, 0x89, 0x5b, 0x12, 0x2d, 0x48, 0x70, 0x05, 0xa3, 0x74, 0x08, 0xf0, 0x22, 0xab, 7540x1c, 0xc1, 0x12, 0x1a, 0xa2, 0xfd, 0x74, 0xf8, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfe, 0xf5, 0x83,
7440x59, 0xaa, 0x5a, 0xa9, 0x5b, 0x12, 0x2d, 0x3c, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x43, 0xe5, 0x5b, 7550xed, 0xf0, 0x0e, 0x12, 0x1c, 0xb0, 0x80, 0xe2, 0xef, 0x54, 0x7f, 0x90, 0xff, 0x81, 0xf0, 0x22,
7450x24, 0x03, 0xf9, 0xe4, 0x35, 0x5a, 0xfa, 0x90, 0xfa, 0xc0, 0x12, 0x1b, 0x43, 0xe4, 0x90, 0xfa, 7560x8b, 0x59, 0x8a, 0x5a, 0x89, 0x5b, 0x12, 0x2e, 0x19, 0x70, 0x05, 0xa3, 0x74, 0x08, 0xf0, 0x22,
7460xbf, 0xf0, 0x78, 0x8b, 0xf6, 0x90, 0xfa, 0xbe, 0xe0, 0xff, 0x78, 0x8b, 0xe6, 0xc3, 0x9f, 0x50, 7570xab, 0x59, 0xaa, 0x5a, 0xa9, 0x5b, 0x12, 0x2e, 0x0d, 0x90, 0xfa, 0xc9, 0x12, 0x1b, 0xf3, 0xe5,
7470x12, 0x12, 0x2d, 0x1a, 0xff, 0x12, 0x2d, 0x23, 0x12, 0x2d, 0x36, 0x78, 0x8b, 0x06, 0x12, 0x2d, 7580x5b, 0x24, 0x03, 0xf9, 0xe4, 0x35, 0x5a, 0xfa, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xf3, 0xe4, 0x90,
7480x32, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x31, 0x4d, 0xe4, 0x93, 0xff, 0x78, 0x74, 7590xfa, 0xc2, 0xf0, 0x78, 0x8b, 0xf6, 0x90, 0xfa, 0xc1, 0xe0, 0xff, 0x78, 0x8b, 0xe6, 0xc3, 0x9f,
7490xf6, 0x54, 0x0f, 0x12, 0x1c, 0xf8, 0xe0, 0x08, 0x76, 0x00, 0x08, 0xf6, 0x18, 0x12, 0x1c, 0x29, 7600x50, 0x12, 0x12, 0x2d, 0xeb, 0xff, 0x12, 0x2d, 0xf4, 0x12, 0x2e, 0x07, 0x78, 0x8b, 0x06, 0x12,
7500xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x75, 0xee, 0xf6, 0x08, 0xef, 0xf6, 0xee, 7610x2e, 0x03, 0x80, 0xe2, 0x22, 0xad, 0x07, 0xac, 0x06, 0x90, 0x32, 0x0a, 0xe4, 0x93, 0xff, 0x78,
7510x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, 0xe0, 0x20, 0xe7, 0x03, 0x7f, 0x00, 7620x74, 0xf6, 0x54, 0x0f, 0x12, 0x1d, 0xa8, 0xe0, 0x08, 0x76, 0x00, 0x08, 0xf6, 0x18, 0x12, 0x1c,
7520x22, 0x78, 0x75, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 7630xd9, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x78, 0x75, 0xee, 0xf6, 0x08, 0xef, 0xf6,
7530x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x90, 7640xee, 0x44, 0xf8, 0x18, 0xf6, 0xef, 0x08, 0xf6, 0x90, 0xff, 0x7a, 0xe0, 0x20, 0xe7, 0x03, 0x7f,
7540x00, 0x03, 0x12, 0x1a, 0x0b, 0x54, 0xf0, 0x24, 0xa0, 0x22, 0x90, 0xfa, 0xc6, 0x12, 0x1b, 0x3a, 7650x00, 0x22, 0x78, 0x75, 0xe6, 0xfe, 0x08, 0xe6, 0xf5, 0x82, 0x8e, 0x83, 0xec, 0xf0, 0xa3, 0xed,
7550x02, 0x19, 0xf2, 0x90, 0xfa, 0xc0, 0x12, 0x1b, 0x3a, 0xef, 0x12, 0x1a, 0x38, 0x90, 0xfa, 0xc7, 7660xf0, 0x90, 0xff, 0x7a, 0x74, 0x02, 0xf0, 0x7f, 0x01, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58,
7560xe4, 0x22, 0x90, 0xfa, 0xc1, 0xe4, 0x75, 0xf0, 0x01, 0x02, 0x1a, 0x6c, 0x90, 0x00, 0x08, 0x12, 7670x90, 0x00, 0x03, 0x12, 0x1a, 0xbb, 0x54, 0xf0, 0x24, 0xa0, 0x22, 0x90, 0xfa, 0xc9, 0x12, 0x1b,
7570x1a, 0x98, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, 0x05, 0x12, 0x1a, 0x0b, 0x90, 0xfa, 7680xea, 0x02, 0x1a, 0xa2, 0x90, 0xfa, 0xc3, 0x12, 0x1b, 0xea, 0xef, 0x12, 0x1a, 0xe8, 0x90, 0xfa,
7580xbe, 0xf0, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x22, 0x90, 0xfa, 0xda, 0xe0, 0xff, 0x7e, 7690xca, 0xe4, 0x22, 0x90, 0xfa, 0xc4, 0xe4, 0x75, 0xf0, 0x01, 0x02, 0x1b, 0x1c, 0x90, 0x00, 0x08,
7590x00, 0xc3, 0x90, 0xfa, 0xd4, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xd3, 0xe0, 0x9e, 0xf0, 0x90, 0xfa, 7700x12, 0x1b, 0x48, 0xaa, 0xf0, 0xf9, 0x7b, 0x01, 0x22, 0x90, 0x00, 0x05, 0x12, 0x1a, 0xbb, 0x90,
7600xd5, 0xee, 0x8f, 0xf0, 0x12, 0x1a, 0x6c, 0xef, 0x25, 0x51, 0xf5, 0x51, 0xee, 0x35, 0x50, 0xf5, 7710xfa, 0xc1, 0xf0, 0x22, 0xab, 0x56, 0xaa, 0x57, 0xa9, 0x58, 0x22, 0x90, 0xfa, 0xdd, 0xe0, 0xff,
7610x50, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0xfa, 0xe3, 7720x7e, 0x00, 0xc3, 0x90, 0xfa, 0xd7, 0xe0, 0x9f, 0xf0, 0x90, 0xfa, 0xd6, 0xe0, 0x9e, 0xf0, 0x90,
7620xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x29, 0xaa, 0x2a, 0xa9, 0x2b, 0x02, 0x1a, 7730xfa, 0xd8, 0xee, 0x8f, 0xf0, 0x12, 0x1b, 0x1c, 0xef, 0x25, 0x51, 0xf5, 0x51, 0xee, 0x35, 0x50,
7630x38, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x64, 0xed, 0x70, 0x0f, 0xe5, 0x64, 0xb4, 7740xf5, 0x50, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0xfa,
7640x03, 0x05, 0x7f, 0x01, 0x02, 0x31, 0x32, 0x7f, 0x02, 0x02, 0x31, 0x32, 0xaf, 0x64, 0x12, 0x2a, 7750xe6, 0xe0, 0x64, 0x03, 0x22, 0x90, 0xff, 0xf2, 0xe0, 0xab, 0x29, 0xaa, 0x2a, 0xa9, 0x2b, 0x02,
7650x06, 0x74, 0x6e, 0x25, 0x64, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, 0xd2, 0x09, 0x12, 0x1c, 0x83, 0xe0, 7760x1a, 0xe8, 0x90, 0xff, 0xf3, 0x74, 0xa0, 0xf0, 0x22, 0x8f, 0x64, 0xed, 0x70, 0x0f, 0xe5, 0x64,
7660x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x64, 0xb4, 0x03, 0x07, 0x7f, 0x81, 0x12, 0x31, 7770xb4, 0x03, 0x05, 0x7f, 0x01, 0x02, 0x31, 0xef, 0x7f, 0x02, 0x02, 0x31, 0xef, 0xaf, 0x64, 0x12,
7670x32, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x31, 0x32, 0x30, 0x09, 0x07, 0x12, 0x1c, 0x83, 0xe0, 0x44, 7780x2a, 0xc7, 0x74, 0x6e, 0x25, 0x64, 0xf8, 0xe6, 0x30, 0xe2, 0x0b, 0xd2, 0x09, 0x12, 0x1d, 0x33,
7680x80, 0xf0, 0x12, 0x31, 0xc7, 0x22, 0x12, 0x10, 0x03, 0x90, 0xff, 0xfd, 0xe0, 0x44, 0x60, 0xf0, 7790xe0, 0x54, 0x7f, 0xf0, 0x80, 0x02, 0xc2, 0x09, 0xe5, 0x64, 0xb4, 0x03, 0x07, 0x7f, 0x81, 0x12,
7690xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0x00, 0xe0, 0x30, 0xe7, 0x13, 7800x31, 0xef, 0x80, 0x05, 0x7f, 0x82, 0x12, 0x31, 0xef, 0x30, 0x09, 0x07, 0x12, 0x1d, 0x33, 0xe0,
7700x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x35, 0x80, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x01, 7810x44, 0x80, 0xf0, 0x12, 0x32, 0x84, 0x22, 0x12, 0x10, 0x4b, 0x90, 0xff, 0xfd, 0xe0, 0x44, 0x60,
7710xf0, 0x80, 0x0d, 0x12, 0x1d, 0x2f, 0x53, 0x35, 0x7f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0xfe, 0xf0, 7820xf0, 0xd2, 0x01, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0xff, 0x00, 0xe0, 0x30, 0xe7,
7720x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0xb0, 0x12, 0x1d, 0x37, 0x02, 0x10, 0x86, 7830x13, 0x90, 0xff, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x35, 0x80, 0x90, 0xff, 0xfc, 0xe0, 0x44,
7730x12, 0x10, 0x03, 0x78, 0x89, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x2a, 0x06, 0x90, 0xf9, 0x67, 0x12, 7840x01, 0xf0, 0x80, 0x0d, 0x12, 0x1d, 0xdf, 0x53, 0x35, 0x7f, 0x90, 0xff, 0xfc, 0xe0, 0x54, 0xfe,
7740x1b, 0x3a, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x80, 0xe6, 0xfe, 0x08, 7850xf0, 0x90, 0xff, 0x81, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x02, 0xde, 0x12, 0x1d, 0xe7, 0x02, 0x10,
7750xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x22, 0x25, 0x12, 0x31, 0xc7, 7860xce, 0x12, 0x10, 0x4b, 0x78, 0x89, 0xef, 0xf6, 0xd2, 0x00, 0x12, 0x2a, 0xc7, 0x90, 0xf9, 0x6a,
7760x78, 0x89, 0xe6, 0xff, 0x12, 0x13, 0x3f, 0x12, 0x30, 0xec, 0x02, 0x10, 0x86, 0x8f, 0x63, 0x12, 7870x12, 0x1b, 0xea, 0xe9, 0x24, 0x03, 0xf9, 0xe4, 0x3a, 0xfa, 0xc0, 0x02, 0x78, 0x80, 0xe6, 0xfe,
7770x2a, 0x06, 0x12, 0x22, 0x07, 0xe0, 0x54, 0x3f, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x21, 0xf3, 7880x08, 0xe6, 0xaa, 0x06, 0xf8, 0xac, 0x02, 0x7d, 0x01, 0xd0, 0x02, 0x12, 0x22, 0xd3, 0x12, 0x32,
7780xe0, 0x54, 0x3f, 0xf0, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0x8e, 0x83, 0x24, 0x0b, 0x12, 0x21, 0xf3, 7890x84, 0x78, 0x89, 0xe6, 0xff, 0x12, 0x13, 0x87, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce, 0x8f, 0x63,
7790xe0, 0x54, 0xf8, 0xf0, 0x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x63, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 7900x12, 0x2a, 0xc7, 0x78, 0x7c, 0x12, 0x22, 0xb7, 0xe0, 0x54, 0x3f, 0xf0, 0xe5, 0x82, 0x24, 0x04,
7800x7f, 0x00, 0x22, 0x8f, 0x23, 0xc2, 0x08, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x12, 0x78, 0x7e, 0x12, 7910x12, 0x22, 0xa1, 0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x23, 0x41, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0,
7810x21, 0xeb, 0xe0, 0x44, 0x01, 0xf0, 0x12, 0x22, 0x4a, 0x12, 0x21, 0xef, 0xe0, 0x20, 0xe0, 0xf6, 7920x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0x74, 0x6e, 0x25, 0x63, 0xf8, 0x74, 0xfb, 0x56, 0xf6, 0x7f,
7820xef, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x31, 0xc7, 7930x00, 0x22, 0x12, 0x10, 0x4b, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xfa, 0x24, 0x06, 0x12, 0x22, 0x9f,
7830xaf, 0x23, 0x12, 0x13, 0x3f, 0x22, 0x12, 0x10, 0x03, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x4a, 0x24, 7940xe0, 0xfd, 0x12, 0x22, 0xe8, 0x90, 0x00, 0x03, 0x12, 0x23, 0x02, 0x24, 0x05, 0x12, 0x22, 0xa1,
7840x06, 0x12, 0x21, 0xf1, 0xe0, 0xfd, 0x12, 0x22, 0x2d, 0x90, 0x00, 0x03, 0x12, 0x22, 0x52, 0x24, 7950xe0, 0x90, 0x00, 0x04, 0x12, 0x1a, 0xfa, 0x12, 0x32, 0x84, 0x7d, 0x02, 0xe4, 0xff, 0x12, 0x2f,
7850x05, 0x12, 0x21, 0xf3, 0xe0, 0x90, 0x00, 0x04, 0x12, 0x1a, 0x4a, 0x12, 0x31, 0xc7, 0x7d, 0x02, 7960xb4, 0x02, 0x10, 0xce, 0xae, 0x05, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa, 0x0e, 0x0e, 0x0e,
7860xe4, 0xff, 0x12, 0x2f, 0x18, 0x02, 0x10, 0x86, 0xae, 0x05, 0x12, 0x1c, 0xde, 0xef, 0x12, 0x1a, 7970xee, 0xd3, 0x95, 0x3c, 0xe4, 0x95, 0x3b, 0x40, 0x02, 0xae, 0x3c, 0xee, 0xd3, 0x94, 0x08, 0x74,
7870x4a, 0x0e, 0x0e, 0x0e, 0xee, 0xd3, 0x95, 0x3c, 0xe4, 0x95, 0x3b, 0x40, 0x02, 0xae, 0x3c, 0xee, 7980x80, 0x94, 0x81, 0x40, 0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 0x12, 0x1a, 0xfa, 0xaf,
7880xd3, 0x94, 0x08, 0x74, 0x80, 0x94, 0x81, 0x40, 0x0a, 0x7e, 0x03, 0x90, 0x00, 0x02, 0x74, 0x02, 7990x06, 0x12, 0x32, 0x6e, 0x22, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 0x60, 0x03, 0x7f, 0x10,
7890x12, 0x1a, 0x4a, 0xaf, 0x06, 0x12, 0x31, 0xb1, 0x22, 0xae, 0x07, 0xed, 0x54, 0x03, 0x64, 0x01, 8000x22, 0xed, 0x54, 0x7c, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 0x74, 0x6e, 0x2e, 0xf8,
7900x60, 0x03, 0x7f, 0x10, 0x22, 0xed, 0x54, 0x7c, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x7f, 0x0b, 0x22, 8010x74, 0x02, 0x46, 0xf6, 0x74, 0x99, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 0xf5, 0x83, 0xed, 0xf0,
7910x74, 0x6e, 0x2e, 0xf8, 0x74, 0x02, 0x46, 0xf6, 0x74, 0x96, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0xfa, 8020x7f, 0x00, 0x22, 0xbf, 0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 0x7c, 0xff, 0x7d, 0xe2,
7920xf5, 0x83, 0xed, 0xf0, 0x7f, 0x00, 0x22, 0xbf, 0x03, 0x06, 0x7c, 0xff, 0x7d, 0xe0, 0x80, 0x04, 8030x8d, 0x82, 0x8c, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 0x12, 0x22, 0xa1, 0xe0,
7930x7c, 0xff, 0x7d, 0xe2, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x82, 0x24, 0x04, 8040x44, 0x80, 0xf0, 0x74, 0x6e, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 0x00, 0x22, 0x12, 0x10,
7940x12, 0x21, 0xf3, 0xe0, 0x44, 0x80, 0xf0, 0x74, 0x6e, 0x2f, 0xf8, 0x74, 0x04, 0x46, 0xf6, 0x7f, 8050x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x16, 0x90, 0xff, 0x83,
7950x00, 0x22, 0x12, 0x10, 0x03, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 8060xe0, 0x54, 0x0f, 0xff, 0xc3, 0xe5, 0x3a, 0x9f, 0xe5, 0x39, 0x94, 0x00, 0x40, 0x05, 0x12, 0x28,
7960x16, 0x90, 0xff, 0x83, 0xe0, 0x54, 0x0f, 0xff, 0xc3, 0xe5, 0x3a, 0x9f, 0xe5, 0x39, 0x94, 0x00, 8070xd7, 0x80, 0x03, 0x12, 0x32, 0x7a, 0x02, 0x10, 0xce, 0x90, 0xff, 0xfc, 0xe0, 0x20, 0xe7, 0x1f,
7970x40, 0x05, 0x12, 0x28, 0x16, 0x80, 0x03, 0x12, 0x31, 0xbd, 0x02, 0x10, 0x86, 0x90, 0xff, 0xfc, 8080xc2, 0xaf, 0x7d, 0xff, 0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 0x7f, 0x00, 0xef, 0x1f,
7980xe0, 0x20, 0xe7, 0x1f, 0xc2, 0xaf, 0x7d, 0xff, 0xac, 0x05, 0x1d, 0xec, 0x60, 0x15, 0x7e, 0x04, 8090xaa, 0x06, 0x70, 0x01, 0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 0xf0, 0x80, 0xef, 0x22,
7990x7f, 0x00, 0xef, 0x1f, 0xaa, 0x06, 0x70, 0x01, 0x1e, 0x4a, 0x60, 0xec, 0x90, 0xff, 0x92, 0xe4, 8100x12, 0x10, 0x4b, 0x78, 0x66, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 0x12, 0x30, 0xe1, 0x0f,
8000xf0, 0x80, 0xef, 0x22, 0x12, 0x10, 0x03, 0x78, 0x66, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x30, 0xe0, 8110x90, 0xff, 0xfc, 0xe0, 0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x12, 0x61, 0x12, 0x1d, 0xf6, 0x02,
8010x12, 0x30, 0xe1, 0x0f, 0x90, 0xff, 0xfc, 0xe0, 0x44, 0x20, 0xf0, 0x7f, 0x04, 0x12, 0x12, 0x19, 8120x10, 0xce, 0x8f, 0x23, 0xc2, 0x08, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x78, 0x7e, 0x12, 0x23,
8020x12, 0x1d, 0x46, 0x02, 0x10, 0x86, 0x8e, 0x5f, 0x8f, 0x60, 0xe5, 0x60, 0x15, 0x60, 0xae, 0x5f, 8130x42, 0x24, 0x0b, 0x12, 0x22, 0xa1, 0xe0, 0x54, 0xf8, 0xf0, 0x12, 0x32, 0x84, 0xaf, 0x23, 0x12,
8030x70, 0x02, 0x15, 0x5f, 0xd3, 0x94, 0x00, 0xee, 0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 8140x13, 0x87, 0x22, 0x8e, 0x5f, 0x8f, 0x60, 0xe5, 0x60, 0x15, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x15,
8040x12, 0x0f, 0xdc, 0x80, 0xe5, 0x22, 0x11, 0x94, 0x2d, 0xf6, 0x23, 0xef, 0x31, 0xa3, 0x2f, 0xf4, 8150x5f, 0xd3, 0x94, 0x00, 0xee, 0x94, 0x00, 0x40, 0x09, 0x7e, 0x07, 0x7f, 0xd0, 0x12, 0x10, 0x24,
8050x2f, 0xa2, 0x30, 0xb2, 0x2e, 0xe6, 0x26, 0x6d, 0x2b, 0xaf, 0x30, 0x55, 0x30, 0x74, 0x1d, 0xb4, 8160x80, 0xe5, 0x22, 0x11, 0xdc, 0x2e, 0xc7, 0x24, 0xb0, 0x32, 0x60, 0x30, 0x90, 0x30, 0x3e, 0x31,
8060x2e, 0x40, 0x2a, 0xe8, 0x0e, 0x12, 0x10, 0x03, 0x78, 0x86, 0x12, 0x22, 0x82, 0x20, 0xe1, 0x07, 8170x6f, 0x2f, 0x82, 0x27, 0x2e, 0x2c, 0x80, 0x31, 0x12, 0x31, 0x31, 0x1e, 0x64, 0x2f, 0x11, 0x2c,
8070x7f, 0x12, 0x12, 0x30, 0xec, 0x80, 0x0a, 0x78, 0x86, 0xe6, 0xff, 0x12, 0x23, 0x49, 0x12, 0x30, 8180x18, 0x0e, 0x12, 0x10, 0x4b, 0x78, 0x86, 0x12, 0x23, 0x31, 0x20, 0xe1, 0x07, 0x7f, 0x12, 0x12,
8080xec, 0x02, 0x10, 0x86, 0x12, 0x10, 0x03, 0x78, 0x87, 0x12, 0x22, 0x82, 0x20, 0xe2, 0x07, 0x7f, 8190x31, 0xa9, 0x80, 0x0a, 0x78, 0x86, 0xe6, 0xff, 0x12, 0x24, 0x0a, 0x12, 0x31, 0xa9, 0x02, 0x10,
8090x11, 0x12, 0x30, 0xec, 0x80, 0x0a, 0x78, 0x87, 0xe6, 0xff, 0x12, 0x2e, 0x7d, 0x12, 0x30, 0xec, 8200xce, 0x12, 0x10, 0x4b, 0x78, 0x87, 0x12, 0x23, 0x31, 0x20, 0xe2, 0x07, 0x7f, 0x11, 0x12, 0x31,
8100x02, 0x10, 0x86, 0x8f, 0x61, 0x12, 0x2e, 0x7d, 0xaf, 0x61, 0x12, 0x2a, 0x06, 0x12, 0x22, 0x12, 8210xa9, 0x80, 0x0a, 0x78, 0x87, 0xe6, 0xff, 0x12, 0x2f, 0x4e, 0x12, 0x31, 0xa9, 0x02, 0x10, 0xce,
8110x12, 0x31, 0xc7, 0x74, 0x6e, 0x25, 0x61, 0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x61, 0x12, 0x13, 8220x8f, 0x61, 0x12, 0x2f, 0x4e, 0xaf, 0x61, 0x12, 0x2a, 0xc7, 0x12, 0x22, 0xc0, 0x12, 0x32, 0x84,
8120x3f, 0x22, 0x12, 0x10, 0x03, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 8230x74, 0x6e, 0x25, 0x61, 0xf8, 0x74, 0xfd, 0x56, 0xf6, 0xaf, 0x61, 0x12, 0x13, 0x87, 0x22, 0x12,
8130x05, 0x12, 0x2c, 0x07, 0x80, 0x06, 0x12, 0x1d, 0x64, 0x12, 0x1d, 0x6c, 0x02, 0x10, 0x86, 0x12, 8240x10, 0x4b, 0xe5, 0x3a, 0x64, 0x09, 0x70, 0x04, 0xe5, 0x39, 0x64, 0x01, 0x60, 0x05, 0x12, 0x2c,
8140x29, 0x93, 0x12, 0x12, 0xbb, 0x90, 0xf8, 0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x12, 8250xd8, 0x80, 0x06, 0x12, 0x1e, 0x14, 0x12, 0x1e, 0x1c, 0x02, 0x10, 0xce, 0x12, 0x2a, 0x54, 0x12,
8150x58, 0x12, 0x29, 0x1d, 0x12, 0x12, 0xf7, 0x12, 0x11, 0x74, 0x80, 0xe3, 0x12, 0x1c, 0xde, 0xef, 8260x13, 0x03, 0x90, 0xf8, 0x04, 0xe0, 0xff, 0x60, 0x05, 0x7d, 0x01, 0x12, 0x12, 0xa0, 0x12, 0x29,
8160x12, 0x1a, 0x4a, 0xe4, 0xf5, 0x33, 0xf5, 0x34, 0xef, 0x60, 0x03, 0x02, 0x31, 0xbd, 0xe4, 0xff, 8270xde, 0x12, 0x13, 0x3f, 0x12, 0x11, 0xbc, 0x80, 0xe3, 0x12, 0x1d, 0x8e, 0xef, 0x12, 0x1a, 0xfa,
8170x12, 0x31, 0xb1, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 8280xe4, 0xf5, 0x33, 0xf5, 0x34, 0xef, 0x60, 0x03, 0x02, 0x32, 0x7a, 0xe4, 0xff, 0x12, 0x32, 0x6e,
8180x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 8290x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0xa0, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff,
8190x54, 0x28, 0x60, 0xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 8300xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0x90, 0xff, 0xf0, 0xe0, 0xff, 0x54, 0x28, 0x60,
8200xd3, 0x22, 0xef, 0x30, 0xe7, 0x08, 0x12, 0x1c, 0x95, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 8310xf7, 0xef, 0x30, 0xe5, 0x08, 0x90, 0xff, 0xf0, 0x44, 0x20, 0xf0, 0xc3, 0x22, 0xd3, 0x22, 0xef,
8210x1c, 0xe8, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 8320x30, 0xe7, 0x08, 0x12, 0x1d, 0x45, 0xe0, 0x54, 0xdf, 0xf0, 0x22, 0xef, 0x12, 0x1d, 0x98, 0xe0,
8220x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x7e, 0x12, 0x22, 8330x54, 0xdf, 0xf0, 0x22, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03, 0x87, 0x40, 0x00, 0x40, 0x00, 0x40,
8230x09, 0xa3, 0xa3, 0xe0, 0xff, 0x30, 0xe7, 0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 8340x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x08, 0x00, 0x78, 0x7e, 0x12, 0x22, 0xb7, 0xa3, 0xa3,
8240x3b, 0x39, 0x85, 0x3c, 0x3a, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 8350xe0, 0xff, 0x30, 0xe7, 0x06, 0x54, 0x7f, 0xf0, 0x44, 0x80, 0xf0, 0x22, 0x85, 0x3b, 0x39, 0x85,
8250xf0, 0x22, 0xe4, 0xfe, 0xee, 0x90, 0x31, 0x47, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 8360x3c, 0x3a, 0x90, 0xff, 0x82, 0xe0, 0x54, 0xf7, 0xf0, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0x22, 0xe4,
8260x07, 0xf2, 0xc3, 0x22, 0x00, 0x08, 0x18, 0x28, 0x38, 0x01, 0x81, 0x10, 0x0a, 0x02, 0x00, 0x00, 8370xfe, 0xee, 0x90, 0x32, 0x04, 0x93, 0xb5, 0x07, 0x02, 0xd3, 0x22, 0x0e, 0xbe, 0x07, 0xf2, 0xc3,
8270x00, 0x00, 0x00, 0x12, 0x10, 0x03, 0x7f, 0x02, 0x12, 0x10, 0x92, 0x12, 0x1d, 0x46, 0x02, 0x10, 8380x22, 0x00, 0x08, 0x18, 0x28, 0x38, 0x01, 0x81, 0x90, 0x0a, 0x02, 0x00, 0x00, 0x11, 0x13, 0x00,
8280x86, 0x75, 0x39, 0x00, 0x8f, 0x3a, 0x12, 0x1c, 0x30, 0x12, 0x2c, 0x07, 0x22, 0x12, 0x1d, 0x6c, 8390x12, 0x10, 0x4b, 0x7f, 0x02, 0x12, 0x10, 0xda, 0x12, 0x1d, 0xf6, 0x02, 0x10, 0xce, 0x75, 0x39,
8290x12, 0x1d, 0x2f, 0x12, 0x1d, 0x64, 0x22, 0xc2, 0x08, 0x22, 8400x00, 0x8f, 0x3a, 0x12, 0x1c, 0xe0, 0x12, 0x2c, 0xd8, 0x22, 0x12, 0x1e, 0x1c, 0x12, 0x1d, 0xdf,
8410x12, 0x1e, 0x14, 0x22, 0xc2, 0x08, 0x22,
830}; 842};
831 843
832#undef IMAGE_VERSION_NAME 844#undef IMAGE_VERSION_NAME
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 544098d2b775..0d3903691e8c 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -48,7 +48,7 @@
48/* 48/*
49 * Version Information 49 * Version Information
50 */ 50 */
51#define DRIVER_VERSION "v0.7" 51#define DRIVER_VERSION "v0.7mode043006"
52#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli" 52#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli"
53#define DRIVER_DESC "Edgeport USB Serial Driver" 53#define DRIVER_DESC "Edgeport USB Serial Driver"
54 54
@@ -173,8 +173,12 @@ static struct usb_device_id edgeport_2port_id_table [] = {
173 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) }, 173 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_221C) },
174 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) }, 174 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
175 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) }, 175 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
176// The 4-port shows up as two 2-port devices 176 /* The 4, 8 and 16 port devices show up as multiple 2 port devices */
177 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) }, 177 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
178 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
179 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
180 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
181 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
178 { } 182 { }
179}; 183};
180 184
@@ -209,6 +213,10 @@ static struct usb_device_id id_table_combined [] = {
209 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) }, 213 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_22C) },
210 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) }, 214 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_21C) },
211 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) }, 215 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_4S) },
216 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8) },
217 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },
218 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },
219 { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) },
212 { } 220 { }
213}; 221};
214 222
@@ -231,6 +239,7 @@ static int TIStayInBootMode = 0;
231static int low_latency = EDGE_LOW_LATENCY; 239static int low_latency = EDGE_LOW_LATENCY;
232static int closing_wait = EDGE_CLOSING_WAIT; 240static int closing_wait = EDGE_CLOSING_WAIT;
233static int ignore_cpu_rev = 0; 241static int ignore_cpu_rev = 0;
242static int default_uart_mode = 0; /* RS232 */
234 243
235 244
236static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length); 245static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length);
@@ -241,6 +250,10 @@ static int restart_read(struct edgeport_port *edge_port);
241static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); 250static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
242static void edge_send(struct usb_serial_port *port); 251static void edge_send(struct usb_serial_port *port);
243 252
253/* sysfs attributes */
254static int edge_create_sysfs_attrs(struct usb_serial_port *port);
255static int edge_remove_sysfs_attrs(struct usb_serial_port *port);
256
244/* circular buffer */ 257/* circular buffer */
245static struct edge_buf *edge_buf_alloc(unsigned int size); 258static struct edge_buf *edge_buf_alloc(unsigned int size);
246static void edge_buf_free(struct edge_buf *eb); 259static void edge_buf_free(struct edge_buf *eb);
@@ -1706,13 +1719,14 @@ static void edge_interrupt_callback (struct urb *urb)
1706 int length = urb->actual_length; 1719 int length = urb->actual_length;
1707 int port_number; 1720 int port_number;
1708 int function; 1721 int function;
1709 int status; 1722 int retval;
1710 __u8 lsr; 1723 __u8 lsr;
1711 __u8 msr; 1724 __u8 msr;
1725 int status = urb->status;
1712 1726
1713 dbg("%s", __FUNCTION__); 1727 dbg("%s", __FUNCTION__);
1714 1728
1715 switch (urb->status) { 1729 switch (status) {
1716 case 0: 1730 case 0:
1717 /* success */ 1731 /* success */
1718 break; 1732 break;
@@ -1720,10 +1734,12 @@ static void edge_interrupt_callback (struct urb *urb)
1720 case -ENOENT: 1734 case -ENOENT:
1721 case -ESHUTDOWN: 1735 case -ESHUTDOWN:
1722 /* this urb is terminated, clean up */ 1736 /* this urb is terminated, clean up */
1723 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 1737 dbg("%s - urb shutting down with status: %d",
1738 __FUNCTION__, status);
1724 return; 1739 return;
1725 default: 1740 default:
1726 dev_err(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __FUNCTION__, urb->status); 1741 dev_err(&urb->dev->dev, "%s - nonzero urb status received: "
1742 "%d\n", __FUNCTION__, status);
1727 goto exit; 1743 goto exit;
1728 } 1744 }
1729 1745
@@ -1781,10 +1797,10 @@ static void edge_interrupt_callback (struct urb *urb)
1781 } 1797 }
1782 1798
1783exit: 1799exit:
1784 status = usb_submit_urb (urb, GFP_ATOMIC); 1800 retval = usb_submit_urb (urb, GFP_ATOMIC);
1785 if (status) 1801 if (retval)
1786 dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n", 1802 dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
1787 __FUNCTION__, status); 1803 __FUNCTION__, retval);
1788} 1804}
1789 1805
1790static void edge_bulk_in_callback (struct urb *urb) 1806static void edge_bulk_in_callback (struct urb *urb)
@@ -1792,12 +1808,13 @@ static void edge_bulk_in_callback (struct urb *urb)
1792 struct edgeport_port *edge_port = (struct edgeport_port *)urb->context; 1808 struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
1793 unsigned char *data = urb->transfer_buffer; 1809 unsigned char *data = urb->transfer_buffer;
1794 struct tty_struct *tty; 1810 struct tty_struct *tty;
1795 int status = 0; 1811 int retval = 0;
1796 int port_number; 1812 int port_number;
1813 int status = urb->status;
1797 1814
1798 dbg("%s", __FUNCTION__); 1815 dbg("%s", __FUNCTION__);
1799 1816
1800 switch (urb->status) { 1817 switch (status) {
1801 case 0: 1818 case 0:
1802 /* success */ 1819 /* success */
1803 break; 1820 break;
@@ -1805,17 +1822,18 @@ static void edge_bulk_in_callback (struct urb *urb)
1805 case -ENOENT: 1822 case -ENOENT:
1806 case -ESHUTDOWN: 1823 case -ESHUTDOWN:
1807 /* this urb is terminated, clean up */ 1824 /* this urb is terminated, clean up */
1808 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 1825 dbg("%s - urb shutting down with status: %d",
1826 __FUNCTION__, status);
1809 return; 1827 return;
1810 default: 1828 default:
1811 dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n", 1829 dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n",
1812 __FUNCTION__, urb->status ); 1830 __FUNCTION__, status);
1813 } 1831 }
1814 1832
1815 if (urb->status == -EPIPE) 1833 if (status == -EPIPE)
1816 goto exit; 1834 goto exit;
1817 1835
1818 if (urb->status) { 1836 if (status) {
1819 dev_err(&urb->dev->dev,"%s - stopping read!\n", __FUNCTION__); 1837 dev_err(&urb->dev->dev,"%s - stopping read!\n", __FUNCTION__);
1820 return; 1838 return;
1821 } 1839 }
@@ -1849,14 +1867,14 @@ exit:
1849 spin_lock(&edge_port->ep_lock); 1867 spin_lock(&edge_port->ep_lock);
1850 if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) { 1868 if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) {
1851 urb->dev = edge_port->port->serial->dev; 1869 urb->dev = edge_port->port->serial->dev;
1852 status = usb_submit_urb(urb, GFP_ATOMIC); 1870 retval = usb_submit_urb(urb, GFP_ATOMIC);
1853 } else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) { 1871 } else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) {
1854 edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED; 1872 edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED;
1855 } 1873 }
1856 spin_unlock(&edge_port->ep_lock); 1874 spin_unlock(&edge_port->ep_lock);
1857 if (status) 1875 if (retval)
1858 dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n", 1876 dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
1859 __FUNCTION__, status); 1877 __FUNCTION__, retval);
1860} 1878}
1861 1879
1862static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length) 1880static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length)
@@ -1883,12 +1901,13 @@ static void edge_bulk_out_callback (struct urb *urb)
1883{ 1901{
1884 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1902 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1885 struct edgeport_port *edge_port = usb_get_serial_port_data(port); 1903 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
1904 int status = urb->status;
1886 1905
1887 dbg ("%s - port %d", __FUNCTION__, port->number); 1906 dbg ("%s - port %d", __FUNCTION__, port->number);
1888 1907
1889 edge_port->ep_write_urb_in_use = 0; 1908 edge_port->ep_write_urb_in_use = 0;
1890 1909
1891 switch (urb->status) { 1910 switch (status) {
1892 case 0: 1911 case 0:
1893 /* success */ 1912 /* success */
1894 break; 1913 break;
@@ -1896,11 +1915,12 @@ static void edge_bulk_out_callback (struct urb *urb)
1896 case -ENOENT: 1915 case -ENOENT:
1897 case -ESHUTDOWN: 1916 case -ESHUTDOWN:
1898 /* this urb is terminated, clean up */ 1917 /* this urb is terminated, clean up */
1899 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 1918 dbg("%s - urb shutting down with status: %d",
1919 __FUNCTION__, status);
1900 return; 1920 return;
1901 default: 1921 default:
1902 dev_err (&urb->dev->dev,"%s - nonzero write bulk status received: %d\n", 1922 dev_err(&urb->dev->dev, "%s - nonzero write bulk status "
1903 __FUNCTION__, urb->status); 1923 "received: %d\n", __FUNCTION__, status);
1904 } 1924 }
1905 1925
1906 /* send any buffered data */ 1926 /* send any buffered data */
@@ -2351,7 +2371,7 @@ static int restart_read(struct edgeport_port *edge_port)
2351 urb->complete = edge_bulk_in_callback; 2371 urb->complete = edge_bulk_in_callback;
2352 urb->context = edge_port; 2372 urb->context = edge_port;
2353 urb->dev = edge_port->port->serial->dev; 2373 urb->dev = edge_port->port->serial->dev;
2354 status = usb_submit_urb(urb, GFP_KERNEL); 2374 status = usb_submit_urb(urb, GFP_ATOMIC);
2355 } 2375 }
2356 edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING; 2376 edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING;
2357 edge_port->shadow_mcr |= MCR_RTS; 2377 edge_port->shadow_mcr |= MCR_RTS;
@@ -2524,14 +2544,6 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
2524 } 2544 }
2525 2545
2526 cflag = tty->termios->c_cflag; 2546 cflag = tty->termios->c_cflag;
2527 /* check that they really want us to change something */
2528 if (old_termios) {
2529 if (cflag == old_termios->c_cflag &&
2530 tty->termios->c_iflag == old_termios->c_iflag) {
2531 dbg ("%s - nothing to change", __FUNCTION__);
2532 return;
2533 }
2534 }
2535 2547
2536 dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 2548 dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
2537 tty->termios->c_cflag, tty->termios->c_iflag); 2549 tty->termios->c_cflag, tty->termios->c_iflag);
@@ -2758,7 +2770,7 @@ static int edge_startup (struct usb_serial *serial)
2758 edge_port->port = serial->port[i]; 2770 edge_port->port = serial->port[i];
2759 edge_port->edge_serial = edge_serial; 2771 edge_port->edge_serial = edge_serial;
2760 usb_set_serial_port_data(serial->port[i], edge_port); 2772 usb_set_serial_port_data(serial->port[i], edge_port);
2761 edge_port->bUartMode = 0; /* Default is RS232 */ 2773 edge_port->bUartMode = default_uart_mode;
2762 } 2774 }
2763 2775
2764 return 0; 2776 return 0;
@@ -2784,6 +2796,7 @@ static void edge_shutdown (struct usb_serial *serial)
2784 2796
2785 for (i=0; i < serial->num_ports; ++i) { 2797 for (i=0; i < serial->num_ports; ++i) {
2786 edge_port = usb_get_serial_port_data(serial->port[i]); 2798 edge_port = usb_get_serial_port_data(serial->port[i]);
2799 edge_remove_sysfs_attrs(edge_port->port);
2787 if (edge_port) { 2800 if (edge_port) {
2788 edge_buf_free(edge_port->ep_out_buf); 2801 edge_buf_free(edge_port->ep_out_buf);
2789 kfree(edge_port); 2802 kfree(edge_port);
@@ -2795,6 +2808,48 @@ static void edge_shutdown (struct usb_serial *serial)
2795} 2808}
2796 2809
2797 2810
2811/* Sysfs Attributes */
2812
2813static ssize_t show_uart_mode(struct device *dev,
2814 struct device_attribute *attr, char *buf)
2815{
2816 struct usb_serial_port *port = to_usb_serial_port(dev);
2817 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
2818
2819 return sprintf(buf, "%d\n", edge_port->bUartMode);
2820}
2821
2822static ssize_t store_uart_mode(struct device *dev,
2823 struct device_attribute *attr, const char *valbuf, size_t count)
2824{
2825 struct usb_serial_port *port = to_usb_serial_port(dev);
2826 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
2827 unsigned int v = simple_strtoul(valbuf, NULL, 0);
2828
2829 dbg("%s: setting uart_mode = %d", __FUNCTION__, v);
2830
2831 if (v < 256)
2832 edge_port->bUartMode = v;
2833 else
2834 dev_err(dev, "%s - uart_mode %d is invalid\n", __FUNCTION__, v);
2835
2836 return count;
2837}
2838
2839static DEVICE_ATTR(uart_mode, S_IWUSR | S_IRUGO, show_uart_mode, store_uart_mode);
2840
2841static int edge_create_sysfs_attrs(struct usb_serial_port *port)
2842{
2843 return device_create_file(&port->dev, &dev_attr_uart_mode);
2844}
2845
2846static int edge_remove_sysfs_attrs(struct usb_serial_port *port)
2847{
2848 device_remove_file(&port->dev, &dev_attr_uart_mode);
2849 return 0;
2850}
2851
2852
2798/* Circular Buffer */ 2853/* Circular Buffer */
2799 2854
2800/* 2855/*
@@ -2991,6 +3046,7 @@ static struct usb_serial_driver edgeport_1port_device = {
2991 .unthrottle = edge_unthrottle, 3046 .unthrottle = edge_unthrottle,
2992 .attach = edge_startup, 3047 .attach = edge_startup,
2993 .shutdown = edge_shutdown, 3048 .shutdown = edge_shutdown,
3049 .port_probe = edge_create_sysfs_attrs,
2994 .ioctl = edge_ioctl, 3050 .ioctl = edge_ioctl,
2995 .set_termios = edge_set_termios, 3051 .set_termios = edge_set_termios,
2996 .tiocmget = edge_tiocmget, 3052 .tiocmget = edge_tiocmget,
@@ -3022,6 +3078,7 @@ static struct usb_serial_driver edgeport_2port_device = {
3022 .unthrottle = edge_unthrottle, 3078 .unthrottle = edge_unthrottle,
3023 .attach = edge_startup, 3079 .attach = edge_startup,
3024 .shutdown = edge_shutdown, 3080 .shutdown = edge_shutdown,
3081 .port_probe = edge_create_sysfs_attrs,
3025 .ioctl = edge_ioctl, 3082 .ioctl = edge_ioctl,
3026 .set_termios = edge_set_termios, 3083 .set_termios = edge_set_termios,
3027 .tiocmget = edge_tiocmget, 3084 .tiocmget = edge_tiocmget,
@@ -3085,3 +3142,6 @@ MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
3085module_param(ignore_cpu_rev, bool, S_IRUGO | S_IWUSR); 3142module_param(ignore_cpu_rev, bool, S_IRUGO | S_IWUSR);
3086MODULE_PARM_DESC(ignore_cpu_rev, "Ignore the cpu revision when connecting to a device"); 3143MODULE_PARM_DESC(ignore_cpu_rev, "Ignore the cpu revision when connecting to a device");
3087 3144
3145module_param(default_uart_mode, int, S_IRUGO | S_IWUSR);
3146MODULE_PARM_DESC(default_uart_mode, "Default uart_mode, 0=RS232, ...");
3147
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h
index e57fa117e486..8e1a491e52a9 100644
--- a/drivers/usb/serial/io_usbvend.h
+++ b/drivers/usb/serial/io_usbvend.h
@@ -131,7 +131,7 @@
131#define ION_DEVICE_ID_TI_EDGEPORT_2I 0x0207 // Edgeport/2i RS422/RS485 131#define ION_DEVICE_ID_TI_EDGEPORT_2I 0x0207 // Edgeport/2i RS422/RS485
132#define ION_DEVICE_ID_TI_EDGEPORT_421 0x020C // Edgeport/421 4 hub 2 RS232 + Parallel (lucent on a different hub port) 132#define ION_DEVICE_ID_TI_EDGEPORT_421 0x020C // Edgeport/421 4 hub 2 RS232 + Parallel (lucent on a different hub port)
133#define ION_DEVICE_ID_TI_EDGEPORT_21 0x020D // Edgeport/21 2 RS232 + Parallel (lucent on a different hub port) 133#define ION_DEVICE_ID_TI_EDGEPORT_21 0x020D // Edgeport/21 2 RS232 + Parallel (lucent on a different hub port)
134#define ION_DEVICE_ID_TI_EDGEPORT_8 0x020F // Edgeport/8 (single-CPU) 134#define ION_DEVICE_ID_TI_EDGEPORT_416 0x0212 // Edgeport/416
135#define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 // Edgeport/1 RS232 135#define ION_DEVICE_ID_TI_EDGEPORT_1 0x0215 // Edgeport/1 RS232
136#define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 // Edgeport/42 4 hub 2 RS232 136#define ION_DEVICE_ID_TI_EDGEPORT_42 0x0217 // Edgeport/42 4 hub 2 RS232
137#define ION_DEVICE_ID_TI_EDGEPORT_22I 0x021A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232 137#define ION_DEVICE_ID_TI_EDGEPORT_22I 0x021A // Edgeport/22I is an Edgeport/4 with ports 1&2 RS422 and ports 3&4 RS232
@@ -143,12 +143,14 @@
143#define ION_DEVICE_ID_TI_EDGEPORT_21C 0x021E // Edgeport/21c is a TI based Edgeport/2 with lucent chip 143#define ION_DEVICE_ID_TI_EDGEPORT_21C 0x021E // Edgeport/21c is a TI based Edgeport/2 with lucent chip
144 144
145// Generation 3 devices -- 3410 based edgport/1 (256 byte I2C) 145// Generation 3 devices -- 3410 based edgport/1 (256 byte I2C)
146#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1 0x240 // Edgeport/1 RS232 146#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1 0x0240 // Edgeport/1 RS232
147#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I 0x241 // Edgeport/1i- RS422 model 147#define ION_DEVICE_ID_TI_TI3410_EDGEPORT_1I 0x0241 // Edgeport/1i- RS422 model
148 148
149// Ti based software switchable RS232/RS422/RS485 devices 149// Ti based software switchable RS232/RS422/RS485 devices
150#define ION_DEVICE_ID_TI_EDGEPORT_4S 0x242 // Edgeport/4s - software switchable model 150#define ION_DEVICE_ID_TI_EDGEPORT_4S 0x0242 // Edgeport/4s - software switchable model
151#define ION_DEVICE_ID_IT_EDGEPORT_8S 0x243 // Edgeport/8s - software switchable model 151#define ION_DEVICE_ID_TI_EDGEPORT_8S 0x0243 // Edgeport/8s - software switchable model
152#define ION_DEVICE_ID_TI_EDGEPORT_8 0x0244 // Edgeport/8 (single-CPU)
153#define ION_DEVICE_ID_TI_EDGEPORT_416B 0x0247 // Edgeport/416
152 154
153 155
154/************************************************************************ 156/************************************************************************
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 4df0ec74e0b1..0455c1552ae9 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -732,11 +732,13 @@ static void ipaq_read_bulk_callback(struct urb *urb)
732 struct tty_struct *tty; 732 struct tty_struct *tty;
733 unsigned char *data = urb->transfer_buffer; 733 unsigned char *data = urb->transfer_buffer;
734 int result; 734 int result;
735 int status = urb->status;
735 736
736 dbg("%s - port %d", __FUNCTION__, port->number); 737 dbg("%s - port %d", __FUNCTION__, port->number);
737 738
738 if (urb->status) { 739 if (status) {
739 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 740 dbg("%s - nonzero read bulk status received: %d",
741 __FUNCTION__, status);
740 return; 742 return;
741 } 743 }
742 744
@@ -870,11 +872,13 @@ static void ipaq_write_bulk_callback(struct urb *urb)
870 struct ipaq_private *priv = usb_get_serial_port_data(port); 872 struct ipaq_private *priv = usb_get_serial_port_data(port);
871 unsigned long flags; 873 unsigned long flags;
872 int result; 874 int result;
875 int status = urb->status;
873 876
874 dbg("%s - port %d", __FUNCTION__, port->number); 877 dbg("%s - port %d", __FUNCTION__, port->number);
875 878
876 if (urb->status) { 879 if (status) {
877 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 880 dbg("%s - nonzero write bulk status received: %d",
881 __FUNCTION__, status);
878 return; 882 return;
879 } 883 }
880 884
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 1bc586064c77..1b94daa61584 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -167,11 +167,13 @@ static void ipw_read_bulk_callback(struct urb *urb)
167 unsigned char *data = urb->transfer_buffer; 167 unsigned char *data = urb->transfer_buffer;
168 struct tty_struct *tty; 168 struct tty_struct *tty;
169 int result; 169 int result;
170 int status = urb->status;
170 171
171 dbg("%s - port %d", __FUNCTION__, port->number); 172 dbg("%s - port %d", __FUNCTION__, port->number);
172 173
173 if (urb->status) { 174 if (status) {
174 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 175 dbg("%s - nonzero read bulk status received: %d",
176 __FUNCTION__, status);
175 return; 177 return;
176 } 178 }
177 179
@@ -369,13 +371,15 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
369static void ipw_write_bulk_callback(struct urb *urb) 371static void ipw_write_bulk_callback(struct urb *urb)
370{ 372{
371 struct usb_serial_port *port = urb->context; 373 struct usb_serial_port *port = urb->context;
374 int status = urb->status;
372 375
373 dbg("%s", __FUNCTION__); 376 dbg("%s", __FUNCTION__);
374 377
375 port->write_urb_busy = 0; 378 port->write_urb_busy = 0;
376 379
377 if (urb->status) 380 if (status)
378 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 381 dbg("%s - nonzero write bulk status received: %d",
382 __FUNCTION__, status);
379 383
380 usb_serial_port_softint(port); 384 usb_serial_port_softint(port);
381} 385}
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 9d847f69291c..5ab6a0c5ac52 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -21,6 +21,10 @@
21 * 21 *
22 * See Documentation/usb/usb-serial.txt for more information on using this driver 22 * See Documentation/usb/usb-serial.txt for more information on using this driver
23 * 23 *
24 * 2007_Jun_21 Alan Cox <alan@redhat.com>
25 * Minimal cleanups for some of the driver problens and tty layer abuse.
26 * Still needs fixing to allow multiple dongles.
27 *
24 * 2002_Mar_07 greg kh 28 * 2002_Mar_07 greg kh
25 * moved some needed structures and #define values from the 29 * moved some needed structures and #define values from the
26 * net/irda/irda-usb.h file into our file, as we don't want to depend on 30 * net/irda/irda-usb.h file into our file, as we don't want to depend on
@@ -109,6 +113,7 @@ static void ir_write_bulk_callback (struct urb *urb);
109static void ir_read_bulk_callback (struct urb *urb); 113static void ir_read_bulk_callback (struct urb *urb);
110static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); 114static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
111 115
116/* Not that this lot means you can only have one per system */
112static u8 ir_baud = 0; 117static u8 ir_baud = 0;
113static u8 ir_xbof = 0; 118static u8 ir_xbof = 0;
114static u8 ir_add_bof = 0; 119static u8 ir_add_bof = 0;
@@ -392,12 +397,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
392static void ir_write_bulk_callback (struct urb *urb) 397static void ir_write_bulk_callback (struct urb *urb)
393{ 398{
394 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 399 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
400 int status = urb->status;
395 401
396 dbg("%s - port %d", __FUNCTION__, port->number); 402 dbg("%s - port %d", __FUNCTION__, port->number);
397 403
398 port->write_urb_busy = 0; 404 port->write_urb_busy = 0;
399 if (urb->status) { 405 if (status) {
400 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 406 dbg("%s - nonzero write bulk status received: %d",
407 __FUNCTION__, status);
401 return; 408 return;
402 } 409 }
403 410
@@ -417,6 +424,7 @@ static void ir_read_bulk_callback (struct urb *urb)
417 struct tty_struct *tty; 424 struct tty_struct *tty;
418 unsigned char *data = urb->transfer_buffer; 425 unsigned char *data = urb->transfer_buffer;
419 int result; 426 int result;
427 int status = urb->status;
420 428
421 dbg("%s - port %d", __FUNCTION__, port->number); 429 dbg("%s - port %d", __FUNCTION__, port->number);
422 430
@@ -425,8 +433,7 @@ static void ir_read_bulk_callback (struct urb *urb)
425 return; 433 return;
426 } 434 }
427 435
428 switch (urb->status) { 436 switch (status) {
429
430 case 0: /* Successful */ 437 case 0: /* Successful */
431 438
432 /* 439 /*
@@ -444,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb)
444 urb->actual_length, 451 urb->actual_length,
445 data); 452 data);
446 453
447 /*
448 * Bypass flip-buffers, and feed the ldisc directly
449 * due to our potentially large buffer size. Since we
450 * used to set low_latency, this is exactly what the
451 * tty layer did anyway :)
452 */
453 tty = port->tty; 454 tty = port->tty;
454 455
455 /* 456 if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
456 * FIXME: must not do this in IRQ context 457 tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
457 */ 458 tty_flip_buffer_push(tty);
458 tty->ldisc.receive_buf( 459 }
459 tty,
460 data+1,
461 NULL,
462 urb->actual_length-1);
463 460
464 /* 461 /*
465 * No break here. 462 * No break here.
@@ -490,7 +487,7 @@ static void ir_read_bulk_callback (struct urb *urb)
490 default: 487 default:
491 dbg("%s - nonzero read bulk status received: %d", 488 dbg("%s - nonzero read bulk status received: %d",
492 __FUNCTION__, 489 __FUNCTION__,
493 urb->status); 490 status);
494 break ; 491 break ;
495 492
496 } 493 }
@@ -501,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb)
501static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) 498static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
502{ 499{
503 unsigned char *transfer_buffer; 500 unsigned char *transfer_buffer;
504 unsigned int cflag;
505 int result; 501 int result;
502 speed_t baud;
503 int ir_baud;
506 504
507 dbg("%s - port %d", __FUNCTION__, port->number); 505 dbg("%s - port %d", __FUNCTION__, port->number);
508 506
@@ -511,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
511 return; 509 return;
512 } 510 }
513 511
514 cflag = port->tty->termios->c_cflag; 512 baud = tty_get_baud_rate(port->tty);
515 /* check that they really want us to change something */ 513
516 if (old_termios) { 514 /*
517 if ((cflag == old_termios->c_cflag) && 515 * FIXME, we should compare the baud request against the
518 (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { 516 * capability stated in the IR header that we got in the
519 dbg("%s - nothing to change...", __FUNCTION__); 517 * startup function.
520 return; 518 */
521 } 519
520 switch (baud) {
521 case 2400: ir_baud = SPEED_2400; break;
522 case 9600: ir_baud = SPEED_9600; break;
523 case 19200: ir_baud = SPEED_19200; break;
524 case 38400: ir_baud = SPEED_38400; break;
525 case 57600: ir_baud = SPEED_57600; break;
526 case 115200: ir_baud = SPEED_115200; break;
527 case 576000: ir_baud = SPEED_576000; break;
528 case 1152000: ir_baud = SPEED_1152000; break;
529 case 4000000: ir_baud = SPEED_4000000; break;
530 break;
531 default:
532 ir_baud = SPEED_9600;
533 baud = 9600;
534 /* And once the new tty stuff is all done we need to
535 call back to correct the baud bits */
522 } 536 }
523 537
524 /* All we can change is the baud rate */ 538 if (xbof == -1)
525 if (cflag & CBAUD) { 539 ir_xbof = ir_xbof_change(ir_add_bof);
526 540 else
527 dbg ("%s - asking for baud %d", 541 ir_xbof = ir_xbof_change(xbof) ;
528 __FUNCTION__,
529 tty_get_baud_rate(port->tty));
530
531 /*
532 * FIXME, we should compare the baud request against the
533 * capability stated in the IR header that we got in the
534 * startup function.
535 */
536 switch (cflag & CBAUD) {
537 case B2400: ir_baud = SPEED_2400; break;
538 default:
539 case B9600: ir_baud = SPEED_9600; break;
540 case B19200: ir_baud = SPEED_19200; break;
541 case B38400: ir_baud = SPEED_38400; break;
542 case B57600: ir_baud = SPEED_57600; break;
543 case B115200: ir_baud = SPEED_115200; break;
544 case B576000: ir_baud = SPEED_576000; break;
545 case B1152000: ir_baud = SPEED_1152000; break;
546#ifdef B4000000
547 case B4000000: ir_baud = SPEED_4000000; break;
548#endif
549 }
550 542
551 if (xbof == -1) { 543 /* FIXME need to check to see if our write urb is busy right
552 ir_xbof = ir_xbof_change(ir_add_bof); 544 * now, or use a urb pool.
553 } else { 545 *
554 ir_xbof = ir_xbof_change(xbof) ; 546 * send the baud change out on an "empty" data packet
555 } 547 */
548 transfer_buffer = port->write_urb->transfer_buffer;
549 *transfer_buffer = ir_xbof | ir_baud;
556 550
557 /* Notify the tty driver that the termios have changed. */ 551 usb_fill_bulk_urb (
558 port->tty->ldisc.set_termios(port->tty, NULL); 552 port->write_urb,
559 553 port->serial->dev,
560 /* FIXME need to check to see if our write urb is busy right 554 usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
561 * now, or use a urb pool. 555 port->write_urb->transfer_buffer,
562 * 556 1,
563 * send the baud change out on an "empty" data packet 557 ir_write_bulk_callback,
564 */ 558 port);
565 transfer_buffer = port->write_urb->transfer_buffer; 559
566 *transfer_buffer = ir_xbof | ir_baud; 560 port->write_urb->transfer_flags = URB_ZERO_PACKET;
567 561
568 usb_fill_bulk_urb ( 562 result = usb_submit_urb (port->write_urb, GFP_KERNEL);
569 port->write_urb, 563 if (result)
570 port->serial->dev, 564 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
571 usb_sndbulkpipe(port->serial->dev,
572 port->bulk_out_endpointAddress),
573 port->write_urb->transfer_buffer,
574 1,
575 ir_write_bulk_callback,
576 port);
577
578 port->write_urb->transfer_flags = URB_ZERO_PACKET;
579
580 result = usb_submit_urb (port->write_urb, GFP_KERNEL);
581 if (result)
582 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
583 }
584 return;
585} 565}
586 566
587 567
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index e6966f12ed5a..f2a6fce5de1e 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -115,12 +115,13 @@ static int debug;
115/* 115/*
116 * Version Information 116 * Version Information
117 */ 117 */
118#define DRIVER_VERSION "v1.1.4" 118#define DRIVER_VERSION "v1.1.5"
119#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu" 119#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
120#define DRIVER_DESC "Keyspan USB to Serial Converter Driver" 120#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
121 121
122#define INSTAT_BUFLEN 32 122#define INSTAT_BUFLEN 32
123#define GLOCONT_BUFLEN 64 123#define GLOCONT_BUFLEN 64
124#define INDAT49W_BUFLEN 512
124 125
125 /* Per device and per port private data */ 126 /* Per device and per port private data */
126struct keyspan_serial_private { 127struct keyspan_serial_private {
@@ -129,9 +130,15 @@ struct keyspan_serial_private {
129 struct urb *instat_urb; 130 struct urb *instat_urb;
130 char instat_buf[INSTAT_BUFLEN]; 131 char instat_buf[INSTAT_BUFLEN];
131 132
133 /* added to support 49wg, where data from all 4 ports comes in on 1 EP */
134 /* and high-speed supported */
135 struct urb *indat_urb;
136 char indat_buf[INDAT49W_BUFLEN];
137
132 /* XXX this one probably will need a lock */ 138 /* XXX this one probably will need a lock */
133 struct urb *glocont_urb; 139 struct urb *glocont_urb;
134 char glocont_buf[GLOCONT_BUFLEN]; 140 char glocont_buf[GLOCONT_BUFLEN];
141 char ctrl_buf[8]; // for EP0 control message
135}; 142};
136 143
137struct keyspan_port_private { 144struct keyspan_port_private {
@@ -179,12 +186,13 @@ struct keyspan_port_private {
179 186
180 187
181/* Include Keyspan message headers. All current Keyspan Adapters 188/* Include Keyspan message headers. All current Keyspan Adapters
182 make use of one of four message formats which are referred 189 make use of one of five message formats which are referred
183 to as USA-26, USA-28 and USA-49, USA-90 by Keyspan and within this driver. */ 190 to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and within this driver. */
184#include "keyspan_usa26msg.h" 191#include "keyspan_usa26msg.h"
185#include "keyspan_usa28msg.h" 192#include "keyspan_usa28msg.h"
186#include "keyspan_usa49msg.h" 193#include "keyspan_usa49msg.h"
187#include "keyspan_usa90msg.h" 194#include "keyspan_usa90msg.h"
195#include "keyspan_usa67msg.h"
188 196
189 197
190/* Functions used by new usb-serial code. */ 198/* Functions used by new usb-serial code. */
@@ -419,14 +427,15 @@ static void usa26_indat_callback(struct urb *urb)
419 struct usb_serial_port *port; 427 struct usb_serial_port *port;
420 struct tty_struct *tty; 428 struct tty_struct *tty;
421 unsigned char *data = urb->transfer_buffer; 429 unsigned char *data = urb->transfer_buffer;
430 int status = urb->status;
422 431
423 dbg ("%s", __FUNCTION__); 432 dbg ("%s", __FUNCTION__);
424 433
425 endpoint = usb_pipeendpoint(urb->pipe); 434 endpoint = usb_pipeendpoint(urb->pipe);
426 435
427 if (urb->status) { 436 if (status) {
428 dbg("%s - nonzero status: %x on endpoint %d.", 437 dbg("%s - nonzero status: %x on endpoint %d.",
429 __FUNCTION__, urb->status, endpoint); 438 __FUNCTION__, status, endpoint);
430 return; 439 return;
431 } 440 }
432 441
@@ -511,11 +520,12 @@ static void usa26_instat_callback(struct urb *urb)
511 struct usb_serial_port *port; 520 struct usb_serial_port *port;
512 struct keyspan_port_private *p_priv; 521 struct keyspan_port_private *p_priv;
513 int old_dcd_state, err; 522 int old_dcd_state, err;
523 int status = urb->status;
514 524
515 serial = (struct usb_serial *) urb->context; 525 serial = (struct usb_serial *) urb->context;
516 526
517 if (urb->status) { 527 if (status) {
518 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status); 528 dbg("%s - nonzero status: %x", __FUNCTION__, status);
519 return; 529 return;
520 } 530 }
521 if (urb->actual_length != 9) { 531 if (urb->actual_length != 9) {
@@ -579,6 +589,7 @@ static void usa28_indat_callback(struct urb *urb)
579 struct tty_struct *tty; 589 struct tty_struct *tty;
580 unsigned char *data; 590 unsigned char *data;
581 struct keyspan_port_private *p_priv; 591 struct keyspan_port_private *p_priv;
592 int status = urb->status;
582 593
583 dbg ("%s", __FUNCTION__); 594 dbg ("%s", __FUNCTION__);
584 595
@@ -590,9 +601,9 @@ static void usa28_indat_callback(struct urb *urb)
590 return; 601 return;
591 602
592 do { 603 do {
593 if (urb->status) { 604 if (status) {
594 dbg("%s - nonzero status: %x on endpoint %d.", 605 dbg("%s - nonzero status: %x on endpoint %d.",
595 __FUNCTION__, urb->status, usb_pipeendpoint(urb->pipe)); 606 __FUNCTION__, status, usb_pipeendpoint(urb->pipe));
596 return; 607 return;
597 } 608 }
598 609
@@ -648,11 +659,12 @@ static void usa28_instat_callback(struct urb *urb)
648 struct usb_serial_port *port; 659 struct usb_serial_port *port;
649 struct keyspan_port_private *p_priv; 660 struct keyspan_port_private *p_priv;
650 int old_dcd_state; 661 int old_dcd_state;
662 int status = urb->status;
651 663
652 serial = (struct usb_serial *) urb->context; 664 serial = (struct usb_serial *) urb->context;
653 665
654 if (urb->status) { 666 if (status) {
655 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status); 667 dbg("%s - nonzero status: %x", __FUNCTION__, status);
656 return; 668 return;
657 } 669 }
658 670
@@ -739,13 +751,14 @@ static void usa49_instat_callback(struct urb *urb)
739 struct usb_serial_port *port; 751 struct usb_serial_port *port;
740 struct keyspan_port_private *p_priv; 752 struct keyspan_port_private *p_priv;
741 int old_dcd_state; 753 int old_dcd_state;
754 int status = urb->status;
742 755
743 dbg ("%s", __FUNCTION__); 756 dbg ("%s", __FUNCTION__);
744 757
745 serial = (struct usb_serial *) urb->context; 758 serial = (struct usb_serial *) urb->context;
746 759
747 if (urb->status) { 760 if (status) {
748 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status); 761 dbg("%s - nonzero status: %x", __FUNCTION__, status);
749 return; 762 return;
750 } 763 }
751 764
@@ -805,14 +818,15 @@ static void usa49_indat_callback(struct urb *urb)
805 struct usb_serial_port *port; 818 struct usb_serial_port *port;
806 struct tty_struct *tty; 819 struct tty_struct *tty;
807 unsigned char *data = urb->transfer_buffer; 820 unsigned char *data = urb->transfer_buffer;
821 int status = urb->status;
808 822
809 dbg ("%s", __FUNCTION__); 823 dbg ("%s", __FUNCTION__);
810 824
811 endpoint = usb_pipeendpoint(urb->pipe); 825 endpoint = usb_pipeendpoint(urb->pipe);
812 826
813 if (urb->status) { 827 if (status) {
814 dbg("%s - nonzero status: %x on endpoint %d.", __FUNCTION__, 828 dbg("%s - nonzero status: %x on endpoint %d.", __FUNCTION__,
815 urb->status, endpoint); 829 status, endpoint);
816 return; 830 return;
817 } 831 }
818 832
@@ -850,13 +864,90 @@ static void usa49_indat_callback(struct urb *urb)
850 } 864 }
851} 865}
852 866
867static void usa49wg_indat_callback(struct urb *urb)
868{
869 int i, len, x, err;
870 struct usb_serial *serial;
871 struct usb_serial_port *port;
872 struct tty_struct *tty;
873 unsigned char *data = urb->transfer_buffer;
874 int status = urb->status;
875
876 dbg ("%s", __FUNCTION__);
877
878 serial = urb->context;
879
880 if (status) {
881 dbg("%s - nonzero status: %x", __FUNCTION__, status);
882 return;
883 }
884
885 /* inbound data is in the form P#, len, status, data */
886 i = 0;
887 len = 0;
888
889 if (urb->actual_length) {
890 while (i < urb->actual_length) {
891
892 /* Check port number from message*/
893 if (data[i] >= serial->num_ports) {
894 dbg ("%s - Unexpected port number %d",
895 __FUNCTION__, data[i]);
896 return;
897 }
898 port = serial->port[data[i++]];
899 tty = port->tty;
900 len = data[i++];
901
902 /* 0x80 bit is error flag */
903 if ((data[i] & 0x80) == 0) {
904 /* no error on any byte */
905 i++;
906 for (x = 1; x < len ; ++x)
907 if (port->open_count)
908 tty_insert_flip_char(tty,
909 data[i++], 0);
910 else
911 i++;
912 } else {
913 /*
914 * some bytes had errors, every byte has status
915 */
916 for (x = 0; x + 1 < len; x += 2) {
917 int stat = data[i], flag = 0;
918 if (stat & RXERROR_OVERRUN)
919 flag |= TTY_OVERRUN;
920 if (stat & RXERROR_FRAMING)
921 flag |= TTY_FRAME;
922 if (stat & RXERROR_PARITY)
923 flag |= TTY_PARITY;
924 /* XXX should handle break (0x10) */
925 if (port->open_count)
926 tty_insert_flip_char(tty,
927 data[i+1], flag);
928 i += 2;
929 }
930 }
931 if (port->open_count)
932 tty_flip_buffer_push(tty);
933 }
934 }
935
936 /* Resubmit urb so we continue receiving */
937 urb->dev = serial->dev;
938
939 err = usb_submit_urb(urb, GFP_ATOMIC);
940 if (err != 0)
941 dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
942}
943
853/* not used, usa-49 doesn't have per-port control endpoints */ 944/* not used, usa-49 doesn't have per-port control endpoints */
854static void usa49_outcont_callback(struct urb *urb) 945static void usa49_outcont_callback(struct urb *urb)
855{ 946{
856 dbg ("%s", __FUNCTION__); 947 dbg ("%s", __FUNCTION__);
857} 948}
858 949
859static void usa90_indat_callback(struct urb *urb) 950static void usa90_indat_callback(struct urb *urb)
860{ 951{
861 int i, err; 952 int i, err;
862 int endpoint; 953 int endpoint;
@@ -864,15 +955,15 @@ static void usa90_indat_callback(struct urb *urb)
864 struct keyspan_port_private *p_priv; 955 struct keyspan_port_private *p_priv;
865 struct tty_struct *tty; 956 struct tty_struct *tty;
866 unsigned char *data = urb->transfer_buffer; 957 unsigned char *data = urb->transfer_buffer;
958 int status = urb->status;
867 959
868 dbg ("%s", __FUNCTION__); 960 dbg ("%s", __FUNCTION__);
869 961
870 endpoint = usb_pipeendpoint(urb->pipe); 962 endpoint = usb_pipeendpoint(urb->pipe);
871 963
872 964 if (status) {
873 if (urb->status) {
874 dbg("%s - nonzero status: %x on endpoint %d.", 965 dbg("%s - nonzero status: %x on endpoint %d.",
875 __FUNCTION__, urb->status, endpoint); 966 __FUNCTION__, status, endpoint);
876 return; 967 return;
877 } 968 }
878 969
@@ -938,11 +1029,12 @@ static void usa90_instat_callback(struct urb *urb)
938 struct usb_serial_port *port; 1029 struct usb_serial_port *port;
939 struct keyspan_port_private *p_priv; 1030 struct keyspan_port_private *p_priv;
940 int old_dcd_state, err; 1031 int old_dcd_state, err;
1032 int status = urb->status;
941 1033
942 serial = (struct usb_serial *) urb->context; 1034 serial = (struct usb_serial *) urb->context;
943 1035
944 if (urb->status) { 1036 if (status) {
945 dbg("%s - nonzero status: %x", __FUNCTION__, urb->status); 1037 dbg("%s - nonzero status: %x", __FUNCTION__, status);
946 return; 1038 return;
947 } 1039 }
948 if (urb->actual_length < 14) { 1040 if (urb->actual_length < 14) {
@@ -995,6 +1087,88 @@ static void usa90_outcont_callback(struct urb *urb)
995 } 1087 }
996} 1088}
997 1089
1090/* Status messages from the 28xg */
1091static void usa67_instat_callback(struct urb *urb)
1092{
1093 int err;
1094 unsigned char *data = urb->transfer_buffer;
1095 struct keyspan_usa67_portStatusMessage *msg;
1096 struct usb_serial *serial;
1097 struct usb_serial_port *port;
1098 struct keyspan_port_private *p_priv;
1099 int old_dcd_state;
1100 int status = urb->status;
1101
1102 dbg ("%s", __FUNCTION__);
1103
1104 serial = urb->context;
1105
1106 if (status) {
1107 dbg("%s - nonzero status: %x", __FUNCTION__, status);
1108 return;
1109 }
1110
1111 if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) {
1112 dbg("%s - bad length %d", __FUNCTION__, urb->actual_length);
1113 return;
1114 }
1115
1116
1117 /* Now do something useful with the data */
1118 msg = (struct keyspan_usa67_portStatusMessage *)data;
1119
1120 /* Check port number from message and retrieve private data */
1121 if (msg->port >= serial->num_ports) {
1122 dbg ("%s - Unexpected port number %d", __FUNCTION__, msg->port);
1123 return;
1124 }
1125
1126 port = serial->port[msg->port];
1127 p_priv = usb_get_serial_port_data(port);
1128
1129 /* Update handshaking pin state information */
1130 old_dcd_state = p_priv->dcd_state;
1131 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
1132 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
1133
1134 if (port->tty && !C_CLOCAL(port->tty)
1135 && old_dcd_state != p_priv->dcd_state) {
1136 if (old_dcd_state)
1137 tty_hangup(port->tty);
1138 /* else */
1139 /* wake_up_interruptible(&p_priv->open_wait); */
1140 }
1141
1142 /* Resubmit urb so we continue receiving */
1143 urb->dev = serial->dev;
1144 err = usb_submit_urb(urb, GFP_ATOMIC);
1145 if (err != 0)
1146 dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
1147}
1148
1149static void usa67_glocont_callback(struct urb *urb)
1150{
1151 struct usb_serial *serial;
1152 struct usb_serial_port *port;
1153 struct keyspan_port_private *p_priv;
1154 int i;
1155
1156 dbg ("%s", __FUNCTION__);
1157
1158 serial = urb->context;
1159 for (i = 0; i < serial->num_ports; ++i) {
1160 port = serial->port[i];
1161 p_priv = usb_get_serial_port_data(port);
1162
1163 if (p_priv->resend_cont) {
1164 dbg ("%s - sending setup", __FUNCTION__);
1165 keyspan_usa67_send_setup(serial, port,
1166 p_priv->resend_cont - 1);
1167 break;
1168 }
1169 }
1170}
1171
998static int keyspan_write_room (struct usb_serial_port *port) 1172static int keyspan_write_room (struct usb_serial_port *port)
999{ 1173{
1000 struct keyspan_port_private *p_priv; 1174 struct keyspan_port_private *p_priv;
@@ -1311,6 +1485,11 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
1311 return NULL; 1485 return NULL;
1312 } 1486 }
1313 1487
1488 if (endpoint == 0) {
1489 /* control EP filled in when used */
1490 return urb;
1491 }
1492
1314 ep_desc = find_ep(serial, endpoint); 1493 ep_desc = find_ep(serial, endpoint);
1315 if (!ep_desc) { 1494 if (!ep_desc) {
1316 /* leak the urb, something's wrong and the callers don't care */ 1495 /* leak the urb, something's wrong and the callers don't care */
@@ -1380,6 +1559,14 @@ static struct callbacks {
1380 .outdat_callback = usa2x_outdat_callback, 1559 .outdat_callback = usa2x_outdat_callback,
1381 .inack_callback = usa28_inack_callback, 1560 .inack_callback = usa28_inack_callback,
1382 .outcont_callback = usa90_outcont_callback, 1561 .outcont_callback = usa90_outcont_callback,
1562 }, {
1563 /* msg_usa67 callbacks */
1564 .instat_callback = usa67_instat_callback,
1565 .glocont_callback = usa67_glocont_callback,
1566 .indat_callback = usa26_indat_callback,
1567 .outdat_callback = usa2x_outdat_callback,
1568 .inack_callback = usa26_inack_callback,
1569 .outcont_callback = usa26_outcont_callback,
1383 } 1570 }
1384}; 1571};
1385 1572
@@ -1410,6 +1597,11 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
1410 serial, s_priv->instat_buf, INSTAT_BUFLEN, 1597 serial, s_priv->instat_buf, INSTAT_BUFLEN,
1411 cback->instat_callback); 1598 cback->instat_callback);
1412 1599
1600 s_priv->indat_urb = keyspan_setup_urb
1601 (serial, d_details->indat_endpoint, USB_DIR_IN,
1602 serial, s_priv->indat_buf, INDAT49W_BUFLEN,
1603 usa49wg_indat_callback);
1604
1413 s_priv->glocont_urb = keyspan_setup_urb 1605 s_priv->glocont_urb = keyspan_setup_urb
1414 (serial, d_details->glocont_endpoint, USB_DIR_OUT, 1606 (serial, d_details->glocont_endpoint, USB_DIR_OUT,
1415 serial, s_priv->glocont_buf, GLOCONT_BUFLEN, 1607 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
@@ -1685,8 +1877,8 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
1685 } 1877 }
1686 1878
1687 /* Save reset port val for resend. 1879 /* Save reset port val for resend.
1688 Don't overwrite resend for close condition. */ 1880 Don't overwrite resend for open/close condition. */
1689 if (p_priv->resend_cont != 3) 1881 if ((reset_port + 1) > p_priv->resend_cont)
1690 p_priv->resend_cont = reset_port + 1; 1882 p_priv->resend_cont = reset_port + 1;
1691 if (this_urb->status == -EINPROGRESS) { 1883 if (this_urb->status == -EINPROGRESS) {
1692 /* dbg ("%s - already writing", __FUNCTION__); */ 1884 /* dbg ("%s - already writing", __FUNCTION__); */
@@ -1836,8 +2028,8 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
1836 } 2028 }
1837 2029
1838 /* Save reset port val for resend. 2030 /* Save reset port val for resend.
1839 Don't overwrite resend for close condition. */ 2031 Don't overwrite resend for open/close condition. */
1840 if (p_priv->resend_cont != 3) 2032 if ((reset_port + 1) > p_priv->resend_cont)
1841 p_priv->resend_cont = reset_port + 1; 2033 p_priv->resend_cont = reset_port + 1;
1842 if (this_urb->status == -EINPROGRESS) { 2034 if (this_urb->status == -EINPROGRESS) {
1843 dbg ("%s already writing", __FUNCTION__); 2035 dbg ("%s already writing", __FUNCTION__);
@@ -1940,11 +2132,11 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1940 struct usb_serial_port *port, 2132 struct usb_serial_port *port,
1941 int reset_port) 2133 int reset_port)
1942{ 2134{
1943 struct keyspan_usa49_portControlMessage msg; 2135 struct keyspan_usa49_portControlMessage msg;
2136 struct usb_ctrlrequest *dr = NULL;
1944 struct keyspan_serial_private *s_priv; 2137 struct keyspan_serial_private *s_priv;
1945 struct keyspan_port_private *p_priv; 2138 struct keyspan_port_private *p_priv;
1946 const struct keyspan_device_details *d_details; 2139 const struct keyspan_device_details *d_details;
1947 int glocont_urb;
1948 struct urb *this_urb; 2140 struct urb *this_urb;
1949 int err, device_port; 2141 int err, device_port;
1950 2142
@@ -1954,10 +2146,9 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1954 p_priv = usb_get_serial_port_data(port); 2146 p_priv = usb_get_serial_port_data(port);
1955 d_details = s_priv->device_details; 2147 d_details = s_priv->device_details;
1956 2148
1957 glocont_urb = d_details->glocont_endpoint;
1958 this_urb = s_priv->glocont_urb; 2149 this_urb = s_priv->glocont_urb;
1959 2150
1960 /* Work out which port within the device is being setup */ 2151 /* Work out which port within the device is being setup */
1961 device_port = port->number - port->serial->minor; 2152 device_port = port->number - port->serial->minor;
1962 2153
1963 dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port); 2154 dbg("%s - endpoint %d port %d (%d)",__FUNCTION__, usb_pipeendpoint(this_urb->pipe), port->number, device_port);
@@ -1969,9 +2160,10 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
1969 } 2160 }
1970 2161
1971 /* Save reset port val for resend. 2162 /* Save reset port val for resend.
1972 Don't overwrite resend for close condition. */ 2163 Don't overwrite resend for open/close condition. */
1973 if (p_priv->resend_cont != 3) 2164 if ((reset_port + 1) > p_priv->resend_cont)
1974 p_priv->resend_cont = reset_port + 1; 2165 p_priv->resend_cont = reset_port + 1;
2166
1975 if (this_urb->status == -EINPROGRESS) { 2167 if (this_urb->status == -EINPROGRESS) {
1976 /* dbg ("%s - already writing", __FUNCTION__); */ 2168 /* dbg ("%s - already writing", __FUNCTION__); */
1977 mdelay(5); 2169 mdelay(5);
@@ -2083,20 +2275,39 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
2083 msg.dtr = p_priv->dtr_state; 2275 msg.dtr = p_priv->dtr_state;
2084 2276
2085 p_priv->resend_cont = 0; 2277 p_priv->resend_cont = 0;
2086 memcpy (this_urb->transfer_buffer, &msg, sizeof(msg)); 2278
2279 /* if the device is a 49wg, we send control message on usb control EP 0 */
2280
2281 if (d_details->product_id == keyspan_usa49wg_product_id) {
2282 dr = (void *)(s_priv->ctrl_buf);
2283 dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT;
2284 dr->bRequest = 0xB0; /* 49wg control message */;
2285 dr->wValue = 0;
2286 dr->wIndex = 0;
2287 dr->wLength = cpu_to_le16(sizeof(msg));
2288
2289 memcpy (s_priv->glocont_buf, &msg, sizeof(msg));
2290
2291 usb_fill_control_urb(this_urb, serial->dev, usb_sndctrlpipe(serial->dev, 0),
2292 (unsigned char *)dr, s_priv->glocont_buf, sizeof(msg),
2293 usa49_glocont_callback, serial);
2294
2295 } else {
2296 memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
2087 2297
2088 /* send the data out the device on control endpoint */ 2298 /* send the data out the device on control endpoint */
2089 this_urb->transfer_buffer_length = sizeof(msg); 2299 this_urb->transfer_buffer_length = sizeof(msg);
2090 2300
2091 this_urb->dev = serial->dev; 2301 this_urb->dev = serial->dev;
2302 }
2092 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) { 2303 if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
2093 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err); 2304 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err);
2094 } 2305 }
2095#if 0 2306#if 0
2096 else { 2307 else {
2097 dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__, 2308 dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __FUNCTION__,
2098 outcont_urb, this_urb->transfer_buffer_length, 2309 outcont_urb, this_urb->transfer_buffer_length,
2099 usb_pipeendpoint(this_urb->pipe)); 2310 usb_pipeendpoint(this_urb->pipe));
2100 } 2311 }
2101#endif 2312#endif
2102 2313
@@ -2241,6 +2452,154 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
2241 return (0); 2452 return (0);
2242} 2453}
2243 2454
2455static int keyspan_usa67_send_setup(struct usb_serial *serial,
2456 struct usb_serial_port *port,
2457 int reset_port)
2458{
2459 struct keyspan_usa67_portControlMessage msg;
2460 struct keyspan_serial_private *s_priv;
2461 struct keyspan_port_private *p_priv;
2462 const struct keyspan_device_details *d_details;
2463 struct urb *this_urb;
2464 int err, device_port;
2465
2466 dbg ("%s", __FUNCTION__);
2467
2468 s_priv = usb_get_serial_data(serial);
2469 p_priv = usb_get_serial_port_data(port);
2470 d_details = s_priv->device_details;
2471
2472 this_urb = s_priv->glocont_urb;
2473
2474 /* Work out which port within the device is being setup */
2475 device_port = port->number - port->serial->minor;
2476
2477 /* Make sure we have an urb then send the message */
2478 if (this_urb == NULL) {
2479 dbg("%s - oops no urb for port %d.", __FUNCTION__,
2480 port->number);
2481 return -1;
2482 }
2483
2484 /* Save reset port val for resend.
2485 Don't overwrite resend for open/close condition. */
2486 if ((reset_port + 1) > p_priv->resend_cont)
2487 p_priv->resend_cont = reset_port + 1;
2488 if (this_urb->status == -EINPROGRESS) {
2489 /* dbg ("%s - already writing", __FUNCTION__); */
2490 mdelay(5);
2491 return(-1);
2492 }
2493
2494 memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));
2495
2496 msg.port = device_port;
2497
2498 /* Only set baud rate if it's changed */
2499 if (p_priv->old_baud != p_priv->baud) {
2500 p_priv->old_baud = p_priv->baud;
2501 msg.setClocking = 0xff;
2502 if (d_details->calculate_baud_rate
2503 (p_priv->baud, d_details->baudclk, &msg.baudHi,
2504 &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
2505 dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__,
2506 p_priv->baud);
2507 msg.baudLo = 0;
2508 msg.baudHi = 125; /* Values for 9600 baud */
2509 msg.prescaler = 10;
2510 }
2511 msg.setPrescaler = 0xff;
2512 }
2513
2514 msg.lcr = (p_priv->cflag & CSTOPB) ? STOPBITS_678_2 : STOPBITS_5678_1;
2515 switch (p_priv->cflag & CSIZE) {
2516 case CS5:
2517 msg.lcr |= USA_DATABITS_5;
2518 break;
2519 case CS6:
2520 msg.lcr |= USA_DATABITS_6;
2521 break;
2522 case CS7:
2523 msg.lcr |= USA_DATABITS_7;
2524 break;
2525 case CS8:
2526 msg.lcr |= USA_DATABITS_8;
2527 break;
2528 }
2529 if (p_priv->cflag & PARENB) {
2530 /* note USA_PARITY_NONE == 0 */
2531 msg.lcr |= (p_priv->cflag & PARODD)?
2532 USA_PARITY_ODD: USA_PARITY_EVEN;
2533 }
2534 msg.setLcr = 0xff;
2535
2536 msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
2537 msg.xonFlowControl = 0;
2538 msg.setFlowControl = 0xff;
2539 msg.forwardingLength = 16;
2540 msg.xonChar = 17;
2541 msg.xoffChar = 19;
2542
2543 if (reset_port == 1) {
2544 /* Opening port */
2545 msg._txOn = 1;
2546 msg._txOff = 0;
2547 msg.txFlush = 0;
2548 msg.txBreak = 0;
2549 msg.rxOn = 1;
2550 msg.rxOff = 0;
2551 msg.rxFlush = 1;
2552 msg.rxForward = 0;
2553 msg.returnStatus = 0;
2554 msg.resetDataToggle = 0xff;
2555 } else if (reset_port == 2) {
2556 /* Closing port */
2557 msg._txOn = 0;
2558 msg._txOff = 1;
2559 msg.txFlush = 0;
2560 msg.txBreak = 0;
2561 msg.rxOn = 0;
2562 msg.rxOff = 1;
2563 msg.rxFlush = 1;
2564 msg.rxForward = 0;
2565 msg.returnStatus = 0;
2566 msg.resetDataToggle = 0;
2567 } else {
2568 /* Sending intermediate configs */
2569 msg._txOn = (! p_priv->break_on);
2570 msg._txOff = 0;
2571 msg.txFlush = 0;
2572 msg.txBreak = (p_priv->break_on);
2573 msg.rxOn = 0;
2574 msg.rxOff = 0;
2575 msg.rxFlush = 0;
2576 msg.rxForward = 0;
2577 msg.returnStatus = 0;
2578 msg.resetDataToggle = 0x0;
2579 }
2580
2581 /* Do handshaking outputs */
2582 msg.setTxTriState_setRts = 0xff;
2583 msg.txTriState_rts = p_priv->rts_state;
2584
2585 msg.setHskoa_setDtr = 0xff;
2586 msg.hskoa_dtr = p_priv->dtr_state;
2587
2588 p_priv->resend_cont = 0;
2589
2590 memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
2591
2592 /* send the data out the device on control endpoint */
2593 this_urb->transfer_buffer_length = sizeof(msg);
2594 this_urb->dev = serial->dev;
2595
2596 err = usb_submit_urb(this_urb, GFP_ATOMIC);
2597 if (err != 0)
2598 dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__,
2599 err);
2600 return (0);
2601}
2602
2244static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) 2603static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
2245{ 2604{
2246 struct usb_serial *serial = port->serial; 2605 struct usb_serial *serial = port->serial;
@@ -2265,6 +2624,9 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
2265 case msg_usa90: 2624 case msg_usa90:
2266 keyspan_usa90_send_setup(serial, port, reset_port); 2625 keyspan_usa90_send_setup(serial, port, reset_port);
2267 break; 2626 break;
2627 case msg_usa67:
2628 keyspan_usa67_send_setup(serial, port, reset_port);
2629 break;
2268 } 2630 }
2269} 2631}
2270 2632
@@ -2313,9 +2675,19 @@ static int keyspan_startup (struct usb_serial *serial)
2313 2675
2314 keyspan_setup_urbs(serial); 2676 keyspan_setup_urbs(serial);
2315 2677
2316 s_priv->instat_urb->dev = serial->dev; 2678 if (s_priv->instat_urb != NULL) {
2317 if ((err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL)) != 0) { 2679 s_priv->instat_urb->dev = serial->dev;
2318 dbg("%s - submit instat urb failed %d", __FUNCTION__, err); 2680 err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL);
2681 if (err != 0)
2682 dbg("%s - submit instat urb failed %d", __FUNCTION__,
2683 err);
2684 }
2685 if (s_priv->indat_urb != NULL) {
2686 s_priv->indat_urb->dev = serial->dev;
2687 err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL);
2688 if (err != 0)
2689 dbg("%s - submit indat urb failed %d", __FUNCTION__,
2690 err);
2319 } 2691 }
2320 2692
2321 return (0); 2693 return (0);
@@ -2335,6 +2707,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
2335 /* Stop reading/writing urbs */ 2707 /* Stop reading/writing urbs */
2336 stop_urb(s_priv->instat_urb); 2708 stop_urb(s_priv->instat_urb);
2337 stop_urb(s_priv->glocont_urb); 2709 stop_urb(s_priv->glocont_urb);
2710 stop_urb(s_priv->indat_urb);
2338 for (i = 0; i < serial->num_ports; ++i) { 2711 for (i = 0; i < serial->num_ports; ++i) {
2339 port = serial->port[i]; 2712 port = serial->port[i];
2340 p_priv = usb_get_serial_port_data(port); 2713 p_priv = usb_get_serial_port_data(port);
@@ -2348,6 +2721,7 @@ static void keyspan_shutdown (struct usb_serial *serial)
2348 2721
2349 /* Now free them */ 2722 /* Now free them */
2350 usb_free_urb(s_priv->instat_urb); 2723 usb_free_urb(s_priv->instat_urb);
2724 usb_free_urb(s_priv->indat_urb);
2351 usb_free_urb(s_priv->glocont_urb); 2725 usb_free_urb(s_priv->glocont_urb);
2352 for (i = 0; i < serial->num_ports; ++i) { 2726 for (i = 0; i < serial->num_ports; ++i) {
2353 port = serial->port[i]; 2727 port = serial->port[i];
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index c6830cbdc6df..8a0d17401529 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -99,6 +99,10 @@ static int keyspan_usa90_send_setup (struct usb_serial *serial,
99 struct usb_serial_port *port, 99 struct usb_serial_port *port,
100 int reset_port); 100 int reset_port);
101 101
102static int keyspan_usa67_send_setup (struct usb_serial *serial,
103 struct usb_serial_port *port,
104 int reset_port);
105
102/* Struct used for firmware - increased size of data section 106/* Struct used for firmware - increased size of data section
103 to allow Keyspan's 'C' firmware struct to be used unmodified */ 107 to allow Keyspan's 'C' firmware struct to be used unmodified */
104struct ezusb_hex_record { 108struct ezusb_hex_record {
@@ -229,15 +233,17 @@ struct ezusb_hex_record {
229#define keyspan_usa28_product_id 0x010f 233#define keyspan_usa28_product_id 0x010f
230#define keyspan_usa28x_product_id 0x0110 234#define keyspan_usa28x_product_id 0x0110
231#define keyspan_usa28xa_product_id 0x0115 235#define keyspan_usa28xa_product_id 0x0115
236#define keyspan_usa28xb_product_id 0x0110
237#define keyspan_usa28xg_product_id 0x0135
232#define keyspan_usa49w_product_id 0x010a 238#define keyspan_usa49w_product_id 0x010a
233#define keyspan_usa49wlc_product_id 0x012a 239#define keyspan_usa49wlc_product_id 0x012a
234 240#define keyspan_usa49wg_product_id 0x0131
235 241
236struct keyspan_device_details { 242struct keyspan_device_details {
237 /* product ID value */ 243 /* product ID value */
238 int product_id; 244 int product_id;
239 245
240 enum {msg_usa26, msg_usa28, msg_usa49, msg_usa90} msg_format; 246 enum {msg_usa26, msg_usa28, msg_usa49, msg_usa90, msg_usa67} msg_format;
241 247
242 /* Number of physical ports */ 248 /* Number of physical ports */
243 int num_ports; 249 int num_ports;
@@ -264,6 +270,9 @@ struct keyspan_device_details {
264 /* Endpoint used for input status */ 270 /* Endpoint used for input status */
265 int instat_endpoint; 271 int instat_endpoint;
266 272
273 /* Endpoint used for input data 49WG only */
274 int indat_endpoint;
275
267 /* Endpoint used for global control functions */ 276 /* Endpoint used for global control functions */
268 int glocont_endpoint; 277 int glocont_endpoint;
269 278
@@ -287,6 +296,7 @@ static const struct keyspan_device_details usa18x_device_details = {
287 .inack_endpoints = {0x85}, 296 .inack_endpoints = {0x85},
288 .outcont_endpoints = {0x05}, 297 .outcont_endpoints = {0x05},
289 .instat_endpoint = 0x87, 298 .instat_endpoint = 0x87,
299 .indat_endpoint = -1,
290 .glocont_endpoint = 0x07, 300 .glocont_endpoint = 0x07,
291 .calculate_baud_rate = keyspan_usa19w_calc_baud, 301 .calculate_baud_rate = keyspan_usa19w_calc_baud,
292 .baudclk = KEYSPAN_USA18X_BAUDCLK, 302 .baudclk = KEYSPAN_USA18X_BAUDCLK,
@@ -303,6 +313,7 @@ static const struct keyspan_device_details usa19_device_details = {
303 .inack_endpoints = {0x83}, 313 .inack_endpoints = {0x83},
304 .outcont_endpoints = {0x03}, 314 .outcont_endpoints = {0x03},
305 .instat_endpoint = 0x84, 315 .instat_endpoint = 0x84,
316 .indat_endpoint = -1,
306 .glocont_endpoint = -1, 317 .glocont_endpoint = -1,
307 .calculate_baud_rate = keyspan_usa19_calc_baud, 318 .calculate_baud_rate = keyspan_usa19_calc_baud,
308 .baudclk = KEYSPAN_USA19_BAUDCLK, 319 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -319,6 +330,7 @@ static const struct keyspan_device_details usa19qi_device_details = {
319 .inack_endpoints = {0x83}, 330 .inack_endpoints = {0x83},
320 .outcont_endpoints = {0x03}, 331 .outcont_endpoints = {0x03},
321 .instat_endpoint = 0x84, 332 .instat_endpoint = 0x84,
333 .indat_endpoint = -1,
322 .glocont_endpoint = -1, 334 .glocont_endpoint = -1,
323 .calculate_baud_rate = keyspan_usa28_calc_baud, 335 .calculate_baud_rate = keyspan_usa28_calc_baud,
324 .baudclk = KEYSPAN_USA19_BAUDCLK, 336 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -335,6 +347,7 @@ static const struct keyspan_device_details mpr_device_details = {
335 .inack_endpoints = {0x83}, 347 .inack_endpoints = {0x83},
336 .outcont_endpoints = {0x03}, 348 .outcont_endpoints = {0x03},
337 .instat_endpoint = 0x84, 349 .instat_endpoint = 0x84,
350 .indat_endpoint = -1,
338 .glocont_endpoint = -1, 351 .glocont_endpoint = -1,
339 .calculate_baud_rate = keyspan_usa28_calc_baud, 352 .calculate_baud_rate = keyspan_usa28_calc_baud,
340 .baudclk = KEYSPAN_USA19_BAUDCLK, 353 .baudclk = KEYSPAN_USA19_BAUDCLK,
@@ -351,6 +364,7 @@ static const struct keyspan_device_details usa19qw_device_details = {
351 .inack_endpoints = {0x85}, 364 .inack_endpoints = {0x85},
352 .outcont_endpoints = {0x05}, 365 .outcont_endpoints = {0x05},
353 .instat_endpoint = 0x87, 366 .instat_endpoint = 0x87,
367 .indat_endpoint = -1,
354 .glocont_endpoint = 0x07, 368 .glocont_endpoint = 0x07,
355 .calculate_baud_rate = keyspan_usa19w_calc_baud, 369 .calculate_baud_rate = keyspan_usa19w_calc_baud,
356 .baudclk = KEYSPAN_USA19W_BAUDCLK, 370 .baudclk = KEYSPAN_USA19W_BAUDCLK,
@@ -367,6 +381,7 @@ static const struct keyspan_device_details usa19w_device_details = {
367 .inack_endpoints = {0x85}, 381 .inack_endpoints = {0x85},
368 .outcont_endpoints = {0x05}, 382 .outcont_endpoints = {0x05},
369 .instat_endpoint = 0x87, 383 .instat_endpoint = 0x87,
384 .indat_endpoint = -1,
370 .glocont_endpoint = 0x07, 385 .glocont_endpoint = 0x07,
371 .calculate_baud_rate = keyspan_usa19w_calc_baud, 386 .calculate_baud_rate = keyspan_usa19w_calc_baud,
372 .baudclk = KEYSPAN_USA19W_BAUDCLK, 387 .baudclk = KEYSPAN_USA19W_BAUDCLK,
@@ -383,6 +398,7 @@ static const struct keyspan_device_details usa19hs_device_details = {
383 .inack_endpoints = {-1}, 398 .inack_endpoints = {-1},
384 .outcont_endpoints = {0x02}, 399 .outcont_endpoints = {0x02},
385 .instat_endpoint = 0x82, 400 .instat_endpoint = 0x82,
401 .indat_endpoint = -1,
386 .glocont_endpoint = -1, 402 .glocont_endpoint = -1,
387 .calculate_baud_rate = keyspan_usa19hs_calc_baud, 403 .calculate_baud_rate = keyspan_usa19hs_calc_baud,
388 .baudclk = KEYSPAN_USA19HS_BAUDCLK, 404 .baudclk = KEYSPAN_USA19HS_BAUDCLK,
@@ -399,6 +415,7 @@ static const struct keyspan_device_details usa28_device_details = {
399 .inack_endpoints = {0x85, 0x86}, 415 .inack_endpoints = {0x85, 0x86},
400 .outcont_endpoints = {0x05, 0x06}, 416 .outcont_endpoints = {0x05, 0x06},
401 .instat_endpoint = 0x87, 417 .instat_endpoint = 0x87,
418 .indat_endpoint = -1,
402 .glocont_endpoint = 0x07, 419 .glocont_endpoint = 0x07,
403 .calculate_baud_rate = keyspan_usa28_calc_baud, 420 .calculate_baud_rate = keyspan_usa28_calc_baud,
404 .baudclk = KEYSPAN_USA28_BAUDCLK, 421 .baudclk = KEYSPAN_USA28_BAUDCLK,
@@ -415,6 +432,7 @@ static const struct keyspan_device_details usa28x_device_details = {
415 .inack_endpoints = {0x85, 0x86}, 432 .inack_endpoints = {0x85, 0x86},
416 .outcont_endpoints = {0x05, 0x06}, 433 .outcont_endpoints = {0x05, 0x06},
417 .instat_endpoint = 0x87, 434 .instat_endpoint = 0x87,
435 .indat_endpoint = -1,
418 .glocont_endpoint = 0x07, 436 .glocont_endpoint = 0x07,
419 .calculate_baud_rate = keyspan_usa19w_calc_baud, 437 .calculate_baud_rate = keyspan_usa19w_calc_baud,
420 .baudclk = KEYSPAN_USA28X_BAUDCLK, 438 .baudclk = KEYSPAN_USA28X_BAUDCLK,
@@ -431,11 +449,28 @@ static const struct keyspan_device_details usa28xa_device_details = {
431 .inack_endpoints = {0x85, 0x86}, 449 .inack_endpoints = {0x85, 0x86},
432 .outcont_endpoints = {0x05, 0x06}, 450 .outcont_endpoints = {0x05, 0x06},
433 .instat_endpoint = 0x87, 451 .instat_endpoint = 0x87,
452 .indat_endpoint = -1,
434 .glocont_endpoint = 0x07, 453 .glocont_endpoint = 0x07,
435 .calculate_baud_rate = keyspan_usa19w_calc_baud, 454 .calculate_baud_rate = keyspan_usa19w_calc_baud,
436 .baudclk = KEYSPAN_USA28X_BAUDCLK, 455 .baudclk = KEYSPAN_USA28X_BAUDCLK,
437}; 456};
438 457
458static const struct keyspan_device_details usa28xg_device_details = {
459 .product_id = keyspan_usa28xg_product_id,
460 .msg_format = msg_usa67,
461 .num_ports = 2,
462 .indat_endp_flip = 0,
463 .outdat_endp_flip = 0,
464 .indat_endpoints = {0x84, 0x88},
465 .outdat_endpoints = {0x02, 0x06},
466 .inack_endpoints = {-1, -1},
467 .outcont_endpoints = {-1, -1},
468 .instat_endpoint = 0x81,
469 .indat_endpoint = -1,
470 .glocont_endpoint = 0x01,
471 .calculate_baud_rate = keyspan_usa19w_calc_baud,
472 .baudclk = KEYSPAN_USA28X_BAUDCLK,
473};
439/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */ 474/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
440 475
441static const struct keyspan_device_details usa49w_device_details = { 476static const struct keyspan_device_details usa49w_device_details = {
@@ -449,6 +484,7 @@ static const struct keyspan_device_details usa49w_device_details = {
449 .inack_endpoints = {-1, -1, -1, -1}, 484 .inack_endpoints = {-1, -1, -1, -1},
450 .outcont_endpoints = {-1, -1, -1, -1}, 485 .outcont_endpoints = {-1, -1, -1, -1},
451 .instat_endpoint = 0x87, 486 .instat_endpoint = 0x87,
487 .indat_endpoint = -1,
452 .glocont_endpoint = 0x07, 488 .glocont_endpoint = 0x07,
453 .calculate_baud_rate = keyspan_usa19w_calc_baud, 489 .calculate_baud_rate = keyspan_usa19w_calc_baud,
454 .baudclk = KEYSPAN_USA49W_BAUDCLK, 490 .baudclk = KEYSPAN_USA49W_BAUDCLK,
@@ -465,11 +501,29 @@ static const struct keyspan_device_details usa49wlc_device_details = {
465 .inack_endpoints = {-1, -1, -1, -1}, 501 .inack_endpoints = {-1, -1, -1, -1},
466 .outcont_endpoints = {-1, -1, -1, -1}, 502 .outcont_endpoints = {-1, -1, -1, -1},
467 .instat_endpoint = 0x87, 503 .instat_endpoint = 0x87,
504 .indat_endpoint = -1,
468 .glocont_endpoint = 0x07, 505 .glocont_endpoint = 0x07,
469 .calculate_baud_rate = keyspan_usa19w_calc_baud, 506 .calculate_baud_rate = keyspan_usa19w_calc_baud,
470 .baudclk = KEYSPAN_USA19W_BAUDCLK, 507 .baudclk = KEYSPAN_USA19W_BAUDCLK,
471}; 508};
472 509
510static const struct keyspan_device_details usa49wg_device_details = {
511 .product_id = keyspan_usa49wg_product_id,
512 .msg_format = msg_usa49,
513 .num_ports = 4,
514 .indat_endp_flip = 0,
515 .outdat_endp_flip = 0,
516 .indat_endpoints = {-1, -1, -1, -1}, /* single 'global' data in EP */
517 .outdat_endpoints = {0x01, 0x02, 0x04, 0x06},
518 .inack_endpoints = {-1, -1, -1, -1},
519 .outcont_endpoints = {-1, -1, -1, -1},
520 .instat_endpoint = 0x81,
521 .indat_endpoint = 0x88,
522 .glocont_endpoint = 0x00, /* uses control EP */
523 .calculate_baud_rate = keyspan_usa19w_calc_baud,
524 .baudclk = KEYSPAN_USA19W_BAUDCLK,
525};
526
473static const struct keyspan_device_details *keyspan_devices[] = { 527static const struct keyspan_device_details *keyspan_devices[] = {
474 &usa18x_device_details, 528 &usa18x_device_details,
475 &usa19_device_details, 529 &usa19_device_details,
@@ -481,9 +535,11 @@ static const struct keyspan_device_details *keyspan_devices[] = {
481 &usa28_device_details, 535 &usa28_device_details,
482 &usa28x_device_details, 536 &usa28x_device_details,
483 &usa28xa_device_details, 537 &usa28xa_device_details,
538 &usa28xg_device_details,
484 /* 28xb not required as it renumerates as a 28x */ 539 /* 28xb not required as it renumerates as a 28x */
485 &usa49w_device_details, 540 &usa49w_device_details,
486 &usa49wlc_device_details, 541 &usa49wlc_device_details,
542 &usa49wg_device_details,
487 NULL, 543 NULL,
488}; 544};
489 545
@@ -510,8 +566,11 @@ static struct usb_device_id keyspan_ids_combined[] = {
510 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, 566 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
511 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, 567 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
512 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, 568 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
569 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
570 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
513 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, 571 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)},
514 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, 572 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
573 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
515 { } /* Terminating entry */ 574 { } /* Terminating entry */
516}; 575};
517 576
@@ -557,12 +616,15 @@ static struct usb_device_id keyspan_2port_ids[] = {
557 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, 616 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
558 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, 617 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
559 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, 618 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
619 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
620 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
560 { } /* Terminating entry */ 621 { } /* Terminating entry */
561}; 622};
562 623
563static struct usb_device_id keyspan_4port_ids[] = { 624static struct usb_device_id keyspan_4port_ids[] = {
564 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) }, 625 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
565 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, 626 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
627 { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wg_product_id)},
566 { } /* Terminating entry */ 628 { } /* Terminating entry */
567}; 629};
568 630
@@ -573,7 +635,6 @@ static struct usb_serial_driver keyspan_pre_device = {
573 .name = "keyspan_no_firm", 635 .name = "keyspan_no_firm",
574 }, 636 },
575 .description = "Keyspan - (without firmware)", 637 .description = "Keyspan - (without firmware)",
576 .usb_driver = &keyspan_driver,
577 .id_table = keyspan_pre_ids, 638 .id_table = keyspan_pre_ids,
578 .num_interrupt_in = NUM_DONT_CARE, 639 .num_interrupt_in = NUM_DONT_CARE,
579 .num_bulk_in = NUM_DONT_CARE, 640 .num_bulk_in = NUM_DONT_CARE,
@@ -588,7 +649,6 @@ static struct usb_serial_driver keyspan_1port_device = {
588 .name = "keyspan_1", 649 .name = "keyspan_1",
589 }, 650 },
590 .description = "Keyspan 1 port adapter", 651 .description = "Keyspan 1 port adapter",
591 .usb_driver = &keyspan_driver,
592 .id_table = keyspan_1port_ids, 652 .id_table = keyspan_1port_ids,
593 .num_interrupt_in = NUM_DONT_CARE, 653 .num_interrupt_in = NUM_DONT_CARE,
594 .num_bulk_in = NUM_DONT_CARE, 654 .num_bulk_in = NUM_DONT_CARE,
@@ -616,7 +676,6 @@ static struct usb_serial_driver keyspan_2port_device = {
616 .name = "keyspan_2", 676 .name = "keyspan_2",
617 }, 677 },
618 .description = "Keyspan 2 port adapter", 678 .description = "Keyspan 2 port adapter",
619 .usb_driver = &keyspan_driver,
620 .id_table = keyspan_2port_ids, 679 .id_table = keyspan_2port_ids,
621 .num_interrupt_in = NUM_DONT_CARE, 680 .num_interrupt_in = NUM_DONT_CARE,
622 .num_bulk_in = NUM_DONT_CARE, 681 .num_bulk_in = NUM_DONT_CARE,
@@ -644,11 +703,10 @@ static struct usb_serial_driver keyspan_4port_device = {
644 .name = "keyspan_4", 703 .name = "keyspan_4",
645 }, 704 },
646 .description = "Keyspan 4 port adapter", 705 .description = "Keyspan 4 port adapter",
647 .usb_driver = &keyspan_driver,
648 .id_table = keyspan_4port_ids, 706 .id_table = keyspan_4port_ids,
649 .num_interrupt_in = NUM_DONT_CARE, 707 .num_interrupt_in = NUM_DONT_CARE,
650 .num_bulk_in = 5, 708 .num_bulk_in = NUM_DONT_CARE,
651 .num_bulk_out = 5, 709 .num_bulk_out = NUM_DONT_CARE,
652 .num_ports = 4, 710 .num_ports = 4,
653 .open = keyspan_open, 711 .open = keyspan_open,
654 .close = keyspan_close, 712 .close = keyspan_close,
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index dd0b66a6ed5d..be9ac20a8f10 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -218,11 +218,12 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
218 struct tty_struct *tty = port->tty; 218 struct tty_struct *tty = port->tty;
219 unsigned char *data = urb->transfer_buffer; 219 unsigned char *data = urb->transfer_buffer;
220 int i; 220 int i;
221 int status; 221 int retval;
222 int status = urb->status;
222 struct keyspan_pda_private *priv; 223 struct keyspan_pda_private *priv;
223 priv = usb_get_serial_port_data(port); 224 priv = usb_get_serial_port_data(port);
224 225
225 switch (urb->status) { 226 switch (status) {
226 case 0: 227 case 0:
227 /* success */ 228 /* success */
228 break; 229 break;
@@ -230,10 +231,12 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
230 case -ENOENT: 231 case -ENOENT:
231 case -ESHUTDOWN: 232 case -ESHUTDOWN:
232 /* this urb is terminated, clean up */ 233 /* this urb is terminated, clean up */
233 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 234 dbg("%s - urb shutting down with status: %d",
235 __FUNCTION__, status);
234 return; 236 return;
235 default: 237 default:
236 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 238 dbg("%s - nonzero urb status received: %d",
239 __FUNCTION__, status);
237 goto exit; 240 goto exit;
238 } 241 }
239 242
@@ -268,10 +271,10 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
268 } 271 }
269 272
270exit: 273exit:
271 status = usb_submit_urb (urb, GFP_ATOMIC); 274 retval = usb_submit_urb (urb, GFP_ATOMIC);
272 if (status) 275 if (retval)
273 err ("%s - usb_submit_urb failed with result %d", 276 err ("%s - usb_submit_urb failed with result %d",
274 __FUNCTION__, status); 277 __FUNCTION__, retval);
275} 278}
276 279
277 280
diff --git a/drivers/usb/serial/keyspan_usa67msg.h b/drivers/usb/serial/keyspan_usa67msg.h
new file mode 100644
index 000000000000..20fa3e2f7187
--- /dev/null
+++ b/drivers/usb/serial/keyspan_usa67msg.h
@@ -0,0 +1,254 @@
1/*
2 usa67msg.h
3
4 Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved
5 This file is available under a BSD-style copyright
6
7 Keyspan USB Async Firmware to run on Anchor FX1
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are
11 met:
12
13 1. Redistributions of source code must retain this licence text
14 without modification, this list of conditions, and the following
15 disclaimer. The following copyright notice must appear immediately at
16 the beginning of all source files:
17
18 Copyright (c) 1998-2007 InnoSys Incorporated. All Rights Reserved
19
20 This file is available under a BSD-style copyright
21
22 2. Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
25
26 3. The name of InnoSys Incorprated may not be used to endorse or promote
27 products derived from this software without specific prior written
28 permission.
29
30 THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
31 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
33 NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
34 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 SUCH DAMAGE.
41
42 Fourth revision: This message format supports the USA28XG
43
44 Buffer formats for RX/TX data messages are not defined by
45 a structure, but are described here:
46
47 USB OUT (host -> USAxx, transmit) messages contain a
48 REQUEST_ACK indicator (set to 0xff to request an ACK at the
49 completion of transmit; 0x00 otherwise), followed by data:
50
51 RQSTACK DAT DAT DAT ...
52
53 with a total data length of up to 63.
54
55 USB IN (USAxx -> host, receive) messages begin with a status
56 byte in which the 0x80 bit is either:
57
58 (a) 0x80 bit clear
59 indicates that the bytes following it are all data
60 bytes:
61
62 STAT DATA DATA DATA DATA DATA ...
63
64 for a total of up to 63 DATA bytes,
65
66 or:
67
68 (b) 0x80 bit set
69 indiates that the bytes following alternate data and
70 status bytes:
71
72 STAT DATA STAT DATA STAT DATA STAT DATA ...
73
74 for a total of up to 32 DATA bytes.
75
76 The valid bits in the STAT bytes are:
77
78 OVERRUN 0x02
79 PARITY 0x04
80 FRAMING 0x08
81 BREAK 0x10
82
83 Notes:
84
85 (1) The OVERRUN bit can appear in either (a) or (b) format
86 messages, but the but the PARITY/FRAMING/BREAK bits
87 only appear in (b) format messages.
88 (2) For the host to determine the exact point at which the
89 overrun occurred (to identify the point in the data
90 stream at which the data was lost), it needs to count
91 128 characters, starting at the first character of the
92 message in which OVERRUN was reported; the lost character(s)
93 would have been received between the 128th and 129th
94 characters.
95 (3) An RX data message in which the first byte has 0x80 clear
96 serves as a "break off" indicator.
97
98 revision history:
99
100 1999feb10 add reportHskiaChanges to allow us to ignore them
101 1999feb10 add txAckThreshold for fast+loose throughput enhancement
102 1999mar30 beef up support for RX error reporting
103 1999apr14 add resetDataToggle to control message
104 2000jan04 merge with usa17msg.h
105 2000jun01 add extended BSD-style copyright text
106 2001jul05 change message format to improve OVERRUN case
107 2002jun05 update copyright date, improve comments
108 2006feb06 modify for FX1 chip
109
110*/
111
112#ifndef __USA67MSG__
113#define __USA67MSG__
114
115
116// all things called "ControlMessage" are sent on the 'control' endpoint
117
118typedef struct keyspan_usa67_portControlMessage
119{
120 u8 port; // 0 or 1 (selects port)
121 /*
122 there are three types of "commands" sent in the control message:
123
124 1. configuration changes which must be requested by setting
125 the corresponding "set" flag (and should only be requested
126 when necessary, to reduce overhead on the device):
127 */
128 u8 setClocking, // host requests baud rate be set
129 baudLo, // host does baud divisor calculation
130 baudHi, // baudHi is only used for first port (gives lower rates)
131 externalClock_txClocking,
132 // 0=internal, other=external
133
134 setLcr, // host requests lcr be set
135 lcr, // use PARITY, STOPBITS, DATABITS below
136
137 setFlowControl, // host requests flow control be set
138 ctsFlowControl, // 1=use CTS flow control, 0=don't
139 xonFlowControl, // 1=use XON/XOFF flow control, 0=don't
140 xonChar, // specified in current character format
141 xoffChar, // specified in current character format
142
143 setTxTriState_setRts,
144 // host requests TX tri-state be set
145 txTriState_rts, // 1=active (normal), 0=tristate (off)
146
147 setHskoa_setDtr,
148 // host requests HSKOA output be set
149 hskoa_dtr, // 1=on, 0=off
150
151 setPrescaler, // host requests prescalar be set (default: 13)
152 prescaler; // specified as N/8; values 8-ff are valid
153 // must be set any time internal baud rate is set;
154 // must not be set when external clocking is used
155
156 /*
157 3. configuration data which is simply used as is (no overhead,
158 but must be specified correctly in every host message).
159 */
160 u8 forwardingLength, // forward when this number of chars available
161 reportHskiaChanges_dsrFlowControl,
162 // 1=normal; 0=ignore external clock
163 // 1=use DSR flow control, 0=don't
164 txAckThreshold, // 0=not allowed, 1=normal, 2-255 deliver ACK faster
165 loopbackMode; // 0=no loopback, 1=loopback enabled
166
167 /*
168 4. commands which are flags only; these are processed in order
169 (so that, e.g., if both _txOn and _txOff flags are set, the
170 port ends in a TX_OFF state); any non-zero value is respected
171 */
172 u8 _txOn, // enable transmitting (and continue if there's data)
173 _txOff, // stop transmitting
174 txFlush, // toss outbound data
175 txBreak, // turn on break (cleared by _txOn)
176 rxOn, // turn on receiver
177 rxOff, // turn off receiver
178 rxFlush, // toss inbound data
179 rxForward, // forward all inbound data, NOW (as if fwdLen==1)
180 returnStatus, // return current status (even if it hasn't changed)
181 resetDataToggle;// reset data toggle state to DATA0
182
183} keyspan_usa67_portControlMessage;
184
185// defines for bits in lcr
186#define USA_DATABITS_5 0x00
187#define USA_DATABITS_6 0x01
188#define USA_DATABITS_7 0x02
189#define USA_DATABITS_8 0x03
190#define STOPBITS_5678_1 0x00 // 1 stop bit for all byte sizes
191#define STOPBITS_5_1p5 0x04 // 1.5 stop bits for 5-bit byte
192#define STOPBITS_678_2 0x04 // 2 stop bits for 6/7/8-bit byte
193#define USA_PARITY_NONE 0x00
194#define USA_PARITY_ODD 0x08
195#define USA_PARITY_EVEN 0x18
196#define PARITY_1 0x28
197#define PARITY_0 0x38
198
199// all things called "StatusMessage" are sent on the status endpoint
200
201typedef struct keyspan_usa67_portStatusMessage // one for each port
202{
203 u8 port, // 0=first, 1=second, other=see below
204 hskia_cts, // reports HSKIA pin
205 gpia_dcd, // reports GPIA pin
206 _txOff, // port has been disabled (by host)
207 _txXoff, // port is in XOFF state (either host or RX XOFF)
208 txAck, // indicates a TX message acknowledgement
209 rxEnabled, // as configured by rxOn/rxOff 1=on, 0=off
210 controlResponse;// 1=a control message has been processed
211} keyspan_usa67_portStatusMessage;
212
213// bits in RX data message when STAT byte is included
214#define RXERROR_OVERRUN 0x02
215#define RXERROR_PARITY 0x04
216#define RXERROR_FRAMING 0x08
217#define RXERROR_BREAK 0x10
218
219typedef struct keyspan_usa67_globalControlMessage
220{
221 u8 port, // 3
222 sendGlobalStatus, // 2=request for two status responses
223 resetStatusToggle, // 1=reset global status toggle
224 resetStatusCount; // a cycling value
225} keyspan_usa67_globalControlMessage;
226
227typedef struct keyspan_usa67_globalStatusMessage
228{
229 u8 port, // 3
230 sendGlobalStatus, // from request, decremented
231 resetStatusCount; // as in request
232} keyspan_usa67_globalStatusMessage;
233
234typedef struct keyspan_usa67_globalDebugMessage
235{
236 u8 port, // 2
237 a,
238 b,
239 c,
240 d;
241} keyspan_usa67_globalDebugMessage;
242
243// ie: the maximum length of an FX1 endpoint buffer
244#define MAX_DATA_LEN 64
245
246// update status approx. 60 times a second (16.6666 ms)
247#define STATUS_UPDATE_INTERVAL 16
248
249// status rationing tuning value (each port gets checked each n ms)
250#define STATUS_RATION 10
251
252#endif
253
254
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 7b085f334ceb..5a4127e62c4a 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -567,12 +567,13 @@ exit:
567static void klsi_105_write_bulk_callback ( struct urb *urb) 567static void klsi_105_write_bulk_callback ( struct urb *urb)
568{ 568{
569 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 569 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
570 int status = urb->status;
570 571
571 dbg("%s - port %d", __FUNCTION__, port->number); 572 dbg("%s - port %d", __FUNCTION__, port->number);
572 573
573 if (urb->status) { 574 if (status) {
574 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, 575 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
575 urb->status); 576 status);
576 return; 577 return;
577 } 578 }
578 579
@@ -631,16 +632,17 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
631 struct tty_struct *tty; 632 struct tty_struct *tty;
632 unsigned char *data = urb->transfer_buffer; 633 unsigned char *data = urb->transfer_buffer;
633 int rc; 634 int rc;
635 int status = urb->status;
634 636
635 dbg("%s - port %d", __FUNCTION__, port->number); 637 dbg("%s - port %d", __FUNCTION__, port->number);
636 638
637 /* The urb might have been killed. */ 639 /* The urb might have been killed. */
638 if (urb->status) { 640 if (status) {
639 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, 641 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__,
640 urb->status); 642 status);
641 return; 643 return;
642 } 644 }
643 645
644 /* The data received is again preceded by a length double-byte in LSB- 646 /* The data received is again preceded by a length double-byte in LSB-
645 * first order (see klsi_105_write() ) 647 * first order (see klsi_105_write() )
646 */ 648 */
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 0683b51f0932..02a86dbc0e97 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -358,24 +358,26 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
358} 358}
359 359
360 360
361static void kobil_read_int_callback( struct urb *purb) 361static void kobil_read_int_callback(struct urb *urb)
362{ 362{
363 int result; 363 int result;
364 struct usb_serial_port *port = (struct usb_serial_port *) purb->context; 364 struct usb_serial_port *port = urb->context;
365 struct tty_struct *tty; 365 struct tty_struct *tty;
366 unsigned char *data = purb->transfer_buffer; 366 unsigned char *data = urb->transfer_buffer;
367 int status = urb->status;
367// char *dbg_data; 368// char *dbg_data;
368 369
369 dbg("%s - port %d", __FUNCTION__, port->number); 370 dbg("%s - port %d", __FUNCTION__, port->number);
370 371
371 if (purb->status) { 372 if (status) {
372 dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status); 373 dbg("%s - port %d Read int status not zero: %d",
374 __FUNCTION__, port->number, status);
373 return; 375 return;
374 } 376 }
375 377
376 tty = port->tty; 378 tty = port->tty;
377 if (purb->actual_length) { 379 if (urb->actual_length) {
378 380
379 // BEGIN DEBUG 381 // BEGIN DEBUG
380 /* 382 /*
381 dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); 383 dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
@@ -390,15 +392,15 @@ static void kobil_read_int_callback( struct urb *purb)
390 */ 392 */
391 // END DEBUG 393 // END DEBUG
392 394
393 tty_buffer_request_room(tty, purb->actual_length); 395 tty_buffer_request_room(tty, urb->actual_length);
394 tty_insert_flip_string(tty, data, purb->actual_length); 396 tty_insert_flip_string(tty, data, urb->actual_length);
395 tty_flip_buffer_push(tty); 397 tty_flip_buffer_push(tty);
396 } 398 }
397 399
398 // someone sets the dev to 0 if the close method has been called 400 // someone sets the dev to 0 if the close method has been called
399 port->interrupt_in_urb->dev = port->serial->dev; 401 port->interrupt_in_urb->dev = port->serial->dev;
400 402
401 result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 403 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
402 dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result); 404 dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
403} 405}
404 406
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 3db1adc25f84..2a3fabcf5186 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -81,7 +81,7 @@
81/* 81/*
82 * Version Information 82 * Version Information
83 */ 83 */
84#define DRIVER_VERSION "z2.0" /* Linux in-kernel version */ 84#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */
85#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>" 85#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
86#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" 86#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
87 87
@@ -110,6 +110,10 @@ static int mct_u232_tiocmget (struct usb_serial_port *port,
110static int mct_u232_tiocmset (struct usb_serial_port *port, 110static int mct_u232_tiocmset (struct usb_serial_port *port,
111 struct file *file, unsigned int set, 111 struct file *file, unsigned int set,
112 unsigned int clear); 112 unsigned int clear);
113static void mct_u232_throttle (struct usb_serial_port *port);
114static void mct_u232_unthrottle (struct usb_serial_port *port);
115
116
113/* 117/*
114 * All of the device info needed for the MCT USB-RS232 converter. 118 * All of the device info needed for the MCT USB-RS232 converter.
115 */ 119 */
@@ -145,6 +149,8 @@ static struct usb_serial_driver mct_u232_device = {
145 .num_ports = 1, 149 .num_ports = 1,
146 .open = mct_u232_open, 150 .open = mct_u232_open,
147 .close = mct_u232_close, 151 .close = mct_u232_close,
152 .throttle = mct_u232_throttle,
153 .unthrottle = mct_u232_unthrottle,
148 .read_int_callback = mct_u232_read_int_callback, 154 .read_int_callback = mct_u232_read_int_callback,
149 .ioctl = mct_u232_ioctl, 155 .ioctl = mct_u232_ioctl,
150 .set_termios = mct_u232_set_termios, 156 .set_termios = mct_u232_set_termios,
@@ -162,8 +168,11 @@ struct mct_u232_private {
162 unsigned char last_lcr; /* Line Control Register */ 168 unsigned char last_lcr; /* Line Control Register */
163 unsigned char last_lsr; /* Line Status Register */ 169 unsigned char last_lsr; /* Line Status Register */
164 unsigned char last_msr; /* Modem Status Register */ 170 unsigned char last_msr; /* Modem Status Register */
171 unsigned int rx_flags; /* Throttling flags */
165}; 172};
166 173
174#define THROTTLED 0x01
175
167/* 176/*
168 * Handle vendor specific USB requests 177 * Handle vendor specific USB requests
169 */ 178 */
@@ -216,11 +225,13 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value)
216 } 225 }
217} 226}
218 227
219static int mct_u232_set_baud_rate(struct usb_serial *serial, int value) 228static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port,
229 int value)
220{ 230{
221 __le32 divisor; 231 __le32 divisor;
222 int rc; 232 int rc;
223 unsigned char zero_byte = 0; 233 unsigned char zero_byte = 0;
234 unsigned char cts_enable_byte = 0;
224 235
225 divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value)); 236 divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
226 237
@@ -238,10 +249,17 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
238 'baud rate change' message. The actual functionality of the 249 'baud rate change' message. The actual functionality of the
239 request codes in these messages is not fully understood but these 250 request codes in these messages is not fully understood but these
240 particular codes are never seen in any operation besides a baud 251 particular codes are never seen in any operation besides a baud
241 rate change. Both of these messages send a single byte of data 252 rate change. Both of these messages send a single byte of data.
242 whose value is always zero. The second of these two extra messages 253 In the first message, the value of this byte is always zero.
243 is required in order for data to be properly written to an RS-232 254
244 device which does not assert the 'CTS' signal. */ 255 The second message has been determined experimentally to control
256 whether data will be transmitted to a device which is not asserting
257 the 'CTS' signal. If the second message's data byte is zero, data
258 will be transmitted even if 'CTS' is not asserted (i.e. no hardware
259 flow control). if the second message's data byte is nonzero (a value
260 of 1 is used by this driver), data will not be transmitted to a device
261 which is not asserting 'CTS'.
262 */
245 263
246 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 264 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
247 MCT_U232_SET_UNKNOWN1_REQUEST, 265 MCT_U232_SET_UNKNOWN1_REQUEST,
@@ -252,14 +270,19 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, int value)
252 err("Sending USB device request code %d failed (error = %d)", 270 err("Sending USB device request code %d failed (error = %d)",
253 MCT_U232_SET_UNKNOWN1_REQUEST, rc); 271 MCT_U232_SET_UNKNOWN1_REQUEST, rc);
254 272
273 if (port && C_CRTSCTS(port->tty)) {
274 cts_enable_byte = 1;
275 }
276
277 dbg("set_baud_rate: send second control message, data = %02X", cts_enable_byte);
255 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 278 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
256 MCT_U232_SET_UNKNOWN2_REQUEST, 279 MCT_U232_SET_CTS_REQUEST,
257 MCT_U232_SET_REQUEST_TYPE, 280 MCT_U232_SET_REQUEST_TYPE,
258 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE, 281 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
259 WDR_TIMEOUT); 282 WDR_TIMEOUT);
260 if (rc < 0) 283 if (rc < 0)
261 err("Sending USB device request code %d failed (error = %d)", 284 err("Sending USB device request code %d failed (error = %d)",
262 MCT_U232_SET_UNKNOWN2_REQUEST, rc); 285 MCT_U232_SET_CTS_REQUEST, rc);
263 286
264 return rc; 287 return rc;
265} /* mct_u232_set_baud_rate */ 288} /* mct_u232_set_baud_rate */
@@ -458,8 +481,25 @@ error:
458 481
459static void mct_u232_close (struct usb_serial_port *port, struct file *filp) 482static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
460{ 483{
484 unsigned int c_cflag;
485 unsigned long flags;
486 unsigned int control_state;
487 struct mct_u232_private *priv = usb_get_serial_port_data(port);
461 dbg("%s port %d", __FUNCTION__, port->number); 488 dbg("%s port %d", __FUNCTION__, port->number);
462 489
490 if (port->tty) {
491 c_cflag = port->tty->termios->c_cflag;
492 if (c_cflag & HUPCL) {
493 /* drop DTR and RTS */
494 spin_lock_irqsave(&priv->lock, flags);
495 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
496 control_state = priv->control_state;
497 spin_unlock_irqrestore(&priv->lock, flags);
498 mct_u232_set_modem_ctrl(port->serial, control_state);
499 }
500 }
501
502
463 if (port->serial->dev) { 503 if (port->serial->dev) {
464 /* shutdown our urbs */ 504 /* shutdown our urbs */
465 usb_kill_urb(port->write_urb); 505 usb_kill_urb(port->write_urb);
@@ -476,10 +516,11 @@ static void mct_u232_read_int_callback (struct urb *urb)
476 struct usb_serial *serial = port->serial; 516 struct usb_serial *serial = port->serial;
477 struct tty_struct *tty; 517 struct tty_struct *tty;
478 unsigned char *data = urb->transfer_buffer; 518 unsigned char *data = urb->transfer_buffer;
479 int status; 519 int retval;
520 int status = urb->status;
480 unsigned long flags; 521 unsigned long flags;
481 522
482 switch (urb->status) { 523 switch (status) {
483 case 0: 524 case 0:
484 /* success */ 525 /* success */
485 break; 526 break;
@@ -487,10 +528,12 @@ static void mct_u232_read_int_callback (struct urb *urb)
487 case -ENOENT: 528 case -ENOENT:
488 case -ESHUTDOWN: 529 case -ESHUTDOWN:
489 /* this urb is terminated, clean up */ 530 /* this urb is terminated, clean up */
490 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 531 dbg("%s - urb shutting down with status: %d",
532 __FUNCTION__, status);
491 return; 533 return;
492 default: 534 default:
493 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 535 dbg("%s - nonzero urb status received: %d",
536 __FUNCTION__, status);
494 goto exit; 537 goto exit;
495 } 538 }
496 539
@@ -554,10 +597,10 @@ static void mct_u232_read_int_callback (struct urb *urb)
554#endif 597#endif
555 spin_unlock_irqrestore(&priv->lock, flags); 598 spin_unlock_irqrestore(&priv->lock, flags);
556exit: 599exit:
557 status = usb_submit_urb (urb, GFP_ATOMIC); 600 retval = usb_submit_urb (urb, GFP_ATOMIC);
558 if (status) 601 if (retval)
559 err ("%s - usb_submit_urb failed with result %d", 602 err ("%s - usb_submit_urb failed with result %d",
560 __FUNCTION__, status); 603 __FUNCTION__, retval);
561} /* mct_u232_read_int_callback */ 604} /* mct_u232_read_int_callback */
562 605
563static void mct_u232_set_termios (struct usb_serial_port *port, 606static void mct_u232_set_termios (struct usb_serial_port *port,
@@ -565,11 +608,10 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
565{ 608{
566 struct usb_serial *serial = port->serial; 609 struct usb_serial *serial = port->serial;
567 struct mct_u232_private *priv = usb_get_serial_port_data(port); 610 struct mct_u232_private *priv = usb_get_serial_port_data(port);
568 unsigned int iflag = port->tty->termios->c_iflag;
569 unsigned int cflag = port->tty->termios->c_cflag; 611 unsigned int cflag = port->tty->termios->c_cflag;
570 unsigned int old_cflag = old_termios->c_cflag; 612 unsigned int old_cflag = old_termios->c_cflag;
571 unsigned long flags; 613 unsigned long flags;
572 unsigned int control_state, new_state; 614 unsigned int control_state;
573 unsigned char last_lcr; 615 unsigned char last_lcr;
574 616
575 /* get a local copy of the current port settings */ 617 /* get a local copy of the current port settings */
@@ -585,18 +627,14 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
585 * Premature optimization is the root of all evil. 627 * Premature optimization is the root of all evil.
586 */ 628 */
587 629
588 /* reassert DTR and (maybe) RTS on transition from B0 */ 630 /* reassert DTR and RTS on transition from B0 */
589 if ((old_cflag & CBAUD) == B0) { 631 if ((old_cflag & CBAUD) == B0) {
590 dbg("%s: baud was B0", __FUNCTION__); 632 dbg("%s: baud was B0", __FUNCTION__);
591 control_state |= TIOCM_DTR; 633 control_state |= TIOCM_DTR | TIOCM_RTS;
592 /* don't set RTS if using hardware flow control */
593 if (!(old_cflag & CRTSCTS)) {
594 control_state |= TIOCM_RTS;
595 }
596 mct_u232_set_modem_ctrl(serial, control_state); 634 mct_u232_set_modem_ctrl(serial, control_state);
597 } 635 }
598 636
599 mct_u232_set_baud_rate(serial, cflag & CBAUD); 637 mct_u232_set_baud_rate(serial, port, cflag & CBAUD);
600 638
601 if ((cflag & CBAUD) == B0 ) { 639 if ((cflag & CBAUD) == B0 ) {
602 dbg("%s: baud is B0", __FUNCTION__); 640 dbg("%s: baud is B0", __FUNCTION__);
@@ -638,21 +676,6 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
638 676
639 mct_u232_set_line_ctrl(serial, last_lcr); 677 mct_u232_set_line_ctrl(serial, last_lcr);
640 678
641 /*
642 * Set flow control: well, I do not really now how to handle DTR/RTS.
643 * Just do what we have seen with SniffUSB on Win98.
644 */
645 /* Drop DTR/RTS if no flow control otherwise assert */
646 new_state = control_state;
647 if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
648 new_state |= TIOCM_DTR | TIOCM_RTS;
649 else
650 new_state &= ~(TIOCM_DTR | TIOCM_RTS);
651 if (new_state != control_state) {
652 mct_u232_set_modem_ctrl(serial, new_state);
653 control_state = new_state;
654 }
655
656 /* save off the modified port settings */ 679 /* save off the modified port settings */
657 spin_lock_irqsave(&priv->lock, flags); 680 spin_lock_irqsave(&priv->lock, flags);
658 priv->control_state = control_state; 681 priv->control_state = control_state;
@@ -747,6 +770,50 @@ static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
747 return 0; 770 return 0;
748} /* mct_u232_ioctl */ 771} /* mct_u232_ioctl */
749 772
773static void mct_u232_throttle (struct usb_serial_port *port)
774{
775 struct mct_u232_private *priv = usb_get_serial_port_data(port);
776 unsigned long flags;
777 unsigned int control_state;
778 struct tty_struct *tty;
779
780 tty = port->tty;
781 dbg("%s - port %d", __FUNCTION__, port->number);
782
783 spin_lock_irqsave(&priv->lock, flags);
784 priv->rx_flags |= THROTTLED;
785 if (C_CRTSCTS(tty)) {
786 priv->control_state &= ~TIOCM_RTS;
787 control_state = priv->control_state;
788 spin_unlock_irqrestore(&priv->lock, flags);
789 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
790 } else {
791 spin_unlock_irqrestore(&priv->lock, flags);
792 }
793}
794
795
796static void mct_u232_unthrottle (struct usb_serial_port *port)
797{
798 struct mct_u232_private *priv = usb_get_serial_port_data(port);
799 unsigned long flags;
800 unsigned int control_state;
801 struct tty_struct *tty;
802
803 dbg("%s - port %d", __FUNCTION__, port->number);
804
805 tty = port->tty;
806 spin_lock_irqsave(&priv->lock, flags);
807 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
808 priv->rx_flags &= ~THROTTLED;
809 priv->control_state |= TIOCM_RTS;
810 control_state = priv->control_state;
811 spin_unlock_irqrestore(&priv->lock, flags);
812 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
813 } else {
814 spin_unlock_irqrestore(&priv->lock, flags);
815 }
816}
750 817
751static int __init mct_u232_init (void) 818static int __init mct_u232_init (void)
752{ 819{
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h
index 73dd0d984cd3..a61bac8f224a 100644
--- a/drivers/usb/serial/mct_u232.h
+++ b/drivers/usb/serial/mct_u232.h
@@ -63,14 +63,15 @@
63#define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */ 63#define MCT_U232_SET_UNKNOWN1_REQUEST 11 /* Unknown functionality */
64#define MCT_U232_SET_UNKNOWN1_SIZE 1 64#define MCT_U232_SET_UNKNOWN1_SIZE 1
65 65
66/* This USB device request code is not well understood. It is transmitted by 66/* This USB device request code appears to control whether CTS is required
67 the MCT-supplied Windows driver whenever the baud rate changes. 67 during transmission.
68 68
69 Without this USB device request, the USB/RS-232 adapter will not write to 69 Sending a zero byte allows data transmission to a device which is not
70 RS-232 devices which do not assert the 'CTS' signal. 70 asserting CTS. Sending a '1' byte will cause transmission to be deferred
71 until the device asserts CTS.
71*/ 72*/
72#define MCT_U232_SET_UNKNOWN2_REQUEST 12 /* Unknown functionality */ 73#define MCT_U232_SET_CTS_REQUEST 12
73#define MCT_U232_SET_UNKNOWN2_SIZE 1 74#define MCT_U232_SET_CTS_SIZE 1
74 75
75/* 76/*
76 * Baud rate (divisor) 77 * Baud rate (divisor)
@@ -439,7 +440,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value);
439 * which says "U232-P9" ;-) 440 * which says "U232-P9" ;-)
440 * 441 *
441 * The circuit board inside the adaptor contains a Philips PDIUSBD12 442 * The circuit board inside the adaptor contains a Philips PDIUSBD12
442 * USB endpoint chip and a Phillips P87C52UBAA microcontroller with 443 * USB endpoint chip and a Philips P87C52UBAA microcontroller with
443 * embedded UART. Exhaustive documentation for these is available at: 444 * embedded UART. Exhaustive documentation for these is available at:
444 * 445 *
445 * http://www.semiconductors.philips.com/pip/p87c52ubaa 446 * http://www.semiconductors.philips.com/pip/p87c52ubaa
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index b563e2ad8728..231b584f6d0f 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -9,9 +9,9 @@
9 * the Free Software Foundation, version 2 of the License. 9 * the Free Software Foundation, version 2 of the License.
10 * 10 *
11 * Developed by: 11 * Developed by:
12 * VijayaKumar.G.N. <vijaykumar@aspirecom.net> 12 * Vijaya Kumar <vijaykumar.gn@gmail.com>
13 * AjayKumar <ajay@aspirecom.net> 13 * Ajay Kumar <naanuajay@yahoo.com>
14 * Gurudeva.N. <gurudev@aspirecom.net> 14 * Gurudeva <ngurudeva@yahoo.com>
15 * 15 *
16 * Cleaned up from the original by: 16 * Cleaned up from the original by:
17 * Greg Kroah-Hartman <gregkh@suse.de> 17 * Greg Kroah-Hartman <gregkh@suse.de>
@@ -103,6 +103,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
103{ 103{
104 int result; 104 int result;
105 int length; 105 int length;
106 int status = urb->status;
106 __u8 *data; 107 __u8 *data;
107 __u8 sp1; 108 __u8 sp1;
108 __u8 sp2; 109 __u8 sp2;
@@ -114,7 +115,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
114 return; 115 return;
115 } 116 }
116 117
117 switch (urb->status) { 118 switch (status) {
118 case 0: 119 case 0:
119 /* success */ 120 /* success */
120 break; 121 break;
@@ -123,11 +124,11 @@ static void mos7720_interrupt_callback(struct urb *urb)
123 case -ESHUTDOWN: 124 case -ESHUTDOWN:
124 /* this urb is terminated, clean up */ 125 /* this urb is terminated, clean up */
125 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 126 dbg("%s - urb shutting down with status: %d", __FUNCTION__,
126 urb->status); 127 status);
127 return; 128 return;
128 default: 129 default:
129 dbg("%s - nonzero urb status received: %d", __FUNCTION__, 130 dbg("%s - nonzero urb status received: %d", __FUNCTION__,
130 urb->status); 131 status);
131 goto exit; 132 goto exit;
132 } 133 }
133 134
@@ -198,14 +199,15 @@ exit:
198 */ 199 */
199static void mos7720_bulk_in_callback(struct urb *urb) 200static void mos7720_bulk_in_callback(struct urb *urb)
200{ 201{
201 int status; 202 int retval;
202 unsigned char *data ; 203 unsigned char *data ;
203 struct usb_serial_port *port; 204 struct usb_serial_port *port;
204 struct moschip_port *mos7720_port; 205 struct moschip_port *mos7720_port;
205 struct tty_struct *tty; 206 struct tty_struct *tty;
207 int status = urb->status;
206 208
207 if (urb->status) { 209 if (status) {
208 dbg("nonzero read bulk status received: %d",urb->status); 210 dbg("nonzero read bulk status received: %d", status);
209 return; 211 return;
210 } 212 }
211 213
@@ -236,10 +238,10 @@ static void mos7720_bulk_in_callback(struct urb *urb)
236 if (port->read_urb->status != -EINPROGRESS) { 238 if (port->read_urb->status != -EINPROGRESS) {
237 port->read_urb->dev = port->serial->dev; 239 port->read_urb->dev = port->serial->dev;
238 240
239 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 241 retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
240 if (status) 242 if (retval)
241 dbg("usb_submit_urb(read bulk) failed, status = %d", 243 dbg("usb_submit_urb(read bulk) failed, retval = %d",
242 status); 244 retval);
243 } 245 }
244} 246}
245 247
@@ -252,9 +254,10 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
252{ 254{
253 struct moschip_port *mos7720_port; 255 struct moschip_port *mos7720_port;
254 struct tty_struct *tty; 256 struct tty_struct *tty;
257 int status = urb->status;
255 258
256 if (urb->status) { 259 if (status) {
257 dbg("nonzero write bulk status received:%d", urb->status); 260 dbg("nonzero write bulk status received:%d", status);
258 return; 261 return;
259 } 262 }
260 263
@@ -1235,16 +1238,6 @@ static void mos7720_set_termios(struct usb_serial_port *port,
1235 return; 1238 return;
1236 } 1239 }
1237 1240
1238 /* check that they really want us to change something */
1239 if (old_termios) {
1240 if ((cflag == old_termios->c_cflag) &&
1241 (RELEVANT_IFLAG(tty->termios->c_iflag) ==
1242 RELEVANT_IFLAG(old_termios->c_iflag))) {
1243 dbg("Nothing to change");
1244 return;
1245 }
1246 }
1247
1248 dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 1241 dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
1249 tty->termios->c_cflag, 1242 tty->termios->c_cflag,
1250 RELEVANT_IFLAG(tty->termios->c_iflag)); 1243 RELEVANT_IFLAG(tty->termios->c_iflag));
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 36620c651079..37f41f576d3d 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -434,6 +434,7 @@ static void mos7840_control_callback(struct urb *urb)
434 struct moschip_port *mos7840_port; 434 struct moschip_port *mos7840_port;
435 __u8 regval = 0x0; 435 __u8 regval = 0x0;
436 int result = 0; 436 int result = 0;
437 int status = urb->status;
437 438
438 if (!urb) { 439 if (!urb) {
439 dbg("%s", "Invalid Pointer !!!!:\n"); 440 dbg("%s", "Invalid Pointer !!!!:\n");
@@ -442,7 +443,7 @@ static void mos7840_control_callback(struct urb *urb)
442 443
443 mos7840_port = (struct moschip_port *)urb->context; 444 mos7840_port = (struct moschip_port *)urb->context;
444 445
445 switch (urb->status) { 446 switch (status) {
446 case 0: 447 case 0:
447 /* success */ 448 /* success */
448 break; 449 break;
@@ -451,11 +452,11 @@ static void mos7840_control_callback(struct urb *urb)
451 case -ESHUTDOWN: 452 case -ESHUTDOWN:
452 /* this urb is terminated, clean up */ 453 /* this urb is terminated, clean up */
453 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 454 dbg("%s - urb shutting down with status: %d", __FUNCTION__,
454 urb->status); 455 status);
455 return; 456 return;
456 default: 457 default:
457 dbg("%s - nonzero urb status received: %d", __FUNCTION__, 458 dbg("%s - nonzero urb status received: %d", __FUNCTION__,
458 urb->status); 459 status);
459 goto exit; 460 goto exit;
460 } 461 }
461 462
@@ -521,6 +522,7 @@ static void mos7840_interrupt_callback(struct urb *urb)
521 __u8 sp[5], st; 522 __u8 sp[5], st;
522 int i, rv = 0; 523 int i, rv = 0;
523 __u16 wval, wreg = 0; 524 __u16 wval, wreg = 0;
525 int status = urb->status;
524 526
525 dbg("%s", " : Entering\n"); 527 dbg("%s", " : Entering\n");
526 if (!urb) { 528 if (!urb) {
@@ -528,7 +530,7 @@ static void mos7840_interrupt_callback(struct urb *urb)
528 return; 530 return;
529 } 531 }
530 532
531 switch (urb->status) { 533 switch (status) {
532 case 0: 534 case 0:
533 /* success */ 535 /* success */
534 break; 536 break;
@@ -537,11 +539,11 @@ static void mos7840_interrupt_callback(struct urb *urb)
537 case -ESHUTDOWN: 539 case -ESHUTDOWN:
538 /* this urb is terminated, clean up */ 540 /* this urb is terminated, clean up */
539 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 541 dbg("%s - urb shutting down with status: %d", __FUNCTION__,
540 urb->status); 542 status);
541 return; 543 return;
542 default: 544 default:
543 dbg("%s - nonzero urb status received: %d", __FUNCTION__, 545 dbg("%s - nonzero urb status received: %d", __FUNCTION__,
544 urb->status); 546 status);
545 goto exit; 547 goto exit;
546 } 548 }
547 549
@@ -666,20 +668,21 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
666 668
667static void mos7840_bulk_in_callback(struct urb *urb) 669static void mos7840_bulk_in_callback(struct urb *urb)
668{ 670{
669 int status; 671 int retval;
670 unsigned char *data; 672 unsigned char *data;
671 struct usb_serial *serial; 673 struct usb_serial *serial;
672 struct usb_serial_port *port; 674 struct usb_serial_port *port;
673 struct moschip_port *mos7840_port; 675 struct moschip_port *mos7840_port;
674 struct tty_struct *tty; 676 struct tty_struct *tty;
677 int status = urb->status;
675 678
676 if (!urb) { 679 if (!urb) {
677 dbg("%s", "Invalid Pointer !!!!:\n"); 680 dbg("%s", "Invalid Pointer !!!!:\n");
678 return; 681 return;
679 } 682 }
680 683
681 if (urb->status) { 684 if (status) {
682 dbg("nonzero read bulk status received: %d", urb->status); 685 dbg("nonzero read bulk status received: %d", status);
683 return; 686 return;
684 } 687 }
685 688
@@ -729,11 +732,11 @@ static void mos7840_bulk_in_callback(struct urb *urb)
729 732
730 mos7840_port->read_urb->dev = serial->dev; 733 mos7840_port->read_urb->dev = serial->dev;
731 734
732 status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); 735 retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
733 736
734 if (status) { 737 if (retval) {
735 dbg(" usb_submit_urb(read bulk) failed, status = %d", 738 dbg(" usb_submit_urb(read bulk) failed, retval = %d",
736 status); 739 retval);
737 } 740 }
738} 741}
739 742
@@ -747,6 +750,7 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
747{ 750{
748 struct moschip_port *mos7840_port; 751 struct moschip_port *mos7840_port;
749 struct tty_struct *tty; 752 struct tty_struct *tty;
753 int status = urb->status;
750 int i; 754 int i;
751 755
752 if (!urb) { 756 if (!urb) {
@@ -764,8 +768,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
764 } 768 }
765 spin_unlock(&mos7840_port->pool_lock); 769 spin_unlock(&mos7840_port->pool_lock);
766 770
767 if (urb->status) { 771 if (status) {
768 dbg("nonzero write bulk status received:%d\n", urb->status); 772 dbg("nonzero write bulk status received:%d\n", status);
769 return; 773 return;
770 } 774 }
771 775
@@ -2185,16 +2189,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
2185 return; 2189 return;
2186 } 2190 }
2187 2191
2188 /* check that they really want us to change something */
2189 if (old_termios) {
2190 if ((cflag == old_termios->c_cflag) &&
2191 (RELEVANT_IFLAG(tty->termios->c_iflag) ==
2192 RELEVANT_IFLAG(old_termios->c_iflag))) {
2193 dbg("%s\n", "Nothing to change");
2194 return;
2195 }
2196 }
2197
2198 dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 2192 dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
2199 tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); 2193 tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
2200 2194
@@ -2254,30 +2248,6 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
2254} 2248}
2255 2249
2256/***************************************************************************** 2250/*****************************************************************************
2257 * mos7840_get_bytes_avail - get number of bytes available
2258 *
2259 * Purpose: Let user call ioctl to get the count of number of bytes available.
2260 *****************************************************************************/
2261
2262static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port,
2263 unsigned int __user *value)
2264{
2265 unsigned int result = 0;
2266 struct tty_struct *tty = mos7840_port->port->tty;
2267
2268 if (!tty)
2269 return -ENOIOCTLCMD;
2270
2271 result = tty->read_cnt;
2272
2273 dbg("%s(%d) = %d", __FUNCTION__, mos7840_port->port->number, result);
2274 if (copy_to_user(value, &result, sizeof(int)))
2275 return -EFAULT;
2276
2277 return -ENOIOCTLCMD;
2278}
2279
2280/*****************************************************************************
2281 * mos7840_set_modem_info 2251 * mos7840_set_modem_info
2282 * function to set modem info 2252 * function to set modem info
2283 *****************************************************************************/ 2253 *****************************************************************************/
@@ -2425,8 +2395,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
2425 struct async_icount cprev; 2395 struct async_icount cprev;
2426 struct serial_icounter_struct icount; 2396 struct serial_icounter_struct icount;
2427 int mosret = 0; 2397 int mosret = 0;
2428 int retval;
2429 struct tty_ldisc *ld;
2430 2398
2431 if (mos7840_port_paranoia_check(port, __FUNCTION__)) { 2399 if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
2432 dbg("%s", "Invalid port \n"); 2400 dbg("%s", "Invalid port \n");
@@ -2445,42 +2413,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
2445 switch (cmd) { 2413 switch (cmd) {
2446 /* return number of bytes available */ 2414 /* return number of bytes available */
2447 2415
2448 case TIOCINQ:
2449 dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number);
2450 return mos7840_get_bytes_avail(mos7840_port, argp);
2451
2452 case TIOCOUTQ:
2453 dbg("%s (%d) TIOCOUTQ", __FUNCTION__, port->number);
2454 return put_user(tty->driver->chars_in_buffer ?
2455 tty->driver->chars_in_buffer(tty) : 0,
2456 (int __user *)arg);
2457
2458 case TCFLSH:
2459 retval = tty_check_change(tty);
2460 if (retval)
2461 return retval;
2462
2463 ld = tty_ldisc_ref(tty);
2464 switch (arg) {
2465 case TCIFLUSH:
2466 if (ld && ld->flush_buffer)
2467 ld->flush_buffer(tty);
2468 break;
2469 case TCIOFLUSH:
2470 if (ld && ld->flush_buffer)
2471 ld->flush_buffer(tty);
2472 /* fall through */
2473 case TCOFLUSH:
2474 if (tty->driver->flush_buffer)
2475 tty->driver->flush_buffer(tty);
2476 break;
2477 default:
2478 tty_ldisc_deref(ld);
2479 return -EINVAL;
2480 }
2481 tty_ldisc_deref(ld);
2482 return 0;
2483
2484 case TIOCSERGETLSR: 2416 case TIOCSERGETLSR:
2485 dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); 2417 dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
2486 return mos7840_get_lsr_info(mos7840_port, argp); 2418 return mos7840_get_lsr_info(mos7840_port, argp);
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index 90701111d746..7f337c9aeb5f 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -37,9 +37,10 @@ static void navman_read_int_callback(struct urb *urb)
37 struct usb_serial_port *port = urb->context; 37 struct usb_serial_port *port = urb->context;
38 unsigned char *data = urb->transfer_buffer; 38 unsigned char *data = urb->transfer_buffer;
39 struct tty_struct *tty; 39 struct tty_struct *tty;
40 int status = urb->status;
40 int result; 41 int result;
41 42
42 switch (urb->status) { 43 switch (status) {
43 case 0: 44 case 0:
44 /* success */ 45 /* success */
45 break; 46 break;
@@ -48,11 +49,11 @@ static void navman_read_int_callback(struct urb *urb)
48 case -ESHUTDOWN: 49 case -ESHUTDOWN:
49 /* this urb is terminated, clean up */ 50 /* this urb is terminated, clean up */
50 dbg("%s - urb shutting down with status: %d", 51 dbg("%s - urb shutting down with status: %d",
51 __FUNCTION__, urb->status); 52 __FUNCTION__, status);
52 return; 53 return;
53 default: 54 default:
54 dbg("%s - nonzero urb status received: %d", 55 dbg("%s - nonzero urb status received: %d",
55 __FUNCTION__, urb->status); 56 __FUNCTION__, status);
56 goto exit; 57 goto exit;
57 } 58 }
58 59
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 00afc1712c39..ee94d9616d82 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * USB ZyXEL omni.net LCD PLUS driver 2 * USB ZyXEL omni.net LCD PLUS driver
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or
5 * it under the terms of the GNU General Public License as published by 5 * modify it under the terms of the GNU General Public License version
6 * the Free Software Foundation; either version 2 of the License, or 6 * 2 as published by the Free Software Foundation.
7 * (at your option) any later version.
8 * 7 *
9 * See Documentation/usb/usb-serial.txt for more information on using this driver 8 * See Documentation/usb/usb-serial.txt for more information on using this driver
10 * 9 *
@@ -201,14 +200,15 @@ static void omninet_read_bulk_callback (struct urb *urb)
201 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 200 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
202 unsigned char *data = urb->transfer_buffer; 201 unsigned char *data = urb->transfer_buffer;
203 struct omninet_header *header = (struct omninet_header *) &data[0]; 202 struct omninet_header *header = (struct omninet_header *) &data[0];
204 203 int status = urb->status;
205 int i; 204 int i;
206 int result; 205 int result;
207 206
208 dbg("%s - port %d", __FUNCTION__, port->number); 207 dbg("%s - port %d", __FUNCTION__, port->number);
209 208
210 if (urb->status) { 209 if (status) {
211 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 210 dbg("%s - nonzero read bulk status received: %d",
211 __FUNCTION__, status);
212 return; 212 return;
213 } 213 }
214 214
@@ -312,12 +312,14 @@ static void omninet_write_bulk_callback (struct urb *urb)
312{ 312{
313/* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */ 313/* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */
314 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 314 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
315 int status = urb->status;
315 316
316 dbg("%s - port %0x\n", __FUNCTION__, port->number); 317 dbg("%s - port %0x\n", __FUNCTION__, port->number);
317 318
318 port->write_urb_busy = 0; 319 port->write_urb_busy = 0;
319 if (urb->status) { 320 if (status) {
320 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 321 dbg("%s - nonzero write bulk status received: %d",
322 __FUNCTION__, status);
321 return; 323 return;
322 } 324 }
323 325
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5d3999e3ff61..84c12b5f1271 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -38,6 +38,7 @@
38#include <linux/tty.h> 38#include <linux/tty.h>
39#include <linux/tty_flip.h> 39#include <linux/tty_flip.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/bitops.h>
41#include <linux/usb.h> 42#include <linux/usb.h>
42#include <linux/usb/serial.h> 43#include <linux/usb/serial.h>
43 44
@@ -240,6 +241,7 @@ struct option_port_private {
240 /* Output endpoints and buffer for this port */ 241 /* Output endpoints and buffer for this port */
241 struct urb *out_urbs[N_OUT_URB]; 242 struct urb *out_urbs[N_OUT_URB];
242 char out_buffer[N_OUT_URB][OUT_BUFLEN]; 243 char out_buffer[N_OUT_URB][OUT_BUFLEN];
244 unsigned long out_busy; /* Bit vector of URBs in use */
243 245
244 /* Settings for the port */ 246 /* Settings for the port */
245 int rts_state; /* Handshaking pins (outputs) */ 247 int rts_state; /* Handshaking pins (outputs) */
@@ -370,7 +372,7 @@ static int option_write(struct usb_serial_port *port,
370 todo = OUT_BUFLEN; 372 todo = OUT_BUFLEN;
371 373
372 this_urb = portdata->out_urbs[i]; 374 this_urb = portdata->out_urbs[i];
373 if (this_urb->status == -EINPROGRESS) { 375 if (test_and_set_bit(i, &portdata->out_busy)) {
374 if (time_before(jiffies, 376 if (time_before(jiffies,
375 portdata->tx_start_time[i] + 10 * HZ)) 377 portdata->tx_start_time[i] + 10 * HZ))
376 continue; 378 continue;
@@ -394,6 +396,7 @@ static int option_write(struct usb_serial_port *port,
394 dbg("usb_submit_urb %p (write bulk) failed " 396 dbg("usb_submit_urb %p (write bulk) failed "
395 "(%d, has %d)", this_urb, 397 "(%d, has %d)", this_urb,
396 err, this_urb->status); 398 err, this_urb->status);
399 clear_bit(i, &portdata->out_busy);
397 continue; 400 continue;
398 } 401 }
399 portdata->tx_start_time[i] = jiffies; 402 portdata->tx_start_time[i] = jiffies;
@@ -413,15 +416,16 @@ static void option_indat_callback(struct urb *urb)
413 struct usb_serial_port *port; 416 struct usb_serial_port *port;
414 struct tty_struct *tty; 417 struct tty_struct *tty;
415 unsigned char *data = urb->transfer_buffer; 418 unsigned char *data = urb->transfer_buffer;
419 int status = urb->status;
416 420
417 dbg("%s: %p", __FUNCTION__, urb); 421 dbg("%s: %p", __FUNCTION__, urb);
418 422
419 endpoint = usb_pipeendpoint(urb->pipe); 423 endpoint = usb_pipeendpoint(urb->pipe);
420 port = (struct usb_serial_port *) urb->context; 424 port = (struct usb_serial_port *) urb->context;
421 425
422 if (urb->status) { 426 if (status) {
423 dbg("%s: nonzero status: %d on endpoint %02x.", 427 dbg("%s: nonzero status: %d on endpoint %02x.",
424 __FUNCTION__, urb->status, endpoint); 428 __FUNCTION__, status, endpoint);
425 } else { 429 } else {
426 tty = port->tty; 430 tty = port->tty;
427 if (urb->actual_length) { 431 if (urb->actual_length) {
@@ -433,7 +437,7 @@ static void option_indat_callback(struct urb *urb)
433 } 437 }
434 438
435 /* Resubmit urb so we continue receiving */ 439 /* Resubmit urb so we continue receiving */
436 if (port->open_count && urb->status != -ESHUTDOWN) { 440 if (port->open_count && status != -ESHUTDOWN) {
437 err = usb_submit_urb(urb, GFP_ATOMIC); 441 err = usb_submit_urb(urb, GFP_ATOMIC);
438 if (err) 442 if (err)
439 printk(KERN_ERR "%s: resubmit read urb failed. " 443 printk(KERN_ERR "%s: resubmit read urb failed. "
@@ -446,17 +450,29 @@ static void option_indat_callback(struct urb *urb)
446static void option_outdat_callback(struct urb *urb) 450static void option_outdat_callback(struct urb *urb)
447{ 451{
448 struct usb_serial_port *port; 452 struct usb_serial_port *port;
453 struct option_port_private *portdata;
454 int i;
449 455
450 dbg("%s", __FUNCTION__); 456 dbg("%s", __FUNCTION__);
451 457
452 port = (struct usb_serial_port *) urb->context; 458 port = (struct usb_serial_port *) urb->context;
453 459
454 usb_serial_port_softint(port); 460 usb_serial_port_softint(port);
461
462 portdata = usb_get_serial_port_data(port);
463 for (i = 0; i < N_OUT_URB; ++i) {
464 if (portdata->out_urbs[i] == urb) {
465 smp_mb__before_clear_bit();
466 clear_bit(i, &portdata->out_busy);
467 break;
468 }
469 }
455} 470}
456 471
457static void option_instat_callback(struct urb *urb) 472static void option_instat_callback(struct urb *urb)
458{ 473{
459 int err; 474 int err;
475 int status = urb->status;
460 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 476 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
461 struct option_port_private *portdata = usb_get_serial_port_data(port); 477 struct option_port_private *portdata = usb_get_serial_port_data(port);
462 struct usb_serial *serial = port->serial; 478 struct usb_serial *serial = port->serial;
@@ -464,7 +480,7 @@ static void option_instat_callback(struct urb *urb)
464 dbg("%s", __FUNCTION__); 480 dbg("%s", __FUNCTION__);
465 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); 481 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
466 482
467 if (urb->status == 0) { 483 if (status == 0) {
468 struct usb_ctrlrequest *req_pkt = 484 struct usb_ctrlrequest *req_pkt =
469 (struct usb_ctrlrequest *)urb->transfer_buffer; 485 (struct usb_ctrlrequest *)urb->transfer_buffer;
470 486
@@ -495,10 +511,10 @@ static void option_instat_callback(struct urb *urb)
495 req_pkt->bRequestType,req_pkt->bRequest); 511 req_pkt->bRequestType,req_pkt->bRequest);
496 } 512 }
497 } else 513 } else
498 dbg("%s: error %d", __FUNCTION__, urb->status); 514 dbg("%s: error %d", __FUNCTION__, status);
499 515
500 /* Resubmit urb so we continue receiving IRQ data */ 516 /* Resubmit urb so we continue receiving IRQ data */
501 if (urb->status != -ESHUTDOWN) { 517 if (status != -ESHUTDOWN) {
502 urb->dev = serial->dev; 518 urb->dev = serial->dev;
503 err = usb_submit_urb(urb, GFP_ATOMIC); 519 err = usb_submit_urb(urb, GFP_ATOMIC);
504 if (err) 520 if (err)
@@ -518,7 +534,7 @@ static int option_write_room(struct usb_serial_port *port)
518 534
519 for (i=0; i < N_OUT_URB; i++) { 535 for (i=0; i < N_OUT_URB; i++) {
520 this_urb = portdata->out_urbs[i]; 536 this_urb = portdata->out_urbs[i];
521 if (this_urb && this_urb->status != -EINPROGRESS) 537 if (this_urb && !test_bit(i, &portdata->out_busy))
522 data_len += OUT_BUFLEN; 538 data_len += OUT_BUFLEN;
523 } 539 }
524 540
@@ -537,7 +553,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
537 553
538 for (i=0; i < N_OUT_URB; i++) { 554 for (i=0; i < N_OUT_URB; i++) {
539 this_urb = portdata->out_urbs[i]; 555 this_urb = portdata->out_urbs[i];
540 if (this_urb && this_urb->status == -EINPROGRESS) 556 if (this_urb && test_bit(i, &portdata->out_busy))
541 data_len += this_urb->transfer_buffer_length; 557 data_len += this_urb->transfer_buffer_length;
542 } 558 }
543 dbg("%s: %d", __FUNCTION__, data_len); 559 dbg("%s: %d", __FUNCTION__, data_len);
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
new file mode 100644
index 000000000000..d7db71eca520
--- /dev/null
+++ b/drivers/usb/serial/oti6858.c
@@ -0,0 +1,1342 @@
1/*
2 * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
3 *
4 * Copyleft (C) 2007 Kees Lemmens (adapted for kernel 2.6.20)
5 * Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail)
6 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2003 IBM Corp.
8 *
9 * Many thanks to the authors of pl2303 driver: all functions in this file
10 * are heavily based on pl2303 code, buffering code is a 1-to-1 copy.
11 *
12 * Warning! You use this driver on your own risk! The only official
13 * description of this device I have is datasheet from manufacturer,
14 * and it doesn't contain almost any information needed to write a driver.
15 * Almost all knowlegde used while writing this driver was gathered by:
16 * - analyzing traffic between device and the M$ Windows 2000 driver,
17 * - trying different bit combinations and checking pin states
18 * with a voltmeter,
19 * - receiving malformed frames and producing buffer overflows
20 * to learn how errors are reported,
21 * So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE
22 * CONNECTED TO IT!
23 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License.
27 *
28 * See Documentation/usb/usb-serial.txt for more information on using this driver
29 *
30 * TODO:
31 * - implement correct flushing for ioctls and oti6858_close()
32 * - check how errors (rx overflow, parity error, framing error) are reported
33 * - implement oti6858_break_ctl()
34 * - implement more ioctls
35 * - test/implement flow control
36 * - allow setting custom baud rates
37 */
38
39#include <linux/kernel.h>
40#include <linux/errno.h>
41#include <linux/init.h>
42#include <linux/slab.h>
43#include <linux/tty.h>
44#include <linux/tty_driver.h>
45#include <linux/tty_flip.h>
46#include <linux/serial.h>
47#include <linux/module.h>
48#include <linux/moduleparam.h>
49#include <linux/spinlock.h>
50#include <linux/usb.h>
51#include <linux/usb/serial.h>
52#include <asm/uaccess.h>
53#include "oti6858.h"
54
55#define OTI6858_DESCRIPTION \
56 "Ours Technology Inc. OTi-6858 USB to serial adapter driver"
57#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
58#define OTI6858_VERSION "0.1"
59
60static struct usb_device_id id_table [] = {
61 { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
62 { }
63};
64
65MODULE_DEVICE_TABLE(usb, id_table);
66
67static struct usb_driver oti6858_driver = {
68 .name = "oti6858",
69 .probe = usb_serial_probe,
70 .disconnect = usb_serial_disconnect,
71 .id_table = id_table,
72 .no_dynamic_id = 1,
73};
74
75static int debug;
76
77
78/* buffering code, copied from pl2303 driver */
79#define PL2303_BUF_SIZE 1024
80#define PL2303_TMP_BUF_SIZE 1024
81
82struct pl2303_buf {
83 unsigned int buf_size;
84 char *buf_buf;
85 char *buf_get;
86 char *buf_put;
87};
88
89/* requests */
90#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
91#define OTI6858_REQ_T_GET_STATUS 0x01
92
93#define OTI6858_REQ_SET_LINE (USB_DIR_OUT | USB_TYPE_VENDOR | 0x00)
94#define OTI6858_REQ_T_SET_LINE 0x00
95
96#define OTI6858_REQ_CHECK_TXBUFF (USB_DIR_IN | USB_TYPE_VENDOR | 0x01)
97#define OTI6858_REQ_T_CHECK_TXBUFF 0x00
98
99/* format of the control packet */
100struct oti6858_control_pkt {
101 u16 divisor; /* baud rate = 96000000 / (16 * divisor), LE */
102#define OTI6858_MAX_BAUD_RATE 3000000
103 u8 frame_fmt;
104#define FMT_STOP_BITS_MASK 0xc0
105#define FMT_STOP_BITS_1 0x00
106#define FMT_STOP_BITS_2 0x40 /* 1.5 stop bits if FMT_DATA_BITS_5 */
107#define FMT_PARITY_MASK 0x38
108#define FMT_PARITY_NONE 0x00
109#define FMT_PARITY_ODD 0x08
110#define FMT_PARITY_EVEN 0x18
111#define FMT_PARITY_MARK 0x28
112#define FMT_PARITY_SPACE 0x38
113#define FMT_DATA_BITS_MASK 0x03
114#define FMT_DATA_BITS_5 0x00
115#define FMT_DATA_BITS_6 0x01
116#define FMT_DATA_BITS_7 0x02
117#define FMT_DATA_BITS_8 0x03
118 u8 something; /* always equals 0x43 */
119 u8 control; /* settings of flow control lines */
120#define CONTROL_MASK 0x0c
121#define CONTROL_DTR_HIGH 0x08
122#define CONTROL_RTS_HIGH 0x04
123 u8 tx_status;
124#define TX_BUFFER_EMPTIED 0x09
125 u8 pin_state;
126#define PIN_MASK 0x3f
127#define PIN_RTS 0x20 /* output pin */
128#define PIN_CTS 0x10 /* input pin, active low */
129#define PIN_DSR 0x08 /* input pin, active low */
130#define PIN_DTR 0x04 /* output pin */
131#define PIN_RI 0x02 /* input pin, active low */
132#define PIN_DCD 0x01 /* input pin, active low */
133 u8 rx_bytes_avail; /* number of bytes in rx buffer */;
134};
135
136#define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt)
137#define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
138 ( ((a)->divisor == (priv)->pending_setup.divisor) \
139 && ((a)->control == (priv)->pending_setup.control) \
140 && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) )
141
142/* function prototypes */
143static int oti6858_open(struct usb_serial_port *port, struct file *filp);
144static void oti6858_close(struct usb_serial_port *port, struct file *filp);
145static void oti6858_set_termios(struct usb_serial_port *port,
146 struct ktermios *old);
147static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
148 unsigned int cmd, unsigned long arg);
149static void oti6858_read_int_callback(struct urb *urb);
150static void oti6858_read_bulk_callback(struct urb *urb);
151static void oti6858_write_bulk_callback(struct urb *urb);
152static int oti6858_write(struct usb_serial_port *port,
153 const unsigned char *buf, int count);
154static int oti6858_write_room(struct usb_serial_port *port);
155static void oti6858_break_ctl(struct usb_serial_port *port, int break_state);
156static int oti6858_chars_in_buffer(struct usb_serial_port *port);
157static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file);
158static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
159 unsigned int set, unsigned int clear);
160static int oti6858_startup(struct usb_serial *serial);
161static void oti6858_shutdown(struct usb_serial *serial);
162
163/* functions operating on buffers */
164static struct pl2303_buf *pl2303_buf_alloc(unsigned int size);
165static void pl2303_buf_free(struct pl2303_buf *pb);
166static void pl2303_buf_clear(struct pl2303_buf *pb);
167static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb);
168static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb);
169static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf,
170 unsigned int count);
171static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
172 unsigned int count);
173
174
175/* device info */
176static struct usb_serial_driver oti6858_device = {
177 .driver = {
178 .owner = THIS_MODULE,
179 .name = "oti6858",
180 },
181 .id_table = id_table,
182 .num_interrupt_in = 1,
183 .num_bulk_in = 1,
184 .num_bulk_out = 1,
185 .num_ports = 1,
186 .open = oti6858_open,
187 .close = oti6858_close,
188 .write = oti6858_write,
189 .ioctl = oti6858_ioctl,
190 .break_ctl = oti6858_break_ctl,
191 .set_termios = oti6858_set_termios,
192 .tiocmget = oti6858_tiocmget,
193 .tiocmset = oti6858_tiocmset,
194 .read_bulk_callback = oti6858_read_bulk_callback,
195 .read_int_callback = oti6858_read_int_callback,
196 .write_bulk_callback = oti6858_write_bulk_callback,
197 .write_room = oti6858_write_room,
198 .chars_in_buffer = oti6858_chars_in_buffer,
199 .attach = oti6858_startup,
200 .shutdown = oti6858_shutdown,
201};
202
203struct oti6858_private {
204 spinlock_t lock;
205
206 struct pl2303_buf *buf;
207 struct oti6858_control_pkt status;
208
209 struct {
210 u8 read_urb_in_use;
211 u8 write_urb_in_use;
212 u8 termios_initialized;
213 } flags;
214 struct delayed_work delayed_write_work;
215
216 struct {
217 u16 divisor;
218 u8 frame_fmt;
219 u8 control;
220 } pending_setup;
221 u8 transient;
222 u8 setup_done;
223 struct delayed_work delayed_setup_work;
224
225 wait_queue_head_t intr_wait;
226 struct usb_serial_port *port; /* USB port with which associated */
227};
228
229#undef dbg
230/* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */
231#define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg)
232
233static void setup_line(struct work_struct *work)
234{
235 struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work);
236 struct usb_serial_port *port = priv->port;
237 struct oti6858_control_pkt *new_setup;
238 unsigned long flags;
239 int result;
240
241 dbg("%s(port = %d)", __FUNCTION__, port->number);
242
243 if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
244 dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__);
245 /* we will try again */
246 schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
247 return;
248 }
249
250 result = usb_control_msg(port->serial->dev,
251 usb_rcvctrlpipe(port->serial->dev, 0),
252 OTI6858_REQ_T_GET_STATUS,
253 OTI6858_REQ_GET_STATUS,
254 0, 0,
255 new_setup, OTI6858_CTRL_PKT_SIZE,
256 100);
257
258 if (result != OTI6858_CTRL_PKT_SIZE) {
259 dev_err(&port->dev, "%s(): error reading status", __FUNCTION__);
260 kfree(new_setup);
261 /* we will try again */
262 schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
263 return;
264 }
265
266 spin_lock_irqsave(&priv->lock, flags);
267 if (!OTI6858_CTRL_EQUALS_PENDING(new_setup, priv)) {
268 new_setup->divisor = priv->pending_setup.divisor;
269 new_setup->control = priv->pending_setup.control;
270 new_setup->frame_fmt = priv->pending_setup.frame_fmt;
271
272 spin_unlock_irqrestore(&priv->lock, flags);
273 result = usb_control_msg(port->serial->dev,
274 usb_sndctrlpipe(port->serial->dev, 0),
275 OTI6858_REQ_T_SET_LINE,
276 OTI6858_REQ_SET_LINE,
277 0, 0,
278 new_setup, OTI6858_CTRL_PKT_SIZE,
279 100);
280 } else {
281 spin_unlock_irqrestore(&priv->lock, flags);
282 result = 0;
283 }
284 kfree(new_setup);
285
286 spin_lock_irqsave(&priv->lock, flags);
287 if (result != OTI6858_CTRL_PKT_SIZE)
288 priv->transient = 0;
289 priv->setup_done = 1;
290 spin_unlock_irqrestore(&priv->lock, flags);
291
292 dbg("%s(): submitting interrupt urb", __FUNCTION__);
293 port->interrupt_in_urb->dev = port->serial->dev;
294 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
295 if (result != 0) {
296 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
297 " with error %d\n", __FUNCTION__, result);
298 }
299}
300
301void send_data(struct work_struct *work)
302{
303 struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work);
304 struct usb_serial_port *port = priv->port;
305 int count = 0, result;
306 unsigned long flags;
307 unsigned char allow;
308
309 dbg("%s(port = %d)", __FUNCTION__, port->number);
310
311 spin_lock_irqsave(&priv->lock, flags);
312 if (priv->flags.write_urb_in_use) {
313 spin_unlock_irqrestore(&priv->lock, flags);
314 schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2));
315 return;
316 }
317 priv->flags.write_urb_in_use = 1;
318
319 count = pl2303_buf_data_avail(priv->buf);
320 spin_unlock_irqrestore(&priv->lock, flags);
321 if (count > port->bulk_out_size)
322 count = port->bulk_out_size;
323
324 if (count != 0) {
325 result = usb_control_msg(port->serial->dev,
326 usb_rcvctrlpipe(port->serial->dev, 0),
327 OTI6858_REQ_T_CHECK_TXBUFF,
328 OTI6858_REQ_CHECK_TXBUFF,
329 count, 0, &allow, 1, 100);
330 if (result != 1 || allow != 0)
331 count = 0;
332 }
333
334 if (count == 0) {
335 priv->flags.write_urb_in_use = 0;
336
337 dbg("%s(): submitting interrupt urb", __FUNCTION__);
338 port->interrupt_in_urb->dev = port->serial->dev;
339 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
340 if (result != 0) {
341 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
342 " with error %d\n", __FUNCTION__, result);
343 }
344 return;
345 }
346
347 spin_lock_irqsave(&priv->lock, flags);
348 pl2303_buf_get(priv->buf, port->write_urb->transfer_buffer, count);
349 spin_unlock_irqrestore(&priv->lock, flags);
350
351 port->write_urb->transfer_buffer_length = count;
352 port->write_urb->dev = port->serial->dev;
353 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
354 if (result != 0) {
355 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
356 " with error %d\n", __FUNCTION__, result);
357 priv->flags.write_urb_in_use = 0;
358 }
359
360 usb_serial_port_softint(port);
361}
362
363static int oti6858_startup(struct usb_serial *serial)
364{
365 struct usb_serial_port *port = serial->port[0];
366 struct oti6858_private *priv;
367 int i;
368
369 for (i = 0; i < serial->num_ports; ++i) {
370 priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
371 if (!priv)
372 break;
373 priv->buf = pl2303_buf_alloc(PL2303_BUF_SIZE);
374 if (priv->buf == NULL) {
375 kfree(priv);
376 break;
377 }
378
379 spin_lock_init(&priv->lock);
380 init_waitqueue_head(&priv->intr_wait);
381// INIT_WORK(&priv->setup_work, setup_line, serial->port[i]);
382// INIT_WORK(&priv->write_work, send_data, serial->port[i]);
383 priv->port = port;
384 INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
385 INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
386
387 usb_set_serial_port_data(serial->port[i], priv);
388 }
389 if (i == serial->num_ports)
390 return 0;
391
392 for (--i; i >= 0; --i) {
393 priv = usb_get_serial_port_data(serial->port[i]);
394 pl2303_buf_free(priv->buf);
395 kfree(priv);
396 usb_set_serial_port_data(serial->port[i], NULL);
397 }
398 return -ENOMEM;
399}
400
401static int oti6858_write(struct usb_serial_port *port,
402 const unsigned char *buf, int count)
403{
404 struct oti6858_private *priv = usb_get_serial_port_data(port);
405 unsigned long flags;
406
407 dbg("%s(port = %d, count = %d)", __FUNCTION__, port->number, count);
408
409 if (!count)
410 return count;
411
412 spin_lock_irqsave(&priv->lock, flags);
413 count = pl2303_buf_put(priv->buf, buf, count);
414 spin_unlock_irqrestore(&priv->lock, flags);
415
416 return count;
417}
418
419static int oti6858_write_room(struct usb_serial_port *port)
420{
421 struct oti6858_private *priv = usb_get_serial_port_data(port);
422 int room = 0;
423 unsigned long flags;
424
425 dbg("%s(port = %d)", __FUNCTION__, port->number);
426
427 spin_lock_irqsave(&priv->lock, flags);
428 room = pl2303_buf_space_avail(priv->buf);
429 spin_unlock_irqrestore(&priv->lock, flags);
430
431 return room;
432}
433
434static int oti6858_chars_in_buffer(struct usb_serial_port *port)
435{
436 struct oti6858_private *priv = usb_get_serial_port_data(port);
437 int chars = 0;
438 unsigned long flags;
439
440 dbg("%s(port = %d)", __FUNCTION__, port->number);
441
442 spin_lock_irqsave(&priv->lock, flags);
443 chars = pl2303_buf_data_avail(priv->buf);
444 spin_unlock_irqrestore(&priv->lock, flags);
445
446 return chars;
447}
448
449static void oti6858_set_termios(struct usb_serial_port *port,
450 struct ktermios *old_termios)
451{
452 struct oti6858_private *priv = usb_get_serial_port_data(port);
453 unsigned long flags;
454 unsigned int cflag;
455 u8 frame_fmt, control;
456 u16 divisor;
457 int br;
458
459 dbg("%s(port = %d)", __FUNCTION__, port->number);
460
461 if ((!port->tty) || (!port->tty->termios)) {
462 dbg("%s(): no tty structures", __FUNCTION__);
463 return;
464 }
465
466 spin_lock_irqsave(&priv->lock, flags);
467 if (!priv->flags.termios_initialized) {
468 *(port->tty->termios) = tty_std_termios;
469 port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
470 priv->flags.termios_initialized = 1;
471 }
472 spin_unlock_irqrestore(&priv->lock, flags);
473
474 cflag = port->tty->termios->c_cflag;
475
476 spin_lock_irqsave(&priv->lock, flags);
477 divisor = priv->pending_setup.divisor;
478 frame_fmt = priv->pending_setup.frame_fmt;
479 control = priv->pending_setup.control;
480 spin_unlock_irqrestore(&priv->lock, flags);
481
482 frame_fmt &= ~FMT_DATA_BITS_MASK;
483 switch (cflag & CSIZE) {
484 case CS5:
485 frame_fmt |= FMT_DATA_BITS_5;
486 break;
487 case CS6:
488 frame_fmt |= FMT_DATA_BITS_6;
489 break;
490 case CS7:
491 frame_fmt |= FMT_DATA_BITS_7;
492 break;
493 default:
494 case CS8:
495 frame_fmt |= FMT_DATA_BITS_8;
496 break;
497 }
498
499 /* manufacturer claims that this device can work with baud rates
500 * up to 3 Mbps; I've tested it only on 115200 bps, so I can't
501 * guarantee that any other baud rate will work (especially
502 * the higher ones)
503 */
504 br = tty_get_baud_rate(port->tty);
505 if (br == 0) {
506 divisor = 0;
507 } else if (br <= OTI6858_MAX_BAUD_RATE) {
508 int real_br;
509
510 divisor = (96000000 + 8 * br) / (16 * br);
511 real_br = 96000000 / (16 * divisor);
512 if ((((real_br - br) * 100 + br - 1) / br) > 2) {
513 dbg("%s(): baud rate %d is invalid", __FUNCTION__, br);
514 return;
515 }
516 divisor = cpu_to_le16(divisor);
517 } else {
518 dbg("%s(): baud rate %d is too high", __FUNCTION__, br);
519 return;
520 }
521
522 frame_fmt &= ~FMT_STOP_BITS_MASK;
523 if ((cflag & CSTOPB) != 0) {
524 frame_fmt |= FMT_STOP_BITS_2;
525 } else {
526 frame_fmt |= FMT_STOP_BITS_1;
527 }
528
529 frame_fmt &= ~FMT_PARITY_MASK;
530 if ((cflag & PARENB) != 0) {
531 if ((cflag & PARODD) != 0) {
532 frame_fmt |= FMT_PARITY_ODD;
533 } else {
534 frame_fmt |= FMT_PARITY_EVEN;
535 }
536 } else {
537 frame_fmt |= FMT_PARITY_NONE;
538 }
539
540 control &= ~CONTROL_MASK;
541 if ((cflag & CRTSCTS) != 0)
542 control |= (CONTROL_DTR_HIGH | CONTROL_RTS_HIGH);
543
544 /* change control lines if we are switching to or from B0 */
545 /* FIXME:
546 spin_lock_irqsave(&priv->lock, flags);
547 control = priv->line_control;
548 if ((cflag & CBAUD) == B0)
549 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
550 else
551 priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
552 if (control != priv->line_control) {
553 control = priv->line_control;
554 spin_unlock_irqrestore(&priv->lock, flags);
555 set_control_lines(serial->dev, control);
556 } else {
557 spin_unlock_irqrestore(&priv->lock, flags);
558 }
559 */
560
561 spin_lock_irqsave(&priv->lock, flags);
562 if (divisor != priv->pending_setup.divisor
563 || control != priv->pending_setup.control
564 || frame_fmt != priv->pending_setup.frame_fmt) {
565 priv->pending_setup.divisor = divisor;
566 priv->pending_setup.control = control;
567 priv->pending_setup.frame_fmt = frame_fmt;
568 }
569 spin_unlock_irqrestore(&priv->lock, flags);
570}
571
572static int oti6858_open(struct usb_serial_port *port, struct file *filp)
573{
574 struct oti6858_private *priv = usb_get_serial_port_data(port);
575 struct ktermios tmp_termios;
576 struct usb_serial *serial = port->serial;
577 struct oti6858_control_pkt *buf;
578 unsigned long flags;
579 int result;
580
581 dbg("%s(port = %d)", __FUNCTION__, port->number);
582
583 usb_clear_halt(serial->dev, port->write_urb->pipe);
584 usb_clear_halt(serial->dev, port->read_urb->pipe);
585
586 if (port->open_count != 1)
587 return 0;
588
589 if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
590 dev_err(&port->dev, "%s(): out of memory!\n", __FUNCTION__);
591 return -ENOMEM;
592 }
593
594 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
595 OTI6858_REQ_T_GET_STATUS,
596 OTI6858_REQ_GET_STATUS,
597 0, 0,
598 buf, OTI6858_CTRL_PKT_SIZE,
599 100);
600 if (result != OTI6858_CTRL_PKT_SIZE) {
601 /* assume default (after power-on reset) values */
602 buf->divisor = cpu_to_le16(0x009c); /* 38400 bps */
603 buf->frame_fmt = 0x03; /* 8N1 */
604 buf->something = 0x43;
605 buf->control = 0x4c; /* DTR, RTS */
606 buf->tx_status = 0x00;
607 buf->pin_state = 0x5b; /* RTS, CTS, DSR, DTR, RI, DCD */
608 buf->rx_bytes_avail = 0x00;
609 }
610
611 spin_lock_irqsave(&priv->lock, flags);
612 memcpy(&priv->status, buf, OTI6858_CTRL_PKT_SIZE);
613 priv->pending_setup.divisor = buf->divisor;
614 priv->pending_setup.frame_fmt = buf->frame_fmt;
615 priv->pending_setup.control = buf->control;
616 spin_unlock_irqrestore(&priv->lock, flags);
617 kfree(buf);
618
619 dbg("%s(): submitting interrupt urb", __FUNCTION__);
620 port->interrupt_in_urb->dev = serial->dev;
621 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
622 if (result != 0) {
623 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
624 " with error %d\n", __FUNCTION__, result);
625 oti6858_close(port, NULL);
626 return -EPROTO;
627 }
628
629 /* setup termios */
630 if (port->tty)
631 oti6858_set_termios(port, &tmp_termios);
632
633 return 0;
634}
635
636static void oti6858_close(struct usb_serial_port *port, struct file *filp)
637{
638 struct oti6858_private *priv = usb_get_serial_port_data(port);
639 unsigned long flags;
640 long timeout;
641 wait_queue_t wait;
642
643 dbg("%s(port = %d)", __FUNCTION__, port->number);
644
645 /* wait for data to drain from the buffer */
646 spin_lock_irqsave(&priv->lock, flags);
647 timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */
648 init_waitqueue_entry(&wait, current);
649 add_wait_queue(&port->tty->write_wait, &wait);
650 dbg("%s(): entering wait loop", __FUNCTION__);
651 for (;;) {
652 set_current_state(TASK_INTERRUPTIBLE);
653 if (pl2303_buf_data_avail(priv->buf) == 0
654 || timeout == 0 || signal_pending(current)
655 || !usb_get_intfdata(port->serial->interface)) /* disconnect */
656 break;
657 spin_unlock_irqrestore(&priv->lock, flags);
658 timeout = schedule_timeout(timeout);
659 spin_lock_irqsave(&priv->lock, flags);
660 }
661 set_current_state(TASK_RUNNING);
662 remove_wait_queue(&port->tty->write_wait, &wait);
663 dbg("%s(): after wait loop", __FUNCTION__);
664
665 /* clear out any remaining data in the buffer */
666 pl2303_buf_clear(priv->buf);
667 spin_unlock_irqrestore(&priv->lock, flags);
668
669 /* wait for characters to drain from the device */
670 /* (this is long enough for the entire 256 byte */
671 /* pl2303 hardware buffer to drain with no flow */
672 /* control for data rates of 1200 bps or more, */
673 /* for lower rates we should really know how much */
674 /* data is in the buffer to compute a delay */
675 /* that is not unnecessarily long) */
676 /* FIXME
677 bps = tty_get_baud_rate(port->tty);
678 if (bps > 1200)
679 timeout = max((HZ*2560)/bps,HZ/10);
680 else
681 */
682 timeout = 2*HZ;
683 schedule_timeout_interruptible(timeout);
684 dbg("%s(): after schedule_timeout_interruptible()", __FUNCTION__);
685
686 /* cancel scheduled setup */
687 cancel_delayed_work(&priv->delayed_setup_work);
688 cancel_delayed_work(&priv->delayed_write_work);
689 flush_scheduled_work();
690
691 /* shutdown our urbs */
692 dbg("%s(): shutting down urbs", __FUNCTION__);
693 usb_kill_urb(port->write_urb);
694 usb_kill_urb(port->read_urb);
695 usb_kill_urb(port->interrupt_in_urb);
696
697 /*
698 if (port->tty && (port->tty->termios->c_cflag) & HUPCL) {
699 // drop DTR and RTS
700 spin_lock_irqsave(&priv->lock, flags);
701 priv->pending_setup.control &= ~CONTROL_MASK;
702 spin_unlock_irqrestore(&priv->lock, flags);
703 }
704 */
705}
706
707static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
708 unsigned int set, unsigned int clear)
709{
710 struct oti6858_private *priv = usb_get_serial_port_data(port);
711 unsigned long flags;
712 u8 control;
713
714 dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)",
715 __FUNCTION__, port->number, set, clear);
716
717 if (!usb_get_intfdata(port->serial->interface))
718 return -ENODEV;
719
720 /* FIXME: check if this is correct (active high/low) */
721 spin_lock_irqsave(&priv->lock, flags);
722 control = priv->pending_setup.control;
723 if ((set & TIOCM_RTS) != 0)
724 control |= CONTROL_RTS_HIGH;
725 if ((set & TIOCM_DTR) != 0)
726 control |= CONTROL_DTR_HIGH;
727 if ((clear & TIOCM_RTS) != 0)
728 control &= ~CONTROL_RTS_HIGH;
729 if ((clear & TIOCM_DTR) != 0)
730 control &= ~CONTROL_DTR_HIGH;
731
732 if (control != priv->pending_setup.control) {
733 priv->pending_setup.control = control;
734 }
735 spin_unlock_irqrestore(&priv->lock, flags);
736
737 return 0;
738}
739
740static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file)
741{
742 struct oti6858_private *priv = usb_get_serial_port_data(port);
743 unsigned long flags;
744 unsigned pin_state;
745 unsigned result = 0;
746
747 dbg("%s(port = %d)", __FUNCTION__, port->number);
748
749 if (!usb_get_intfdata(port->serial->interface))
750 return -ENODEV;
751
752 spin_lock_irqsave(&priv->lock, flags);
753 pin_state = priv->status.pin_state & PIN_MASK;
754 spin_unlock_irqrestore(&priv->lock, flags);
755
756 /* FIXME: check if this is correct (active high/low) */
757 if ((pin_state & PIN_RTS) != 0)
758 result |= TIOCM_RTS;
759 if ((pin_state & PIN_CTS) != 0)
760 result |= TIOCM_CTS;
761 if ((pin_state & PIN_DSR) != 0)
762 result |= TIOCM_DSR;
763 if ((pin_state & PIN_DTR) != 0)
764 result |= TIOCM_DTR;
765 if ((pin_state & PIN_RI) != 0)
766 result |= TIOCM_RI;
767 if ((pin_state & PIN_DCD) != 0)
768 result |= TIOCM_CD;
769
770 dbg("%s() = 0x%08x", __FUNCTION__, result);
771
772 return result;
773}
774
775static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
776{
777 struct oti6858_private *priv = usb_get_serial_port_data(port);
778 unsigned long flags;
779 unsigned int prev, status;
780 unsigned int changed;
781
782 spin_lock_irqsave(&priv->lock, flags);
783 prev = priv->status.pin_state;
784 spin_unlock_irqrestore(&priv->lock, flags);
785
786 while (1) {
787 wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev);
788 if (signal_pending(current))
789 return -ERESTARTSYS;
790
791 spin_lock_irqsave(&priv->lock, flags);
792 status = priv->status.pin_state & PIN_MASK;
793 spin_unlock_irqrestore(&priv->lock, flags);
794
795 changed = prev ^ status;
796 /* FIXME: check if this is correct (active high/low) */
797 if ( ((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
798 ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
799 ((arg & TIOCM_CD) && (changed & PIN_DCD)) ||
800 ((arg & TIOCM_CTS) && (changed & PIN_CTS))) {
801 return 0;
802 }
803 prev = status;
804 }
805
806 /* NOTREACHED */
807 return 0;
808}
809
810static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
811 unsigned int cmd, unsigned long arg)
812{
813 void __user *user_arg = (void __user *) arg;
814 unsigned int x;
815
816 dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)",
817 __FUNCTION__, port->number, cmd, arg);
818
819 switch (cmd) {
820 case TCGETS:
821 if (copy_to_user(user_arg, port->tty->termios,
822 sizeof(struct ktermios))) {
823 return -EFAULT;
824 }
825 return 0;
826
827 case TCSETS:
828 case TCSETSW: /* FIXME: this is not the same! */
829 case TCSETSF: /* FIXME: this is not the same! */
830 if (copy_from_user(port->tty->termios, user_arg,
831 sizeof(struct ktermios))) {
832 return -EFAULT;
833 }
834 oti6858_set_termios(port, NULL);
835 return 0;
836
837 case TCFLSH:
838 /* FIXME */
839 return 0;
840
841 case TIOCMBIS:
842 if (copy_from_user(&x, user_arg, sizeof(x)))
843 return -EFAULT;
844 return oti6858_tiocmset(port, NULL, x, 0);
845
846 case TIOCMBIC:
847 if (copy_from_user(&x, user_arg, sizeof(x)))
848 return -EFAULT;
849 return oti6858_tiocmset(port, NULL, 0, x);
850
851 case TIOCGSERIAL:
852 if (copy_to_user(user_arg, port->tty->termios,
853 sizeof(struct ktermios))) {
854 return -EFAULT;
855 }
856 return 0;
857
858 case TIOCSSERIAL:
859 if (copy_from_user(port->tty->termios, user_arg,
860 sizeof(struct ktermios))) {
861 return -EFAULT;
862 }
863 oti6858_set_termios(port, NULL);
864 return 0;
865
866 case TIOCMIWAIT:
867 dbg("%s(): TIOCMIWAIT", __FUNCTION__);
868 return wait_modem_info(port, arg);
869
870 default:
871 dbg("%s(): 0x%04x not supported", __FUNCTION__, cmd);
872 break;
873 }
874
875 return -ENOIOCTLCMD;
876}
877
878static void oti6858_break_ctl(struct usb_serial_port *port, int break_state)
879{
880 int state;
881
882 dbg("%s(port = %d)", __FUNCTION__, port->number);
883
884 state = (break_state == 0) ? 0 : 1;
885 dbg("%s(): turning break %s", __FUNCTION__, state ? "on" : "off");
886
887 /* FIXME */
888/*
889 result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
890 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
891 0, NULL, 0, 100);
892 if (result != 0)
893 dbg("%s(): error sending break", __FUNCTION__);
894 */
895}
896
897static void oti6858_shutdown(struct usb_serial *serial)
898{
899 struct oti6858_private *priv;
900 int i;
901
902 dbg("%s()", __FUNCTION__);
903
904 for (i = 0; i < serial->num_ports; ++i) {
905 priv = usb_get_serial_port_data(serial->port[i]);
906 if (priv) {
907 pl2303_buf_free(priv->buf);
908 kfree(priv);
909 usb_set_serial_port_data(serial->port[i], NULL);
910 }
911 }
912}
913
914static void oti6858_read_int_callback(struct urb *urb)
915{
916 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
917 struct oti6858_private *priv = usb_get_serial_port_data(port);
918 int transient = 0, can_recv = 0, resubmit = 1;
919 int status = urb->status;
920
921 dbg("%s(port = %d, status = %d)",
922 __FUNCTION__, port->number, status);
923
924 switch (status) {
925 case 0:
926 /* success */
927 break;
928 case -ECONNRESET:
929 case -ENOENT:
930 case -ESHUTDOWN:
931 /* this urb is terminated, clean up */
932 dbg("%s(): urb shutting down with status: %d",
933 __FUNCTION__, status);
934 return;
935 default:
936 dbg("%s(): nonzero urb status received: %d",
937 __FUNCTION__, status);
938 break;
939 }
940
941 if (status == 0 && urb->actual_length == OTI6858_CTRL_PKT_SIZE) {
942 struct oti6858_control_pkt *xs = urb->transfer_buffer;
943 unsigned long flags;
944
945 spin_lock_irqsave(&priv->lock, flags);
946
947 if (!priv->transient) {
948 if (!OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
949 if (xs->rx_bytes_avail == 0) {
950 priv->transient = 4;
951 priv->setup_done = 0;
952 resubmit = 0;
953 dbg("%s(): scheduling setup_line()",
954 __FUNCTION__);
955 schedule_delayed_work(&priv->delayed_setup_work, 0);
956 }
957 }
958 } else {
959 if (OTI6858_CTRL_EQUALS_PENDING(xs, priv)) {
960 priv->transient = 0;
961 } else if (!priv->setup_done) {
962 resubmit = 0;
963 } else if (--priv->transient == 0) {
964 if (xs->rx_bytes_avail == 0) {
965 priv->transient = 4;
966 priv->setup_done = 0;
967 resubmit = 0;
968 dbg("%s(): scheduling setup_line()",
969 __FUNCTION__);
970 schedule_delayed_work(&priv->delayed_setup_work, 0);
971 }
972 }
973 }
974
975 if (!priv->transient) {
976 if (xs->pin_state != priv->status.pin_state)
977 wake_up_interruptible(&priv->intr_wait);
978 memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
979 }
980
981 if (!priv->transient && xs->rx_bytes_avail != 0) {
982 can_recv = xs->rx_bytes_avail;
983 priv->flags.read_urb_in_use = 1;
984 }
985
986 transient = priv->transient;
987 spin_unlock_irqrestore(&priv->lock, flags);
988 }
989
990 if (can_recv) {
991 int result;
992
993 port->read_urb->dev = port->serial->dev;
994 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
995 if (result != 0) {
996 priv->flags.read_urb_in_use = 0;
997 dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
998 " error %d\n", __FUNCTION__, result);
999 } else {
1000 resubmit = 0;
1001 }
1002 } else if (!transient) {
1003 unsigned long flags;
1004
1005 spin_lock_irqsave(&priv->lock, flags);
1006 if (priv->flags.write_urb_in_use == 0
1007 && pl2303_buf_data_avail(priv->buf) != 0) {
1008 schedule_delayed_work(&priv->delayed_write_work,0);
1009 resubmit = 0;
1010 }
1011 spin_unlock_irqrestore(&priv->lock, flags);
1012 }
1013
1014 if (resubmit) {
1015 int result;
1016
1017// dbg("%s(): submitting interrupt urb", __FUNCTION__);
1018 urb->dev = port->serial->dev;
1019 result = usb_submit_urb(urb, GFP_ATOMIC);
1020 if (result != 0) {
1021 dev_err(&urb->dev->dev,
1022 "%s(): usb_submit_urb() failed with"
1023 " error %d\n", __FUNCTION__, result);
1024 }
1025 }
1026}
1027
1028static void oti6858_read_bulk_callback(struct urb *urb)
1029{
1030 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
1031 struct oti6858_private *priv = usb_get_serial_port_data(port);
1032 struct tty_struct *tty;
1033 unsigned char *data = urb->transfer_buffer;
1034 unsigned long flags;
1035 int i, result;
1036 int status = urb->status;
1037 char tty_flag;
1038
1039 dbg("%s(port = %d, status = %d)",
1040 __FUNCTION__, port->number, status);
1041
1042 spin_lock_irqsave(&priv->lock, flags);
1043 priv->flags.read_urb_in_use = 0;
1044 spin_unlock_irqrestore(&priv->lock, flags);
1045
1046 if (status != 0) {
1047 if (!port->open_count) {
1048 dbg("%s(): port is closed, exiting", __FUNCTION__);
1049 return;
1050 }
1051 /*
1052 if (status == -EPROTO) {
1053 // PL2303 mysteriously fails with -EPROTO reschedule the read
1054 dbg("%s - caught -EPROTO, resubmitting the urb", __FUNCTION__);
1055 result = usb_submit_urb(urb, GFP_ATOMIC);
1056 if (result)
1057 dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
1058 return;
1059 }
1060 */
1061 dbg("%s(): unable to handle the error, exiting", __FUNCTION__);
1062 return;
1063 }
1064
1065 // get tty_flag from status
1066 tty_flag = TTY_NORMAL;
1067
1068/* FIXME: probably, errors will be signalled using interrupt pipe! */
1069/*
1070 // break takes precedence over parity,
1071 // which takes precedence over framing errors
1072 if (status & UART_BREAK_ERROR )
1073 tty_flag = TTY_BREAK;
1074 else if (status & UART_PARITY_ERROR)
1075 tty_flag = TTY_PARITY;
1076 else if (status & UART_FRAME_ERROR)
1077 tty_flag = TTY_FRAME;
1078 dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag);
1079*/
1080
1081 tty = port->tty;
1082 if (tty != NULL && urb->actual_length > 0) {
1083 tty_buffer_request_room(tty, urb->actual_length);
1084 for (i = 0; i < urb->actual_length; ++i)
1085 tty_insert_flip_char(tty, data[i], tty_flag);
1086 tty_flip_buffer_push(tty);
1087 }
1088
1089 // schedule the interrupt urb if we are still open */
1090 if (port->open_count != 0) {
1091 port->interrupt_in_urb->dev = port->serial->dev;
1092 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1093 if (result != 0) {
1094 dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
1095 " error %d\n", __FUNCTION__, result);
1096 }
1097 }
1098}
1099
1100static void oti6858_write_bulk_callback(struct urb *urb)
1101{
1102 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
1103 struct oti6858_private *priv = usb_get_serial_port_data(port);
1104 int status = urb->status;
1105 int result;
1106
1107 dbg("%s(port = %d, status = %d)",
1108 __FUNCTION__, port->number, status);
1109
1110 switch (status) {
1111 case 0:
1112 /* success */
1113 break;
1114 case -ECONNRESET:
1115 case -ENOENT:
1116 case -ESHUTDOWN:
1117 /* this urb is terminated, clean up */
1118 dbg("%s(): urb shutting down with status: %d",
1119 __FUNCTION__, status);
1120 priv->flags.write_urb_in_use = 0;
1121 return;
1122 default:
1123 /* error in the urb, so we have to resubmit it */
1124 dbg("%s(): nonzero write bulk status received: %d",
1125 __FUNCTION__, status);
1126 dbg("%s(): overflow in write", __FUNCTION__);
1127
1128 port->write_urb->transfer_buffer_length = 1;
1129 port->write_urb->dev = port->serial->dev;
1130 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
1131 if (result) {
1132 dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
1133 " error %d\n", __FUNCTION__, result);
1134 } else {
1135 return;
1136 }
1137 }
1138
1139 priv->flags.write_urb_in_use = 0;
1140
1141 // schedule the interrupt urb if we are still open */
1142 port->interrupt_in_urb->dev = port->serial->dev;
1143 dbg("%s(): submitting interrupt urb", __FUNCTION__);
1144 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
1145 if (result != 0) {
1146 dev_err(&port->dev, "%s(): failed submitting int urb,"
1147 " error %d\n", __FUNCTION__, result);
1148 }
1149}
1150
1151
1152/*
1153 * pl2303_buf_alloc
1154 *
1155 * Allocate a circular buffer and all associated memory.
1156 */
1157static struct pl2303_buf *pl2303_buf_alloc(unsigned int size)
1158{
1159 struct pl2303_buf *pb;
1160
1161 if (size == 0)
1162 return NULL;
1163
1164 pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
1165 if (pb == NULL)
1166 return NULL;
1167
1168 pb->buf_buf = kmalloc(size, GFP_KERNEL);
1169 if (pb->buf_buf == NULL) {
1170 kfree(pb);
1171 return NULL;
1172 }
1173
1174 pb->buf_size = size;
1175 pb->buf_get = pb->buf_put = pb->buf_buf;
1176
1177 return pb;
1178}
1179
1180/*
1181 * pl2303_buf_free
1182 *
1183 * Free the buffer and all associated memory.
1184 */
1185static void pl2303_buf_free(struct pl2303_buf *pb)
1186{
1187 if (pb) {
1188 kfree(pb->buf_buf);
1189 kfree(pb);
1190 }
1191}
1192
1193/*
1194 * pl2303_buf_clear
1195 *
1196 * Clear out all data in the circular buffer.
1197 */
1198static void pl2303_buf_clear(struct pl2303_buf *pb)
1199{
1200 if (pb != NULL) {
1201 /* equivalent to a get of all data available */
1202 pb->buf_get = pb->buf_put;
1203 }
1204}
1205
1206/*
1207 * pl2303_buf_data_avail
1208 *
1209 * Return the number of bytes of data available in the circular
1210 * buffer.
1211 */
1212static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb)
1213{
1214 if (pb == NULL)
1215 return 0;
1216 return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
1217}
1218
1219/*
1220 * pl2303_buf_space_avail
1221 *
1222 * Return the number of bytes of space available in the circular
1223 * buffer.
1224 */
1225static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb)
1226{
1227 if (pb == NULL)
1228 return 0;
1229 return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
1230}
1231
1232/*
1233 * pl2303_buf_put
1234 *
1235 * Copy data data from a user buffer and put it into the circular buffer.
1236 * Restrict to the amount of space available.
1237 *
1238 * Return the number of bytes copied.
1239 */
1240static unsigned int pl2303_buf_put(struct pl2303_buf *pb, const char *buf,
1241 unsigned int count)
1242{
1243 unsigned int len;
1244
1245 if (pb == NULL)
1246 return 0;
1247
1248 len = pl2303_buf_space_avail(pb);
1249 if (count > len)
1250 count = len;
1251
1252 if (count == 0)
1253 return 0;
1254
1255 len = pb->buf_buf + pb->buf_size - pb->buf_put;
1256 if (count > len) {
1257 memcpy(pb->buf_put, buf, len);
1258 memcpy(pb->buf_buf, buf+len, count - len);
1259 pb->buf_put = pb->buf_buf + count - len;
1260 } else {
1261 memcpy(pb->buf_put, buf, count);
1262 if (count < len)
1263 pb->buf_put += count;
1264 else /* count == len */
1265 pb->buf_put = pb->buf_buf;
1266 }
1267
1268 return count;
1269}
1270
1271/*
1272 * pl2303_buf_get
1273 *
1274 * Get data from the circular buffer and copy to the given buffer.
1275 * Restrict to the amount of data available.
1276 *
1277 * Return the number of bytes copied.
1278 */
1279static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf,
1280 unsigned int count)
1281{
1282 unsigned int len;
1283
1284 if (pb == NULL)
1285 return 0;
1286
1287 len = pl2303_buf_data_avail(pb);
1288 if (count > len)
1289 count = len;
1290
1291 if (count == 0)
1292 return 0;
1293
1294 len = pb->buf_buf + pb->buf_size - pb->buf_get;
1295 if (count > len) {
1296 memcpy(buf, pb->buf_get, len);
1297 memcpy(buf+len, pb->buf_buf, count - len);
1298 pb->buf_get = pb->buf_buf + count - len;
1299 } else {
1300 memcpy(buf, pb->buf_get, count);
1301 if (count < len)
1302 pb->buf_get += count;
1303 else /* count == len */
1304 pb->buf_get = pb->buf_buf;
1305 }
1306
1307 return count;
1308}
1309
1310/* module description and (de)initialization */
1311
1312static int __init oti6858_init(void)
1313{
1314 int retval;
1315
1316 if ((retval = usb_serial_register(&oti6858_device)) == 0) {
1317 if ((retval = usb_register(&oti6858_driver)) != 0)
1318 usb_serial_deregister(&oti6858_device);
1319 else
1320 return 0;
1321 }
1322
1323 return retval;
1324}
1325
1326static void __exit oti6858_exit(void)
1327{
1328 usb_deregister(&oti6858_driver);
1329 usb_serial_deregister(&oti6858_device);
1330}
1331
1332module_init(oti6858_init);
1333module_exit(oti6858_exit);
1334
1335MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
1336MODULE_AUTHOR(OTI6858_AUTHOR);
1337MODULE_VERSION(OTI6858_VERSION);
1338MODULE_LICENSE("GPL");
1339
1340module_param(debug, bool, S_IRUGO | S_IWUSR);
1341MODULE_PARM_DESC(debug, "enable debug output");
1342
diff --git a/drivers/usb/serial/oti6858.h b/drivers/usb/serial/oti6858.h
new file mode 100644
index 000000000000..704ac3a532b3
--- /dev/null
+++ b/drivers/usb/serial/oti6858.h
@@ -0,0 +1,15 @@
1/*
2 * Ours Technology Inc. OTi-6858 USB to serial adapter driver.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef __LINUX_USB_SERIAL_OTI6858_H
10#define __LINUX_USB_SERIAL_OTI6858_H
11
12#define OTI6858_VENDOR_ID 0x0ea0
13#define OTI6858_PRODUCT_ID 0x6858
14
15#endif
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 83dfae93a45d..f9f85f56f0db 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -1,14 +1,14 @@
1/* 1/*
2 * Prolific PL2303 USB to serial adaptor driver 2 * Prolific PL2303 USB to serial adaptor driver
3 * 3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2001-2007 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2003 IBM Corp. 5 * Copyright (C) 2003 IBM Corp.
6 * 6 *
7 * Original driver for 2.2.x by anonymous 7 * Original driver for 2.2.x by anonymous
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or
10 * it under the terms of the GNU General Public License as published by 10 * modify it under the terms of the GNU General Public License version
11 * the Free Software Foundation; either version 2 of the License. 11 * 2 as published by the Free Software Foundation.
12 * 12 *
13 * See Documentation/usb/usb-serial.txt for more information on using this driver 13 * See Documentation/usb/usb-serial.txt for more information on using this driver
14 * 14 *
@@ -484,15 +484,6 @@ static void pl2303_set_termios(struct usb_serial_port *port,
484 spin_unlock_irqrestore(&priv->lock, flags); 484 spin_unlock_irqrestore(&priv->lock, flags);
485 485
486 cflag = port->tty->termios->c_cflag; 486 cflag = port->tty->termios->c_cflag;
487 /* check that they really want us to change something */
488 if (old_termios) {
489 if ((cflag == old_termios->c_cflag) &&
490 (RELEVANT_IFLAG(port->tty->termios->c_iflag) ==
491 RELEVANT_IFLAG(old_termios->c_iflag))) {
492 dbg("%s - nothing to change...", __FUNCTION__);
493 return;
494 }
495 }
496 487
497 buf = kzalloc(7, GFP_KERNEL); 488 buf = kzalloc(7, GFP_KERNEL);
498 if (!buf) { 489 if (!buf) {
@@ -517,29 +508,7 @@ static void pl2303_set_termios(struct usb_serial_port *port,
517 dbg("%s - data bits = %d", __FUNCTION__, buf[6]); 508 dbg("%s - data bits = %d", __FUNCTION__, buf[6]);
518 } 509 }
519 510
520 baud = 0; 511 baud = tty_get_baud_rate(port->tty);;
521 switch (cflag & CBAUD) {
522 case B0: baud = 0; break;
523 case B75: baud = 75; break;
524 case B150: baud = 150; break;
525 case B300: baud = 300; break;
526 case B600: baud = 600; break;
527 case B1200: baud = 1200; break;
528 case B1800: baud = 1800; break;
529 case B2400: baud = 2400; break;
530 case B4800: baud = 4800; break;
531 case B9600: baud = 9600; break;
532 case B19200: baud = 19200; break;
533 case B38400: baud = 38400; break;
534 case B57600: baud = 57600; break;
535 case B115200: baud = 115200; break;
536 case B230400: baud = 230400; break;
537 case B460800: baud = 460800; break;
538 default:
539 dev_err(&port->dev, "pl2303 driver does not support"
540 " the baudrate requested (fix it)\n");
541 break;
542 }
543 dbg("%s - baud = %d", __FUNCTION__, baud); 512 dbg("%s - baud = %d", __FUNCTION__, baud);
544 if (baud) { 513 if (baud) {
545 buf[0] = baud & 0xff; 514 buf[0] = baud & 0xff;
@@ -617,6 +586,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
617 VENDOR_WRITE_REQUEST_TYPE, 586 VENDOR_WRITE_REQUEST_TYPE,
618 0x0, index, NULL, 0, 100); 587 0x0, index, NULL, 0, 100);
619 dbg("0x40:0x1:0x0:0x%x %d", index, i); 588 dbg("0x40:0x1:0x0:0x%x %d", index, i);
589 } else {
590 i = usb_control_msg(serial->dev,
591 usb_sndctrlpipe(serial->dev, 0),
592 VENDOR_WRITE_REQUEST,
593 VENDOR_WRITE_REQUEST_TYPE,
594 0x0, 0x0, NULL, 0, 100);
595 dbg ("0x40:0x1:0x0:0x0 %d", i);
620 } 596 }
621 597
622 kfree(buf); 598 kfree(buf);
@@ -954,11 +930,12 @@ static void pl2303_read_int_callback(struct urb *urb)
954 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 930 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
955 unsigned char *data = urb->transfer_buffer; 931 unsigned char *data = urb->transfer_buffer;
956 unsigned int actual_length = urb->actual_length; 932 unsigned int actual_length = urb->actual_length;
957 int status; 933 int status = urb->status;
934 int retval;
958 935
959 dbg("%s (%d)", __FUNCTION__, port->number); 936 dbg("%s (%d)", __FUNCTION__, port->number);
960 937
961 switch (urb->status) { 938 switch (status) {
962 case 0: 939 case 0:
963 /* success */ 940 /* success */
964 break; 941 break;
@@ -967,11 +944,11 @@ static void pl2303_read_int_callback(struct urb *urb)
967 case -ESHUTDOWN: 944 case -ESHUTDOWN:
968 /* this urb is terminated, clean up */ 945 /* this urb is terminated, clean up */
969 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 946 dbg("%s - urb shutting down with status: %d", __FUNCTION__,
970 urb->status); 947 status);
971 return; 948 return;
972 default: 949 default:
973 dbg("%s - nonzero urb status received: %d", __FUNCTION__, 950 dbg("%s - nonzero urb status received: %d", __FUNCTION__,
974 urb->status); 951 status);
975 goto exit; 952 goto exit;
976 } 953 }
977 954
@@ -981,11 +958,11 @@ static void pl2303_read_int_callback(struct urb *urb)
981 pl2303_update_line_status(port, data, actual_length); 958 pl2303_update_line_status(port, data, actual_length);
982 959
983exit: 960exit:
984 status = usb_submit_urb(urb, GFP_ATOMIC); 961 retval = usb_submit_urb(urb, GFP_ATOMIC);
985 if (status) 962 if (retval)
986 dev_err(&urb->dev->dev, 963 dev_err(&urb->dev->dev,
987 "%s - usb_submit_urb failed with result %d\n", 964 "%s - usb_submit_urb failed with result %d\n",
988 __FUNCTION__, status); 965 __FUNCTION__, retval);
989} 966}
990 967
991static void pl2303_read_bulk_callback(struct urb *urb) 968static void pl2303_read_bulk_callback(struct urb *urb)
@@ -997,23 +974,23 @@ static void pl2303_read_bulk_callback(struct urb *urb)
997 unsigned long flags; 974 unsigned long flags;
998 int i; 975 int i;
999 int result; 976 int result;
1000 u8 status; 977 int status = urb->status;
978 u8 line_status;
1001 char tty_flag; 979 char tty_flag;
1002 980
1003 dbg("%s - port %d", __FUNCTION__, port->number); 981 dbg("%s - port %d", __FUNCTION__, port->number);
1004 982
1005 if (urb->status) { 983 if (status) {
1006 dbg("%s - urb->status = %d", __FUNCTION__, urb->status); 984 dbg("%s - urb status = %d", __FUNCTION__, status);
1007 if (!port->open_count) { 985 if (!port->open_count) {
1008 dbg("%s - port is closed, exiting.", __FUNCTION__); 986 dbg("%s - port is closed, exiting.", __FUNCTION__);
1009 return; 987 return;
1010 } 988 }
1011 if (urb->status == -EPROTO) { 989 if (status == -EPROTO) {
1012 /* PL2303 mysteriously fails with -EPROTO reschedule 990 /* PL2303 mysteriously fails with -EPROTO reschedule
1013 * the read */ 991 * the read */
1014 dbg("%s - caught -EPROTO, resubmitting the urb", 992 dbg("%s - caught -EPROTO, resubmitting the urb",
1015 __FUNCTION__); 993 __FUNCTION__);
1016 urb->status = 0;
1017 urb->dev = port->serial->dev; 994 urb->dev = port->serial->dev;
1018 result = usb_submit_urb(urb, GFP_ATOMIC); 995 result = usb_submit_urb(urb, GFP_ATOMIC);
1019 if (result) 996 if (result)
@@ -1033,18 +1010,18 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1033 tty_flag = TTY_NORMAL; 1010 tty_flag = TTY_NORMAL;
1034 1011
1035 spin_lock_irqsave(&priv->lock, flags); 1012 spin_lock_irqsave(&priv->lock, flags);
1036 status = priv->line_status; 1013 line_status = priv->line_status;
1037 priv->line_status &= ~UART_STATE_TRANSIENT_MASK; 1014 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
1038 spin_unlock_irqrestore(&priv->lock, flags); 1015 spin_unlock_irqrestore(&priv->lock, flags);
1039 wake_up_interruptible(&priv->delta_msr_wait); 1016 wake_up_interruptible(&priv->delta_msr_wait);
1040 1017
1041 /* break takes precedence over parity, */ 1018 /* break takes precedence over parity, */
1042 /* which takes precedence over framing errors */ 1019 /* which takes precedence over framing errors */
1043 if (status & UART_BREAK_ERROR ) 1020 if (line_status & UART_BREAK_ERROR )
1044 tty_flag = TTY_BREAK; 1021 tty_flag = TTY_BREAK;
1045 else if (status & UART_PARITY_ERROR) 1022 else if (line_status & UART_PARITY_ERROR)
1046 tty_flag = TTY_PARITY; 1023 tty_flag = TTY_PARITY;
1047 else if (status & UART_FRAME_ERROR) 1024 else if (line_status & UART_FRAME_ERROR)
1048 tty_flag = TTY_FRAME; 1025 tty_flag = TTY_FRAME;
1049 dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag); 1026 dbg("%s - tty_flag = %d", __FUNCTION__, tty_flag);
1050 1027
@@ -1052,7 +1029,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1052 if (tty && urb->actual_length) { 1029 if (tty && urb->actual_length) {
1053 tty_buffer_request_room(tty, urb->actual_length + 1); 1030 tty_buffer_request_room(tty, urb->actual_length + 1);
1054 /* overrun is special, not associated with a char */ 1031 /* overrun is special, not associated with a char */
1055 if (status & UART_OVERRUN_ERROR) 1032 if (line_status & UART_OVERRUN_ERROR)
1056 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1033 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1057 for (i = 0; i < urb->actual_length; ++i) 1034 for (i = 0; i < urb->actual_length; ++i)
1058 tty_insert_flip_char(tty, data[i], tty_flag); 1035 tty_insert_flip_char(tty, data[i], tty_flag);
@@ -1076,10 +1053,11 @@ static void pl2303_write_bulk_callback(struct urb *urb)
1076 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 1053 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
1077 struct pl2303_private *priv = usb_get_serial_port_data(port); 1054 struct pl2303_private *priv = usb_get_serial_port_data(port);
1078 int result; 1055 int result;
1056 int status = urb->status;
1079 1057
1080 dbg("%s - port %d", __FUNCTION__, port->number); 1058 dbg("%s - port %d", __FUNCTION__, port->number);
1081 1059
1082 switch (urb->status) { 1060 switch (status) {
1083 case 0: 1061 case 0:
1084 /* success */ 1062 /* success */
1085 break; 1063 break;
@@ -1088,14 +1066,14 @@ static void pl2303_write_bulk_callback(struct urb *urb)
1088 case -ESHUTDOWN: 1066 case -ESHUTDOWN:
1089 /* this urb is terminated, clean up */ 1067 /* this urb is terminated, clean up */
1090 dbg("%s - urb shutting down with status: %d", __FUNCTION__, 1068 dbg("%s - urb shutting down with status: %d", __FUNCTION__,
1091 urb->status); 1069 status);
1092 priv->write_urb_in_use = 0; 1070 priv->write_urb_in_use = 0;
1093 return; 1071 return;
1094 default: 1072 default:
1095 /* error in the urb, so we have to resubmit it */ 1073 /* error in the urb, so we have to resubmit it */
1096 dbg("%s - Overflow in write", __FUNCTION__); 1074 dbg("%s - Overflow in write", __FUNCTION__);
1097 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, 1075 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__,
1098 urb->status); 1076 status);
1099 port->write_urb->transfer_buffer_length = 1; 1077 port->write_urb->transfer_buffer_length = 1;
1100 port->write_urb->dev = port->serial->dev; 1078 port->write_urb->dev = port->serial->dev;
1101 result = usb_submit_urb(port->write_urb, GFP_ATOMIC); 1079 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 5a03a3fc9386..86899d55d8d8 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -211,11 +211,13 @@ static void safe_read_bulk_callback (struct urb *urb)
211 unsigned char length = urb->actual_length; 211 unsigned char length = urb->actual_length;
212 int i; 212 int i;
213 int result; 213 int result;
214 int status = urb->status;
214 215
215 dbg ("%s", __FUNCTION__); 216 dbg ("%s", __FUNCTION__);
216 217
217 if (urb->status) { 218 if (status) {
218 dbg ("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 219 dbg("%s - nonzero read bulk status received: %d",
220 __FUNCTION__, status);
219 return; 221 return;
220 } 222 }
221 223
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ac1829c6e8f0..e7db20343d1a 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -86,15 +86,14 @@ static int debug;
86#define N_IN_URB 4 86#define N_IN_URB 4
87#define N_OUT_URB 4 87#define N_OUT_URB 4
88#define IN_BUFLEN 4096 88#define IN_BUFLEN 4096
89#define OUT_BUFLEN 128
90 89
91struct sierra_port_private { 90struct sierra_port_private {
91 spinlock_t lock; /* lock the structure */
92 int outstanding_urbs; /* number of out urbs in flight */
93
92 /* Input endpoints and buffer for this port */ 94 /* Input endpoints and buffer for this port */
93 struct urb *in_urbs[N_IN_URB]; 95 struct urb *in_urbs[N_IN_URB];
94 char in_buffer[N_IN_URB][IN_BUFLEN]; 96 char in_buffer[N_IN_URB][IN_BUFLEN];
95 /* Output endpoints and buffer for this port */
96 struct urb *out_urbs[N_OUT_URB];
97 char out_buffer[N_OUT_URB][OUT_BUFLEN];
98 97
99 /* Settings for the port */ 98 /* Settings for the port */
100 int rts_state; /* Handshaking pins (outputs) */ 99 int rts_state; /* Handshaking pins (outputs) */
@@ -103,8 +102,6 @@ struct sierra_port_private {
103 int dsr_state; 102 int dsr_state;
104 int dcd_state; 103 int dcd_state;
105 int ri_state; 104 int ri_state;
106
107 unsigned long tx_start_time[N_OUT_URB];
108}; 105};
109 106
110static int sierra_send_setup(struct usb_serial_port *port) 107static int sierra_send_setup(struct usb_serial_port *port)
@@ -197,61 +194,98 @@ static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
197 return -ENOIOCTLCMD; 194 return -ENOIOCTLCMD;
198} 195}
199 196
197static void sierra_outdat_callback(struct urb *urb)
198{
199 struct usb_serial_port *port = urb->context;
200 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
201 int status = urb->status;
202 unsigned long flags;
203
204 dbg("%s - port %d", __FUNCTION__, port->number);
205
206 /* free up the transfer buffer, as usb_free_urb() does not do this */
207 kfree(urb->transfer_buffer);
208
209 if (status)
210 dbg("%s - nonzero write bulk status received: %d",
211 __FUNCTION__, status);
212
213 spin_lock_irqsave(&portdata->lock, flags);
214 --portdata->outstanding_urbs;
215 spin_unlock_irqrestore(&portdata->lock, flags);
216
217 usb_serial_port_softint(port);
218}
219
200/* Write */ 220/* Write */
201static int sierra_write(struct usb_serial_port *port, 221static int sierra_write(struct usb_serial_port *port,
202 const unsigned char *buf, int count) 222 const unsigned char *buf, int count)
203{ 223{
204 struct sierra_port_private *portdata; 224 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
205 int i; 225 struct usb_serial *serial = port->serial;
206 int left, todo; 226 unsigned long flags;
207 struct urb *this_urb = NULL; /* spurious */ 227 unsigned char *buffer;
208 int err; 228 struct urb *urb;
229 int status;
209 230
210 portdata = usb_get_serial_port_data(port); 231 portdata = usb_get_serial_port_data(port);
211 232
212 dbg("%s: write (%d chars)", __FUNCTION__, count); 233 dbg("%s: write (%d chars)", __FUNCTION__, count);
213 234
214 i = 0; 235 spin_lock_irqsave(&portdata->lock, flags);
215 left = count; 236 if (portdata->outstanding_urbs > N_OUT_URB) {
216 for (i=0; left > 0 && i < N_OUT_URB; i++) { 237 spin_unlock_irqrestore(&portdata->lock, flags);
217 todo = left; 238 dbg("%s - write limit hit\n", __FUNCTION__);
218 if (todo > OUT_BUFLEN) 239 return 0;
219 todo = OUT_BUFLEN; 240 }
220 241 portdata->outstanding_urbs++;
221 this_urb = portdata->out_urbs[i]; 242 spin_unlock_irqrestore(&portdata->lock, flags);
222 if (this_urb->status == -EINPROGRESS) { 243
223 if (time_before(jiffies, 244 buffer = kmalloc(count, GFP_ATOMIC);
224 portdata->tx_start_time[i] + 10 * HZ)) 245 if (!buffer) {
225 continue; 246 dev_err(&port->dev, "out of memory\n");
226 usb_unlink_urb(this_urb); 247 count = -ENOMEM;
227 continue; 248 goto error_no_buffer;
228 } 249 }
229 if (this_urb->status != 0) 250
230 dbg("usb_write %p failed (err=%d)", 251 urb = usb_alloc_urb(0, GFP_ATOMIC);
231 this_urb, this_urb->status); 252 if (!urb) {
232 253 dev_err(&port->dev, "no more free urbs\n");
233 dbg("%s: endpoint %d buf %d", __FUNCTION__, 254 count = -ENOMEM;
234 usb_pipeendpoint(this_urb->pipe), i); 255 goto error_no_urb;
235 256 }
236 /* send the data */ 257
237 memcpy (this_urb->transfer_buffer, buf, todo); 258 memcpy(buffer, buf, count);
238 this_urb->transfer_buffer_length = todo; 259
239 260 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
240 this_urb->dev = port->serial->dev; 261
241 err = usb_submit_urb(this_urb, GFP_ATOMIC); 262 usb_fill_bulk_urb(urb, serial->dev,
242 if (err) { 263 usb_sndbulkpipe(serial->dev,
243 dbg("usb_submit_urb %p (write bulk) failed " 264 port->bulk_out_endpointAddress),
244 "(%d, has %d)", this_urb, 265 buffer, count, sierra_outdat_callback, port);
245 err, this_urb->status); 266
246 continue; 267 /* send it down the pipe */
247 } 268 status = usb_submit_urb(urb, GFP_ATOMIC);
248 portdata->tx_start_time[i] = jiffies; 269 if (status) {
249 buf += todo; 270 dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
250 left -= todo; 271 "with status = %d\n", __FUNCTION__, status);
272 count = status;
273 goto error;
251 } 274 }
252 275
253 count -= left; 276 /* we are done with this urb, so let the host driver
254 dbg("%s: wrote (did %d)", __FUNCTION__, count); 277 * really free it when it is finished with it */
278 usb_free_urb(urb);
279
280 return count;
281error:
282 usb_free_urb(urb);
283error_no_urb:
284 kfree(buffer);
285error_no_buffer:
286 spin_lock_irqsave(&portdata->lock, flags);
287 --portdata->outstanding_urbs;
288 spin_unlock_irqrestore(&portdata->lock, flags);
255 return count; 289 return count;
256} 290}
257 291
@@ -262,15 +296,16 @@ static void sierra_indat_callback(struct urb *urb)
262 struct usb_serial_port *port; 296 struct usb_serial_port *port;
263 struct tty_struct *tty; 297 struct tty_struct *tty;
264 unsigned char *data = urb->transfer_buffer; 298 unsigned char *data = urb->transfer_buffer;
299 int status = urb->status;
265 300
266 dbg("%s: %p", __FUNCTION__, urb); 301 dbg("%s: %p", __FUNCTION__, urb);
267 302
268 endpoint = usb_pipeendpoint(urb->pipe); 303 endpoint = usb_pipeendpoint(urb->pipe);
269 port = (struct usb_serial_port *) urb->context; 304 port = (struct usb_serial_port *) urb->context;
270 305
271 if (urb->status) { 306 if (status) {
272 dbg("%s: nonzero status: %d on endpoint %02x.", 307 dbg("%s: nonzero status: %d on endpoint %02x.",
273 __FUNCTION__, urb->status, endpoint); 308 __FUNCTION__, status, endpoint);
274 } else { 309 } else {
275 tty = port->tty; 310 tty = port->tty;
276 if (urb->actual_length) { 311 if (urb->actual_length) {
@@ -282,30 +317,20 @@ static void sierra_indat_callback(struct urb *urb)
282 } 317 }
283 318
284 /* Resubmit urb so we continue receiving */ 319 /* Resubmit urb so we continue receiving */
285 if (port->open_count && urb->status != -ESHUTDOWN) { 320 if (port->open_count && status != -ESHUTDOWN) {
286 err = usb_submit_urb(urb, GFP_ATOMIC); 321 err = usb_submit_urb(urb, GFP_ATOMIC);
287 if (err) 322 if (err)
288 printk(KERN_ERR "%s: resubmit read urb failed. " 323 dev_err(&port->dev, "resubmit read urb failed."
289 "(%d)", __FUNCTION__, err); 324 "(%d)", err);
290 } 325 }
291 } 326 }
292 return; 327 return;
293} 328}
294 329
295static void sierra_outdat_callback(struct urb *urb)
296{
297 struct usb_serial_port *port;
298
299 dbg("%s", __FUNCTION__);
300
301 port = (struct usb_serial_port *) urb->context;
302
303 usb_serial_port_softint(port);
304}
305
306static void sierra_instat_callback(struct urb *urb) 330static void sierra_instat_callback(struct urb *urb)
307{ 331{
308 int err; 332 int err;
333 int status = urb->status;
309 struct usb_serial_port *port = (struct usb_serial_port *) urb->context; 334 struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
310 struct sierra_port_private *portdata = usb_get_serial_port_data(port); 335 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
311 struct usb_serial *serial = port->serial; 336 struct usb_serial *serial = port->serial;
@@ -313,7 +338,7 @@ static void sierra_instat_callback(struct urb *urb)
313 dbg("%s", __FUNCTION__); 338 dbg("%s", __FUNCTION__);
314 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); 339 dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
315 340
316 if (urb->status == 0) { 341 if (status == 0) {
317 struct usb_ctrlrequest *req_pkt = 342 struct usb_ctrlrequest *req_pkt =
318 (struct usb_ctrlrequest *)urb->transfer_buffer; 343 (struct usb_ctrlrequest *)urb->transfer_buffer;
319 344
@@ -344,10 +369,10 @@ static void sierra_instat_callback(struct urb *urb)
344 req_pkt->bRequestType,req_pkt->bRequest); 369 req_pkt->bRequestType,req_pkt->bRequest);
345 } 370 }
346 } else 371 } else
347 dbg("%s: error %d", __FUNCTION__, urb->status); 372 dbg("%s: error %d", __FUNCTION__, status);
348 373
349 /* Resubmit urb so we continue receiving IRQ data */ 374 /* Resubmit urb so we continue receiving IRQ data */
350 if (urb->status != -ESHUTDOWN) { 375 if (status != -ESHUTDOWN) {
351 urb->dev = serial->dev; 376 urb->dev = serial->dev;
352 err = usb_submit_urb(urb, GFP_ATOMIC); 377 err = usb_submit_urb(urb, GFP_ATOMIC);
353 if (err) 378 if (err)
@@ -358,46 +383,42 @@ static void sierra_instat_callback(struct urb *urb)
358 383
359static int sierra_write_room(struct usb_serial_port *port) 384static int sierra_write_room(struct usb_serial_port *port)
360{ 385{
361 struct sierra_port_private *portdata; 386 struct sierra_port_private *portdata = usb_get_serial_port_data(port);
362 int i; 387 unsigned long flags;
363 int data_len = 0;
364 struct urb *this_urb;
365 388
366 portdata = usb_get_serial_port_data(port); 389 dbg("%s - port %d", __FUNCTION__, port->number);
367 390
368 for (i=0; i < N_OUT_URB; i++) { 391 /* try to give a good number back based on if we have any free urbs at
369 this_urb = portdata->out_urbs[i]; 392 * this point in time */
370 if (this_urb && this_urb->status != -EINPROGRESS) 393 spin_lock_irqsave(&portdata->lock, flags);
371 data_len += OUT_BUFLEN; 394 if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
395 spin_unlock_irqrestore(&portdata->lock, flags);
396 dbg("%s - write limit hit\n", __FUNCTION__);
397 return 0;
372 } 398 }
399 spin_unlock_irqrestore(&portdata->lock, flags);
373 400
374 dbg("%s: %d", __FUNCTION__, data_len); 401 return 2048;
375 return data_len;
376} 402}
377 403
378static int sierra_chars_in_buffer(struct usb_serial_port *port) 404static int sierra_chars_in_buffer(struct usb_serial_port *port)
379{ 405{
380 struct sierra_port_private *portdata; 406 dbg("%s - port %d", __FUNCTION__, port->number);
381 int i; 407
382 int data_len = 0; 408 /*
383 struct urb *this_urb; 409 * We can't really account for how much data we
384 410 * have sent out, but hasn't made it through to the
385 portdata = usb_get_serial_port_data(port); 411 * device as we can't see the backend here, so just
386 412 * tell the tty layer that everything is flushed.
387 for (i=0; i < N_OUT_URB; i++) { 413 */
388 this_urb = portdata->out_urbs[i]; 414 return 0;
389 if (this_urb && this_urb->status == -EINPROGRESS)
390 data_len += this_urb->transfer_buffer_length;
391 }
392 dbg("%s: %d", __FUNCTION__, data_len);
393 return data_len;
394} 415}
395 416
396static int sierra_open(struct usb_serial_port *port, struct file *filp) 417static int sierra_open(struct usb_serial_port *port, struct file *filp)
397{ 418{
398 struct sierra_port_private *portdata; 419 struct sierra_port_private *portdata;
399 struct usb_serial *serial = port->serial; 420 struct usb_serial *serial = port->serial;
400 int i, err; 421 int i;
401 struct urb *urb; 422 struct urb *urb;
402 int result; 423 int result;
403 __u16 set_mode_dzero = 0x0000; 424 __u16 set_mode_dzero = 0x0000;
@@ -413,7 +434,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
413 /* Reset low level data toggle and start reading from endpoints */ 434 /* Reset low level data toggle and start reading from endpoints */
414 for (i = 0; i < N_IN_URB; i++) { 435 for (i = 0; i < N_IN_URB; i++) {
415 urb = portdata->in_urbs[i]; 436 urb = portdata->in_urbs[i];
416 if (! urb) 437 if (!urb)
417 continue; 438 continue;
418 if (urb->dev != serial->dev) { 439 if (urb->dev != serial->dev) {
419 dbg("%s: dev %p != %p", __FUNCTION__, 440 dbg("%s: dev %p != %p", __FUNCTION__,
@@ -427,24 +448,13 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
427 */ 448 */
428 usb_clear_halt(urb->dev, urb->pipe); 449 usb_clear_halt(urb->dev, urb->pipe);
429 450
430 err = usb_submit_urb(urb, GFP_KERNEL); 451 result = usb_submit_urb(urb, GFP_KERNEL);
431 if (err) { 452 if (result) {
432 dbg("%s: submit urb %d failed (%d) %d", 453 dev_err(&port->dev, "submit urb %d failed (%d) %d",
433 __FUNCTION__, i, err, 454 i, result, urb->transfer_buffer_length);
434 urb->transfer_buffer_length);
435 } 455 }
436 } 456 }
437 457
438 /* Reset low level data toggle on out endpoints */
439 for (i = 0; i < N_OUT_URB; i++) {
440 urb = portdata->out_urbs[i];
441 if (! urb)
442 continue;
443 urb->dev = serial->dev;
444 /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
445 usb_pipeout(urb->pipe), 0); */
446 }
447
448 port->tty->low_latency = 1; 458 port->tty->low_latency = 1;
449 459
450 /* set mode to D0 */ 460 /* set mode to D0 */
@@ -455,7 +465,14 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
455 465
456 sierra_send_setup(port); 466 sierra_send_setup(port);
457 467
458 return (0); 468 /* start up the interrupt endpoint if we have one */
469 if (port->interrupt_in_urb) {
470 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
471 if (result)
472 dev_err(&port->dev, "submit irq_in urb failed %d",
473 result);
474 }
475 return 0;
459} 476}
460 477
461static void sierra_close(struct usb_serial_port *port, struct file *filp) 478static void sierra_close(struct usb_serial_port *port, struct file *filp)
@@ -475,71 +492,21 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
475 492
476 /* Stop reading/writing urbs */ 493 /* Stop reading/writing urbs */
477 for (i = 0; i < N_IN_URB; i++) 494 for (i = 0; i < N_IN_URB; i++)
478 usb_unlink_urb(portdata->in_urbs[i]); 495 usb_kill_urb(portdata->in_urbs[i]);
479 for (i = 0; i < N_OUT_URB; i++)
480 usb_unlink_urb(portdata->out_urbs[i]);
481 } 496 }
482 port->tty = NULL;
483}
484
485/* Helper functions used by sierra_setup_urbs */
486static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
487 int dir, void *ctx, char *buf, int len,
488 usb_complete_t callback)
489{
490 struct urb *urb;
491
492 if (endpoint == -1)
493 return NULL; /* endpoint not needed */
494
495 urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
496 if (urb == NULL) {
497 dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
498 return NULL;
499 }
500
501 /* Fill URB using supplied data. */
502 usb_fill_bulk_urb(urb, serial->dev,
503 usb_sndbulkpipe(serial->dev, endpoint) | dir,
504 buf, len, callback, ctx);
505
506 return urb;
507}
508 497
509/* Setup urbs */ 498 usb_kill_urb(port->interrupt_in_urb);
510static void sierra_setup_urbs(struct usb_serial *serial)
511{
512 int i,j;
513 struct usb_serial_port *port;
514 struct sierra_port_private *portdata;
515
516 dbg("%s", __FUNCTION__);
517 499
518 for (i = 0; i < serial->num_ports; i++) { 500 port->tty = NULL;
519 port = serial->port[i];
520 portdata = usb_get_serial_port_data(port);
521
522 /* Do indat endpoints first */
523 for (j = 0; j < N_IN_URB; ++j) {
524 portdata->in_urbs[j] = sierra_setup_urb (serial,
525 port->bulk_in_endpointAddress, USB_DIR_IN, port,
526 portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback);
527 }
528
529 /* outdat endpoints */
530 for (j = 0; j < N_OUT_URB; ++j) {
531 portdata->out_urbs[j] = sierra_setup_urb (serial,
532 port->bulk_out_endpointAddress, USB_DIR_OUT, port,
533 portdata->out_buffer[j], OUT_BUFLEN, sierra_outdat_callback);
534 }
535 }
536} 501}
537 502
538static int sierra_startup(struct usb_serial *serial) 503static int sierra_startup(struct usb_serial *serial)
539{ 504{
540 int i, err;
541 struct usb_serial_port *port; 505 struct usb_serial_port *port;
542 struct sierra_port_private *portdata; 506 struct sierra_port_private *portdata;
507 struct urb *urb;
508 int i;
509 int j;
543 510
544 dbg("%s", __FUNCTION__); 511 dbg("%s", __FUNCTION__);
545 512
@@ -550,22 +517,31 @@ static int sierra_startup(struct usb_serial *serial)
550 if (!portdata) { 517 if (!portdata) {
551 dbg("%s: kmalloc for sierra_port_private (%d) failed!.", 518 dbg("%s: kmalloc for sierra_port_private (%d) failed!.",
552 __FUNCTION__, i); 519 __FUNCTION__, i);
553 return (1); 520 return -ENOMEM;
554 } 521 }
522 spin_lock_init(&portdata->lock);
555 523
556 usb_set_serial_port_data(port, portdata); 524 usb_set_serial_port_data(port, portdata);
557 525
558 if (! port->interrupt_in_urb) 526 /* initialize the in urbs */
559 continue; 527 for (j = 0; j < N_IN_URB; ++j) {
560 err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 528 urb = usb_alloc_urb(0, GFP_KERNEL);
561 if (err) 529 if (urb == NULL) {
562 dbg("%s: submit irq_in urb failed %d", 530 dbg("%s: alloc for in port failed.",
563 __FUNCTION__, err); 531 __FUNCTION__);
532 continue;
533 }
534 /* Fill URB using supplied data. */
535 usb_fill_bulk_urb(urb, serial->dev,
536 usb_rcvbulkpipe(serial->dev,
537 port->bulk_in_endpointAddress),
538 portdata->in_buffer[j], IN_BUFLEN,
539 sierra_indat_callback, port);
540 portdata->in_urbs[j] = urb;
541 }
564 } 542 }
565 543
566 sierra_setup_urbs(serial); 544 return 0;
567
568 return (0);
569} 545}
570 546
571static void sierra_shutdown(struct usb_serial *serial) 547static void sierra_shutdown(struct usb_serial *serial)
@@ -576,22 +552,6 @@ static void sierra_shutdown(struct usb_serial *serial)
576 552
577 dbg("%s", __FUNCTION__); 553 dbg("%s", __FUNCTION__);
578 554
579 /* Stop reading/writing urbs */
580 for (i = 0; i < serial->num_ports; ++i) {
581 port = serial->port[i];
582 if (!port)
583 continue;
584 portdata = usb_get_serial_port_data(port);
585 if (!portdata)
586 continue;
587
588 for (j = 0; j < N_IN_URB; j++)
589 usb_unlink_urb(portdata->in_urbs[j]);
590 for (j = 0; j < N_OUT_URB; j++)
591 usb_unlink_urb(portdata->out_urbs[j]);
592 }
593
594 /* Now free them */
595 for (i = 0; i < serial->num_ports; ++i) { 555 for (i = 0; i < serial->num_ports; ++i) {
596 port = serial->port[i]; 556 port = serial->port[i];
597 if (!port) 557 if (!port)
@@ -601,25 +561,12 @@ static void sierra_shutdown(struct usb_serial *serial)
601 continue; 561 continue;
602 562
603 for (j = 0; j < N_IN_URB; j++) { 563 for (j = 0; j < N_IN_URB; j++) {
604 if (portdata->in_urbs[j]) { 564 usb_kill_urb(portdata->in_urbs[j]);
605 usb_free_urb(portdata->in_urbs[j]); 565 usb_free_urb(portdata->in_urbs[j]);
606 portdata->in_urbs[j] = NULL; 566 portdata->in_urbs[j] = NULL;
607 }
608 } 567 }
609 for (j = 0; j < N_OUT_URB; j++) { 568 kfree(portdata);
610 if (portdata->out_urbs[j]) { 569 usb_set_serial_port_data(port, NULL);
611 usb_free_urb(portdata->out_urbs[j]);
612 portdata->out_urbs[j] = NULL;
613 }
614 }
615 }
616
617 /* Now free per port private data */
618 for (i = 0; i < serial->num_ports; i++) {
619 port = serial->port[i];
620 if (!port)
621 continue;
622 kfree(usb_get_serial_port_data(port));
623 } 570 }
624} 571}
625 572
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 3d505fd0645b..f98626ae75fe 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1112,22 +1112,24 @@ static void ti_interrupt_callback(struct urb *urb)
1112 int length = urb->actual_length; 1112 int length = urb->actual_length;
1113 int port_number; 1113 int port_number;
1114 int function; 1114 int function;
1115 int status; 1115 int status = urb->status;
1116 int retval;
1116 __u8 msr; 1117 __u8 msr;
1117 1118
1118 dbg("%s", __FUNCTION__); 1119 dbg("%s", __FUNCTION__);
1119 1120
1120 switch (urb->status) { 1121 switch (status) {
1121 case 0: 1122 case 0:
1122 break; 1123 break;
1123 case -ECONNRESET: 1124 case -ECONNRESET:
1124 case -ENOENT: 1125 case -ENOENT:
1125 case -ESHUTDOWN: 1126 case -ESHUTDOWN:
1126 dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status); 1127 dbg("%s - urb shutting down, %d", __FUNCTION__, status);
1127 tdev->td_urb_error = 1; 1128 tdev->td_urb_error = 1;
1128 return; 1129 return;
1129 default: 1130 default:
1130 dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status); 1131 dev_err(dev, "%s - nonzero urb status, %d\n",
1132 __FUNCTION__, status);
1131 tdev->td_urb_error = 1; 1133 tdev->td_urb_error = 1;
1132 goto exit; 1134 goto exit;
1133 } 1135 }
@@ -1175,9 +1177,10 @@ static void ti_interrupt_callback(struct urb *urb)
1175 } 1177 }
1176 1178
1177exit: 1179exit:
1178 status = usb_submit_urb(urb, GFP_ATOMIC); 1180 retval = usb_submit_urb(urb, GFP_ATOMIC);
1179 if (status) 1181 if (retval)
1180 dev_err(dev, "%s - resubmit interrupt urb failed, %d\n", __FUNCTION__, status); 1182 dev_err(dev, "%s - resubmit interrupt urb failed, %d\n",
1183 __FUNCTION__, retval);
1181} 1184}
1182 1185
1183 1186
@@ -1186,30 +1189,32 @@ static void ti_bulk_in_callback(struct urb *urb)
1186 struct ti_port *tport = (struct ti_port *)urb->context; 1189 struct ti_port *tport = (struct ti_port *)urb->context;
1187 struct usb_serial_port *port = tport->tp_port; 1190 struct usb_serial_port *port = tport->tp_port;
1188 struct device *dev = &urb->dev->dev; 1191 struct device *dev = &urb->dev->dev;
1189 int status = 0; 1192 int status = urb->status;
1193 int retval = 0;
1190 1194
1191 dbg("%s", __FUNCTION__); 1195 dbg("%s", __FUNCTION__);
1192 1196
1193 switch (urb->status) { 1197 switch (status) {
1194 case 0: 1198 case 0:
1195 break; 1199 break;
1196 case -ECONNRESET: 1200 case -ECONNRESET:
1197 case -ENOENT: 1201 case -ENOENT:
1198 case -ESHUTDOWN: 1202 case -ESHUTDOWN:
1199 dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status); 1203 dbg("%s - urb shutting down, %d", __FUNCTION__, status);
1200 tport->tp_tdev->td_urb_error = 1; 1204 tport->tp_tdev->td_urb_error = 1;
1201 wake_up_interruptible(&tport->tp_write_wait); 1205 wake_up_interruptible(&tport->tp_write_wait);
1202 return; 1206 return;
1203 default: 1207 default:
1204 dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status ); 1208 dev_err(dev, "%s - nonzero urb status, %d\n",
1209 __FUNCTION__, status );
1205 tport->tp_tdev->td_urb_error = 1; 1210 tport->tp_tdev->td_urb_error = 1;
1206 wake_up_interruptible(&tport->tp_write_wait); 1211 wake_up_interruptible(&tport->tp_write_wait);
1207 } 1212 }
1208 1213
1209 if (urb->status == -EPIPE) 1214 if (status == -EPIPE)
1210 goto exit; 1215 goto exit;
1211 1216
1212 if (urb->status) { 1217 if (status) {
1213 dev_err(dev, "%s - stopping read!\n", __FUNCTION__); 1218 dev_err(dev, "%s - stopping read!\n", __FUNCTION__);
1214 return; 1219 return;
1215 } 1220 }
@@ -1234,13 +1239,14 @@ exit:
1234 spin_lock(&tport->tp_lock); 1239 spin_lock(&tport->tp_lock);
1235 if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) { 1240 if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) {
1236 urb->dev = port->serial->dev; 1241 urb->dev = port->serial->dev;
1237 status = usb_submit_urb(urb, GFP_ATOMIC); 1242 retval = usb_submit_urb(urb, GFP_ATOMIC);
1238 } else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) { 1243 } else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) {
1239 tport->tp_read_urb_state = TI_READ_URB_STOPPED; 1244 tport->tp_read_urb_state = TI_READ_URB_STOPPED;
1240 } 1245 }
1241 spin_unlock(&tport->tp_lock); 1246 spin_unlock(&tport->tp_lock);
1242 if (status) 1247 if (retval)
1243 dev_err(dev, "%s - resubmit read urb failed, %d\n", __FUNCTION__, status); 1248 dev_err(dev, "%s - resubmit read urb failed, %d\n",
1249 __FUNCTION__, retval);
1244} 1250}
1245 1251
1246 1252
@@ -1249,23 +1255,25 @@ static void ti_bulk_out_callback(struct urb *urb)
1249 struct ti_port *tport = (struct ti_port *)urb->context; 1255 struct ti_port *tport = (struct ti_port *)urb->context;
1250 struct usb_serial_port *port = tport->tp_port; 1256 struct usb_serial_port *port = tport->tp_port;
1251 struct device *dev = &urb->dev->dev; 1257 struct device *dev = &urb->dev->dev;
1258 int status = urb->status;
1252 1259
1253 dbg("%s - port %d", __FUNCTION__, port->number); 1260 dbg("%s - port %d", __FUNCTION__, port->number);
1254 1261
1255 tport->tp_write_urb_in_use = 0; 1262 tport->tp_write_urb_in_use = 0;
1256 1263
1257 switch (urb->status) { 1264 switch (status) {
1258 case 0: 1265 case 0:
1259 break; 1266 break;
1260 case -ECONNRESET: 1267 case -ECONNRESET:
1261 case -ENOENT: 1268 case -ENOENT:
1262 case -ESHUTDOWN: 1269 case -ESHUTDOWN:
1263 dbg("%s - urb shutting down, %d", __FUNCTION__, urb->status); 1270 dbg("%s - urb shutting down, %d", __FUNCTION__, status);
1264 tport->tp_tdev->td_urb_error = 1; 1271 tport->tp_tdev->td_urb_error = 1;
1265 wake_up_interruptible(&tport->tp_write_wait); 1272 wake_up_interruptible(&tport->tp_write_wait);
1266 return; 1273 return;
1267 default: 1274 default:
1268 dev_err(dev, "%s - nonzero urb status, %d\n", __FUNCTION__, urb->status); 1275 dev_err(dev, "%s - nonzero urb status, %d\n",
1276 __FUNCTION__, status);
1269 tport->tp_tdev->td_urb_error = 1; 1277 tport->tp_tdev->td_urb_error = 1;
1270 wake_up_interruptible(&tport->tp_write_wait); 1278 wake_up_interruptible(&tport->tp_write_wait);
1271 } 1279 }
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 87f378806db6..a3665659d13b 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -46,6 +46,8 @@ static struct usb_driver usb_serial_driver = {
46 .name = "usbserial", 46 .name = "usbserial",
47 .probe = usb_serial_probe, 47 .probe = usb_serial_probe,
48 .disconnect = usb_serial_disconnect, 48 .disconnect = usb_serial_disconnect,
49 .suspend = usb_serial_suspend,
50 .resume = usb_serial_resume,
49 .no_dynamic_id = 1, 51 .no_dynamic_id = 1,
50}; 52};
51 53
@@ -120,11 +122,9 @@ static void return_serial(struct usb_serial *serial)
120 if (serial == NULL) 122 if (serial == NULL)
121 return; 123 return;
122 124
123 spin_lock(&table_lock);
124 for (i = 0; i < serial->num_ports; ++i) { 125 for (i = 0; i < serial->num_ports; ++i) {
125 serial_table[serial->minor + i] = NULL; 126 serial_table[serial->minor + i] = NULL;
126 } 127 }
127 spin_unlock(&table_lock);
128} 128}
129 129
130static void destroy_serial(struct kref *kref) 130static void destroy_serial(struct kref *kref)
@@ -172,7 +172,9 @@ static void destroy_serial(struct kref *kref)
172 172
173void usb_serial_put(struct usb_serial *serial) 173void usb_serial_put(struct usb_serial *serial)
174{ 174{
175 spin_lock(&table_lock);
175 kref_put(&serial->kref, destroy_serial); 176 kref_put(&serial->kref, destroy_serial);
177 spin_unlock(&table_lock);
176} 178}
177 179
178/***************************************************************************** 180/*****************************************************************************
@@ -1069,6 +1071,35 @@ void usb_serial_disconnect(struct usb_interface *interface)
1069 dev_info(dev, "device disconnected\n"); 1071 dev_info(dev, "device disconnected\n");
1070} 1072}
1071 1073
1074int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
1075{
1076 struct usb_serial *serial = usb_get_intfdata(intf);
1077 struct usb_serial_port *port;
1078 int i, r = 0;
1079
1080 if (serial) {
1081 for (i = 0; i < serial->num_ports; ++i) {
1082 port = serial->port[i];
1083 if (port)
1084 kill_traffic(port);
1085 }
1086 }
1087
1088 if (serial->type->suspend)
1089 serial->type->suspend(serial, message);
1090
1091 return r;
1092}
1093EXPORT_SYMBOL(usb_serial_suspend);
1094
1095int usb_serial_resume(struct usb_interface *intf)
1096{
1097 struct usb_serial *serial = usb_get_intfdata(intf);
1098
1099 return serial->type->resume(serial);
1100}
1101EXPORT_SYMBOL(usb_serial_resume);
1102
1072static const struct tty_operations serial_ops = { 1103static const struct tty_operations serial_ops = {
1073 .open = serial_open, 1104 .open = serial_open,
1074 .close = serial_close, 1105 .close = serial_close,
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index ffbe601cde2a..7d84a7647e81 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -5,9 +5,9 @@
5 * Copyright (C) 1999 - 2004 5 * Copyright (C) 1999 - 2004
6 * Greg Kroah-Hartman (greg@kroah.com) 6 * Greg Kroah-Hartman (greg@kroah.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or
9 * it under the terms of the GNU General Public License as published by 9 * modify it under the terms of the GNU General Public License version
10 * the Free Software Foundation; either version 2 of the License. 10 * 2 as published by the Free Software Foundation.
11 * 11 *
12 * See Documentation/usb/usb-serial.txt for more information on using this driver 12 * See Documentation/usb/usb-serial.txt for more information on using this driver
13 * 13 *
@@ -273,7 +273,8 @@ struct visor_private {
273 int bytes_in; 273 int bytes_in;
274 int bytes_out; 274 int bytes_out;
275 int outstanding_urbs; 275 int outstanding_urbs;
276 int throttled; 276 unsigned char throttled;
277 unsigned char actually_throttled;
277}; 278};
278 279
279/* number of outstanding urbs to prevent userspace DoS from happening */ 280/* number of outstanding urbs to prevent userspace DoS from happening */
@@ -484,16 +485,17 @@ static void visor_write_bulk_callback (struct urb *urb)
484{ 485{
485 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 486 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
486 struct visor_private *priv = usb_get_serial_port_data(port); 487 struct visor_private *priv = usb_get_serial_port_data(port);
488 int status = urb->status;
487 unsigned long flags; 489 unsigned long flags;
488 490
489 /* free up the transfer buffer, as usb_free_urb() does not do this */ 491 /* free up the transfer buffer, as usb_free_urb() does not do this */
490 kfree (urb->transfer_buffer); 492 kfree (urb->transfer_buffer);
491 493
492 dbg("%s - port %d", __FUNCTION__, port->number); 494 dbg("%s - port %d", __FUNCTION__, port->number);
493 495
494 if (urb->status) 496 if (status)
495 dbg("%s - nonzero write bulk status received: %d", 497 dbg("%s - nonzero write bulk status received: %d",
496 __FUNCTION__, urb->status); 498 __FUNCTION__, status);
497 499
498 spin_lock_irqsave(&priv->lock, flags); 500 spin_lock_irqsave(&priv->lock, flags);
499 --priv->outstanding_urbs; 501 --priv->outstanding_urbs;
@@ -508,15 +510,16 @@ static void visor_read_bulk_callback (struct urb *urb)
508 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 510 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
509 struct visor_private *priv = usb_get_serial_port_data(port); 511 struct visor_private *priv = usb_get_serial_port_data(port);
510 unsigned char *data = urb->transfer_buffer; 512 unsigned char *data = urb->transfer_buffer;
513 int status = urb->status;
511 struct tty_struct *tty; 514 struct tty_struct *tty;
512 unsigned long flags;
513 int throttled;
514 int result; 515 int result;
516 int available_room;
515 517
516 dbg("%s - port %d", __FUNCTION__, port->number); 518 dbg("%s - port %d", __FUNCTION__, port->number);
517 519
518 if (urb->status) { 520 if (status) {
519 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 521 dbg("%s - nonzero read bulk status received: %d",
522 __FUNCTION__, status);
520 return; 523 return;
521 } 524 }
522 525
@@ -524,17 +527,20 @@ static void visor_read_bulk_callback (struct urb *urb)
524 527
525 tty = port->tty; 528 tty = port->tty;
526 if (tty && urb->actual_length) { 529 if (tty && urb->actual_length) {
527 tty_buffer_request_room(tty, urb->actual_length); 530 available_room = tty_buffer_request_room(tty, urb->actual_length);
528 tty_insert_flip_string(tty, data, urb->actual_length); 531 if (available_room) {
529 tty_flip_buffer_push(tty); 532 tty_insert_flip_string(tty, data, available_room);
533 tty_flip_buffer_push(tty);
534 }
535 spin_lock(&priv->lock);
536 priv->bytes_in += available_room;
537
538 } else {
539 spin_lock(&priv->lock);
530 } 540 }
531 spin_lock_irqsave(&priv->lock, flags);
532 priv->bytes_in += urb->actual_length;
533 throttled = priv->throttled;
534 spin_unlock_irqrestore(&priv->lock, flags);
535 541
536 /* Continue trying to always read if we should */ 542 /* Continue trying to always read if we should */
537 if (!throttled) { 543 if (!priv->throttled) {
538 usb_fill_bulk_urb (port->read_urb, port->serial->dev, 544 usb_fill_bulk_urb (port->read_urb, port->serial->dev,
539 usb_rcvbulkpipe(port->serial->dev, 545 usb_rcvbulkpipe(port->serial->dev,
540 port->bulk_in_endpointAddress), 546 port->bulk_in_endpointAddress),
@@ -544,16 +550,19 @@ static void visor_read_bulk_callback (struct urb *urb)
544 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 550 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
545 if (result) 551 if (result)
546 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 552 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
553 } else {
554 priv->actually_throttled = 1;
547 } 555 }
548 return; 556 spin_unlock(&priv->lock);
549} 557}
550 558
551static void visor_read_int_callback (struct urb *urb) 559static void visor_read_int_callback (struct urb *urb)
552{ 560{
553 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 561 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
562 int status = urb->status;
554 int result; 563 int result;
555 564
556 switch (urb->status) { 565 switch (status) {
557 case 0: 566 case 0:
558 /* success */ 567 /* success */
559 break; 568 break;
@@ -562,11 +571,11 @@ static void visor_read_int_callback (struct urb *urb)
562 case -ESHUTDOWN: 571 case -ESHUTDOWN:
563 /* this urb is terminated, clean up */ 572 /* this urb is terminated, clean up */
564 dbg("%s - urb shutting down with status: %d", 573 dbg("%s - urb shutting down with status: %d",
565 __FUNCTION__, urb->status); 574 __FUNCTION__, status);
566 return; 575 return;
567 default: 576 default:
568 dbg("%s - nonzero urb status received: %d", 577 dbg("%s - nonzero urb status received: %d",
569 __FUNCTION__, urb->status); 578 __FUNCTION__, status);
570 goto exit; 579 goto exit;
571 } 580 }
572 581
@@ -608,6 +617,7 @@ static void visor_unthrottle (struct usb_serial_port *port)
608 dbg("%s - port %d", __FUNCTION__, port->number); 617 dbg("%s - port %d", __FUNCTION__, port->number);
609 spin_lock_irqsave(&priv->lock, flags); 618 spin_lock_irqsave(&priv->lock, flags);
610 priv->throttled = 0; 619 priv->throttled = 0;
620 priv->actually_throttled = 0;
611 spin_unlock_irqrestore(&priv->lock, flags); 621 spin_unlock_irqrestore(&priv->lock, flags);
612 622
613 port->read_urb->dev = port->serial->dev; 623 port->read_urb->dev = port->serial->dev;
@@ -938,14 +948,6 @@ static void visor_set_termios (struct usb_serial_port *port, struct ktermios *ol
938 } 948 }
939 949
940 cflag = port->tty->termios->c_cflag; 950 cflag = port->tty->termios->c_cflag;
941 /* check that they really want us to change something */
942 if (old_termios) {
943 if ((cflag == old_termios->c_cflag) &&
944 (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
945 dbg("%s - nothing to change...", __FUNCTION__);
946 return;
947 }
948 }
949 951
950 /* get the byte size */ 952 /* get the byte size */
951 switch (cflag & CSIZE) { 953 switch (cflag & CSIZE) {
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 27c5f8f9a2d5..cc8b44c08712 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -74,6 +74,7 @@
74#include <linux/tty_flip.h> 74#include <linux/tty_flip.h>
75#include <linux/module.h> 75#include <linux/module.h>
76#include <linux/spinlock.h> 76#include <linux/spinlock.h>
77#include <linux/mutex.h>
77#include <asm/uaccess.h> 78#include <asm/uaccess.h>
78#include <asm/termbits.h> 79#include <asm/termbits.h>
79#include <linux/usb.h> 80#include <linux/usb.h>
@@ -203,7 +204,7 @@ static struct usb_serial_driver whiteheat_device = {
203 204
204 205
205struct whiteheat_command_private { 206struct whiteheat_command_private {
206 spinlock_t lock; 207 struct mutex mutex;
207 __u8 port_running; 208 __u8 port_running;
208 __u8 command_finished; 209 __u8 command_finished;
209 wait_queue_head_t wait_command; /* for handling sleeping while waiting for a command to finish */ 210 wait_queue_head_t wait_command; /* for handling sleeping while waiting for a command to finish */
@@ -232,6 +233,7 @@ struct whiteheat_private {
232 struct usb_serial_port *port; 233 struct usb_serial_port *port;
233 struct list_head tx_urbs_free; 234 struct list_head tx_urbs_free;
234 struct list_head tx_urbs_submitted; 235 struct list_head tx_urbs_submitted;
236 struct mutex deathwarrant;
235}; 237};
236 238
237 239
@@ -425,6 +427,7 @@ static int whiteheat_attach (struct usb_serial *serial)
425 } 427 }
426 428
427 spin_lock_init(&info->lock); 429 spin_lock_init(&info->lock);
430 mutex_init(&info->deathwarrant);
428 info->flags = 0; 431 info->flags = 0;
429 info->mcr = 0; 432 info->mcr = 0;
430 INIT_WORK(&info->rx_work, rx_data_softint); 433 INIT_WORK(&info->rx_work, rx_data_softint);
@@ -495,7 +498,7 @@ static int whiteheat_attach (struct usb_serial *serial)
495 goto no_command_private; 498 goto no_command_private;
496 } 499 }
497 500
498 spin_lock_init(&command_info->lock); 501 mutex_init(&command_info->mutex);
499 command_info->port_running = 0; 502 command_info->port_running = 0;
500 init_waitqueue_head(&command_info->wait_command); 503 init_waitqueue_head(&command_info->wait_command);
501 usb_set_serial_port_data(command_port, command_info); 504 usb_set_serial_port_data(command_port, command_info);
@@ -654,7 +657,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
654 struct urb *urb; 657 struct urb *urb;
655 struct list_head *tmp; 658 struct list_head *tmp;
656 struct list_head *tmp2; 659 struct list_head *tmp2;
657 unsigned long flags;
658 660
659 dbg("%s - port %d", __FUNCTION__, port->number); 661 dbg("%s - port %d", __FUNCTION__, port->number);
660 662
@@ -683,24 +685,32 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
683 685
684 firm_close(port); 686 firm_close(port);
685 687
688printk(KERN_ERR"Before processing rx_urbs_submitted.\n");
686 /* shutdown our bulk reads and writes */ 689 /* shutdown our bulk reads and writes */
687 spin_lock_irqsave(&info->lock, flags); 690 mutex_lock(&info->deathwarrant);
691 spin_lock_irq(&info->lock);
688 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { 692 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
689 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); 693 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
690 urb = wrap->urb; 694 urb = wrap->urb;
695 list_del(tmp);
696 spin_unlock_irq(&info->lock);
691 usb_kill_urb(urb); 697 usb_kill_urb(urb);
692 list_move(tmp, &info->rx_urbs_free); 698 spin_lock_irq(&info->lock);
699 list_add(tmp, &info->rx_urbs_free);
693 } 700 }
694 list_for_each_safe(tmp, tmp2, &info->rx_urb_q) 701 list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
695 list_move(tmp, &info->rx_urbs_free); 702 list_move(tmp, &info->rx_urbs_free);
696
697 list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) { 703 list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
698 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); 704 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
699 urb = wrap->urb; 705 urb = wrap->urb;
706 list_del(tmp);
707 spin_unlock_irq(&info->lock);
700 usb_kill_urb(urb); 708 usb_kill_urb(urb);
701 list_move(tmp, &info->tx_urbs_free); 709 spin_lock_irq(&info->lock);
710 list_add(tmp, &info->tx_urbs_free);
702 } 711 }
703 spin_unlock_irqrestore(&info->lock, flags); 712 spin_unlock_irq(&info->lock);
713 mutex_unlock(&info->deathwarrant);
704 714
705 stop_command_port(port->serial); 715 stop_command_port(port->serial);
706 716
@@ -872,7 +882,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
872} 882}
873 883
874 884
875static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) 885static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
876{ 886{
877 dbg("%s -port %d", __FUNCTION__, port->number); 887 dbg("%s -port %d", __FUNCTION__, port->number);
878 888
@@ -881,15 +891,6 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios
881 goto exit; 891 goto exit;
882 } 892 }
883 893
884 /* check that they really want us to change something */
885 if (old_termios) {
886 if ((port->tty->termios->c_cflag == old_termios->c_cflag) &&
887 (port->tty->termios->c_iflag == old_termios->c_iflag)) {
888 dbg("%s - nothing to change...", __FUNCTION__);
889 goto exit;
890 }
891 }
892
893 firm_setup_port(port); 894 firm_setup_port(port);
894 895
895exit: 896exit:
@@ -920,7 +921,7 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
920 spin_unlock_irqrestore(&info->lock, flags); 921 spin_unlock_irqrestore(&info->lock, flags);
921 922
922 dbg ("%s - returns %d", __FUNCTION__, chars); 923 dbg ("%s - returns %d", __FUNCTION__, chars);
923 return (chars); 924 return chars;
924} 925}
925 926
926 927
@@ -962,54 +963,57 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
962/***************************************************************************** 963/*****************************************************************************
963 * Connect Tech's White Heat callback routines 964 * Connect Tech's White Heat callback routines
964 *****************************************************************************/ 965 *****************************************************************************/
965static void command_port_write_callback (struct urb *urb) 966static void command_port_write_callback(struct urb *urb)
966{ 967{
968 int status = urb->status;
969
967 dbg("%s", __FUNCTION__); 970 dbg("%s", __FUNCTION__);
968 971
969 if (urb->status) { 972 if (status) {
970 dbg ("nonzero urb status: %d", urb->status); 973 dbg("nonzero urb status: %d", status);
971 return; 974 return;
972 } 975 }
973} 976}
974 977
975 978
976static void command_port_read_callback (struct urb *urb) 979static void command_port_read_callback(struct urb *urb)
977{ 980{
978 struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context; 981 struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
979 struct whiteheat_command_private *command_info; 982 struct whiteheat_command_private *command_info;
983 int status = urb->status;
980 unsigned char *data = urb->transfer_buffer; 984 unsigned char *data = urb->transfer_buffer;
981 int result; 985 int result;
982 unsigned long flags;
983 986
984 dbg("%s", __FUNCTION__); 987 dbg("%s", __FUNCTION__);
985 988
986 if (urb->status) {
987 dbg("%s - nonzero urb status: %d", __FUNCTION__, urb->status);
988 return;
989 }
990
991 usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data);
992
993 command_info = usb_get_serial_port_data(command_port); 989 command_info = usb_get_serial_port_data(command_port);
994 if (!command_info) { 990 if (!command_info) {
995 dbg ("%s - command_info is NULL, exiting.", __FUNCTION__); 991 dbg ("%s - command_info is NULL, exiting.", __FUNCTION__);
996 return; 992 return;
997 } 993 }
998 spin_lock_irqsave(&command_info->lock, flags); 994 if (status) {
995 dbg("%s - nonzero urb status: %d", __FUNCTION__, status);
996 if (status != -ENOENT)
997 command_info->command_finished = WHITEHEAT_CMD_FAILURE;
998 wake_up(&command_info->wait_command);
999 return;
1000 }
1001
1002 usb_serial_debug_data(debug, &command_port->dev, __FUNCTION__, urb->actual_length, data);
999 1003
1000 if (data[0] == WHITEHEAT_CMD_COMPLETE) { 1004 if (data[0] == WHITEHEAT_CMD_COMPLETE) {
1001 command_info->command_finished = WHITEHEAT_CMD_COMPLETE; 1005 command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
1002 wake_up_interruptible(&command_info->wait_command); 1006 wake_up(&command_info->wait_command);
1003 } else if (data[0] == WHITEHEAT_CMD_FAILURE) { 1007 } else if (data[0] == WHITEHEAT_CMD_FAILURE) {
1004 command_info->command_finished = WHITEHEAT_CMD_FAILURE; 1008 command_info->command_finished = WHITEHEAT_CMD_FAILURE;
1005 wake_up_interruptible(&command_info->wait_command); 1009 wake_up(&command_info->wait_command);
1006 } else if (data[0] == WHITEHEAT_EVENT) { 1010 } else if (data[0] == WHITEHEAT_EVENT) {
1007 /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */ 1011 /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
1008 dbg("%s - event received", __FUNCTION__); 1012 dbg("%s - event received", __FUNCTION__);
1009 } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { 1013 } else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
1010 memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1); 1014 memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
1011 command_info->command_finished = WHITEHEAT_CMD_COMPLETE; 1015 command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
1012 wake_up_interruptible(&command_info->wait_command); 1016 wake_up(&command_info->wait_command);
1013 } else { 1017 } else {
1014 dbg("%s - bad reply from firmware", __FUNCTION__); 1018 dbg("%s - bad reply from firmware", __FUNCTION__);
1015 } 1019 }
@@ -1017,7 +1021,6 @@ static void command_port_read_callback (struct urb *urb)
1017 /* Continue trying to always read */ 1021 /* Continue trying to always read */
1018 command_port->read_urb->dev = command_port->serial->dev; 1022 command_port->read_urb->dev = command_port->serial->dev;
1019 result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC); 1023 result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
1020 spin_unlock_irqrestore(&command_info->lock, flags);
1021 if (result) 1024 if (result)
1022 dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); 1025 dbg("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
1023} 1026}
@@ -1029,6 +1032,7 @@ static void whiteheat_read_callback(struct urb *urb)
1029 struct whiteheat_urb_wrap *wrap; 1032 struct whiteheat_urb_wrap *wrap;
1030 unsigned char *data = urb->transfer_buffer; 1033 unsigned char *data = urb->transfer_buffer;
1031 struct whiteheat_private *info = usb_get_serial_port_data(port); 1034 struct whiteheat_private *info = usb_get_serial_port_data(port);
1035 int status = urb->status;
1032 1036
1033 dbg("%s - port %d", __FUNCTION__, port->number); 1037 dbg("%s - port %d", __FUNCTION__, port->number);
1034 1038
@@ -1042,8 +1046,9 @@ static void whiteheat_read_callback(struct urb *urb)
1042 list_del(&wrap->list); 1046 list_del(&wrap->list);
1043 spin_unlock(&info->lock); 1047 spin_unlock(&info->lock);
1044 1048
1045 if (urb->status) { 1049 if (status) {
1046 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 1050 dbg("%s - nonzero read bulk status received: %d",
1051 __FUNCTION__, status);
1047 spin_lock(&info->lock); 1052 spin_lock(&info->lock);
1048 list_add(&wrap->list, &info->rx_urbs_free); 1053 list_add(&wrap->list, &info->rx_urbs_free);
1049 spin_unlock(&info->lock); 1054 spin_unlock(&info->lock);
@@ -1070,6 +1075,7 @@ static void whiteheat_write_callback(struct urb *urb)
1070 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1075 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1071 struct whiteheat_private *info = usb_get_serial_port_data(port); 1076 struct whiteheat_private *info = usb_get_serial_port_data(port);
1072 struct whiteheat_urb_wrap *wrap; 1077 struct whiteheat_urb_wrap *wrap;
1078 int status = urb->status;
1073 1079
1074 dbg("%s - port %d", __FUNCTION__, port->number); 1080 dbg("%s - port %d", __FUNCTION__, port->number);
1075 1081
@@ -1083,8 +1089,9 @@ static void whiteheat_write_callback(struct urb *urb)
1083 list_move(&wrap->list, &info->tx_urbs_free); 1089 list_move(&wrap->list, &info->tx_urbs_free);
1084 spin_unlock(&info->lock); 1090 spin_unlock(&info->lock);
1085 1091
1086 if (urb->status) { 1092 if (status) {
1087 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 1093 dbg("%s - nonzero write bulk status received: %d",
1094 __FUNCTION__, status);
1088 return; 1095 return;
1089 } 1096 }
1090 1097
@@ -1095,20 +1102,20 @@ static void whiteheat_write_callback(struct urb *urb)
1095/***************************************************************************** 1102/*****************************************************************************
1096 * Connect Tech's White Heat firmware interface 1103 * Connect Tech's White Heat firmware interface
1097 *****************************************************************************/ 1104 *****************************************************************************/
1098static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize) 1105static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize)
1099{ 1106{
1100 struct usb_serial_port *command_port; 1107 struct usb_serial_port *command_port;
1101 struct whiteheat_command_private *command_info; 1108 struct whiteheat_command_private *command_info;
1102 struct whiteheat_private *info; 1109 struct whiteheat_private *info;
1103 __u8 *transfer_buffer; 1110 __u8 *transfer_buffer;
1104 int retval = 0; 1111 int retval = 0;
1105 unsigned long flags; 1112 int t;
1106 1113
1107 dbg("%s - command %d", __FUNCTION__, command); 1114 dbg("%s - command %d", __FUNCTION__, command);
1108 1115
1109 command_port = port->serial->port[COMMAND_PORT]; 1116 command_port = port->serial->port[COMMAND_PORT];
1110 command_info = usb_get_serial_port_data(command_port); 1117 command_info = usb_get_serial_port_data(command_port);
1111 spin_lock_irqsave(&command_info->lock, flags); 1118 mutex_lock(&command_info->mutex);
1112 command_info->command_finished = false; 1119 command_info->command_finished = false;
1113 1120
1114 transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer; 1121 transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
@@ -1116,18 +1123,17 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *
1116 memcpy (&transfer_buffer[1], data, datasize); 1123 memcpy (&transfer_buffer[1], data, datasize);
1117 command_port->write_urb->transfer_buffer_length = datasize + 1; 1124 command_port->write_urb->transfer_buffer_length = datasize + 1;
1118 command_port->write_urb->dev = port->serial->dev; 1125 command_port->write_urb->dev = port->serial->dev;
1119 retval = usb_submit_urb (command_port->write_urb, GFP_KERNEL); 1126 retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
1120 if (retval) { 1127 if (retval) {
1121 dbg("%s - submit urb failed", __FUNCTION__); 1128 dbg("%s - submit urb failed", __FUNCTION__);
1122 goto exit; 1129 goto exit;
1123 } 1130 }
1124 spin_unlock_irqrestore(&command_info->lock, flags);
1125 1131
1126 /* wait for the command to complete */ 1132 /* wait for the command to complete */
1127 wait_event_interruptible_timeout(command_info->wait_command, 1133 t = wait_event_timeout(command_info->wait_command,
1128 (bool)command_info->command_finished, COMMAND_TIMEOUT); 1134 (bool)command_info->command_finished, COMMAND_TIMEOUT);
1129 1135 if (!t)
1130 spin_lock_irqsave(&command_info->lock, flags); 1136 usb_kill_urb(command_port->write_urb);
1131 1137
1132 if (command_info->command_finished == false) { 1138 if (command_info->command_finished == false) {
1133 dbg("%s - command timed out.", __FUNCTION__); 1139 dbg("%s - command timed out.", __FUNCTION__);
@@ -1152,7 +1158,7 @@ static int firm_send_command (struct usb_serial_port *port, __u8 command, __u8 *
1152 } 1158 }
1153 1159
1154exit: 1160exit:
1155 spin_unlock_irqrestore(&command_info->lock, flags); 1161 mutex_unlock(&command_info->mutex);
1156 return retval; 1162 return retval;
1157} 1163}
1158 1164
@@ -1305,12 +1311,11 @@ static int start_command_port(struct usb_serial *serial)
1305{ 1311{
1306 struct usb_serial_port *command_port; 1312 struct usb_serial_port *command_port;
1307 struct whiteheat_command_private *command_info; 1313 struct whiteheat_command_private *command_info;
1308 unsigned long flags;
1309 int retval = 0; 1314 int retval = 0;
1310 1315
1311 command_port = serial->port[COMMAND_PORT]; 1316 command_port = serial->port[COMMAND_PORT];
1312 command_info = usb_get_serial_port_data(command_port); 1317 command_info = usb_get_serial_port_data(command_port);
1313 spin_lock_irqsave(&command_info->lock, flags); 1318 mutex_lock(&command_info->mutex);
1314 if (!command_info->port_running) { 1319 if (!command_info->port_running) {
1315 /* Work around HCD bugs */ 1320 /* Work around HCD bugs */
1316 usb_clear_halt(serial->dev, command_port->read_urb->pipe); 1321 usb_clear_halt(serial->dev, command_port->read_urb->pipe);
@@ -1325,7 +1330,7 @@ static int start_command_port(struct usb_serial *serial)
1325 command_info->port_running++; 1330 command_info->port_running++;
1326 1331
1327exit: 1332exit:
1328 spin_unlock_irqrestore(&command_info->lock, flags); 1333 mutex_unlock(&command_info->mutex);
1329 return retval; 1334 return retval;
1330} 1335}
1331 1336
@@ -1334,15 +1339,14 @@ static void stop_command_port(struct usb_serial *serial)
1334{ 1339{
1335 struct usb_serial_port *command_port; 1340 struct usb_serial_port *command_port;
1336 struct whiteheat_command_private *command_info; 1341 struct whiteheat_command_private *command_info;
1337 unsigned long flags;
1338 1342
1339 command_port = serial->port[COMMAND_PORT]; 1343 command_port = serial->port[COMMAND_PORT];
1340 command_info = usb_get_serial_port_data(command_port); 1344 command_info = usb_get_serial_port_data(command_port);
1341 spin_lock_irqsave(&command_info->lock, flags); 1345 mutex_lock(&command_info->mutex);
1342 command_info->port_running--; 1346 command_info->port_running--;
1343 if (!command_info->port_running) 1347 if (!command_info->port_running)
1344 usb_kill_urb(command_port->read_urb); 1348 usb_kill_urb(command_port->read_urb);
1345 spin_unlock_irqrestore(&command_info->lock, flags); 1349 mutex_unlock(&command_info->mutex);
1346} 1350}
1347 1351
1348 1352
@@ -1363,17 +1367,23 @@ static int start_port_read(struct usb_serial_port *port)
1363 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); 1367 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1364 urb = wrap->urb; 1368 urb = wrap->urb;
1365 urb->dev = port->serial->dev; 1369 urb->dev = port->serial->dev;
1370 spin_unlock_irqrestore(&info->lock, flags);
1366 retval = usb_submit_urb(urb, GFP_KERNEL); 1371 retval = usb_submit_urb(urb, GFP_KERNEL);
1367 if (retval) { 1372 if (retval) {
1373 spin_lock_irqsave(&info->lock, flags);
1368 list_add(tmp, &info->rx_urbs_free); 1374 list_add(tmp, &info->rx_urbs_free);
1369 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) { 1375 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
1370 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list); 1376 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1371 urb = wrap->urb; 1377 urb = wrap->urb;
1378 list_del(tmp);
1379 spin_unlock_irqrestore(&info->lock, flags);
1372 usb_kill_urb(urb); 1380 usb_kill_urb(urb);
1373 list_move(tmp, &info->rx_urbs_free); 1381 spin_lock_irqsave(&info->lock, flags);
1382 list_add(tmp, &info->rx_urbs_free);
1374 } 1383 }
1375 break; 1384 break;
1376 } 1385 }
1386 spin_lock_irqsave(&info->lock, flags);
1377 list_add(tmp, &info->rx_urbs_submitted); 1387 list_add(tmp, &info->rx_urbs_submitted);
1378 } 1388 }
1379 1389