0001
0002
0003
0004
0005
0006
0007
0008 #include "oxfw.h"
0009
0010 int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
0011 unsigned int pid, u8 *format, unsigned int len)
0012 {
0013 u8 *buf;
0014 int err;
0015
0016 buf = kmalloc(len + 10, GFP_KERNEL);
0017 if (buf == NULL)
0018 return -ENOMEM;
0019
0020 buf[0] = 0x00;
0021 buf[1] = 0xff;
0022 buf[2] = 0xbf;
0023 buf[3] = 0xc0;
0024 buf[4] = dir;
0025 buf[5] = 0x00;
0026 buf[6] = 0x00;
0027 buf[7] = 0xff & pid;
0028 buf[8] = 0xff;
0029 buf[9] = 0xff;
0030 memcpy(buf + 10, format, len);
0031
0032
0033 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10,
0034 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0035 BIT(6) | BIT(7) | BIT(8));
0036 if (err < 0)
0037 ;
0038 else if (err < len + 10)
0039 err = -EIO;
0040 else if (buf[0] == 0x08)
0041 err = -ENXIO;
0042 else if (buf[0] == 0x0a)
0043 err = -EINVAL;
0044 else
0045 err = 0;
0046
0047 kfree(buf);
0048
0049 return err;
0050 }
0051
0052 int avc_stream_get_format(struct fw_unit *unit,
0053 enum avc_general_plug_dir dir, unsigned int pid,
0054 u8 *buf, unsigned int *len, unsigned int eid)
0055 {
0056 unsigned int subfunc;
0057 int err;
0058
0059 if (eid == 0xff)
0060 subfunc = 0xc0;
0061 else
0062 subfunc = 0xc1;
0063
0064 buf[0] = 0x01;
0065 buf[1] = 0xff;
0066 buf[2] = 0xbf;
0067 buf[3] = subfunc;
0068 buf[4] = dir;
0069 buf[5] = 0x00;
0070 buf[6] = 0x00;
0071 buf[7] = 0xff & pid;
0072 buf[8] = 0xff;
0073 buf[9] = 0xff;
0074 buf[10] = 0xff & eid;
0075 buf[11] = 0xff;
0076
0077
0078 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
0079 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0080 BIT(6) | BIT(7));
0081 if (err < 0)
0082 ;
0083 else if (err < 12)
0084 err = -EIO;
0085 else if (buf[0] == 0x08)
0086 err = -ENXIO;
0087 else if (buf[0] == 0x0a)
0088 err = -EINVAL;
0089 else if (buf[0] == 0x0b)
0090 err = -EAGAIN;
0091
0092 else if ((subfunc == 0xc1) && (buf[10] != eid))
0093 err = -EIO;
0094 if (err < 0)
0095 goto end;
0096
0097
0098 if (subfunc == 0xc0) {
0099 memmove(buf, buf + 10, err - 10);
0100 *len = err - 10;
0101 } else {
0102 memmove(buf, buf + 11, err - 11);
0103 *len = err - 11;
0104 }
0105
0106 err = 0;
0107 end:
0108 return err;
0109 }
0110
0111 int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
0112 enum avc_general_plug_dir dir,
0113 unsigned short pid)
0114 {
0115 unsigned int sfc;
0116 u8 *buf;
0117 int err;
0118
0119 for (sfc = 0; sfc < CIP_SFC_COUNT; sfc++) {
0120 if (amdtp_rate_table[sfc] == rate)
0121 break;
0122 }
0123 if (sfc == CIP_SFC_COUNT)
0124 return -EINVAL;
0125
0126 buf = kzalloc(8, GFP_KERNEL);
0127 if (buf == NULL)
0128 return -ENOMEM;
0129
0130 buf[0] = 0x02;
0131 buf[1] = 0xff;
0132 if (dir == AVC_GENERAL_PLUG_DIR_IN)
0133 buf[2] = 0x19;
0134 else
0135 buf[2] = 0x18;
0136 buf[3] = 0xff & pid;
0137 buf[4] = 0x90;
0138 buf[5] = 0x07 & sfc;
0139 buf[6] = 0xff;
0140 buf[7] = 0xff;
0141
0142
0143 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
0144 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
0145 if (err < 0)
0146 ;
0147 else if (err < 8)
0148 err = -EIO;
0149 else if (buf[0] == 0x08)
0150 err = -ENXIO;
0151 if (err < 0)
0152 goto end;
0153
0154 err = 0;
0155 end:
0156 kfree(buf);
0157 return err;
0158 }