uplcom.c (187176) | uplcom.c (187259) |
---|---|
1/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */ 2 3#include <sys/cdefs.h> | 1/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */ 2 3#include <sys/cdefs.h> |
4__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uplcom2.c 187176 2009-01-13 19:03:47Z thompsa $"); | 4__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uplcom2.c 187259 2009-01-15 02:35:40Z thompsa $"); |
5 6/*- 7 * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: --- 103 unchanged lines hidden (view full) --- 116#define UPLCOM_IFACE_INDEX 0 117#define UPLCOM_SECOND_IFACE_INDEX 1 118 119#ifndef UPLCOM_INTR_INTERVAL 120#define UPLCOM_INTR_INTERVAL 0 /* default */ 121#endif 122 123#define UPLCOM_BULK_BUF_SIZE 1024 /* bytes */ | 5 6/*- 7 * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: --- 103 unchanged lines hidden (view full) --- 116#define UPLCOM_IFACE_INDEX 0 117#define UPLCOM_SECOND_IFACE_INDEX 1 118 119#ifndef UPLCOM_INTR_INTERVAL 120#define UPLCOM_INTR_INTERVAL 0 /* default */ 121#endif 122 123#define UPLCOM_BULK_BUF_SIZE 1024 /* bytes */ |
124#define UPLCOM_N_TRANSFER 6 | |
125 126#define UPLCOM_SET_REQUEST 0x01 127#define UPLCOM_SET_CRTSCTS 0x41 128#define UPLCOM_SET_CRTSCTS_PL2303X 0x61 129#define RSAQ_STATUS_CTS 0x80 130#define RSAQ_STATUS_DSR 0x02 131#define RSAQ_STATUS_DCD 0x01 132 133#define TYPE_PL2303 0 134#define TYPE_PL2303X 1 135 | 124 125#define UPLCOM_SET_REQUEST 0x01 126#define UPLCOM_SET_CRTSCTS 0x41 127#define UPLCOM_SET_CRTSCTS_PL2303X 0x61 128#define RSAQ_STATUS_CTS 0x80 129#define RSAQ_STATUS_DSR 0x02 130#define RSAQ_STATUS_DCD 0x01 131 132#define TYPE_PL2303 0 133#define TYPE_PL2303X 1 134 |
135enum { 136 UPLCOM_BULK_DT_WR, 137 UPLCOM_BULK_DT_RD, 138 UPLCOM_BULK_CS_WR, 139 UPLCOM_BULK_CS_RD, 140 UPLCOM_INTR_DT_RD, 141 UPLCOM_INTR_CS_RD, 142 UPLCOM_N_TRANSFER = 6, 143}; 144 |
|
136struct uplcom_softc { 137 struct usb2_com_super_softc sc_super_ucom; 138 struct usb2_com_softc sc_ucom; 139 140 struct usb2_xfer *sc_xfer[UPLCOM_N_TRANSFER]; 141 struct usb2_device *sc_udev; 142 143 uint16_t sc_line; --- 37 unchanged lines hidden (view full) --- 181static usb2_callback_t uplcom_intr_clear_stall_callback; 182static usb2_callback_t uplcom_write_callback; 183static usb2_callback_t uplcom_write_clear_stall_callback; 184static usb2_callback_t uplcom_read_callback; 185static usb2_callback_t uplcom_read_clear_stall_callback; 186 187static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = { 188 | 145struct uplcom_softc { 146 struct usb2_com_super_softc sc_super_ucom; 147 struct usb2_com_softc sc_ucom; 148 149 struct usb2_xfer *sc_xfer[UPLCOM_N_TRANSFER]; 150 struct usb2_device *sc_udev; 151 152 uint16_t sc_line; --- 37 unchanged lines hidden (view full) --- 190static usb2_callback_t uplcom_intr_clear_stall_callback; 191static usb2_callback_t uplcom_write_callback; 192static usb2_callback_t uplcom_write_clear_stall_callback; 193static usb2_callback_t uplcom_read_callback; 194static usb2_callback_t uplcom_read_clear_stall_callback; 195 196static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = { 197 |
189 [0] = { | 198 [UPLCOM_BULK_DT_WR] = { |
190 .type = UE_BULK, 191 .endpoint = UE_ADDR_ANY, 192 .direction = UE_DIR_OUT, 193 .mh.bufsize = UPLCOM_BULK_BUF_SIZE, 194 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 195 .mh.callback = &uplcom_write_callback, 196 .if_index = 0, 197 }, 198 | 199 .type = UE_BULK, 200 .endpoint = UE_ADDR_ANY, 201 .direction = UE_DIR_OUT, 202 .mh.bufsize = UPLCOM_BULK_BUF_SIZE, 203 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 204 .mh.callback = &uplcom_write_callback, 205 .if_index = 0, 206 }, 207 |
199 [1] = { | 208 [UPLCOM_BULK_DT_RD] = { |
200 .type = UE_BULK, 201 .endpoint = UE_ADDR_ANY, 202 .direction = UE_DIR_IN, 203 .mh.bufsize = UPLCOM_BULK_BUF_SIZE, 204 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 205 .mh.callback = &uplcom_read_callback, 206 .if_index = 0, 207 }, 208 | 209 .type = UE_BULK, 210 .endpoint = UE_ADDR_ANY, 211 .direction = UE_DIR_IN, 212 .mh.bufsize = UPLCOM_BULK_BUF_SIZE, 213 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 214 .mh.callback = &uplcom_read_callback, 215 .if_index = 0, 216 }, 217 |
209 [2] = { | 218 [UPLCOM_BULK_CS_WR] = { |
210 .type = UE_CONTROL, 211 .endpoint = 0x00, /* Control pipe */ 212 .direction = UE_DIR_ANY, 213 .mh.bufsize = sizeof(struct usb2_device_request), 214 .mh.callback = &uplcom_write_clear_stall_callback, 215 .mh.timeout = 1000, /* 1 second */ 216 .mh.interval = 50, /* 50ms */ 217 .if_index = 0, 218 }, 219 | 219 .type = UE_CONTROL, 220 .endpoint = 0x00, /* Control pipe */ 221 .direction = UE_DIR_ANY, 222 .mh.bufsize = sizeof(struct usb2_device_request), 223 .mh.callback = &uplcom_write_clear_stall_callback, 224 .mh.timeout = 1000, /* 1 second */ 225 .mh.interval = 50, /* 50ms */ 226 .if_index = 0, 227 }, 228 |
220 [3] = { | 229 [UPLCOM_BULK_CS_RD] = { |
221 .type = UE_CONTROL, 222 .endpoint = 0x00, /* Control pipe */ 223 .direction = UE_DIR_ANY, 224 .mh.bufsize = sizeof(struct usb2_device_request), 225 .mh.callback = &uplcom_read_clear_stall_callback, 226 .mh.timeout = 1000, /* 1 second */ 227 .mh.interval = 50, /* 50ms */ 228 .if_index = 0, 229 }, 230 | 230 .type = UE_CONTROL, 231 .endpoint = 0x00, /* Control pipe */ 232 .direction = UE_DIR_ANY, 233 .mh.bufsize = sizeof(struct usb2_device_request), 234 .mh.callback = &uplcom_read_clear_stall_callback, 235 .mh.timeout = 1000, /* 1 second */ 236 .mh.interval = 50, /* 50ms */ 237 .if_index = 0, 238 }, 239 |
231 [4] = { | 240 [UPLCOM_INTR_DT_RD] = { |
232 .type = UE_INTERRUPT, 233 .endpoint = UE_ADDR_ANY, 234 .direction = UE_DIR_IN, 235 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 236 .mh.bufsize = 0, /* use wMaxPacketSize */ 237 .mh.callback = &uplcom_intr_callback, 238 .if_index = 1, 239 }, 240 | 241 .type = UE_INTERRUPT, 242 .endpoint = UE_ADDR_ANY, 243 .direction = UE_DIR_IN, 244 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 245 .mh.bufsize = 0, /* use wMaxPacketSize */ 246 .mh.callback = &uplcom_intr_callback, 247 .if_index = 1, 248 }, 249 |
241 [5] = { | 250 [UPLCOM_INTR_CS_RD] = { |
242 .type = UE_CONTROL, 243 .endpoint = 0x00, /* Control pipe */ 244 .direction = UE_DIR_ANY, 245 .mh.bufsize = sizeof(struct usb2_device_request), 246 .mh.callback = &uplcom_intr_clear_stall_callback, 247 .mh.timeout = 1000, /* 1 second */ 248 .mh.interval = 50, /* 50ms */ 249 .if_index = 1, --- 462 unchanged lines hidden (view full) --- 712} 713 714static void 715uplcom_start_read(struct usb2_com_softc *ucom) 716{ 717 struct uplcom_softc *sc = ucom->sc_parent; 718 719 /* start interrupt endpoint */ | 251 .type = UE_CONTROL, 252 .endpoint = 0x00, /* Control pipe */ 253 .direction = UE_DIR_ANY, 254 .mh.bufsize = sizeof(struct usb2_device_request), 255 .mh.callback = &uplcom_intr_clear_stall_callback, 256 .mh.timeout = 1000, /* 1 second */ 257 .mh.interval = 50, /* 50ms */ 258 .if_index = 1, --- 462 unchanged lines hidden (view full) --- 721} 722 723static void 724uplcom_start_read(struct usb2_com_softc *ucom) 725{ 726 struct uplcom_softc *sc = ucom->sc_parent; 727 728 /* start interrupt endpoint */ |
720 usb2_transfer_start(sc->sc_xfer[4]); | 729 usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_DT_RD]); |
721 722 /* start read endpoint */ | 730 731 /* start read endpoint */ |
723 usb2_transfer_start(sc->sc_xfer[1]); | 732 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_RD]); |
724} 725 726static void 727uplcom_stop_read(struct usb2_com_softc *ucom) 728{ 729 struct uplcom_softc *sc = ucom->sc_parent; 730 731 /* stop interrupt endpoint */ | 733} 734 735static void 736uplcom_stop_read(struct usb2_com_softc *ucom) 737{ 738 struct uplcom_softc *sc = ucom->sc_parent; 739 740 /* stop interrupt endpoint */ |
732 usb2_transfer_stop(sc->sc_xfer[4]); | 741 usb2_transfer_stop(sc->sc_xfer[UPLCOM_INTR_DT_RD]); |
733 734 /* stop read endpoint */ | 742 743 /* stop read endpoint */ |
735 usb2_transfer_stop(sc->sc_xfer[3]); 736 usb2_transfer_stop(sc->sc_xfer[1]); | 744 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_RD]); 745 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_RD]); |
737} 738 739static void 740uplcom_start_write(struct usb2_com_softc *ucom) 741{ 742 struct uplcom_softc *sc = ucom->sc_parent; 743 | 746} 747 748static void 749uplcom_start_write(struct usb2_com_softc *ucom) 750{ 751 struct uplcom_softc *sc = ucom->sc_parent; 752 |
744 usb2_transfer_start(sc->sc_xfer[0]); | 753 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_WR]); |
745} 746 747static void 748uplcom_stop_write(struct usb2_com_softc *ucom) 749{ 750 struct uplcom_softc *sc = ucom->sc_parent; 751 | 754} 755 756static void 757uplcom_stop_write(struct usb2_com_softc *ucom) 758{ 759 struct uplcom_softc *sc = ucom->sc_parent; 760 |
752 usb2_transfer_stop(sc->sc_xfer[2]); 753 usb2_transfer_stop(sc->sc_xfer[0]); | 761 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_WR]); 762 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_WR]); |
754} 755 756static void 757uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr) 758{ 759 struct uplcom_softc *sc = ucom->sc_parent; 760 761 DPRINTF("\n"); --- 30 unchanged lines hidden (view full) --- 792 } 793 if (buf[8] & RSAQ_STATUS_DCD) { 794 sc->sc_msr |= SER_DCD; 795 } 796 usb2_com_status_change(&sc->sc_ucom); 797 } 798 case USB_ST_SETUP: 799 if (sc->sc_flag & UPLCOM_FLAG_INTR_STALL) { | 763} 764 765static void 766uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr) 767{ 768 struct uplcom_softc *sc = ucom->sc_parent; 769 770 DPRINTF("\n"); --- 30 unchanged lines hidden (view full) --- 801 } 802 if (buf[8] & RSAQ_STATUS_DCD) { 803 sc->sc_msr |= SER_DCD; 804 } 805 usb2_com_status_change(&sc->sc_ucom); 806 } 807 case USB_ST_SETUP: 808 if (sc->sc_flag & UPLCOM_FLAG_INTR_STALL) { |
800 usb2_transfer_start(sc->sc_xfer[5]); | 809 usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]); |
801 } else { 802 xfer->frlengths[0] = xfer->max_data_length; 803 usb2_start_hardware(xfer); 804 } 805 return; 806 807 default: /* Error */ 808 if (xfer->error != USB_ERR_CANCELLED) { 809 sc->sc_flag |= UPLCOM_FLAG_INTR_STALL; | 810 } else { 811 xfer->frlengths[0] = xfer->max_data_length; 812 usb2_start_hardware(xfer); 813 } 814 return; 815 816 default: /* Error */ 817 if (xfer->error != USB_ERR_CANCELLED) { 818 sc->sc_flag |= UPLCOM_FLAG_INTR_STALL; |
810 usb2_transfer_start(sc->sc_xfer[5]); | 819 usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]); |
811 } 812 return; 813 814 } 815} 816 817static void 818uplcom_intr_clear_stall_callback(struct usb2_xfer *xfer) 819{ 820 struct uplcom_softc *sc = xfer->priv_sc; | 820 } 821 return; 822 823 } 824} 825 826static void 827uplcom_intr_clear_stall_callback(struct usb2_xfer *xfer) 828{ 829 struct uplcom_softc *sc = xfer->priv_sc; |
821 struct usb2_xfer *xfer_other = sc->sc_xfer[4]; | 830 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_INTR_DT_RD]; |
822 823 if (usb2_clear_stall_callback(xfer, xfer_other)) { 824 DPRINTF("stall cleared\n"); 825 sc->sc_flag &= ~UPLCOM_FLAG_INTR_STALL; 826 usb2_transfer_start(xfer_other); 827 } 828} 829 830static void 831uplcom_write_callback(struct usb2_xfer *xfer) 832{ 833 struct uplcom_softc *sc = xfer->priv_sc; 834 uint32_t actlen; 835 836 switch (USB_GET_STATE(xfer)) { 837 case USB_ST_SETUP: 838 case USB_ST_TRANSFERRED: 839 if (sc->sc_flag & UPLCOM_FLAG_WRITE_STALL) { | 831 832 if (usb2_clear_stall_callback(xfer, xfer_other)) { 833 DPRINTF("stall cleared\n"); 834 sc->sc_flag &= ~UPLCOM_FLAG_INTR_STALL; 835 usb2_transfer_start(xfer_other); 836 } 837} 838 839static void 840uplcom_write_callback(struct usb2_xfer *xfer) 841{ 842 struct uplcom_softc *sc = xfer->priv_sc; 843 uint32_t actlen; 844 845 switch (USB_GET_STATE(xfer)) { 846 case USB_ST_SETUP: 847 case USB_ST_TRANSFERRED: 848 if (sc->sc_flag & UPLCOM_FLAG_WRITE_STALL) { |
840 usb2_transfer_start(sc->sc_xfer[2]); | 849 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]); |
841 return; 842 } 843 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0, 844 UPLCOM_BULK_BUF_SIZE, &actlen)) { 845 846 DPRINTF("actlen = %d\n", actlen); 847 848 xfer->frlengths[0] = actlen; 849 usb2_start_hardware(xfer); 850 } 851 return; 852 853 default: /* Error */ 854 if (xfer->error != USB_ERR_CANCELLED) { 855 sc->sc_flag |= UPLCOM_FLAG_WRITE_STALL; | 850 return; 851 } 852 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0, 853 UPLCOM_BULK_BUF_SIZE, &actlen)) { 854 855 DPRINTF("actlen = %d\n", actlen); 856 857 xfer->frlengths[0] = actlen; 858 usb2_start_hardware(xfer); 859 } 860 return; 861 862 default: /* Error */ 863 if (xfer->error != USB_ERR_CANCELLED) { 864 sc->sc_flag |= UPLCOM_FLAG_WRITE_STALL; |
856 usb2_transfer_start(sc->sc_xfer[2]); | 865 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]); |
857 } 858 return; 859 860 } 861} 862 863static void 864uplcom_write_clear_stall_callback(struct usb2_xfer *xfer) 865{ 866 struct uplcom_softc *sc = xfer->priv_sc; | 866 } 867 return; 868 869 } 870} 871 872static void 873uplcom_write_clear_stall_callback(struct usb2_xfer *xfer) 874{ 875 struct uplcom_softc *sc = xfer->priv_sc; |
867 struct usb2_xfer *xfer_other = sc->sc_xfer[0]; | 876 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_WR]; |
868 869 if (usb2_clear_stall_callback(xfer, xfer_other)) { 870 DPRINTF("stall cleared\n"); 871 sc->sc_flag &= ~UPLCOM_FLAG_WRITE_STALL; 872 usb2_transfer_start(xfer_other); 873 } 874} 875 876static void 877uplcom_read_callback(struct usb2_xfer *xfer) 878{ 879 struct uplcom_softc *sc = xfer->priv_sc; 880 881 switch (USB_GET_STATE(xfer)) { 882 case USB_ST_TRANSFERRED: 883 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen); 884 885 case USB_ST_SETUP: 886 if (sc->sc_flag & UPLCOM_FLAG_READ_STALL) { | 877 878 if (usb2_clear_stall_callback(xfer, xfer_other)) { 879 DPRINTF("stall cleared\n"); 880 sc->sc_flag &= ~UPLCOM_FLAG_WRITE_STALL; 881 usb2_transfer_start(xfer_other); 882 } 883} 884 885static void 886uplcom_read_callback(struct usb2_xfer *xfer) 887{ 888 struct uplcom_softc *sc = xfer->priv_sc; 889 890 switch (USB_GET_STATE(xfer)) { 891 case USB_ST_TRANSFERRED: 892 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen); 893 894 case USB_ST_SETUP: 895 if (sc->sc_flag & UPLCOM_FLAG_READ_STALL) { |
887 usb2_transfer_start(sc->sc_xfer[3]); | 896 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]); |
888 } else { 889 xfer->frlengths[0] = xfer->max_data_length; 890 usb2_start_hardware(xfer); 891 } 892 return; 893 894 default: /* Error */ 895 if (xfer->error != USB_ERR_CANCELLED) { 896 sc->sc_flag |= UPLCOM_FLAG_READ_STALL; | 897 } else { 898 xfer->frlengths[0] = xfer->max_data_length; 899 usb2_start_hardware(xfer); 900 } 901 return; 902 903 default: /* Error */ 904 if (xfer->error != USB_ERR_CANCELLED) { 905 sc->sc_flag |= UPLCOM_FLAG_READ_STALL; |
897 usb2_transfer_start(sc->sc_xfer[3]); | 906 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]); |
898 } 899 return; 900 901 } 902} 903 904static void 905uplcom_read_clear_stall_callback(struct usb2_xfer *xfer) 906{ 907 struct uplcom_softc *sc = xfer->priv_sc; | 907 } 908 return; 909 910 } 911} 912 913static void 914uplcom_read_clear_stall_callback(struct usb2_xfer *xfer) 915{ 916 struct uplcom_softc *sc = xfer->priv_sc; |
908 struct usb2_xfer *xfer_other = sc->sc_xfer[1]; | 917 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_RD]; |
909 910 if (usb2_clear_stall_callback(xfer, xfer_other)) { 911 DPRINTF("stall cleared\n"); 912 sc->sc_flag &= ~UPLCOM_FLAG_READ_STALL; 913 usb2_transfer_start(xfer_other); 914 } 915} 916 --- 26 unchanged lines hidden --- | 918 919 if (usb2_clear_stall_callback(xfer, xfer_other)) { 920 DPRINTF("stall cleared\n"); 921 sc->sc_flag &= ~UPLCOM_FLAG_READ_STALL; 922 usb2_transfer_start(xfer_other); 923 } 924} 925 --- 26 unchanged lines hidden --- |