.. | .. |
---|
| 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) |
---|