summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/core-cdev.c16
-rw-r--r--drivers/firewire/core-transaction.c20
-rw-r--r--drivers/firewire/core.h6
-rw-r--r--include/linux/firewire.h5
4 files changed, 25 insertions, 22 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 93dd80d8d4e1..7fa49e51bae8 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -111,6 +111,7 @@ struct inbound_transaction_resource {
struct client_resource resource;
struct fw_card *card;
struct fw_request *request;
+ bool is_fcp;
void *data;
size_t length;
};
@@ -643,18 +644,13 @@ static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
client->device->max_speed);
}
-static inline bool is_fcp_request(struct fw_request *request)
-{
- return request == NULL;
-}
-
static void release_request(struct client *client,
struct client_resource *resource)
{
struct inbound_transaction_resource *r = container_of(resource,
struct inbound_transaction_resource, resource);
- if (is_fcp_request(r->request))
+ if (r->is_fcp)
kfree(r->data);
else
fw_send_response(r->card, r->request, RCODE_CONFLICT_ERROR);
@@ -669,6 +665,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
void *payload, size_t length, void *callback_data)
{
struct address_handler_resource *handler = callback_data;
+ bool is_fcp = is_in_fcp_region(offset, length);
struct inbound_transaction_resource *r;
struct inbound_transaction_event *e;
size_t event_size0;
@@ -685,10 +682,11 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
r->card = card;
r->request = request;
+ r->is_fcp = is_fcp;
r->data = payload;
r->length = length;
- if (is_fcp_request(request)) {
+ if (is_fcp) {
/*
* FIXME: Let core-transaction.c manage a
* single reference-counted copy?
@@ -743,7 +741,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
kfree(e);
kfree(fcp_frame);
- if (!is_fcp_request(request))
+ if (!is_fcp)
fw_send_response(card, request, RCODE_CONFLICT_ERROR);
fw_card_put(card);
@@ -819,7 +817,7 @@ static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
r = container_of(resource, struct inbound_transaction_resource,
resource);
- if (is_fcp_request(r->request)) {
+ if (r->is_fcp) {
kfree(r->data);
goto out;
}
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 83f61cf1aa8f..a9f70c96323e 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -535,12 +535,6 @@ const struct fw_address_region fw_unit_space_region =
{ .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
#endif /* 0 */
-static bool is_in_fcp_region(u64 offset, size_t length)
-{
- return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
- offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
-}
-
/**
* fw_core_add_address_handler() - register for incoming requests
* @handler: callback
@@ -822,12 +816,18 @@ static struct fw_request *allocate_request(struct fw_card *card,
return request;
}
+/**
+ * fw_send_response: - send response packet for asynchronous transaction.
+ * @card: interface to send the response at.
+ * @request: firewire request data for the transaction.
+ * @rcode: response code to send.
+ *
+ * Submit a response packet into the asynchronous response transmission queue. The @request
+ * is going to be released when the transmission successfully finishes later.
+ */
void fw_send_response(struct fw_card *card,
struct fw_request *request, int rcode)
{
- if (WARN_ONCE(!request, "invalid for FCP address handlers"))
- return;
-
/* unified transaction or broadcast transaction: don't respond */
if (request->ack != ACK_PENDING ||
HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
@@ -935,7 +935,7 @@ static void handle_fcp_region_request(struct fw_card *card,
rcu_read_lock();
list_for_each_entry_rcu(handler, &address_handler_list, link) {
if (is_enclosing_handler(handler, offset, request->length))
- handler->address_callback(card, NULL, tcode,
+ handler->address_callback(card, request, tcode,
destination, source,
p->generation, offset,
request->data,
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index 78c99f1d27fa..eafa4eaae737 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -257,4 +257,10 @@ static inline bool is_ping_packet(u32 *data)
return (data[0] & 0xc0ffffff) == 0 && ~data[0] == data[1];
}
+static inline bool is_in_fcp_region(u64 offset, size_t length)
+{
+ return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
+ offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
+}
+
#endif /* _FIREWIRE_CORE_H */
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 980019053e54..56505436d159 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -278,9 +278,8 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
* Otherwise there is a danger of recursion of inbound and outbound
* transactions from and to the local node.
*
- * The callback is responsible that either fw_send_response() or kfree()
- * is called on the @request, except for FCP registers for which the core
- * takes care of that.
+ * The callback is responsible that fw_send_response() is called on the @request, except for FCP
+ * registers for which the core takes care of that.
*/
typedef void (*fw_address_callback_t)(struct fw_card *card,
struct fw_request *request,