| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for USB Windows Media Center Ed. eHome Infrared Transceivers |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 19 | 20 | * remote/transceiver requirements and specification document, found at |
|---|
| 20 | 21 | * download.microsoft.com, title |
|---|
| 21 | 22 | * Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf |
|---|
| 22 | | - * |
|---|
| 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, or |
|---|
| 27 | | - * (at your option) any later version. |
|---|
| 28 | | - * |
|---|
| 29 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 30 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 31 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 32 | | - * GNU General Public License for more details. |
|---|
| 33 | | - * |
|---|
| 34 | 23 | */ |
|---|
| 35 | 24 | |
|---|
| 36 | 25 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 80 | 69 | #define MCE_CMD 0x1f |
|---|
| 81 | 70 | #define MCE_PORT_IR 0x4 /* (0x4 << 5) | MCE_CMD = 0x9f */ |
|---|
| 82 | 71 | #define MCE_PORT_SYS 0x7 /* (0x7 << 5) | MCE_CMD = 0xff */ |
|---|
| 83 | | -#define MCE_PORT_SER 0x6 /* 0xc0 thru 0xdf flush & 0x1f bytes */ |
|---|
| 72 | +#define MCE_PORT_SER 0x6 /* 0xc0 through 0xdf flush & 0x1f bytes */ |
|---|
| 84 | 73 | #define MCE_PORT_MASK 0xe0 /* Mask out command bits */ |
|---|
| 85 | 74 | |
|---|
| 86 | 75 | /* Command port headers */ |
|---|
| .. | .. |
|---|
| 433 | 422 | .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 434 | 423 | { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb139), |
|---|
| 435 | 424 | .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 425 | + /* Hauppauge WinTV-HVR-935C - based on cx231xx */ |
|---|
| 426 | + { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb151), |
|---|
| 427 | + .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 428 | + /* Hauppauge WinTV-HVR-955Q - based on cx231xx */ |
|---|
| 429 | + { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb123), |
|---|
| 430 | + .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 431 | + /* Hauppauge WinTV-HVR-975 - based on cx231xx */ |
|---|
| 432 | + { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb150), |
|---|
| 433 | + .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 436 | 434 | { USB_DEVICE(VENDOR_PCTV, 0x0259), |
|---|
| 437 | 435 | .driver_info = HAUPPAUGE_CX_HYBRID_TV }, |
|---|
| 438 | 436 | { USB_DEVICE(VENDOR_PCTV, 0x025e), |
|---|
| .. | .. |
|---|
| 464 | 462 | |
|---|
| 465 | 463 | /* usb */ |
|---|
| 466 | 464 | struct usb_device *usbdev; |
|---|
| 465 | + struct usb_interface *usbintf; |
|---|
| 467 | 466 | struct urb *urb_in; |
|---|
| 468 | 467 | unsigned int pipe_in; |
|---|
| 469 | 468 | struct usb_endpoint_descriptor *usb_ep_out; |
|---|
| .. | .. |
|---|
| 520 | 519 | unsigned long kevent_flags; |
|---|
| 521 | 520 | # define EVENT_TX_HALT 0 |
|---|
| 522 | 521 | # define EVENT_RX_HALT 1 |
|---|
| 522 | +# define EVENT_RST_PEND 31 |
|---|
| 523 | 523 | }; |
|---|
| 524 | 524 | |
|---|
| 525 | 525 | /* MCE Device Command Strings, generally a port and command pair */ |
|---|
| .. | .. |
|---|
| 564 | 564 | datasize = 4; |
|---|
| 565 | 565 | break; |
|---|
| 566 | 566 | case MCE_CMD_G_REVISION: |
|---|
| 567 | | - datasize = 2; |
|---|
| 567 | + datasize = 4; |
|---|
| 568 | 568 | break; |
|---|
| 569 | 569 | case MCE_RSP_EQWAKESUPPORT: |
|---|
| 570 | 570 | case MCE_RSP_GETWAKESOURCE: |
|---|
| .. | .. |
|---|
| 600 | 600 | char *inout; |
|---|
| 601 | 601 | u8 cmd, subcmd, *data; |
|---|
| 602 | 602 | struct device *dev = ir->dev; |
|---|
| 603 | | - int start, skip = 0; |
|---|
| 604 | 603 | u32 carrier, period; |
|---|
| 605 | 604 | |
|---|
| 606 | | - /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
|---|
| 607 | | - if (ir->flags.microsoft_gen1 && !out && !offset) |
|---|
| 608 | | - skip = 2; |
|---|
| 609 | | - |
|---|
| 610 | | - if (len <= skip) |
|---|
| 605 | + if (offset < 0 || offset >= buf_len) |
|---|
| 611 | 606 | return; |
|---|
| 612 | 607 | |
|---|
| 613 | 608 | dev_dbg(dev, "%cx data[%d]: %*ph (len=%d sz=%d)", |
|---|
| .. | .. |
|---|
| 616 | 611 | |
|---|
| 617 | 612 | inout = out ? "Request" : "Got"; |
|---|
| 618 | 613 | |
|---|
| 619 | | - start = offset + skip; |
|---|
| 620 | | - cmd = buf[start] & 0xff; |
|---|
| 621 | | - subcmd = buf[start + 1] & 0xff; |
|---|
| 622 | | - data = buf + start + 2; |
|---|
| 614 | + cmd = buf[offset]; |
|---|
| 615 | + subcmd = (offset + 1 < buf_len) ? buf[offset + 1] : 0; |
|---|
| 616 | + data = &buf[offset] + 2; |
|---|
| 623 | 617 | |
|---|
| 618 | + /* Trace meaningless 0xb1 0x60 header bytes on original receiver */ |
|---|
| 619 | + if (ir->flags.microsoft_gen1 && !out && !offset) { |
|---|
| 620 | + dev_dbg(dev, "MCE gen 1 header"); |
|---|
| 621 | + return; |
|---|
| 622 | + } |
|---|
| 623 | + |
|---|
| 624 | + /* Trace IR data header or trailer */ |
|---|
| 625 | + if (cmd != MCE_CMD_PORT_IR && |
|---|
| 626 | + (cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA) { |
|---|
| 627 | + if (cmd == MCE_IRDATA_TRAILER) |
|---|
| 628 | + dev_dbg(dev, "End of raw IR data"); |
|---|
| 629 | + else |
|---|
| 630 | + dev_dbg(dev, "Raw IR data, %d pulse/space samples", |
|---|
| 631 | + cmd & MCE_PACKET_LENGTH_MASK); |
|---|
| 632 | + return; |
|---|
| 633 | + } |
|---|
| 634 | + |
|---|
| 635 | + /* Unexpected end of buffer? */ |
|---|
| 636 | + if (offset + len > buf_len) |
|---|
| 637 | + return; |
|---|
| 638 | + |
|---|
| 639 | + /* Decode MCE command/response */ |
|---|
| 624 | 640 | switch (cmd) { |
|---|
| 625 | 641 | case MCE_CMD_NULL: |
|---|
| 626 | 642 | if (subcmd == MCE_CMD_NULL) |
|---|
| .. | .. |
|---|
| 644 | 660 | dev_dbg(dev, "Get hw/sw rev?"); |
|---|
| 645 | 661 | else |
|---|
| 646 | 662 | dev_dbg(dev, "hw/sw rev %*ph", |
|---|
| 647 | | - 4, &buf[start + 2]); |
|---|
| 663 | + 4, &buf[offset + 2]); |
|---|
| 648 | 664 | break; |
|---|
| 649 | 665 | case MCE_CMD_RESUME: |
|---|
| 650 | 666 | dev_dbg(dev, "Device resume requested"); |
|---|
| .. | .. |
|---|
| 753 | 769 | default: |
|---|
| 754 | 770 | break; |
|---|
| 755 | 771 | } |
|---|
| 756 | | - |
|---|
| 757 | | - if (cmd == MCE_IRDATA_TRAILER) |
|---|
| 758 | | - dev_dbg(dev, "End of raw IR data"); |
|---|
| 759 | | - else if ((cmd != MCE_CMD_PORT_IR) && |
|---|
| 760 | | - ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA)) |
|---|
| 761 | | - dev_dbg(dev, "Raw IR data, %d pulse/space samples", |
|---|
| 762 | | - cmd & MCE_PACKET_LENGTH_MASK); |
|---|
| 763 | 772 | #endif |
|---|
| 764 | 773 | } |
|---|
| 765 | 774 | |
|---|
| .. | .. |
|---|
| 772 | 781 | static void mceusb_defer_kevent(struct mceusb_dev *ir, int kevent) |
|---|
| 773 | 782 | { |
|---|
| 774 | 783 | set_bit(kevent, &ir->kevent_flags); |
|---|
| 784 | + |
|---|
| 785 | + if (test_bit(EVENT_RST_PEND, &ir->kevent_flags)) { |
|---|
| 786 | + dev_dbg(ir->dev, "kevent %d dropped pending USB Reset Device", |
|---|
| 787 | + kevent); |
|---|
| 788 | + return; |
|---|
| 789 | + } |
|---|
| 790 | + |
|---|
| 775 | 791 | if (!schedule_work(&ir->kevent)) |
|---|
| 776 | | - dev_err(ir->dev, "kevent %d may have been dropped", kevent); |
|---|
| 792 | + dev_dbg(ir->dev, "kevent %d already scheduled", kevent); |
|---|
| 777 | 793 | else |
|---|
| 778 | 794 | dev_dbg(ir->dev, "kevent %d scheduled", kevent); |
|---|
| 779 | 795 | } |
|---|
| .. | .. |
|---|
| 1061 | 1077 | struct mceusb_dev *ir = dev->priv; |
|---|
| 1062 | 1078 | unsigned int units; |
|---|
| 1063 | 1079 | |
|---|
| 1064 | | - units = DIV_ROUND_CLOSEST(timeout, US_TO_NS(MCE_TIME_UNIT)); |
|---|
| 1080 | + units = DIV_ROUND_UP(timeout, MCE_TIME_UNIT); |
|---|
| 1065 | 1081 | |
|---|
| 1066 | 1082 | cmdbuf[2] = units >> 8; |
|---|
| 1067 | 1083 | cmdbuf[3] = units; |
|---|
| .. | .. |
|---|
| 1136 | 1152 | } |
|---|
| 1137 | 1153 | |
|---|
| 1138 | 1154 | /* |
|---|
| 1155 | + * Handle PORT_SYS/IR command response received from the MCE device. |
|---|
| 1156 | + * |
|---|
| 1157 | + * Assumes single response with all its data (not truncated) |
|---|
| 1158 | + * in buf_in[]. The response itself determines its total length |
|---|
| 1159 | + * (mceusb_cmd_datasize() + 2) and hence the minimum size of buf_in[]. |
|---|
| 1160 | + * |
|---|
| 1139 | 1161 | * We don't do anything but print debug spew for many of the command bits |
|---|
| 1140 | 1162 | * we receive from the hardware, but some of them are useful information |
|---|
| 1141 | 1163 | * we want to store so that we can use them. |
|---|
| 1142 | 1164 | */ |
|---|
| 1143 | | -static void mceusb_handle_command(struct mceusb_dev *ir, int index) |
|---|
| 1165 | +static void mceusb_handle_command(struct mceusb_dev *ir, u8 *buf_in) |
|---|
| 1144 | 1166 | { |
|---|
| 1145 | | - DEFINE_IR_RAW_EVENT(rawir); |
|---|
| 1146 | | - u8 hi = ir->buf_in[index + 1] & 0xff; |
|---|
| 1147 | | - u8 lo = ir->buf_in[index + 2] & 0xff; |
|---|
| 1167 | + u8 cmd = buf_in[0]; |
|---|
| 1168 | + u8 subcmd = buf_in[1]; |
|---|
| 1169 | + u8 *hi = &buf_in[2]; /* read only when required */ |
|---|
| 1170 | + u8 *lo = &buf_in[3]; /* read only when required */ |
|---|
| 1171 | + struct ir_raw_event rawir = {}; |
|---|
| 1148 | 1172 | u32 carrier_cycles; |
|---|
| 1149 | 1173 | u32 cycles_fix; |
|---|
| 1150 | 1174 | |
|---|
| 1151 | | - switch (ir->buf_in[index]) { |
|---|
| 1152 | | - /* the one and only 5-byte return value command */ |
|---|
| 1153 | | - case MCE_RSP_GETPORTSTATUS: |
|---|
| 1154 | | - if ((ir->buf_in[index + 4] & 0xff) == 0x00) |
|---|
| 1155 | | - ir->txports_cabled |= 1 << hi; |
|---|
| 1156 | | - break; |
|---|
| 1175 | + if (cmd == MCE_CMD_PORT_SYS) { |
|---|
| 1176 | + switch (subcmd) { |
|---|
| 1177 | + /* the one and only 5-byte return value command */ |
|---|
| 1178 | + case MCE_RSP_GETPORTSTATUS: |
|---|
| 1179 | + if (buf_in[5] == 0 && *hi < 8) |
|---|
| 1180 | + ir->txports_cabled |= 1 << *hi; |
|---|
| 1181 | + break; |
|---|
| 1157 | 1182 | |
|---|
| 1183 | + /* 1-byte return value commands */ |
|---|
| 1184 | + case MCE_RSP_EQEMVER: |
|---|
| 1185 | + ir->emver = *hi; |
|---|
| 1186 | + break; |
|---|
| 1187 | + |
|---|
| 1188 | + /* No return value commands */ |
|---|
| 1189 | + case MCE_RSP_CMD_ILLEGAL: |
|---|
| 1190 | + ir->need_reset = true; |
|---|
| 1191 | + break; |
|---|
| 1192 | + |
|---|
| 1193 | + default: |
|---|
| 1194 | + break; |
|---|
| 1195 | + } |
|---|
| 1196 | + |
|---|
| 1197 | + return; |
|---|
| 1198 | + } |
|---|
| 1199 | + |
|---|
| 1200 | + if (cmd != MCE_CMD_PORT_IR) |
|---|
| 1201 | + return; |
|---|
| 1202 | + |
|---|
| 1203 | + switch (subcmd) { |
|---|
| 1158 | 1204 | /* 2-byte return value commands */ |
|---|
| 1159 | 1205 | case MCE_RSP_EQIRTIMEOUT: |
|---|
| 1160 | | - ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT); |
|---|
| 1206 | + ir->rc->timeout = (*hi << 8 | *lo) * MCE_TIME_UNIT; |
|---|
| 1161 | 1207 | break; |
|---|
| 1162 | 1208 | case MCE_RSP_EQIRNUMPORTS: |
|---|
| 1163 | | - ir->num_txports = hi; |
|---|
| 1164 | | - ir->num_rxports = lo; |
|---|
| 1209 | + ir->num_txports = *hi; |
|---|
| 1210 | + ir->num_rxports = *lo; |
|---|
| 1165 | 1211 | break; |
|---|
| 1166 | 1212 | case MCE_RSP_EQIRRXCFCNT: |
|---|
| 1167 | 1213 | /* |
|---|
| .. | .. |
|---|
| 1174 | 1220 | */ |
|---|
| 1175 | 1221 | if (ir->carrier_report_enabled && ir->learning_active && |
|---|
| 1176 | 1222 | ir->pulse_tunit > 0) { |
|---|
| 1177 | | - carrier_cycles = (hi << 8 | lo); |
|---|
| 1223 | + carrier_cycles = (*hi << 8 | *lo); |
|---|
| 1178 | 1224 | /* |
|---|
| 1179 | 1225 | * Adjust carrier cycle count by adding |
|---|
| 1180 | 1226 | * 1 missed count per pulse "on" |
|---|
| .. | .. |
|---|
| 1192 | 1238 | break; |
|---|
| 1193 | 1239 | |
|---|
| 1194 | 1240 | /* 1-byte return value commands */ |
|---|
| 1195 | | - case MCE_RSP_EQEMVER: |
|---|
| 1196 | | - ir->emver = hi; |
|---|
| 1197 | | - break; |
|---|
| 1198 | 1241 | case MCE_RSP_EQIRTXPORTS: |
|---|
| 1199 | | - ir->tx_mask = hi; |
|---|
| 1242 | + ir->tx_mask = *hi; |
|---|
| 1200 | 1243 | break; |
|---|
| 1201 | 1244 | case MCE_RSP_EQIRRXPORTEN: |
|---|
| 1202 | | - ir->learning_active = ((hi & 0x02) == 0x02); |
|---|
| 1203 | | - if (ir->rxports_active != hi) { |
|---|
| 1245 | + ir->learning_active = ((*hi & 0x02) == 0x02); |
|---|
| 1246 | + if (ir->rxports_active != *hi) { |
|---|
| 1204 | 1247 | dev_info(ir->dev, "%s-range (0x%x) receiver active", |
|---|
| 1205 | | - ir->learning_active ? "short" : "long", hi); |
|---|
| 1206 | | - ir->rxports_active = hi; |
|---|
| 1248 | + ir->learning_active ? "short" : "long", *hi); |
|---|
| 1249 | + ir->rxports_active = *hi; |
|---|
| 1207 | 1250 | } |
|---|
| 1208 | 1251 | break; |
|---|
| 1252 | + |
|---|
| 1253 | + /* No return value commands */ |
|---|
| 1209 | 1254 | case MCE_RSP_CMD_ILLEGAL: |
|---|
| 1210 | 1255 | case MCE_RSP_TX_TIMEOUT: |
|---|
| 1211 | 1256 | ir->need_reset = true; |
|---|
| 1212 | 1257 | break; |
|---|
| 1258 | + |
|---|
| 1213 | 1259 | default: |
|---|
| 1214 | 1260 | break; |
|---|
| 1215 | 1261 | } |
|---|
| .. | .. |
|---|
| 1217 | 1263 | |
|---|
| 1218 | 1264 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) |
|---|
| 1219 | 1265 | { |
|---|
| 1220 | | - DEFINE_IR_RAW_EVENT(rawir); |
|---|
| 1266 | + struct ir_raw_event rawir = {}; |
|---|
| 1221 | 1267 | bool event = false; |
|---|
| 1222 | 1268 | int i = 0; |
|---|
| 1223 | 1269 | |
|---|
| .. | .. |
|---|
| 1235 | 1281 | ir->rem = mceusb_cmd_datasize(ir->cmd, ir->buf_in[i]); |
|---|
| 1236 | 1282 | mceusb_dev_printdata(ir, ir->buf_in, buf_len, i - 1, |
|---|
| 1237 | 1283 | ir->rem + 2, false); |
|---|
| 1238 | | - mceusb_handle_command(ir, i); |
|---|
| 1284 | + if (i + ir->rem < buf_len) |
|---|
| 1285 | + mceusb_handle_command(ir, &ir->buf_in[i - 1]); |
|---|
| 1239 | 1286 | ir->parser_state = CMD_DATA; |
|---|
| 1240 | 1287 | break; |
|---|
| 1241 | 1288 | case PARSE_IRDATA: |
|---|
| 1242 | 1289 | ir->rem--; |
|---|
| 1243 | | - init_ir_raw_event(&rawir); |
|---|
| 1244 | 1290 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); |
|---|
| 1245 | 1291 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK); |
|---|
| 1246 | 1292 | if (unlikely(!rawir.duration)) { |
|---|
| 1247 | | - dev_warn(ir->dev, "nonsensical irdata %02x with duration 0", |
|---|
| 1248 | | - ir->buf_in[i]); |
|---|
| 1293 | + dev_dbg(ir->dev, "nonsensical irdata %02x with duration 0", |
|---|
| 1294 | + ir->buf_in[i]); |
|---|
| 1249 | 1295 | break; |
|---|
| 1250 | 1296 | } |
|---|
| 1251 | 1297 | if (rawir.pulse) { |
|---|
| 1252 | 1298 | ir->pulse_tunit += rawir.duration; |
|---|
| 1253 | 1299 | ir->pulse_count++; |
|---|
| 1254 | 1300 | } |
|---|
| 1255 | | - rawir.duration *= US_TO_NS(MCE_TIME_UNIT); |
|---|
| 1301 | + rawir.duration *= MCE_TIME_UNIT; |
|---|
| 1256 | 1302 | |
|---|
| 1257 | | - dev_dbg(ir->dev, "Storing %s %u ns (%02x)", |
|---|
| 1303 | + dev_dbg(ir->dev, "Storing %s %u us (%02x)", |
|---|
| 1258 | 1304 | rawir.pulse ? "pulse" : "space", |
|---|
| 1259 | 1305 | rawir.duration, ir->buf_in[i]); |
|---|
| 1260 | 1306 | |
|---|
| .. | .. |
|---|
| 1265 | 1311 | ir->rem--; |
|---|
| 1266 | 1312 | break; |
|---|
| 1267 | 1313 | case CMD_HEADER: |
|---|
| 1268 | | - /* decode mce packets of the form (84),AA,BB,CC,DD */ |
|---|
| 1269 | | - /* IR data packets can span USB messages - rem */ |
|---|
| 1270 | 1314 | ir->cmd = ir->buf_in[i]; |
|---|
| 1271 | 1315 | if ((ir->cmd == MCE_CMD_PORT_IR) || |
|---|
| 1272 | 1316 | ((ir->cmd & MCE_PORT_MASK) != |
|---|
| 1273 | 1317 | MCE_COMMAND_IRDATA)) { |
|---|
| 1318 | + /* |
|---|
| 1319 | + * got PORT_SYS, PORT_IR, or unknown |
|---|
| 1320 | + * command response prefix |
|---|
| 1321 | + */ |
|---|
| 1274 | 1322 | ir->parser_state = SUBCMD; |
|---|
| 1275 | 1323 | continue; |
|---|
| 1276 | 1324 | } |
|---|
| 1325 | + /* |
|---|
| 1326 | + * got IR data prefix (0x80 + num_bytes) |
|---|
| 1327 | + * decode MCE packets of the form {0x83, AA, BB, CC} |
|---|
| 1328 | + * IR data packets can span USB messages |
|---|
| 1329 | + */ |
|---|
| 1277 | 1330 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); |
|---|
| 1278 | 1331 | mceusb_dev_printdata(ir, ir->buf_in, buf_len, |
|---|
| 1279 | 1332 | i, ir->rem + 1, false); |
|---|
| 1280 | 1333 | if (ir->rem) { |
|---|
| 1281 | 1334 | ir->parser_state = PARSE_IRDATA; |
|---|
| 1282 | 1335 | } else { |
|---|
| 1283 | | - init_ir_raw_event(&rawir); |
|---|
| 1284 | | - rawir.timeout = 1; |
|---|
| 1285 | | - rawir.duration = ir->rc->timeout; |
|---|
| 1336 | + struct ir_raw_event ev = { |
|---|
| 1337 | + .timeout = 1, |
|---|
| 1338 | + .duration = ir->rc->timeout |
|---|
| 1339 | + }; |
|---|
| 1340 | + |
|---|
| 1286 | 1341 | if (ir_raw_event_store_with_filter(ir->rc, |
|---|
| 1287 | | - &rawir)) |
|---|
| 1342 | + &ev)) |
|---|
| 1288 | 1343 | event = true; |
|---|
| 1289 | 1344 | ir->pulse_tunit = 0; |
|---|
| 1290 | 1345 | ir->pulse_count = 0; |
|---|
| .. | .. |
|---|
| 1295 | 1350 | if (ir->parser_state != CMD_HEADER && !ir->rem) |
|---|
| 1296 | 1351 | ir->parser_state = CMD_HEADER; |
|---|
| 1297 | 1352 | } |
|---|
| 1353 | + |
|---|
| 1354 | + /* |
|---|
| 1355 | + * Accept IR data spanning multiple rx buffers. |
|---|
| 1356 | + * Reject MCE command response spanning multiple rx buffers. |
|---|
| 1357 | + */ |
|---|
| 1358 | + if (ir->parser_state != PARSE_IRDATA || !ir->rem) |
|---|
| 1359 | + ir->parser_state = CMD_HEADER; |
|---|
| 1360 | + |
|---|
| 1298 | 1361 | if (event) { |
|---|
| 1299 | 1362 | dev_dbg(ir->dev, "processed IR data"); |
|---|
| 1300 | 1363 | ir_raw_event_handle(ir->rc); |
|---|
| .. | .. |
|---|
| 1353 | 1416 | { |
|---|
| 1354 | 1417 | int ret; |
|---|
| 1355 | 1418 | struct device *dev = ir->dev; |
|---|
| 1356 | | - char *data; |
|---|
| 1357 | | - |
|---|
| 1358 | | - data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); |
|---|
| 1359 | | - if (!data) { |
|---|
| 1360 | | - dev_err(dev, "%s: memory allocation failed!", __func__); |
|---|
| 1361 | | - return; |
|---|
| 1362 | | - } |
|---|
| 1419 | + char data[USB_CTRL_MSG_SZ]; |
|---|
| 1363 | 1420 | |
|---|
| 1364 | 1421 | /* |
|---|
| 1365 | 1422 | * This is a strange one. Windows issues a set address to the device |
|---|
| 1366 | 1423 | * on the receive control pipe and expect a certain value pair back |
|---|
| 1367 | 1424 | */ |
|---|
| 1368 | | - ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
|---|
| 1369 | | - USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, |
|---|
| 1370 | | - data, USB_CTRL_MSG_SZ, 3000); |
|---|
| 1425 | + ret = usb_control_msg_recv(ir->usbdev, 0, USB_REQ_SET_ADDRESS, |
|---|
| 1426 | + USB_DIR_IN | USB_TYPE_VENDOR, |
|---|
| 1427 | + 0, 0, data, USB_CTRL_MSG_SZ, 3000, |
|---|
| 1428 | + GFP_KERNEL); |
|---|
| 1371 | 1429 | dev_dbg(dev, "set address - ret = %d", ret); |
|---|
| 1372 | 1430 | dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", |
|---|
| 1373 | 1431 | data[0], data[1]); |
|---|
| 1374 | 1432 | |
|---|
| 1375 | 1433 | /* set feature: bit rate 38400 bps */ |
|---|
| 1376 | | - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
|---|
| 1377 | | - USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
|---|
| 1378 | | - 0xc04e, 0x0000, NULL, 0, 3000); |
|---|
| 1434 | + ret = usb_control_msg_send(ir->usbdev, 0, |
|---|
| 1435 | + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
|---|
| 1436 | + 0xc04e, 0x0000, NULL, 0, 3000, GFP_KERNEL); |
|---|
| 1379 | 1437 | |
|---|
| 1380 | 1438 | dev_dbg(dev, "set feature - ret = %d", ret); |
|---|
| 1381 | 1439 | |
|---|
| 1382 | 1440 | /* bRequest 4: set char length to 8 bits */ |
|---|
| 1383 | | - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
|---|
| 1384 | | - 4, USB_TYPE_VENDOR, |
|---|
| 1385 | | - 0x0808, 0x0000, NULL, 0, 3000); |
|---|
| 1441 | + ret = usb_control_msg_send(ir->usbdev, 0, |
|---|
| 1442 | + 4, USB_TYPE_VENDOR, |
|---|
| 1443 | + 0x0808, 0x0000, NULL, 0, 3000, GFP_KERNEL); |
|---|
| 1386 | 1444 | dev_dbg(dev, "set char length - retB = %d", ret); |
|---|
| 1387 | 1445 | |
|---|
| 1388 | 1446 | /* bRequest 2: set handshaking to use DTR/DSR */ |
|---|
| 1389 | | - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
|---|
| 1390 | | - 2, USB_TYPE_VENDOR, |
|---|
| 1391 | | - 0x0000, 0x0100, NULL, 0, 3000); |
|---|
| 1447 | + ret = usb_control_msg_send(ir->usbdev, 0, |
|---|
| 1448 | + 2, USB_TYPE_VENDOR, |
|---|
| 1449 | + 0x0000, 0x0100, NULL, 0, 3000, GFP_KERNEL); |
|---|
| 1392 | 1450 | dev_dbg(dev, "set handshake - retC = %d", ret); |
|---|
| 1393 | 1451 | |
|---|
| 1394 | 1452 | /* device resume */ |
|---|
| .. | .. |
|---|
| 1396 | 1454 | |
|---|
| 1397 | 1455 | /* get hw/sw revision? */ |
|---|
| 1398 | 1456 | mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
|---|
| 1399 | | - |
|---|
| 1400 | | - kfree(data); |
|---|
| 1401 | 1457 | } |
|---|
| 1402 | 1458 | |
|---|
| 1403 | 1459 | static void mceusb_gen2_init(struct mceusb_dev *ir) |
|---|
| .. | .. |
|---|
| 1465 | 1521 | container_of(work, struct mceusb_dev, kevent); |
|---|
| 1466 | 1522 | int status; |
|---|
| 1467 | 1523 | |
|---|
| 1524 | + dev_err(ir->dev, "kevent handler called (flags 0x%lx)", |
|---|
| 1525 | + ir->kevent_flags); |
|---|
| 1526 | + |
|---|
| 1527 | + if (test_bit(EVENT_RST_PEND, &ir->kevent_flags)) { |
|---|
| 1528 | + dev_err(ir->dev, "kevent handler canceled pending USB Reset Device"); |
|---|
| 1529 | + return; |
|---|
| 1530 | + } |
|---|
| 1531 | + |
|---|
| 1468 | 1532 | if (test_bit(EVENT_RX_HALT, &ir->kevent_flags)) { |
|---|
| 1469 | 1533 | usb_unlink_urb(ir->urb_in); |
|---|
| 1470 | 1534 | status = usb_clear_halt(ir->usbdev, ir->pipe_in); |
|---|
| 1535 | + dev_err(ir->dev, "rx clear halt status = %d", status); |
|---|
| 1471 | 1536 | if (status < 0) { |
|---|
| 1472 | | - dev_err(ir->dev, "rx clear halt error %d", |
|---|
| 1473 | | - status); |
|---|
| 1537 | + /* |
|---|
| 1538 | + * Unable to clear RX halt/stall. |
|---|
| 1539 | + * Will need to call usb_reset_device(). |
|---|
| 1540 | + */ |
|---|
| 1541 | + dev_err(ir->dev, |
|---|
| 1542 | + "stuck RX HALT state requires USB Reset Device to clear"); |
|---|
| 1543 | + usb_queue_reset_device(ir->usbintf); |
|---|
| 1544 | + set_bit(EVENT_RST_PEND, &ir->kevent_flags); |
|---|
| 1545 | + clear_bit(EVENT_RX_HALT, &ir->kevent_flags); |
|---|
| 1546 | + |
|---|
| 1547 | + /* Cancel all other error events and handlers */ |
|---|
| 1548 | + clear_bit(EVENT_TX_HALT, &ir->kevent_flags); |
|---|
| 1549 | + return; |
|---|
| 1474 | 1550 | } |
|---|
| 1475 | 1551 | clear_bit(EVENT_RX_HALT, &ir->kevent_flags); |
|---|
| 1476 | | - if (status == 0) { |
|---|
| 1477 | | - status = usb_submit_urb(ir->urb_in, GFP_KERNEL); |
|---|
| 1478 | | - if (status < 0) { |
|---|
| 1479 | | - dev_err(ir->dev, |
|---|
| 1480 | | - "rx unhalt submit urb error %d", |
|---|
| 1481 | | - status); |
|---|
| 1482 | | - } |
|---|
| 1552 | + status = usb_submit_urb(ir->urb_in, GFP_KERNEL); |
|---|
| 1553 | + if (status < 0) { |
|---|
| 1554 | + dev_err(ir->dev, "rx unhalt submit urb error = %d", |
|---|
| 1555 | + status); |
|---|
| 1483 | 1556 | } |
|---|
| 1484 | 1557 | } |
|---|
| 1485 | 1558 | |
|---|
| 1486 | 1559 | if (test_bit(EVENT_TX_HALT, &ir->kevent_flags)) { |
|---|
| 1487 | 1560 | status = usb_clear_halt(ir->usbdev, ir->pipe_out); |
|---|
| 1488 | | - if (status < 0) |
|---|
| 1489 | | - dev_err(ir->dev, "tx clear halt error %d", status); |
|---|
| 1561 | + dev_err(ir->dev, "tx clear halt status = %d", status); |
|---|
| 1562 | + if (status < 0) { |
|---|
| 1563 | + /* |
|---|
| 1564 | + * Unable to clear TX halt/stall. |
|---|
| 1565 | + * Will need to call usb_reset_device(). |
|---|
| 1566 | + */ |
|---|
| 1567 | + dev_err(ir->dev, |
|---|
| 1568 | + "stuck TX HALT state requires USB Reset Device to clear"); |
|---|
| 1569 | + usb_queue_reset_device(ir->usbintf); |
|---|
| 1570 | + set_bit(EVENT_RST_PEND, &ir->kevent_flags); |
|---|
| 1571 | + clear_bit(EVENT_TX_HALT, &ir->kevent_flags); |
|---|
| 1572 | + |
|---|
| 1573 | + /* Cancel all other error events and handlers */ |
|---|
| 1574 | + clear_bit(EVENT_RX_HALT, &ir->kevent_flags); |
|---|
| 1575 | + return; |
|---|
| 1576 | + } |
|---|
| 1490 | 1577 | clear_bit(EVENT_TX_HALT, &ir->kevent_flags); |
|---|
| 1491 | 1578 | } |
|---|
| 1492 | 1579 | } |
|---|
| .. | .. |
|---|
| 1519 | 1606 | rc->dev.parent = dev; |
|---|
| 1520 | 1607 | rc->priv = ir; |
|---|
| 1521 | 1608 | rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; |
|---|
| 1522 | | - rc->min_timeout = US_TO_NS(MCE_TIME_UNIT); |
|---|
| 1523 | | - rc->timeout = MS_TO_NS(100); |
|---|
| 1609 | + rc->min_timeout = MCE_TIME_UNIT; |
|---|
| 1610 | + rc->timeout = MS_TO_US(100); |
|---|
| 1524 | 1611 | if (!mceusb_model[ir->model].broken_irtimeout) { |
|---|
| 1525 | 1612 | rc->s_timeout = mceusb_set_timeout; |
|---|
| 1526 | 1613 | rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; |
|---|
| .. | .. |
|---|
| 1640 | 1727 | goto mem_alloc_fail; |
|---|
| 1641 | 1728 | |
|---|
| 1642 | 1729 | ir->pipe_in = pipe; |
|---|
| 1643 | | - ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in); |
|---|
| 1730 | + ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_KERNEL, &ir->dma_in); |
|---|
| 1644 | 1731 | if (!ir->buf_in) |
|---|
| 1645 | 1732 | goto buf_in_alloc_fail; |
|---|
| 1646 | 1733 | |
|---|
| .. | .. |
|---|
| 1648 | 1735 | if (!ir->urb_in) |
|---|
| 1649 | 1736 | goto urb_in_alloc_fail; |
|---|
| 1650 | 1737 | |
|---|
| 1738 | + ir->usbintf = intf; |
|---|
| 1651 | 1739 | ir->usbdev = usb_get_dev(dev); |
|---|
| 1652 | 1740 | ir->dev = &intf->dev; |
|---|
| 1653 | 1741 | ir->len_in = maxp; |
|---|
| .. | .. |
|---|
| 1669 | 1757 | if (dev->descriptor.iManufacturer |
|---|
| 1670 | 1758 | && usb_string(dev, dev->descriptor.iManufacturer, |
|---|
| 1671 | 1759 | buf, sizeof(buf)) > 0) |
|---|
| 1672 | | - strlcpy(name, buf, sizeof(name)); |
|---|
| 1760 | + strscpy(name, buf, sizeof(name)); |
|---|
| 1673 | 1761 | if (dev->descriptor.iProduct |
|---|
| 1674 | 1762 | && usb_string(dev, dev->descriptor.iProduct, |
|---|
| 1675 | 1763 | buf, sizeof(buf)) > 0) |
|---|
| .. | .. |
|---|
| 1755 | 1843 | struct usb_device *dev = interface_to_usbdev(intf); |
|---|
| 1756 | 1844 | struct mceusb_dev *ir = usb_get_intfdata(intf); |
|---|
| 1757 | 1845 | |
|---|
| 1846 | + dev_dbg(&intf->dev, "%s called", __func__); |
|---|
| 1847 | + |
|---|
| 1758 | 1848 | usb_set_intfdata(intf, NULL); |
|---|
| 1759 | 1849 | |
|---|
| 1760 | 1850 | if (!ir) |
|---|