1da607e19SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2eb7b3a05STakashi Sakamoto /*
3eb7b3a05STakashi Sakamoto * bebob_command.c - driver for BeBoB based devices
4eb7b3a05STakashi Sakamoto *
5eb7b3a05STakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto
6eb7b3a05STakashi Sakamoto */
7eb7b3a05STakashi Sakamoto
8eb7b3a05STakashi Sakamoto #include "./bebob.h"
9eb7b3a05STakashi Sakamoto
avc_audio_set_selector(struct fw_unit * unit,unsigned int subunit_id,unsigned int fb_id,unsigned int num)101fc9522aSTakashi Sakamoto int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
111fc9522aSTakashi Sakamoto unsigned int fb_id, unsigned int num)
121fc9522aSTakashi Sakamoto {
131fc9522aSTakashi Sakamoto u8 *buf;
141fc9522aSTakashi Sakamoto int err;
151fc9522aSTakashi Sakamoto
161fc9522aSTakashi Sakamoto buf = kzalloc(12, GFP_KERNEL);
171fc9522aSTakashi Sakamoto if (buf == NULL)
181fc9522aSTakashi Sakamoto return -ENOMEM;
191fc9522aSTakashi Sakamoto
201fc9522aSTakashi Sakamoto buf[0] = 0x00; /* AV/C CONTROL */
211fc9522aSTakashi Sakamoto buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
221fc9522aSTakashi Sakamoto buf[2] = 0xb8; /* FUNCTION BLOCK */
231fc9522aSTakashi Sakamoto buf[3] = 0x80; /* type is 'selector'*/
241fc9522aSTakashi Sakamoto buf[4] = 0xff & fb_id; /* function block id */
251fc9522aSTakashi Sakamoto buf[5] = 0x10; /* control attribute is CURRENT */
261fc9522aSTakashi Sakamoto buf[6] = 0x02; /* selector length is 2 */
271fc9522aSTakashi Sakamoto buf[7] = 0xff & num; /* input function block plug number */
281fc9522aSTakashi Sakamoto buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
291fc9522aSTakashi Sakamoto
301fc9522aSTakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 12,
311fc9522aSTakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
321fc9522aSTakashi Sakamoto BIT(6) | BIT(7) | BIT(8));
337e1621deSTakashi Sakamoto if (err < 0)
347e1621deSTakashi Sakamoto ;
357e1621deSTakashi Sakamoto else if (err < 9)
361fc9522aSTakashi Sakamoto err = -EIO;
371fc9522aSTakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
381fc9522aSTakashi Sakamoto err = -ENOSYS;
391fc9522aSTakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
401fc9522aSTakashi Sakamoto err = -EINVAL;
417e1621deSTakashi Sakamoto else
421fc9522aSTakashi Sakamoto err = 0;
431fc9522aSTakashi Sakamoto
441fc9522aSTakashi Sakamoto kfree(buf);
451fc9522aSTakashi Sakamoto return err;
461fc9522aSTakashi Sakamoto }
471fc9522aSTakashi Sakamoto
avc_audio_get_selector(struct fw_unit * unit,unsigned int subunit_id,unsigned int fb_id,unsigned int * num)481fc9522aSTakashi Sakamoto int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
491fc9522aSTakashi Sakamoto unsigned int fb_id, unsigned int *num)
501fc9522aSTakashi Sakamoto {
511fc9522aSTakashi Sakamoto u8 *buf;
521fc9522aSTakashi Sakamoto int err;
531fc9522aSTakashi Sakamoto
541fc9522aSTakashi Sakamoto buf = kzalloc(12, GFP_KERNEL);
551fc9522aSTakashi Sakamoto if (buf == NULL)
561fc9522aSTakashi Sakamoto return -ENOMEM;
571fc9522aSTakashi Sakamoto
581fc9522aSTakashi Sakamoto buf[0] = 0x01; /* AV/C STATUS */
591fc9522aSTakashi Sakamoto buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
601fc9522aSTakashi Sakamoto buf[2] = 0xb8; /* FUNCTION BLOCK */
611fc9522aSTakashi Sakamoto buf[3] = 0x80; /* type is 'selector'*/
621fc9522aSTakashi Sakamoto buf[4] = 0xff & fb_id; /* function block id */
631fc9522aSTakashi Sakamoto buf[5] = 0x10; /* control attribute is CURRENT */
641fc9522aSTakashi Sakamoto buf[6] = 0x02; /* selector length is 2 */
651fc9522aSTakashi Sakamoto buf[7] = 0xff; /* input function block plug number */
661fc9522aSTakashi Sakamoto buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
671fc9522aSTakashi Sakamoto
681fc9522aSTakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 12,
691fc9522aSTakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
701fc9522aSTakashi Sakamoto BIT(6) | BIT(8));
717e1621deSTakashi Sakamoto if (err < 0)
727e1621deSTakashi Sakamoto ;
737e1621deSTakashi Sakamoto else if (err < 9)
741fc9522aSTakashi Sakamoto err = -EIO;
751fc9522aSTakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
761fc9522aSTakashi Sakamoto err = -ENOSYS;
771fc9522aSTakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
781fc9522aSTakashi Sakamoto err = -EINVAL;
791fc9522aSTakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
801fc9522aSTakashi Sakamoto err = -EAGAIN;
811fc9522aSTakashi Sakamoto if (err < 0)
821fc9522aSTakashi Sakamoto goto end;
831fc9522aSTakashi Sakamoto
841fc9522aSTakashi Sakamoto *num = buf[7];
851fc9522aSTakashi Sakamoto err = 0;
861fc9522aSTakashi Sakamoto end:
871fc9522aSTakashi Sakamoto kfree(buf);
881fc9522aSTakashi Sakamoto return err;
891fc9522aSTakashi Sakamoto }
901fc9522aSTakashi Sakamoto
91eb7b3a05STakashi Sakamoto static inline void
avc_bridgeco_fill_extension_addr(u8 * buf,u8 * addr)92eb7b3a05STakashi Sakamoto avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
93eb7b3a05STakashi Sakamoto {
94eb7b3a05STakashi Sakamoto buf[1] = addr[0];
95eb7b3a05STakashi Sakamoto memcpy(buf + 4, addr + 1, 5);
96eb7b3a05STakashi Sakamoto }
97eb7b3a05STakashi Sakamoto
98eb7b3a05STakashi Sakamoto static inline void
avc_bridgeco_fill_plug_info_extension_command(u8 * buf,u8 * addr,unsigned int itype)99eb7b3a05STakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
100eb7b3a05STakashi Sakamoto unsigned int itype)
101eb7b3a05STakashi Sakamoto {
102eb7b3a05STakashi Sakamoto buf[0] = 0x01; /* AV/C STATUS */
103eb7b3a05STakashi Sakamoto buf[2] = 0x02; /* AV/C GENERAL PLUG INFO */
104eb7b3a05STakashi Sakamoto buf[3] = 0xc0; /* BridgeCo extension */
105eb7b3a05STakashi Sakamoto avc_bridgeco_fill_extension_addr(buf, addr);
106eb7b3a05STakashi Sakamoto buf[9] = itype; /* info type */
107eb7b3a05STakashi Sakamoto }
108eb7b3a05STakashi Sakamoto
avc_bridgeco_get_plug_type(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],enum avc_bridgeco_plug_type * type)109eb7b3a05STakashi Sakamoto int avc_bridgeco_get_plug_type(struct fw_unit *unit,
110eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES],
111eb7b3a05STakashi Sakamoto enum avc_bridgeco_plug_type *type)
112eb7b3a05STakashi Sakamoto {
113eb7b3a05STakashi Sakamoto u8 *buf;
114eb7b3a05STakashi Sakamoto int err;
115eb7b3a05STakashi Sakamoto
116eb7b3a05STakashi Sakamoto buf = kzalloc(12, GFP_KERNEL);
117eb7b3a05STakashi Sakamoto if (buf == NULL)
118eb7b3a05STakashi Sakamoto return -ENOMEM;
119eb7b3a05STakashi Sakamoto
120eb7b3a05STakashi Sakamoto /* Info type is 'plug type'. */
121eb7b3a05STakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
122eb7b3a05STakashi Sakamoto
123eb7b3a05STakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 12,
124eb7b3a05STakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
125eb7b3a05STakashi Sakamoto BIT(6) | BIT(7) | BIT(9));
1267e1621deSTakashi Sakamoto if (err < 0)
1277e1621deSTakashi Sakamoto ;
1287e1621deSTakashi Sakamoto else if (err < 11)
129eb7b3a05STakashi Sakamoto err = -EIO;
130eb7b3a05STakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
131eb7b3a05STakashi Sakamoto err = -ENOSYS;
132eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
133eb7b3a05STakashi Sakamoto err = -EINVAL;
134eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
135eb7b3a05STakashi Sakamoto err = -EAGAIN;
136eb7b3a05STakashi Sakamoto if (err < 0)
137eb7b3a05STakashi Sakamoto goto end;
138eb7b3a05STakashi Sakamoto
139eb7b3a05STakashi Sakamoto *type = buf[10];
140eb7b3a05STakashi Sakamoto err = 0;
141eb7b3a05STakashi Sakamoto end:
142eb7b3a05STakashi Sakamoto kfree(buf);
143eb7b3a05STakashi Sakamoto return err;
144eb7b3a05STakashi Sakamoto }
145eb7b3a05STakashi Sakamoto
avc_bridgeco_get_plug_ch_count(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],unsigned int * ch_count)146*5c6ea94fSTakashi Sakamoto int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
147*5c6ea94fSTakashi Sakamoto unsigned int *ch_count)
148*5c6ea94fSTakashi Sakamoto {
149*5c6ea94fSTakashi Sakamoto u8 *buf;
150*5c6ea94fSTakashi Sakamoto int err;
151*5c6ea94fSTakashi Sakamoto
152*5c6ea94fSTakashi Sakamoto buf = kzalloc(12, GFP_KERNEL);
153*5c6ea94fSTakashi Sakamoto if (buf == NULL)
154*5c6ea94fSTakashi Sakamoto return -ENOMEM;
155*5c6ea94fSTakashi Sakamoto
156*5c6ea94fSTakashi Sakamoto // Info type is 'plug type'.
157*5c6ea94fSTakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x02);
158*5c6ea94fSTakashi Sakamoto
159*5c6ea94fSTakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 12,
160*5c6ea94fSTakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
161*5c6ea94fSTakashi Sakamoto BIT(6) | BIT(7) | BIT(9));
162*5c6ea94fSTakashi Sakamoto if (err < 0)
163*5c6ea94fSTakashi Sakamoto ;
164*5c6ea94fSTakashi Sakamoto else if (err < 11)
165*5c6ea94fSTakashi Sakamoto err = -EIO;
166*5c6ea94fSTakashi Sakamoto else if (buf[0] == 0x08) // NOT IMPLEMENTED
167*5c6ea94fSTakashi Sakamoto err = -ENOSYS;
168*5c6ea94fSTakashi Sakamoto else if (buf[0] == 0x0a) // REJECTED
169*5c6ea94fSTakashi Sakamoto err = -EINVAL;
170*5c6ea94fSTakashi Sakamoto else if (buf[0] == 0x0b) // IN TRANSITION
171*5c6ea94fSTakashi Sakamoto err = -EAGAIN;
172*5c6ea94fSTakashi Sakamoto if (err < 0)
173*5c6ea94fSTakashi Sakamoto goto end;
174*5c6ea94fSTakashi Sakamoto
175*5c6ea94fSTakashi Sakamoto *ch_count = buf[10];
176*5c6ea94fSTakashi Sakamoto err = 0;
177*5c6ea94fSTakashi Sakamoto end:
178*5c6ea94fSTakashi Sakamoto kfree(buf);
179*5c6ea94fSTakashi Sakamoto return err;
180*5c6ea94fSTakashi Sakamoto }
181*5c6ea94fSTakashi Sakamoto
avc_bridgeco_get_plug_ch_pos(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],u8 * buf,unsigned int len)182eb7b3a05STakashi Sakamoto int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
183eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES],
184eb7b3a05STakashi Sakamoto u8 *buf, unsigned int len)
185eb7b3a05STakashi Sakamoto {
186eb7b3a05STakashi Sakamoto int err;
187eb7b3a05STakashi Sakamoto
188eb7b3a05STakashi Sakamoto /* Info type is 'channel position'. */
189eb7b3a05STakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
190eb7b3a05STakashi Sakamoto
191eb7b3a05STakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 256,
192eb7b3a05STakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) |
193eb7b3a05STakashi Sakamoto BIT(5) | BIT(6) | BIT(7) | BIT(9));
1947e1621deSTakashi Sakamoto if (err < 0)
1957e1621deSTakashi Sakamoto ;
1967e1621deSTakashi Sakamoto else if (err < 11)
197eb7b3a05STakashi Sakamoto err = -EIO;
198eb7b3a05STakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
199eb7b3a05STakashi Sakamoto err = -ENOSYS;
200eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
201eb7b3a05STakashi Sakamoto err = -EINVAL;
202eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
203eb7b3a05STakashi Sakamoto err = -EAGAIN;
204eb7b3a05STakashi Sakamoto if (err < 0)
205eb7b3a05STakashi Sakamoto goto end;
206eb7b3a05STakashi Sakamoto
207eb7b3a05STakashi Sakamoto /* Pick up specific data. */
208eb7b3a05STakashi Sakamoto memmove(buf, buf + 10, err - 10);
209eb7b3a05STakashi Sakamoto err = 0;
210eb7b3a05STakashi Sakamoto end:
211eb7b3a05STakashi Sakamoto return err;
212eb7b3a05STakashi Sakamoto }
213eb7b3a05STakashi Sakamoto
avc_bridgeco_get_plug_section_type(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],unsigned int id,u8 * type)214eb7b3a05STakashi Sakamoto int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
215eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES],
216eb7b3a05STakashi Sakamoto unsigned int id, u8 *type)
217eb7b3a05STakashi Sakamoto {
218eb7b3a05STakashi Sakamoto u8 *buf;
219eb7b3a05STakashi Sakamoto int err;
220eb7b3a05STakashi Sakamoto
221eb7b3a05STakashi Sakamoto /* section info includes charactors but this module don't need it */
222eb7b3a05STakashi Sakamoto buf = kzalloc(12, GFP_KERNEL);
223eb7b3a05STakashi Sakamoto if (buf == NULL)
224eb7b3a05STakashi Sakamoto return -ENOMEM;
225eb7b3a05STakashi Sakamoto
226eb7b3a05STakashi Sakamoto /* Info type is 'section info'. */
227eb7b3a05STakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
228eb7b3a05STakashi Sakamoto buf[10] = 0xff & ++id; /* section id */
229eb7b3a05STakashi Sakamoto
230eb7b3a05STakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, 12,
231eb7b3a05STakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
232eb7b3a05STakashi Sakamoto BIT(6) | BIT(7) | BIT(9) | BIT(10));
2337e1621deSTakashi Sakamoto if (err < 0)
2347e1621deSTakashi Sakamoto ;
2357e1621deSTakashi Sakamoto else if (err < 12)
236eb7b3a05STakashi Sakamoto err = -EIO;
237eb7b3a05STakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
238eb7b3a05STakashi Sakamoto err = -ENOSYS;
239eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
240eb7b3a05STakashi Sakamoto err = -EINVAL;
241eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
242eb7b3a05STakashi Sakamoto err = -EAGAIN;
243eb7b3a05STakashi Sakamoto if (err < 0)
244eb7b3a05STakashi Sakamoto goto end;
245eb7b3a05STakashi Sakamoto
246eb7b3a05STakashi Sakamoto *type = buf[11];
247eb7b3a05STakashi Sakamoto err = 0;
248eb7b3a05STakashi Sakamoto end:
249eb7b3a05STakashi Sakamoto kfree(buf);
250eb7b3a05STakashi Sakamoto return err;
251eb7b3a05STakashi Sakamoto }
252eb7b3a05STakashi Sakamoto
avc_bridgeco_get_plug_input(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],u8 input[7])253eb7b3a05STakashi Sakamoto int avc_bridgeco_get_plug_input(struct fw_unit *unit,
254eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
255eb7b3a05STakashi Sakamoto {
256eb7b3a05STakashi Sakamoto int err;
257eb7b3a05STakashi Sakamoto u8 *buf;
258eb7b3a05STakashi Sakamoto
259eb7b3a05STakashi Sakamoto buf = kzalloc(18, GFP_KERNEL);
260eb7b3a05STakashi Sakamoto if (buf == NULL)
261eb7b3a05STakashi Sakamoto return -ENOMEM;
262eb7b3a05STakashi Sakamoto
263eb7b3a05STakashi Sakamoto /* Info type is 'plug input'. */
264eb7b3a05STakashi Sakamoto avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
265eb7b3a05STakashi Sakamoto
266eb7b3a05STakashi Sakamoto err = fcp_avc_transaction(unit, buf, 16, buf, 16,
267eb7b3a05STakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
268eb7b3a05STakashi Sakamoto BIT(6) | BIT(7));
2697e1621deSTakashi Sakamoto if (err < 0)
2707e1621deSTakashi Sakamoto ;
2717e1621deSTakashi Sakamoto else if (err < 16)
272eb7b3a05STakashi Sakamoto err = -EIO;
273eb7b3a05STakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
274eb7b3a05STakashi Sakamoto err = -ENOSYS;
275eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
276eb7b3a05STakashi Sakamoto err = -EINVAL;
277eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
278eb7b3a05STakashi Sakamoto err = -EAGAIN;
279eb7b3a05STakashi Sakamoto if (err < 0)
280eb7b3a05STakashi Sakamoto goto end;
281eb7b3a05STakashi Sakamoto
282eb7b3a05STakashi Sakamoto memcpy(input, buf + 10, 5);
283eb7b3a05STakashi Sakamoto err = 0;
284eb7b3a05STakashi Sakamoto end:
285eb7b3a05STakashi Sakamoto kfree(buf);
286eb7b3a05STakashi Sakamoto return err;
287eb7b3a05STakashi Sakamoto }
288eb7b3a05STakashi Sakamoto
avc_bridgeco_get_plug_strm_fmt(struct fw_unit * unit,u8 addr[AVC_BRIDGECO_ADDR_BYTES],u8 * buf,unsigned int * len,unsigned int eid)289eb7b3a05STakashi Sakamoto int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
290eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf,
291eb7b3a05STakashi Sakamoto unsigned int *len, unsigned int eid)
292eb7b3a05STakashi Sakamoto {
293eb7b3a05STakashi Sakamoto int err;
294eb7b3a05STakashi Sakamoto
295eb7b3a05STakashi Sakamoto /* check given buffer */
296eb7b3a05STakashi Sakamoto if ((buf == NULL) || (*len < 12)) {
297eb7b3a05STakashi Sakamoto err = -EINVAL;
298eb7b3a05STakashi Sakamoto goto end;
299eb7b3a05STakashi Sakamoto }
300eb7b3a05STakashi Sakamoto
301eb7b3a05STakashi Sakamoto buf[0] = 0x01; /* AV/C STATUS */
302eb7b3a05STakashi Sakamoto buf[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */
303eb7b3a05STakashi Sakamoto buf[3] = 0xc1; /* Bridgeco extension - List Request */
304eb7b3a05STakashi Sakamoto avc_bridgeco_fill_extension_addr(buf, addr);
305eb7b3a05STakashi Sakamoto buf[10] = 0xff & eid; /* Entry ID */
306eb7b3a05STakashi Sakamoto
307eb7b3a05STakashi Sakamoto err = fcp_avc_transaction(unit, buf, 12, buf, *len,
308eb7b3a05STakashi Sakamoto BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
309eb7b3a05STakashi Sakamoto BIT(6) | BIT(7) | BIT(10));
3107e1621deSTakashi Sakamoto if (err < 0)
3117e1621deSTakashi Sakamoto ;
3127e1621deSTakashi Sakamoto else if (err < 12)
313eb7b3a05STakashi Sakamoto err = -EIO;
314eb7b3a05STakashi Sakamoto else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
315eb7b3a05STakashi Sakamoto err = -ENOSYS;
316eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0a) /* REJECTED */
317eb7b3a05STakashi Sakamoto err = -EINVAL;
318eb7b3a05STakashi Sakamoto else if (buf[0] == 0x0b) /* IN TRANSITION */
319eb7b3a05STakashi Sakamoto err = -EAGAIN;
320eb7b3a05STakashi Sakamoto else if (buf[10] != eid)
321eb7b3a05STakashi Sakamoto err = -EIO;
322eb7b3a05STakashi Sakamoto if (err < 0)
323eb7b3a05STakashi Sakamoto goto end;
324eb7b3a05STakashi Sakamoto
325eb7b3a05STakashi Sakamoto /* Pick up 'stream format info'. */
326eb7b3a05STakashi Sakamoto memmove(buf, buf + 11, err - 11);
327eb7b3a05STakashi Sakamoto *len = err - 11;
328eb7b3a05STakashi Sakamoto err = 0;
329eb7b3a05STakashi Sakamoto end:
330eb7b3a05STakashi Sakamoto return err;
331eb7b3a05STakashi Sakamoto }
332