diff options
Diffstat (limited to 'drivers/usb/serial/io_edgeport.c')
-rw-r--r-- | drivers/usb/serial/io_edgeport.c | 417 |
1 files changed, 327 insertions, 90 deletions
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index f623d58370a4..6a26a2e683a6 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -146,6 +146,8 @@ struct edgeport_serial { | |||
146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ | 146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ |
147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ | 147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ |
148 | struct edgeport_product_info product_info; /* Product Info */ | 148 | struct edgeport_product_info product_info; /* Product Info */ |
149 | struct edge_compatibility_descriptor epic_descriptor; /* Edgeport compatible descriptor */ | ||
150 | int is_epic; /* flag if EPiC device or not */ | ||
149 | 151 | ||
150 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ | 152 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ |
151 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ | 153 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ |
@@ -240,14 +242,6 @@ static void edge_shutdown (struct usb_serial *serial); | |||
240 | 242 | ||
241 | #include "io_tables.h" /* all of the devices that this driver supports */ | 243 | #include "io_tables.h" /* all of the devices that this driver supports */ |
242 | 244 | ||
243 | static struct usb_driver io_driver = { | ||
244 | .name = "io_edgeport", | ||
245 | .probe = usb_serial_probe, | ||
246 | .disconnect = usb_serial_disconnect, | ||
247 | .id_table = id_table_combined, | ||
248 | .no_dynamic_id = 1, | ||
249 | }; | ||
250 | |||
251 | /* function prototypes for all of our local functions */ | 245 | /* function prototypes for all of our local functions */ |
252 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); | 246 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); |
253 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); | 247 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); |
@@ -397,6 +391,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) | |||
397 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); | 391 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); |
398 | 392 | ||
399 | kfree(pStringDesc); | 393 | kfree(pStringDesc); |
394 | dbg("%s - USB String %s", __FUNCTION__, string); | ||
400 | return strlen(string); | 395 | return strlen(string); |
401 | } | 396 | } |
402 | 397 | ||
@@ -434,6 +429,34 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de | |||
434 | } | 429 | } |
435 | #endif | 430 | #endif |
436 | 431 | ||
432 | static void dump_product_info(struct edgeport_product_info *product_info) | ||
433 | { | ||
434 | // Dump Product Info structure | ||
435 | dbg("**Product Information:"); | ||
436 | dbg(" ProductId %x", product_info->ProductId ); | ||
437 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
438 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
439 | dbg(" IsServer %d", product_info->IsServer); | ||
440 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
441 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
442 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
443 | dbg(" RomSize %d", product_info->RomSize ); | ||
444 | dbg(" RamSize %d", product_info->RamSize ); | ||
445 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
446 | dbg(" BoardRev %x", product_info->BoardRev); | ||
447 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
448 | product_info->BootMinorVersion, | ||
449 | le16_to_cpu(product_info->BootBuildNumber)); | ||
450 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
451 | product_info->FirmwareMinorVersion, | ||
452 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
453 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
454 | product_info->ManufactureDescDate[1], | ||
455 | product_info->ManufactureDescDate[2]+1900); | ||
456 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
457 | dbg(" EpicVer %d", product_info->EpicVer); | ||
458 | } | ||
459 | |||
437 | static void get_product_info(struct edgeport_serial *edge_serial) | 460 | static void get_product_info(struct edgeport_serial *edge_serial) |
438 | { | 461 | { |
439 | struct edgeport_product_info *product_info = &edge_serial->product_info; | 462 | struct edgeport_product_info *product_info = &edge_serial->product_info; |
@@ -495,30 +518,60 @@ static void get_product_info(struct edgeport_serial *edge_serial) | |||
495 | break; | 518 | break; |
496 | } | 519 | } |
497 | 520 | ||
498 | // Dump Product Info structure | 521 | dump_product_info(product_info); |
499 | dbg("**Product Information:"); | 522 | } |
500 | dbg(" ProductId %x", product_info->ProductId ); | ||
501 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
502 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
503 | dbg(" IsServer %d", product_info->IsServer); | ||
504 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
505 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
506 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
507 | dbg(" RomSize %d", product_info->RomSize ); | ||
508 | dbg(" RamSize %d", product_info->RamSize ); | ||
509 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
510 | dbg(" BoardRev %x", product_info->BoardRev); | ||
511 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
512 | product_info->BootMinorVersion, | ||
513 | le16_to_cpu(product_info->BootBuildNumber)); | ||
514 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
515 | product_info->FirmwareMinorVersion, | ||
516 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
517 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
518 | product_info->ManufactureDescDate[1], | ||
519 | product_info->ManufactureDescDate[2]+1900); | ||
520 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
521 | 523 | ||
524 | static int get_epic_descriptor(struct edgeport_serial *ep) | ||
525 | { | ||
526 | int result; | ||
527 | struct usb_serial *serial = ep->serial; | ||
528 | struct edgeport_product_info *product_info = &ep->product_info; | ||
529 | struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; | ||
530 | struct edge_compatibility_bits *bits; | ||
531 | |||
532 | ep->is_epic = 0; | ||
533 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
534 | USB_REQUEST_ION_GET_EPIC_DESC, | ||
535 | 0xC0, 0x00, 0x00, | ||
536 | &ep->epic_descriptor, | ||
537 | sizeof(struct edge_compatibility_descriptor), | ||
538 | 300); | ||
539 | |||
540 | dbg("%s result = %d", __FUNCTION__, result); | ||
541 | |||
542 | if (result > 0) { | ||
543 | ep->is_epic = 1; | ||
544 | memset(product_info, 0, sizeof(struct edgeport_product_info)); | ||
545 | |||
546 | product_info->NumPorts = epic->NumPorts; | ||
547 | product_info->ProdInfoVer = 0; | ||
548 | product_info->FirmwareMajorVersion = epic->MajorVersion; | ||
549 | product_info->FirmwareMinorVersion = epic->MinorVersion; | ||
550 | product_info->FirmwareBuildNumber = epic->BuildNumber; | ||
551 | product_info->iDownloadFile = epic->iDownloadFile; | ||
552 | product_info->EpicVer = epic->EpicVer; | ||
553 | product_info->Epic = epic->Supports; | ||
554 | product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE; | ||
555 | dump_product_info(product_info); | ||
556 | |||
557 | bits = &ep->epic_descriptor.Supports; | ||
558 | dbg("**EPIC descriptor:"); | ||
559 | dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE"); | ||
560 | dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE" ); | ||
561 | dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE" ); | ||
562 | dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE" ); | ||
563 | dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE" ); | ||
564 | dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE" ); | ||
565 | dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE" ); | ||
566 | dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE" ); | ||
567 | dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE" ); | ||
568 | dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE" ); | ||
569 | dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE" ); | ||
570 | dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE" ); | ||
571 | dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE" ); | ||
572 | } | ||
573 | |||
574 | return result; | ||
522 | } | 575 | } |
523 | 576 | ||
524 | 577 | ||
@@ -1017,21 +1070,29 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) | |||
1017 | 1070 | ||
1018 | edge_port->closePending = TRUE; | 1071 | edge_port->closePending = TRUE; |
1019 | 1072 | ||
1020 | /* flush and chase */ | 1073 | if ((!edge_serial->is_epic) || |
1021 | edge_port->chaseResponsePending = TRUE; | 1074 | ((edge_serial->is_epic) && |
1022 | 1075 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1023 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1076 | /* flush and chase */ |
1024 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1077 | edge_port->chaseResponsePending = TRUE; |
1025 | if (status == 0) { | 1078 | |
1026 | // block until chase finished | 1079 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1027 | block_until_chase_response(edge_port); | 1080 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1028 | } else { | 1081 | if (status == 0) { |
1029 | edge_port->chaseResponsePending = FALSE; | 1082 | // block until chase finished |
1083 | block_until_chase_response(edge_port); | ||
1084 | } else { | ||
1085 | edge_port->chaseResponsePending = FALSE; | ||
1086 | } | ||
1030 | } | 1087 | } |
1031 | 1088 | ||
1032 | /* close the port */ | 1089 | if ((!edge_serial->is_epic) || |
1033 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | 1090 | ((edge_serial->is_epic) && |
1034 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | 1091 | (edge_serial->epic_descriptor.Supports.IOSPClose))) { |
1092 | /* close the port */ | ||
1093 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | ||
1094 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | ||
1095 | } | ||
1035 | 1096 | ||
1036 | //port->close = TRUE; | 1097 | //port->close = TRUE; |
1037 | edge_port->closePending = FALSE; | 1098 | edge_port->closePending = FALSE; |
@@ -1694,29 +1755,38 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned | |||
1694 | static void edge_break (struct usb_serial_port *port, int break_state) | 1755 | static void edge_break (struct usb_serial_port *port, int break_state) |
1695 | { | 1756 | { |
1696 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1757 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1758 | struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); | ||
1697 | int status; | 1759 | int status; |
1698 | 1760 | ||
1699 | /* flush and chase */ | 1761 | if ((!edge_serial->is_epic) || |
1700 | edge_port->chaseResponsePending = TRUE; | 1762 | ((edge_serial->is_epic) && |
1701 | 1763 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1702 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1764 | /* flush and chase */ |
1703 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1765 | edge_port->chaseResponsePending = TRUE; |
1704 | if (status == 0) { | 1766 | |
1705 | // block until chase finished | 1767 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1706 | block_until_chase_response(edge_port); | 1768 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1707 | } else { | 1769 | if (status == 0) { |
1708 | edge_port->chaseResponsePending = FALSE; | 1770 | // block until chase finished |
1771 | block_until_chase_response(edge_port); | ||
1772 | } else { | ||
1773 | edge_port->chaseResponsePending = FALSE; | ||
1774 | } | ||
1709 | } | 1775 | } |
1710 | 1776 | ||
1711 | if (break_state == -1) { | 1777 | if ((!edge_serial->is_epic) || |
1712 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); | 1778 | ((edge_serial->is_epic) && |
1713 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); | 1779 | (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { |
1714 | } else { | 1780 | if (break_state == -1) { |
1715 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); | 1781 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); |
1716 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); | 1782 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); |
1717 | } | 1783 | } else { |
1718 | if (status) { | 1784 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); |
1719 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | 1785 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); |
1786 | } | ||
1787 | if (status) { | ||
1788 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | ||
1789 | } | ||
1720 | } | 1790 | } |
1721 | 1791 | ||
1722 | return; | 1792 | return; |
@@ -2288,6 +2358,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer | |||
2288 | *****************************************************************************/ | 2358 | *****************************************************************************/ |
2289 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) | 2359 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) |
2290 | { | 2360 | { |
2361 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2291 | unsigned char *cmdBuffer; | 2362 | unsigned char *cmdBuffer; |
2292 | unsigned char *currCmd; | 2363 | unsigned char *currCmd; |
2293 | int cmdLen = 0; | 2364 | int cmdLen = 0; |
@@ -2295,6 +2366,14 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa | |||
2295 | int status; | 2366 | int status; |
2296 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; | 2367 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; |
2297 | 2368 | ||
2369 | if ((!edge_serial->is_epic) || | ||
2370 | ((edge_serial->is_epic) && | ||
2371 | (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { | ||
2372 | dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", | ||
2373 | edge_port->port->number, baudRate); | ||
2374 | return 0; | ||
2375 | } | ||
2376 | |||
2298 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); | 2377 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); |
2299 | 2378 | ||
2300 | status = calc_baud_rate_divisor (baudRate, &divisor); | 2379 | status = calc_baud_rate_divisor (baudRate, &divisor); |
@@ -2374,6 +2453,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
2374 | *****************************************************************************/ | 2453 | *****************************************************************************/ |
2375 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) | 2454 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) |
2376 | { | 2455 | { |
2456 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2377 | unsigned char *cmdBuffer; | 2457 | unsigned char *cmdBuffer; |
2378 | unsigned char *currCmd; | 2458 | unsigned char *currCmd; |
2379 | unsigned long cmdLen = 0; | 2459 | unsigned long cmdLen = 0; |
@@ -2381,6 +2461,22 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2381 | 2461 | ||
2382 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); | 2462 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); |
2383 | 2463 | ||
2464 | if ((!edge_serial->is_epic) || | ||
2465 | ((edge_serial->is_epic) && | ||
2466 | (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && | ||
2467 | (regNum == MCR))) { | ||
2468 | dbg("SendCmdWriteUartReg - Not writting to MCR Register"); | ||
2469 | return 0; | ||
2470 | } | ||
2471 | |||
2472 | if ((!edge_serial->is_epic) || | ||
2473 | ((edge_serial->is_epic) && | ||
2474 | (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && | ||
2475 | (regNum == LCR))) { | ||
2476 | dbg ("SendCmdWriteUartReg - Not writting to LCR Register"); | ||
2477 | return 0; | ||
2478 | } | ||
2479 | |||
2384 | // Alloc memory for the string of commands. | 2480 | // Alloc memory for the string of commands. |
2385 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); | 2481 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); |
2386 | if (cmdBuffer == NULL ) { | 2482 | if (cmdBuffer == NULL ) { |
@@ -2414,6 +2510,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2414 | #endif | 2510 | #endif |
2415 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) | 2511 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) |
2416 | { | 2512 | { |
2513 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2417 | struct tty_struct *tty; | 2514 | struct tty_struct *tty; |
2418 | int baud; | 2515 | int baud; |
2419 | unsigned cflag; | 2516 | unsigned cflag; |
@@ -2494,8 +2591,12 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2494 | unsigned char stop_char = STOP_CHAR(tty); | 2591 | unsigned char stop_char = STOP_CHAR(tty); |
2495 | unsigned char start_char = START_CHAR(tty); | 2592 | unsigned char start_char = START_CHAR(tty); |
2496 | 2593 | ||
2497 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | 2594 | if ((!edge_serial->is_epic) || |
2498 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | 2595 | ((edge_serial->is_epic) && |
2596 | (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { | ||
2597 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | ||
2598 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | ||
2599 | } | ||
2499 | 2600 | ||
2500 | /* if we are implementing INBOUND XON/XOFF */ | 2601 | /* if we are implementing INBOUND XON/XOFF */ |
2501 | if (I_IXOFF(tty)) { | 2602 | if (I_IXOFF(tty)) { |
@@ -2515,8 +2616,14 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi | |||
2515 | } | 2616 | } |
2516 | 2617 | ||
2517 | /* Set flow control to the configured value */ | 2618 | /* Set flow control to the configured value */ |
2518 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | 2619 | if ((!edge_serial->is_epic) || |
2519 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | 2620 | ((edge_serial->is_epic) && |
2621 | (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) | ||
2622 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | ||
2623 | if ((!edge_serial->is_epic) || | ||
2624 | ((edge_serial->is_epic) && | ||
2625 | (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) | ||
2626 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | ||
2520 | 2627 | ||
2521 | 2628 | ||
2522 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | 2629 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); |
@@ -2728,6 +2835,13 @@ static int edge_startup (struct usb_serial *serial) | |||
2728 | struct edgeport_port *edge_port; | 2835 | struct edgeport_port *edge_port; |
2729 | struct usb_device *dev; | 2836 | struct usb_device *dev; |
2730 | int i, j; | 2837 | int i, j; |
2838 | int response; | ||
2839 | int interrupt_in_found; | ||
2840 | int bulk_in_found; | ||
2841 | int bulk_out_found; | ||
2842 | static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, | ||
2843 | EDGE_COMPATIBILITY_MASK1, | ||
2844 | EDGE_COMPATIBILITY_MASK2 }; | ||
2731 | 2845 | ||
2732 | dev = serial->dev; | 2846 | dev = serial->dev; |
2733 | 2847 | ||
@@ -2750,38 +2864,50 @@ static int edge_startup (struct usb_serial *serial) | |||
2750 | 2864 | ||
2751 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); | 2865 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); |
2752 | 2866 | ||
2753 | /* get the manufacturing descriptor for this device */ | 2867 | /* Read the epic descriptor */ |
2754 | get_manufacturing_desc (edge_serial); | 2868 | if (get_epic_descriptor(edge_serial) <= 0) { |
2869 | /* memcpy descriptor to Supports structures */ | ||
2870 | memcpy(&edge_serial->epic_descriptor.Supports, descriptor, | ||
2871 | sizeof(struct edge_compatibility_bits)); | ||
2872 | |||
2873 | /* get the manufacturing descriptor for this device */ | ||
2874 | get_manufacturing_desc (edge_serial); | ||
2755 | 2875 | ||
2756 | /* get the boot descriptor */ | 2876 | /* get the boot descriptor */ |
2757 | get_boot_desc (edge_serial); | 2877 | get_boot_desc (edge_serial); |
2758 | 2878 | ||
2759 | get_product_info(edge_serial); | 2879 | get_product_info(edge_serial); |
2880 | } | ||
2760 | 2881 | ||
2761 | /* set the number of ports from the manufacturing description */ | 2882 | /* set the number of ports from the manufacturing description */ |
2762 | /* serial->num_ports = serial->product_info.NumPorts; */ | 2883 | /* serial->num_ports = serial->product_info.NumPorts; */ |
2763 | if (edge_serial->product_info.NumPorts != serial->num_ports) { | 2884 | if ((!edge_serial->is_epic) && |
2764 | warn("%s - Device Reported %d serial ports vs core " | 2885 | (edge_serial->product_info.NumPorts != serial->num_ports)) { |
2765 | "thinking we have %d ports, email greg@kroah.com this info.", | 2886 | dev_warn(&serial->dev->dev, "Device Reported %d serial ports " |
2766 | __FUNCTION__, edge_serial->product_info.NumPorts, | 2887 | "vs. core thinking we have %d ports, email " |
2767 | serial->num_ports); | 2888 | "greg@kroah.com this information.", |
2889 | edge_serial->product_info.NumPorts, | ||
2890 | serial->num_ports); | ||
2768 | } | 2891 | } |
2769 | 2892 | ||
2770 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); | 2893 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); |
2771 | 2894 | ||
2772 | /* now load the application firmware into this device */ | 2895 | /* If not an EPiC device */ |
2773 | load_application_firmware (edge_serial); | 2896 | if (!edge_serial->is_epic) { |
2897 | /* now load the application firmware into this device */ | ||
2898 | load_application_firmware (edge_serial); | ||
2774 | 2899 | ||
2775 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); | 2900 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); |
2776 | 2901 | ||
2777 | /* Check current Edgeport EEPROM and update if necessary */ | 2902 | /* Check current Edgeport EEPROM and update if necessary */ |
2778 | update_edgeport_E2PROM (edge_serial); | 2903 | update_edgeport_E2PROM (edge_serial); |
2779 | |||
2780 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); | ||
2781 | 2904 | ||
2782 | /* set the configuration to use #1 */ | 2905 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); |
2783 | // dbg("set_configuration 1"); | 2906 | |
2784 | // usb_set_configuration (dev, 1); | 2907 | /* set the configuration to use #1 */ |
2908 | // dbg("set_configuration 1"); | ||
2909 | // usb_set_configuration (dev, 1); | ||
2910 | } | ||
2785 | 2911 | ||
2786 | /* we set up the pointers to the endpoints in the edge_open function, | 2912 | /* we set up the pointers to the endpoints in the edge_open function, |
2787 | * as the structures aren't created yet. */ | 2913 | * as the structures aren't created yet. */ |
@@ -2804,8 +2930,101 @@ static int edge_startup (struct usb_serial *serial) | |||
2804 | edge_port->port = serial->port[i]; | 2930 | edge_port->port = serial->port[i]; |
2805 | usb_set_serial_port_data(serial->port[i], edge_port); | 2931 | usb_set_serial_port_data(serial->port[i], edge_port); |
2806 | } | 2932 | } |
2807 | 2933 | ||
2808 | return 0; | 2934 | response = 0; |
2935 | |||
2936 | if (edge_serial->is_epic) { | ||
2937 | /* EPIC thing, set up our interrupt polling now and our read urb, so | ||
2938 | * that the device knows it really is connected. */ | ||
2939 | interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; | ||
2940 | for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { | ||
2941 | struct usb_endpoint_descriptor *endpoint; | ||
2942 | int buffer_size; | ||
2943 | |||
2944 | endpoint = &serial->interface->altsetting[0].endpoint[i].desc; | ||
2945 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
2946 | if ((!interrupt_in_found) && | ||
2947 | (usb_endpoint_is_int_in(endpoint))) { | ||
2948 | /* we found a interrupt in endpoint */ | ||
2949 | dbg("found interrupt in"); | ||
2950 | |||
2951 | /* not set up yet, so do it now */ | ||
2952 | edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2953 | if (!edge_serial->interrupt_read_urb) { | ||
2954 | err("out of memory"); | ||
2955 | return -ENOMEM; | ||
2956 | } | ||
2957 | edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2958 | if (!edge_serial->interrupt_in_buffer) { | ||
2959 | err("out of memory"); | ||
2960 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
2961 | return -ENOMEM; | ||
2962 | } | ||
2963 | edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress; | ||
2964 | |||
2965 | /* set up our interrupt urb */ | ||
2966 | usb_fill_int_urb(edge_serial->interrupt_read_urb, | ||
2967 | dev, | ||
2968 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
2969 | edge_serial->interrupt_in_buffer, | ||
2970 | buffer_size, | ||
2971 | edge_interrupt_callback, | ||
2972 | edge_serial, | ||
2973 | endpoint->bInterval); | ||
2974 | |||
2975 | interrupt_in_found = TRUE; | ||
2976 | } | ||
2977 | |||
2978 | if ((!bulk_in_found) && | ||
2979 | (usb_endpoint_is_bulk_in(endpoint))) { | ||
2980 | /* we found a bulk in endpoint */ | ||
2981 | dbg("found bulk in"); | ||
2982 | |||
2983 | /* not set up yet, so do it now */ | ||
2984 | edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2985 | if (!edge_serial->read_urb) { | ||
2986 | err("out of memory"); | ||
2987 | return -ENOMEM; | ||
2988 | } | ||
2989 | edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2990 | if (!edge_serial->bulk_in_buffer) { | ||
2991 | err ("out of memory"); | ||
2992 | usb_free_urb(edge_serial->read_urb); | ||
2993 | return -ENOMEM; | ||
2994 | } | ||
2995 | edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress; | ||
2996 | |||
2997 | /* set up our bulk in urb */ | ||
2998 | usb_fill_bulk_urb(edge_serial->read_urb, dev, | ||
2999 | usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), | ||
3000 | edge_serial->bulk_in_buffer, | ||
3001 | endpoint->wMaxPacketSize, | ||
3002 | edge_bulk_in_callback, | ||
3003 | edge_serial); | ||
3004 | bulk_in_found = TRUE; | ||
3005 | } | ||
3006 | |||
3007 | if ((!bulk_out_found) && | ||
3008 | (usb_endpoint_is_bulk_out(endpoint))) { | ||
3009 | /* we found a bulk out endpoint */ | ||
3010 | dbg("found bulk out"); | ||
3011 | edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; | ||
3012 | bulk_out_found = TRUE; | ||
3013 | } | ||
3014 | } | ||
3015 | |||
3016 | if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { | ||
3017 | err ("Error - the proper endpoints were not found!"); | ||
3018 | return -ENODEV; | ||
3019 | } | ||
3020 | |||
3021 | /* start interrupt read for this edgeport this interrupt will | ||
3022 | * continue as long as the edgeport is connected */ | ||
3023 | response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); | ||
3024 | if (response) | ||
3025 | err("%s - Error %d submitting control urb", __FUNCTION__, response); | ||
3026 | } | ||
3027 | return response; | ||
2809 | } | 3028 | } |
2810 | 3029 | ||
2811 | 3030 | ||
@@ -2815,6 +3034,7 @@ static int edge_startup (struct usb_serial *serial) | |||
2815 | ****************************************************************************/ | 3034 | ****************************************************************************/ |
2816 | static void edge_shutdown (struct usb_serial *serial) | 3035 | static void edge_shutdown (struct usb_serial *serial) |
2817 | { | 3036 | { |
3037 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | ||
2818 | int i; | 3038 | int i; |
2819 | 3039 | ||
2820 | dbg("%s", __FUNCTION__); | 3040 | dbg("%s", __FUNCTION__); |
@@ -2824,7 +3044,18 @@ static void edge_shutdown (struct usb_serial *serial) | |||
2824 | kfree (usb_get_serial_port_data(serial->port[i])); | 3044 | kfree (usb_get_serial_port_data(serial->port[i])); |
2825 | usb_set_serial_port_data(serial->port[i], NULL); | 3045 | usb_set_serial_port_data(serial->port[i], NULL); |
2826 | } | 3046 | } |
2827 | kfree (usb_get_serial_data(serial)); | 3047 | /* free up our endpoint stuff */ |
3048 | if (edge_serial->is_epic) { | ||
3049 | usb_unlink_urb(edge_serial->interrupt_read_urb); | ||
3050 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
3051 | kfree(edge_serial->interrupt_in_buffer); | ||
3052 | |||
3053 | usb_unlink_urb(edge_serial->read_urb); | ||
3054 | usb_free_urb(edge_serial->read_urb); | ||
3055 | kfree(edge_serial->bulk_in_buffer); | ||
3056 | } | ||
3057 | |||
3058 | kfree(edge_serial); | ||
2828 | usb_set_serial_data(serial, NULL); | 3059 | usb_set_serial_data(serial, NULL); |
2829 | } | 3060 | } |
2830 | 3061 | ||
@@ -2846,6 +3077,9 @@ static int __init edgeport_init(void) | |||
2846 | retval = usb_serial_register(&edgeport_8port_device); | 3077 | retval = usb_serial_register(&edgeport_8port_device); |
2847 | if (retval) | 3078 | if (retval) |
2848 | goto failed_8port_device_register; | 3079 | goto failed_8port_device_register; |
3080 | retval = usb_serial_register(&epic_device); | ||
3081 | if (retval) | ||
3082 | goto failed_epic_device_register; | ||
2849 | retval = usb_register(&io_driver); | 3083 | retval = usb_register(&io_driver); |
2850 | if (retval) | 3084 | if (retval) |
2851 | goto failed_usb_register; | 3085 | goto failed_usb_register; |
@@ -2853,6 +3087,8 @@ static int __init edgeport_init(void) | |||
2853 | return 0; | 3087 | return 0; |
2854 | 3088 | ||
2855 | failed_usb_register: | 3089 | failed_usb_register: |
3090 | usb_serial_deregister(&epic_device); | ||
3091 | failed_epic_device_register: | ||
2856 | usb_serial_deregister(&edgeport_8port_device); | 3092 | usb_serial_deregister(&edgeport_8port_device); |
2857 | failed_8port_device_register: | 3093 | failed_8port_device_register: |
2858 | usb_serial_deregister(&edgeport_4port_device); | 3094 | usb_serial_deregister(&edgeport_4port_device); |
@@ -2873,6 +3109,7 @@ static void __exit edgeport_exit (void) | |||
2873 | usb_serial_deregister (&edgeport_2port_device); | 3109 | usb_serial_deregister (&edgeport_2port_device); |
2874 | usb_serial_deregister (&edgeport_4port_device); | 3110 | usb_serial_deregister (&edgeport_4port_device); |
2875 | usb_serial_deregister (&edgeport_8port_device); | 3111 | usb_serial_deregister (&edgeport_8port_device); |
3112 | usb_serial_deregister (&epic_device); | ||
2876 | } | 3113 | } |
2877 | 3114 | ||
2878 | module_init(edgeport_init); | 3115 | module_init(edgeport_init); |