xref: /linux/sound/firewire/fcp.c (revision 1017abed18ae7087e7f3e256c48421d09d83176e)
131ef9134SClemens Ladisch /*
231ef9134SClemens Ladisch  * Function Control Protocol (IEC 61883-1) helper functions
331ef9134SClemens Ladisch  *
431ef9134SClemens Ladisch  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
531ef9134SClemens Ladisch  * Licensed under the terms of the GNU General Public License, version 2.
631ef9134SClemens Ladisch  */
731ef9134SClemens Ladisch 
831ef9134SClemens Ladisch #include <linux/device.h>
931ef9134SClemens Ladisch #include <linux/firewire.h>
1031ef9134SClemens Ladisch #include <linux/firewire-constants.h>
1131ef9134SClemens Ladisch #include <linux/list.h>
1231ef9134SClemens Ladisch #include <linux/module.h>
13*1017abedSTakashi Sakamoto #include <linux/slab.h>
1431ef9134SClemens Ladisch #include <linux/sched.h>
1531ef9134SClemens Ladisch #include <linux/spinlock.h>
1631ef9134SClemens Ladisch #include <linux/wait.h>
175de0ee57SStephen Rothwell #include <linux/delay.h>
1831ef9134SClemens Ladisch #include "fcp.h"
1931ef9134SClemens Ladisch #include "lib.h"
20*1017abedSTakashi Sakamoto #include "amdtp.h"
2131ef9134SClemens Ladisch 
2231ef9134SClemens Ladisch #define CTS_AVC 0x00
2331ef9134SClemens Ladisch 
2431ef9134SClemens Ladisch #define ERROR_RETRIES	3
2531ef9134SClemens Ladisch #define ERROR_DELAY_MS	5
2631ef9134SClemens Ladisch #define FCP_TIMEOUT_MS	125
2731ef9134SClemens Ladisch 
28*1017abedSTakashi Sakamoto int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate,
29*1017abedSTakashi Sakamoto 			    enum avc_general_plug_dir dir,
30*1017abedSTakashi Sakamoto 			    unsigned short pid)
31*1017abedSTakashi Sakamoto {
32*1017abedSTakashi Sakamoto 	unsigned int sfc;
33*1017abedSTakashi Sakamoto 	u8 *buf;
34*1017abedSTakashi Sakamoto 	bool flag;
35*1017abedSTakashi Sakamoto 	int err;
36*1017abedSTakashi Sakamoto 
37*1017abedSTakashi Sakamoto 	flag = false;
38*1017abedSTakashi Sakamoto 	for (sfc = 0; sfc < CIP_SFC_COUNT; sfc++) {
39*1017abedSTakashi Sakamoto 		if (amdtp_rate_table[sfc] == rate) {
40*1017abedSTakashi Sakamoto 			flag = true;
41*1017abedSTakashi Sakamoto 			break;
42*1017abedSTakashi Sakamoto 		}
43*1017abedSTakashi Sakamoto 	}
44*1017abedSTakashi Sakamoto 	if (!flag)
45*1017abedSTakashi Sakamoto 		return -EINVAL;
46*1017abedSTakashi Sakamoto 
47*1017abedSTakashi Sakamoto 	buf = kzalloc(8, GFP_KERNEL);
48*1017abedSTakashi Sakamoto 	if (buf == NULL)
49*1017abedSTakashi Sakamoto 		return -ENOMEM;
50*1017abedSTakashi Sakamoto 
51*1017abedSTakashi Sakamoto 	buf[0] = 0x00;		/* AV/C CONTROL */
52*1017abedSTakashi Sakamoto 	buf[1] = 0xff;		/* UNIT */
53*1017abedSTakashi Sakamoto 	if (dir == AVC_GENERAL_PLUG_DIR_IN)
54*1017abedSTakashi Sakamoto 		buf[2] = 0x19;	/* INPUT PLUG SIGNAL FORMAT */
55*1017abedSTakashi Sakamoto 	else
56*1017abedSTakashi Sakamoto 		buf[2] = 0x18;	/* OUTPUT PLUG SIGNAL FORMAT */
57*1017abedSTakashi Sakamoto 	buf[3] = 0xff & pid;	/* plug id */
58*1017abedSTakashi Sakamoto 	buf[4] = 0x90;		/* EOH_1, Form_1, FMT. AM824 */
59*1017abedSTakashi Sakamoto 	buf[5] = 0x07 & sfc;	/* FDF-hi. AM824, frequency */
60*1017abedSTakashi Sakamoto 	buf[6] = 0xff;		/* FDF-mid. AM824, SYT hi (not used)*/
61*1017abedSTakashi Sakamoto 	buf[7] = 0xff;		/* FDF-low. AM824, SYT lo (not used) */
62*1017abedSTakashi Sakamoto 
63*1017abedSTakashi Sakamoto 	/* do transaction and check buf[1-5] are the same against command */
64*1017abedSTakashi Sakamoto 	err = fcp_avc_transaction(unit, buf, 8, buf, 8,
65*1017abedSTakashi Sakamoto 				  BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
66*1017abedSTakashi Sakamoto 	if (err >= 0 && err < 8)
67*1017abedSTakashi Sakamoto 		err = -EIO;
68*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
69*1017abedSTakashi Sakamoto 		err = -ENOSYS;
70*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x0a) /* REJECTED */
71*1017abedSTakashi Sakamoto 		err = -EINVAL;
72*1017abedSTakashi Sakamoto 	if (err < 0)
73*1017abedSTakashi Sakamoto 		goto end;
74*1017abedSTakashi Sakamoto 
75*1017abedSTakashi Sakamoto 	err = 0;
76*1017abedSTakashi Sakamoto end:
77*1017abedSTakashi Sakamoto 	kfree(buf);
78*1017abedSTakashi Sakamoto 	return err;
79*1017abedSTakashi Sakamoto }
80*1017abedSTakashi Sakamoto EXPORT_SYMBOL(avc_general_set_sig_fmt);
81*1017abedSTakashi Sakamoto 
82*1017abedSTakashi Sakamoto int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate,
83*1017abedSTakashi Sakamoto 			    enum avc_general_plug_dir dir,
84*1017abedSTakashi Sakamoto 			    unsigned short pid)
85*1017abedSTakashi Sakamoto {
86*1017abedSTakashi Sakamoto 	unsigned int sfc;
87*1017abedSTakashi Sakamoto 	u8 *buf;
88*1017abedSTakashi Sakamoto 	int err;
89*1017abedSTakashi Sakamoto 
90*1017abedSTakashi Sakamoto 	buf = kzalloc(8, GFP_KERNEL);
91*1017abedSTakashi Sakamoto 	if (buf == NULL)
92*1017abedSTakashi Sakamoto 		return -ENOMEM;
93*1017abedSTakashi Sakamoto 
94*1017abedSTakashi Sakamoto 	buf[0] = 0x01;		/* AV/C STATUS */
95*1017abedSTakashi Sakamoto 	buf[1] = 0xff;		/* Unit */
96*1017abedSTakashi Sakamoto 	if (dir == AVC_GENERAL_PLUG_DIR_IN)
97*1017abedSTakashi Sakamoto 		buf[2] = 0x19;	/* INPUT PLUG SIGNAL FORMAT */
98*1017abedSTakashi Sakamoto 	else
99*1017abedSTakashi Sakamoto 		buf[2] = 0x18;	/* OUTPUT PLUG SIGNAL FORMAT */
100*1017abedSTakashi Sakamoto 	buf[3] = 0xff & pid;	/* plug id */
101*1017abedSTakashi Sakamoto 	buf[4] = 0x90;		/* EOH_1, Form_1, FMT. AM824 */
102*1017abedSTakashi Sakamoto 	buf[5] = 0xff;		/* FDF-hi. AM824, frequency */
103*1017abedSTakashi Sakamoto 	buf[6] = 0xff;		/* FDF-mid. AM824, SYT hi (not used) */
104*1017abedSTakashi Sakamoto 	buf[7] = 0xff;		/* FDF-low. AM824, SYT lo (not used) */
105*1017abedSTakashi Sakamoto 
106*1017abedSTakashi Sakamoto 	/* do transaction and check buf[1-4] are the same against command */
107*1017abedSTakashi Sakamoto 	err = fcp_avc_transaction(unit, buf, 8, buf, 8,
108*1017abedSTakashi Sakamoto 				  BIT(1) | BIT(2) | BIT(3) | BIT(4));
109*1017abedSTakashi Sakamoto 	if (err >= 0 && err < 8)
110*1017abedSTakashi Sakamoto 		err = -EIO;
111*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
112*1017abedSTakashi Sakamoto 		err = -ENOSYS;
113*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x0a) /* REJECTED */
114*1017abedSTakashi Sakamoto 		err = -EINVAL;
115*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x0b) /* IN TRANSITION */
116*1017abedSTakashi Sakamoto 		err = -EAGAIN;
117*1017abedSTakashi Sakamoto 	if (err < 0)
118*1017abedSTakashi Sakamoto 		goto end;
119*1017abedSTakashi Sakamoto 
120*1017abedSTakashi Sakamoto 	/* check sfc field and pick up rate */
121*1017abedSTakashi Sakamoto 	sfc = 0x07 & buf[5];
122*1017abedSTakashi Sakamoto 	if (sfc >= CIP_SFC_COUNT) {
123*1017abedSTakashi Sakamoto 		err = -EAGAIN;	/* also in transition */
124*1017abedSTakashi Sakamoto 		goto end;
125*1017abedSTakashi Sakamoto 	}
126*1017abedSTakashi Sakamoto 
127*1017abedSTakashi Sakamoto 	*rate = amdtp_rate_table[sfc];
128*1017abedSTakashi Sakamoto 	err = 0;
129*1017abedSTakashi Sakamoto end:
130*1017abedSTakashi Sakamoto 	kfree(buf);
131*1017abedSTakashi Sakamoto 	return err;
132*1017abedSTakashi Sakamoto }
133*1017abedSTakashi Sakamoto EXPORT_SYMBOL(avc_general_get_sig_fmt);
134*1017abedSTakashi Sakamoto 
135*1017abedSTakashi Sakamoto int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type,
136*1017abedSTakashi Sakamoto 			      unsigned int subunit_id, unsigned int subfunction,
137*1017abedSTakashi Sakamoto 			      u8 info[AVC_PLUG_INFO_BUF_BYTES])
138*1017abedSTakashi Sakamoto {
139*1017abedSTakashi Sakamoto 	u8 *buf;
140*1017abedSTakashi Sakamoto 	int err;
141*1017abedSTakashi Sakamoto 
142*1017abedSTakashi Sakamoto 	/* extended subunit in spec.4.2 is not supported */
143*1017abedSTakashi Sakamoto 	if ((subunit_type == 0x1E) || (subunit_id == 5))
144*1017abedSTakashi Sakamoto 		return -EINVAL;
145*1017abedSTakashi Sakamoto 
146*1017abedSTakashi Sakamoto 	buf = kzalloc(8, GFP_KERNEL);
147*1017abedSTakashi Sakamoto 	if (buf == NULL)
148*1017abedSTakashi Sakamoto 		return -ENOMEM;
149*1017abedSTakashi Sakamoto 
150*1017abedSTakashi Sakamoto 	buf[0] = 0x01;	/* AV/C STATUS */
151*1017abedSTakashi Sakamoto 	/* UNIT or Subunit, Functionblock */
152*1017abedSTakashi Sakamoto 	buf[1] = ((subunit_type & 0x1f) << 3) | (subunit_id & 0x7);
153*1017abedSTakashi Sakamoto 	buf[2] = 0x02;	/* PLUG INFO */
154*1017abedSTakashi Sakamoto 	buf[3] = 0xff & subfunction;
155*1017abedSTakashi Sakamoto 
156*1017abedSTakashi Sakamoto 	err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));
157*1017abedSTakashi Sakamoto 	if (err >= 0 && err < 8)
158*1017abedSTakashi Sakamoto 		err = -EIO;
159*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
160*1017abedSTakashi Sakamoto 		err = -ENOSYS;
161*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x0a) /* REJECTED */
162*1017abedSTakashi Sakamoto 		err = -EINVAL;
163*1017abedSTakashi Sakamoto 	else if (buf[0] == 0x0b) /* IN TRANSITION */
164*1017abedSTakashi Sakamoto 		err = -EAGAIN;
165*1017abedSTakashi Sakamoto 	if (err < 0)
166*1017abedSTakashi Sakamoto 		goto end;
167*1017abedSTakashi Sakamoto 
168*1017abedSTakashi Sakamoto 	info[0] = buf[4];
169*1017abedSTakashi Sakamoto 	info[1] = buf[5];
170*1017abedSTakashi Sakamoto 	info[2] = buf[6];
171*1017abedSTakashi Sakamoto 	info[3] = buf[7];
172*1017abedSTakashi Sakamoto 
173*1017abedSTakashi Sakamoto 	err = 0;
174*1017abedSTakashi Sakamoto end:
175*1017abedSTakashi Sakamoto 	kfree(buf);
176*1017abedSTakashi Sakamoto 	return err;
177*1017abedSTakashi Sakamoto }
178*1017abedSTakashi Sakamoto EXPORT_SYMBOL(avc_general_get_plug_info);
179*1017abedSTakashi Sakamoto 
18031ef9134SClemens Ladisch static DEFINE_SPINLOCK(transactions_lock);
18131ef9134SClemens Ladisch static LIST_HEAD(transactions);
18231ef9134SClemens Ladisch 
18331ef9134SClemens Ladisch enum fcp_state {
18431ef9134SClemens Ladisch 	STATE_PENDING,
18531ef9134SClemens Ladisch 	STATE_BUS_RESET,
18631ef9134SClemens Ladisch 	STATE_COMPLETE,
18700a7bb81STakashi Sakamoto 	STATE_DEFERRED,
18831ef9134SClemens Ladisch };
18931ef9134SClemens Ladisch 
19031ef9134SClemens Ladisch struct fcp_transaction {
19131ef9134SClemens Ladisch 	struct list_head list;
19231ef9134SClemens Ladisch 	struct fw_unit *unit;
19331ef9134SClemens Ladisch 	void *response_buffer;
19431ef9134SClemens Ladisch 	unsigned int response_size;
19531ef9134SClemens Ladisch 	unsigned int response_match_bytes;
19631ef9134SClemens Ladisch 	enum fcp_state state;
19731ef9134SClemens Ladisch 	wait_queue_head_t wait;
19800a7bb81STakashi Sakamoto 	bool deferrable;
19931ef9134SClemens Ladisch };
20031ef9134SClemens Ladisch 
20131ef9134SClemens Ladisch /**
20231ef9134SClemens Ladisch  * fcp_avc_transaction - send an AV/C command and wait for its response
20331ef9134SClemens Ladisch  * @unit: a unit on the target device
20431ef9134SClemens Ladisch  * @command: a buffer containing the command frame; must be DMA-able
20531ef9134SClemens Ladisch  * @command_size: the size of @command
20631ef9134SClemens Ladisch  * @response: a buffer for the response frame
20731ef9134SClemens Ladisch  * @response_size: the maximum size of @response
20831ef9134SClemens Ladisch  * @response_match_bytes: a bitmap specifying the bytes used to detect the
20931ef9134SClemens Ladisch  *                        correct response frame
21031ef9134SClemens Ladisch  *
21131ef9134SClemens Ladisch  * This function sends a FCP command frame to the target and waits for the
21231ef9134SClemens Ladisch  * corresponding response frame to be returned.
21331ef9134SClemens Ladisch  *
21431ef9134SClemens Ladisch  * Because it is possible for multiple FCP transactions to be active at the
21531ef9134SClemens Ladisch  * same time, the correct response frame is detected by the value of certain
21631ef9134SClemens Ladisch  * bytes.  These bytes must be set in @response before calling this function,
21731ef9134SClemens Ladisch  * and the corresponding bits must be set in @response_match_bytes.
21831ef9134SClemens Ladisch  *
21931ef9134SClemens Ladisch  * @command and @response can point to the same buffer.
22031ef9134SClemens Ladisch  *
22131ef9134SClemens Ladisch  * Asynchronous operation (INTERIM, NOTIFY) is not supported at the moment.
22231ef9134SClemens Ladisch  *
22331ef9134SClemens Ladisch  * Returns the actual size of the response frame, or a negative error code.
22431ef9134SClemens Ladisch  */
22531ef9134SClemens Ladisch int fcp_avc_transaction(struct fw_unit *unit,
22631ef9134SClemens Ladisch 			const void *command, unsigned int command_size,
22731ef9134SClemens Ladisch 			void *response, unsigned int response_size,
22831ef9134SClemens Ladisch 			unsigned int response_match_bytes)
22931ef9134SClemens Ladisch {
23031ef9134SClemens Ladisch 	struct fcp_transaction t;
23131ef9134SClemens Ladisch 	int tcode, ret, tries = 0;
23231ef9134SClemens Ladisch 
23331ef9134SClemens Ladisch 	t.unit = unit;
23431ef9134SClemens Ladisch 	t.response_buffer = response;
23531ef9134SClemens Ladisch 	t.response_size = response_size;
23631ef9134SClemens Ladisch 	t.response_match_bytes = response_match_bytes;
23731ef9134SClemens Ladisch 	t.state = STATE_PENDING;
23831ef9134SClemens Ladisch 	init_waitqueue_head(&t.wait);
23931ef9134SClemens Ladisch 
24000a7bb81STakashi Sakamoto 	if (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03)
24100a7bb81STakashi Sakamoto 		t.deferrable = true;
24200a7bb81STakashi Sakamoto 
24331ef9134SClemens Ladisch 	spin_lock_irq(&transactions_lock);
24431ef9134SClemens Ladisch 	list_add_tail(&t.list, &transactions);
24531ef9134SClemens Ladisch 	spin_unlock_irq(&transactions_lock);
24631ef9134SClemens Ladisch 
24731ef9134SClemens Ladisch 	for (;;) {
24831ef9134SClemens Ladisch 		tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
24931ef9134SClemens Ladisch 					  : TCODE_WRITE_BLOCK_REQUEST;
25031ef9134SClemens Ladisch 		ret = snd_fw_transaction(t.unit, tcode,
25131ef9134SClemens Ladisch 					 CSR_REGISTER_BASE + CSR_FCP_COMMAND,
2521b70485fSClemens Ladisch 					 (void *)command, command_size, 0);
25331ef9134SClemens Ladisch 		if (ret < 0)
25431ef9134SClemens Ladisch 			break;
25500a7bb81STakashi Sakamoto deferred:
25631ef9134SClemens Ladisch 		wait_event_timeout(t.wait, t.state != STATE_PENDING,
25731ef9134SClemens Ladisch 				   msecs_to_jiffies(FCP_TIMEOUT_MS));
25831ef9134SClemens Ladisch 
25900a7bb81STakashi Sakamoto 		if (t.state == STATE_DEFERRED) {
26000a7bb81STakashi Sakamoto 			/*
26100a7bb81STakashi Sakamoto 			 * 'AV/C General Specification' define no time limit
26200a7bb81STakashi Sakamoto 			 * on command completion once an INTERIM response has
26300a7bb81STakashi Sakamoto 			 * been sent. but we promise to finish this function
26400a7bb81STakashi Sakamoto 			 * for a caller. Here we use FCP_TIMEOUT_MS for next
26500a7bb81STakashi Sakamoto 			 * interval. This is not in the specification.
26600a7bb81STakashi Sakamoto 			 */
26700a7bb81STakashi Sakamoto 			t.state = STATE_PENDING;
26800a7bb81STakashi Sakamoto 			goto deferred;
26900a7bb81STakashi Sakamoto 		} else if (t.state == STATE_COMPLETE) {
27031ef9134SClemens Ladisch 			ret = t.response_size;
27131ef9134SClemens Ladisch 			break;
27231ef9134SClemens Ladisch 		} else if (t.state == STATE_BUS_RESET) {
27331ef9134SClemens Ladisch 			msleep(ERROR_DELAY_MS);
27431ef9134SClemens Ladisch 		} else if (++tries >= ERROR_RETRIES) {
27531ef9134SClemens Ladisch 			dev_err(&t.unit->device, "FCP command timed out\n");
27631ef9134SClemens Ladisch 			ret = -EIO;
27731ef9134SClemens Ladisch 			break;
27831ef9134SClemens Ladisch 		}
27931ef9134SClemens Ladisch 	}
28031ef9134SClemens Ladisch 
28131ef9134SClemens Ladisch 	spin_lock_irq(&transactions_lock);
28231ef9134SClemens Ladisch 	list_del(&t.list);
28331ef9134SClemens Ladisch 	spin_unlock_irq(&transactions_lock);
28431ef9134SClemens Ladisch 
28531ef9134SClemens Ladisch 	return ret;
28631ef9134SClemens Ladisch }
28731ef9134SClemens Ladisch EXPORT_SYMBOL(fcp_avc_transaction);
28831ef9134SClemens Ladisch 
28931ef9134SClemens Ladisch /**
29031ef9134SClemens Ladisch  * fcp_bus_reset - inform the target handler about a bus reset
29131ef9134SClemens Ladisch  * @unit: the unit that might be used by fcp_avc_transaction()
29231ef9134SClemens Ladisch  *
29331ef9134SClemens Ladisch  * This function must be called from the driver's .update handler to inform
29431ef9134SClemens Ladisch  * the FCP transaction handler that a bus reset has happened.  Any pending FCP
29531ef9134SClemens Ladisch  * transactions are retried.
29631ef9134SClemens Ladisch  */
29731ef9134SClemens Ladisch void fcp_bus_reset(struct fw_unit *unit)
29831ef9134SClemens Ladisch {
29931ef9134SClemens Ladisch 	struct fcp_transaction *t;
30031ef9134SClemens Ladisch 
30131ef9134SClemens Ladisch 	spin_lock_irq(&transactions_lock);
30231ef9134SClemens Ladisch 	list_for_each_entry(t, &transactions, list) {
30331ef9134SClemens Ladisch 		if (t->unit == unit &&
30400a7bb81STakashi Sakamoto 		    (t->state == STATE_PENDING ||
30500a7bb81STakashi Sakamoto 		     t->state == STATE_DEFERRED)) {
30631ef9134SClemens Ladisch 			t->state = STATE_BUS_RESET;
30731ef9134SClemens Ladisch 			wake_up(&t->wait);
30831ef9134SClemens Ladisch 		}
30931ef9134SClemens Ladisch 	}
31031ef9134SClemens Ladisch 	spin_unlock_irq(&transactions_lock);
31131ef9134SClemens Ladisch }
31231ef9134SClemens Ladisch EXPORT_SYMBOL(fcp_bus_reset);
31331ef9134SClemens Ladisch 
31431ef9134SClemens Ladisch /* checks whether the response matches the masked bytes in response_buffer */
31531ef9134SClemens Ladisch static bool is_matching_response(struct fcp_transaction *transaction,
31631ef9134SClemens Ladisch 				 const void *response, size_t length)
31731ef9134SClemens Ladisch {
31831ef9134SClemens Ladisch 	const u8 *p1, *p2;
31931ef9134SClemens Ladisch 	unsigned int mask, i;
32031ef9134SClemens Ladisch 
32131ef9134SClemens Ladisch 	p1 = response;
32231ef9134SClemens Ladisch 	p2 = transaction->response_buffer;
32331ef9134SClemens Ladisch 	mask = transaction->response_match_bytes;
32431ef9134SClemens Ladisch 
32531ef9134SClemens Ladisch 	for (i = 0; ; ++i) {
32631ef9134SClemens Ladisch 		if ((mask & 1) && p1[i] != p2[i])
32731ef9134SClemens Ladisch 			return false;
32831ef9134SClemens Ladisch 		mask >>= 1;
32931ef9134SClemens Ladisch 		if (!mask)
33031ef9134SClemens Ladisch 			return true;
33131ef9134SClemens Ladisch 		if (--length == 0)
33231ef9134SClemens Ladisch 			return false;
33331ef9134SClemens Ladisch 	}
33431ef9134SClemens Ladisch }
33531ef9134SClemens Ladisch 
33631ef9134SClemens Ladisch static void fcp_response(struct fw_card *card, struct fw_request *request,
33731ef9134SClemens Ladisch 			 int tcode, int destination, int source,
33831ef9134SClemens Ladisch 			 int generation, unsigned long long offset,
33931ef9134SClemens Ladisch 			 void *data, size_t length, void *callback_data)
34031ef9134SClemens Ladisch {
34131ef9134SClemens Ladisch 	struct fcp_transaction *t;
34231ef9134SClemens Ladisch 	unsigned long flags;
34331ef9134SClemens Ladisch 
34431ef9134SClemens Ladisch 	if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
34531ef9134SClemens Ladisch 		return;
34631ef9134SClemens Ladisch 
34731ef9134SClemens Ladisch 	spin_lock_irqsave(&transactions_lock, flags);
34831ef9134SClemens Ladisch 	list_for_each_entry(t, &transactions, list) {
34931ef9134SClemens Ladisch 		struct fw_device *device = fw_parent_device(t->unit);
35031ef9134SClemens Ladisch 		if (device->card != card ||
35131ef9134SClemens Ladisch 		    device->generation != generation)
35231ef9134SClemens Ladisch 			continue;
35331ef9134SClemens Ladisch 		smp_rmb(); /* node_id vs. generation */
35431ef9134SClemens Ladisch 		if (device->node_id != source)
35531ef9134SClemens Ladisch 			continue;
35631ef9134SClemens Ladisch 
35731ef9134SClemens Ladisch 		if (t->state == STATE_PENDING &&
35831ef9134SClemens Ladisch 		    is_matching_response(t, data, length)) {
35900a7bb81STakashi Sakamoto 			if (t->deferrable && *(const u8 *)data == 0x0f) {
36000a7bb81STakashi Sakamoto 				t->state = STATE_DEFERRED;
36100a7bb81STakashi Sakamoto 			} else {
36231ef9134SClemens Ladisch 				t->state = STATE_COMPLETE;
36300a7bb81STakashi Sakamoto 				t->response_size = min_t(unsigned int, length,
36431ef9134SClemens Ladisch 							 t->response_size);
36500a7bb81STakashi Sakamoto 				memcpy(t->response_buffer, data,
36600a7bb81STakashi Sakamoto 				       t->response_size);
36700a7bb81STakashi Sakamoto 			}
36831ef9134SClemens Ladisch 			wake_up(&t->wait);
36931ef9134SClemens Ladisch 		}
37031ef9134SClemens Ladisch 	}
37131ef9134SClemens Ladisch 	spin_unlock_irqrestore(&transactions_lock, flags);
37231ef9134SClemens Ladisch }
37331ef9134SClemens Ladisch 
37431ef9134SClemens Ladisch static struct fw_address_handler response_register_handler = {
37531ef9134SClemens Ladisch 	.length = 0x200,
37631ef9134SClemens Ladisch 	.address_callback = fcp_response,
37731ef9134SClemens Ladisch };
37831ef9134SClemens Ladisch 
37931ef9134SClemens Ladisch static int __init fcp_module_init(void)
38031ef9134SClemens Ladisch {
38131ef9134SClemens Ladisch 	static const struct fw_address_region response_register_region = {
38231ef9134SClemens Ladisch 		.start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
38331ef9134SClemens Ladisch 		.end = CSR_REGISTER_BASE + CSR_FCP_END,
38431ef9134SClemens Ladisch 	};
38531ef9134SClemens Ladisch 
38631ef9134SClemens Ladisch 	fw_core_add_address_handler(&response_register_handler,
38731ef9134SClemens Ladisch 				    &response_register_region);
38831ef9134SClemens Ladisch 
38931ef9134SClemens Ladisch 	return 0;
39031ef9134SClemens Ladisch }
39131ef9134SClemens Ladisch 
39231ef9134SClemens Ladisch static void __exit fcp_module_exit(void)
39331ef9134SClemens Ladisch {
39431ef9134SClemens Ladisch 	WARN_ON(!list_empty(&transactions));
39531ef9134SClemens Ladisch 	fw_core_remove_address_handler(&response_register_handler);
39631ef9134SClemens Ladisch }
39731ef9134SClemens Ladisch 
39831ef9134SClemens Ladisch module_init(fcp_module_init);
39931ef9134SClemens Ladisch module_exit(fcp_module_exit);
400