| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Core IEEE1394 transaction logic |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2004-2006 Kristian Hoegsberg <krh@bitplanet.net> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; if not, write to the Free Software Foundation, |
|---|
| 18 | | - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 19 | 6 | */ |
|---|
| 20 | 7 | |
|---|
| 21 | 8 | #include <linux/bug.h> |
|---|
| .. | .. |
|---|
| 86 | 73 | static int close_transaction(struct fw_transaction *transaction, |
|---|
| 87 | 74 | struct fw_card *card, int rcode) |
|---|
| 88 | 75 | { |
|---|
| 89 | | - struct fw_transaction *t; |
|---|
| 76 | + struct fw_transaction *t = NULL, *iter; |
|---|
| 90 | 77 | unsigned long flags; |
|---|
| 91 | 78 | |
|---|
| 92 | 79 | spin_lock_irqsave(&card->lock, flags); |
|---|
| 93 | | - list_for_each_entry(t, &card->transaction_list, link) { |
|---|
| 94 | | - if (t == transaction) { |
|---|
| 95 | | - if (!try_cancel_split_timeout(t)) { |
|---|
| 80 | + list_for_each_entry(iter, &card->transaction_list, link) { |
|---|
| 81 | + if (iter == transaction) { |
|---|
| 82 | + if (!try_cancel_split_timeout(iter)) { |
|---|
| 96 | 83 | spin_unlock_irqrestore(&card->lock, flags); |
|---|
| 97 | 84 | goto timed_out; |
|---|
| 98 | 85 | } |
|---|
| 99 | | - list_del_init(&t->link); |
|---|
| 100 | | - card->tlabel_mask &= ~(1ULL << t->tlabel); |
|---|
| 86 | + list_del_init(&iter->link); |
|---|
| 87 | + card->tlabel_mask &= ~(1ULL << iter->tlabel); |
|---|
| 88 | + t = iter; |
|---|
| 101 | 89 | break; |
|---|
| 102 | 90 | } |
|---|
| 103 | 91 | } |
|---|
| 104 | 92 | spin_unlock_irqrestore(&card->lock, flags); |
|---|
| 105 | 93 | |
|---|
| 106 | | - if (&t->link != &card->transaction_list) { |
|---|
| 94 | + if (t) { |
|---|
| 107 | 95 | t->callback(card, rcode, NULL, 0, t->callback_data); |
|---|
| 108 | 96 | return 0; |
|---|
| 109 | 97 | } |
|---|
| .. | .. |
|---|
| 410 | 398 | |
|---|
| 411 | 399 | /** |
|---|
| 412 | 400 | * fw_run_transaction() - send request and sleep until transaction is completed |
|---|
| 401 | + * @card: card interface for this request |
|---|
| 402 | + * @tcode: transaction code |
|---|
| 403 | + * @destination_id: destination node ID, consisting of bus_ID and phy_ID |
|---|
| 404 | + * @generation: bus generation in which request and response are valid |
|---|
| 405 | + * @speed: transmission speed |
|---|
| 406 | + * @offset: 48bit wide offset into destination's address space |
|---|
| 407 | + * @payload: data payload for the request subaction |
|---|
| 408 | + * @length: length of the payload, in bytes |
|---|
| 413 | 409 | * |
|---|
| 414 | 410 | * Returns the RCODE. See fw_send_request() for parameter documentation. |
|---|
| 415 | 411 | * Unlike fw_send_request(), @data points to the payload of the request or/and |
|---|
| .. | .. |
|---|
| 604 | 600 | |
|---|
| 605 | 601 | /** |
|---|
| 606 | 602 | * fw_core_remove_address_handler() - unregister an address handler |
|---|
| 603 | + * @handler: callback |
|---|
| 607 | 604 | * |
|---|
| 608 | 605 | * To be called in process context. |
|---|
| 609 | 606 | * |
|---|
| .. | .. |
|---|
| 624 | 621 | u32 request_header[4]; |
|---|
| 625 | 622 | int ack; |
|---|
| 626 | 623 | u32 length; |
|---|
| 627 | | - u32 data[0]; |
|---|
| 624 | + u32 data[]; |
|---|
| 628 | 625 | }; |
|---|
| 629 | 626 | |
|---|
| 630 | 627 | static void free_response_callback(struct fw_packet *packet, |
|---|
| .. | .. |
|---|
| 828 | 825 | |
|---|
| 829 | 826 | /** |
|---|
| 830 | 827 | * fw_get_request_speed() - returns speed at which the @request was received |
|---|
| 828 | + * @request: firewire request data |
|---|
| 831 | 829 | */ |
|---|
| 832 | 830 | int fw_get_request_speed(struct fw_request *request) |
|---|
| 833 | 831 | { |
|---|
| .. | .. |
|---|
| 938 | 936 | |
|---|
| 939 | 937 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) |
|---|
| 940 | 938 | { |
|---|
| 941 | | - struct fw_transaction *t; |
|---|
| 939 | + struct fw_transaction *t = NULL, *iter; |
|---|
| 942 | 940 | unsigned long flags; |
|---|
| 943 | 941 | u32 *data; |
|---|
| 944 | 942 | size_t data_length; |
|---|
| .. | .. |
|---|
| 950 | 948 | rcode = HEADER_GET_RCODE(p->header[1]); |
|---|
| 951 | 949 | |
|---|
| 952 | 950 | spin_lock_irqsave(&card->lock, flags); |
|---|
| 953 | | - list_for_each_entry(t, &card->transaction_list, link) { |
|---|
| 954 | | - if (t->node_id == source && t->tlabel == tlabel) { |
|---|
| 955 | | - if (!try_cancel_split_timeout(t)) { |
|---|
| 951 | + list_for_each_entry(iter, &card->transaction_list, link) { |
|---|
| 952 | + if (iter->node_id == source && iter->tlabel == tlabel) { |
|---|
| 953 | + if (!try_cancel_split_timeout(iter)) { |
|---|
| 956 | 954 | spin_unlock_irqrestore(&card->lock, flags); |
|---|
| 957 | 955 | goto timed_out; |
|---|
| 958 | 956 | } |
|---|
| 959 | | - list_del_init(&t->link); |
|---|
| 960 | | - card->tlabel_mask &= ~(1ULL << t->tlabel); |
|---|
| 957 | + list_del_init(&iter->link); |
|---|
| 958 | + card->tlabel_mask &= ~(1ULL << iter->tlabel); |
|---|
| 959 | + t = iter; |
|---|
| 961 | 960 | break; |
|---|
| 962 | 961 | } |
|---|
| 963 | 962 | } |
|---|
| 964 | 963 | spin_unlock_irqrestore(&card->lock, flags); |
|---|
| 965 | 964 | |
|---|
| 966 | | - if (&t->link == &card->transaction_list) { |
|---|
| 965 | + if (!t) { |
|---|
| 967 | 966 | timed_out: |
|---|
| 968 | 967 | fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", |
|---|
| 969 | 968 | source, tlabel); |
|---|
| .. | .. |
|---|
| 1100 | 1099 | rcode = RCODE_ADDRESS_ERROR; |
|---|
| 1101 | 1100 | break; |
|---|
| 1102 | 1101 | } |
|---|
| 1103 | | - /* else fall through */ |
|---|
| 1102 | + fallthrough; |
|---|
| 1104 | 1103 | |
|---|
| 1105 | 1104 | case CSR_NODE_IDS: |
|---|
| 1106 | 1105 | /* |
|---|
| 1107 | 1106 | * per IEEE 1394-2008 8.3.22.3, not IEEE 1394.1-2004 3.2.8 |
|---|
| 1108 | 1107 | * and 9.6, but interoperable with IEEE 1394.1-2004 bridges |
|---|
| 1109 | 1108 | */ |
|---|
| 1110 | | - /* fall through */ |
|---|
| 1109 | + fallthrough; |
|---|
| 1111 | 1110 | |
|---|
| 1112 | 1111 | case CSR_STATE_CLEAR: |
|---|
| 1113 | 1112 | case CSR_STATE_SET: |
|---|