Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Function Control Protocol (IEC 61883-1) helper functions
0004  *
0005  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/firewire.h>
0010 #include <linux/firewire-constants.h>
0011 #include <linux/list.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/sched.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/wait.h>
0017 #include <linux/delay.h>
0018 #include "fcp.h"
0019 #include "lib.h"
0020 #include "amdtp-stream.h"
0021 
0022 #define CTS_AVC 0x00
0023 
0024 #define ERROR_RETRIES   3
0025 #define ERROR_DELAY_MS  5
0026 #define FCP_TIMEOUT_MS  125
0027 
0028 int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate,
0029                 enum avc_general_plug_dir dir,
0030                 unsigned short pid)
0031 {
0032     unsigned int sfc;
0033     u8 *buf;
0034     bool flag;
0035     int err;
0036 
0037     flag = false;
0038     for (sfc = 0; sfc < CIP_SFC_COUNT; sfc++) {
0039         if (amdtp_rate_table[sfc] == rate) {
0040             flag = true;
0041             break;
0042         }
0043     }
0044     if (!flag)
0045         return -EINVAL;
0046 
0047     buf = kzalloc(8, GFP_KERNEL);
0048     if (buf == NULL)
0049         return -ENOMEM;
0050 
0051     buf[0] = 0x00;      /* AV/C CONTROL */
0052     buf[1] = 0xff;      /* UNIT */
0053     if (dir == AVC_GENERAL_PLUG_DIR_IN)
0054         buf[2] = 0x19;  /* INPUT PLUG SIGNAL FORMAT */
0055     else
0056         buf[2] = 0x18;  /* OUTPUT PLUG SIGNAL FORMAT */
0057     buf[3] = 0xff & pid;    /* plug id */
0058     buf[4] = 0x90;      /* EOH_1, Form_1, FMT. AM824 */
0059     buf[5] = 0x07 & sfc;    /* FDF-hi. AM824, frequency */
0060     buf[6] = 0xff;      /* FDF-mid. AM824, SYT hi (not used)*/
0061     buf[7] = 0xff;      /* FDF-low. AM824, SYT lo (not used) */
0062 
0063     /* do transaction and check buf[1-5] are the same against command */
0064     err = fcp_avc_transaction(unit, buf, 8, buf, 8,
0065                   BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
0066     if (err < 0)
0067         ;
0068     else if (err < 8)
0069         err = -EIO;
0070     else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
0071         err = -ENOSYS;
0072     else if (buf[0] == 0x0a) /* REJECTED */
0073         err = -EINVAL;
0074     if (err < 0)
0075         goto end;
0076 
0077     err = 0;
0078 end:
0079     kfree(buf);
0080     return err;
0081 }
0082 EXPORT_SYMBOL(avc_general_set_sig_fmt);
0083 
0084 int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate,
0085                 enum avc_general_plug_dir dir,
0086                 unsigned short pid)
0087 {
0088     unsigned int sfc;
0089     u8 *buf;
0090     int err;
0091 
0092     buf = kzalloc(8, GFP_KERNEL);
0093     if (buf == NULL)
0094         return -ENOMEM;
0095 
0096     buf[0] = 0x01;      /* AV/C STATUS */
0097     buf[1] = 0xff;      /* Unit */
0098     if (dir == AVC_GENERAL_PLUG_DIR_IN)
0099         buf[2] = 0x19;  /* INPUT PLUG SIGNAL FORMAT */
0100     else
0101         buf[2] = 0x18;  /* OUTPUT PLUG SIGNAL FORMAT */
0102     buf[3] = 0xff & pid;    /* plug id */
0103     buf[4] = 0x90;      /* EOH_1, Form_1, FMT. AM824 */
0104     buf[5] = 0xff;      /* FDF-hi. AM824, frequency */
0105     buf[6] = 0xff;      /* FDF-mid. AM824, SYT hi (not used) */
0106     buf[7] = 0xff;      /* FDF-low. AM824, SYT lo (not used) */
0107 
0108     /* do transaction and check buf[1-4] are the same against command */
0109     err = fcp_avc_transaction(unit, buf, 8, buf, 8,
0110                   BIT(1) | BIT(2) | BIT(3) | BIT(4));
0111     if (err < 0)
0112         ;
0113     else if (err < 8)
0114         err = -EIO;
0115     else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
0116         err = -ENOSYS;
0117     else if (buf[0] == 0x0a) /* REJECTED */
0118         err = -EINVAL;
0119     else if (buf[0] == 0x0b) /* IN TRANSITION */
0120         err = -EAGAIN;
0121     if (err < 0)
0122         goto end;
0123 
0124     /* check sfc field and pick up rate */
0125     sfc = 0x07 & buf[5];
0126     if (sfc >= CIP_SFC_COUNT) {
0127         err = -EAGAIN;  /* also in transition */
0128         goto end;
0129     }
0130 
0131     *rate = amdtp_rate_table[sfc];
0132     err = 0;
0133 end:
0134     kfree(buf);
0135     return err;
0136 }
0137 EXPORT_SYMBOL(avc_general_get_sig_fmt);
0138 
0139 int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type,
0140                   unsigned int subunit_id, unsigned int subfunction,
0141                   u8 info[AVC_PLUG_INFO_BUF_BYTES])
0142 {
0143     u8 *buf;
0144     int err;
0145 
0146     /* extended subunit in spec.4.2 is not supported */
0147     if ((subunit_type == 0x1E) || (subunit_id == 5))
0148         return -EINVAL;
0149 
0150     buf = kzalloc(8, GFP_KERNEL);
0151     if (buf == NULL)
0152         return -ENOMEM;
0153 
0154     buf[0] = 0x01;  /* AV/C STATUS */
0155     /* UNIT or Subunit, Functionblock */
0156     buf[1] = ((subunit_type & 0x1f) << 3) | (subunit_id & 0x7);
0157     buf[2] = 0x02;  /* PLUG INFO */
0158     buf[3] = 0xff & subfunction;
0159 
0160     err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));
0161     if (err < 0)
0162         ;
0163     else if (err < 8)
0164         err = -EIO;
0165     else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
0166         err = -ENOSYS;
0167     else if (buf[0] == 0x0a) /* REJECTED */
0168         err = -EINVAL;
0169     else if (buf[0] == 0x0b) /* IN TRANSITION */
0170         err = -EAGAIN;
0171     if (err < 0)
0172         goto end;
0173 
0174     info[0] = buf[4];
0175     info[1] = buf[5];
0176     info[2] = buf[6];
0177     info[3] = buf[7];
0178 
0179     err = 0;
0180 end:
0181     kfree(buf);
0182     return err;
0183 }
0184 EXPORT_SYMBOL(avc_general_get_plug_info);
0185 
0186 static DEFINE_SPINLOCK(transactions_lock);
0187 static LIST_HEAD(transactions);
0188 
0189 enum fcp_state {
0190     STATE_PENDING,
0191     STATE_BUS_RESET,
0192     STATE_COMPLETE,
0193     STATE_DEFERRED,
0194 };
0195 
0196 struct fcp_transaction {
0197     struct list_head list;
0198     struct fw_unit *unit;
0199     void *response_buffer;
0200     unsigned int response_size;
0201     unsigned int response_match_bytes;
0202     enum fcp_state state;
0203     wait_queue_head_t wait;
0204     bool deferrable;
0205 };
0206 
0207 /**
0208  * fcp_avc_transaction - send an AV/C command and wait for its response
0209  * @unit: a unit on the target device
0210  * @command: a buffer containing the command frame; must be DMA-able
0211  * @command_size: the size of @command
0212  * @response: a buffer for the response frame
0213  * @response_size: the maximum size of @response
0214  * @response_match_bytes: a bitmap specifying the bytes used to detect the
0215  *                        correct response frame
0216  *
0217  * This function sends a FCP command frame to the target and waits for the
0218  * corresponding response frame to be returned.
0219  *
0220  * Because it is possible for multiple FCP transactions to be active at the
0221  * same time, the correct response frame is detected by the value of certain
0222  * bytes.  These bytes must be set in @response before calling this function,
0223  * and the corresponding bits must be set in @response_match_bytes.
0224  *
0225  * @command and @response can point to the same buffer.
0226  *
0227  * Returns the actual size of the response frame, or a negative error code.
0228  */
0229 int fcp_avc_transaction(struct fw_unit *unit,
0230             const void *command, unsigned int command_size,
0231             void *response, unsigned int response_size,
0232             unsigned int response_match_bytes)
0233 {
0234     struct fcp_transaction t;
0235     int tcode, ret, tries = 0;
0236 
0237     t.unit = unit;
0238     t.response_buffer = response;
0239     t.response_size = response_size;
0240     t.response_match_bytes = response_match_bytes;
0241     t.state = STATE_PENDING;
0242     init_waitqueue_head(&t.wait);
0243     t.deferrable = (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03);
0244 
0245     spin_lock_irq(&transactions_lock);
0246     list_add_tail(&t.list, &transactions);
0247     spin_unlock_irq(&transactions_lock);
0248 
0249     for (;;) {
0250         tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
0251                       : TCODE_WRITE_BLOCK_REQUEST;
0252         ret = snd_fw_transaction(t.unit, tcode,
0253                      CSR_REGISTER_BASE + CSR_FCP_COMMAND,
0254                      (void *)command, command_size, 0);
0255         if (ret < 0)
0256             break;
0257 deferred:
0258         wait_event_timeout(t.wait, t.state != STATE_PENDING,
0259                    msecs_to_jiffies(FCP_TIMEOUT_MS));
0260 
0261         if (t.state == STATE_DEFERRED) {
0262             /*
0263              * 'AV/C General Specification' define no time limit
0264              * on command completion once an INTERIM response has
0265              * been sent. but we promise to finish this function
0266              * for a caller. Here we use FCP_TIMEOUT_MS for next
0267              * interval. This is not in the specification.
0268              */
0269             t.state = STATE_PENDING;
0270             goto deferred;
0271         } else if (t.state == STATE_COMPLETE) {
0272             ret = t.response_size;
0273             break;
0274         } else if (t.state == STATE_BUS_RESET) {
0275             msleep(ERROR_DELAY_MS);
0276         } else if (++tries >= ERROR_RETRIES) {
0277             dev_err(&t.unit->device, "FCP command timed out\n");
0278             ret = -EIO;
0279             break;
0280         }
0281     }
0282 
0283     spin_lock_irq(&transactions_lock);
0284     list_del(&t.list);
0285     spin_unlock_irq(&transactions_lock);
0286 
0287     return ret;
0288 }
0289 EXPORT_SYMBOL(fcp_avc_transaction);
0290 
0291 /**
0292  * fcp_bus_reset - inform the target handler about a bus reset
0293  * @unit: the unit that might be used by fcp_avc_transaction()
0294  *
0295  * This function must be called from the driver's .update handler to inform
0296  * the FCP transaction handler that a bus reset has happened.  Any pending FCP
0297  * transactions are retried.
0298  */
0299 void fcp_bus_reset(struct fw_unit *unit)
0300 {
0301     struct fcp_transaction *t;
0302 
0303     spin_lock_irq(&transactions_lock);
0304     list_for_each_entry(t, &transactions, list) {
0305         if (t->unit == unit &&
0306             (t->state == STATE_PENDING ||
0307              t->state == STATE_DEFERRED)) {
0308             t->state = STATE_BUS_RESET;
0309             wake_up(&t->wait);
0310         }
0311     }
0312     spin_unlock_irq(&transactions_lock);
0313 }
0314 EXPORT_SYMBOL(fcp_bus_reset);
0315 
0316 /* checks whether the response matches the masked bytes in response_buffer */
0317 static bool is_matching_response(struct fcp_transaction *transaction,
0318                  const void *response, size_t length)
0319 {
0320     const u8 *p1, *p2;
0321     unsigned int mask, i;
0322 
0323     p1 = response;
0324     p2 = transaction->response_buffer;
0325     mask = transaction->response_match_bytes;
0326 
0327     for (i = 0; ; ++i) {
0328         if ((mask & 1) && p1[i] != p2[i])
0329             return false;
0330         mask >>= 1;
0331         if (!mask)
0332             return true;
0333         if (--length == 0)
0334             return false;
0335     }
0336 }
0337 
0338 static void fcp_response(struct fw_card *card, struct fw_request *request,
0339              int tcode, int destination, int source,
0340              int generation, unsigned long long offset,
0341              void *data, size_t length, void *callback_data)
0342 {
0343     struct fcp_transaction *t;
0344     unsigned long flags;
0345 
0346     if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
0347         return;
0348 
0349     spin_lock_irqsave(&transactions_lock, flags);
0350     list_for_each_entry(t, &transactions, list) {
0351         struct fw_device *device = fw_parent_device(t->unit);
0352         if (device->card != card ||
0353             device->generation != generation)
0354             continue;
0355         smp_rmb(); /* node_id vs. generation */
0356         if (device->node_id != source)
0357             continue;
0358 
0359         if (t->state == STATE_PENDING &&
0360             is_matching_response(t, data, length)) {
0361             if (t->deferrable && *(const u8 *)data == 0x0f) {
0362                 t->state = STATE_DEFERRED;
0363             } else {
0364                 t->state = STATE_COMPLETE;
0365                 t->response_size = min_t(unsigned int, length,
0366                              t->response_size);
0367                 memcpy(t->response_buffer, data,
0368                        t->response_size);
0369             }
0370             wake_up(&t->wait);
0371         }
0372     }
0373     spin_unlock_irqrestore(&transactions_lock, flags);
0374 }
0375 
0376 static struct fw_address_handler response_register_handler = {
0377     .length = 0x200,
0378     .address_callback = fcp_response,
0379 };
0380 
0381 static int __init fcp_module_init(void)
0382 {
0383     static const struct fw_address_region response_register_region = {
0384         .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
0385         .end = CSR_REGISTER_BASE + CSR_FCP_END,
0386     };
0387 
0388     fw_core_add_address_handler(&response_register_handler,
0389                     &response_register_region);
0390 
0391     return 0;
0392 }
0393 
0394 static void __exit fcp_module_exit(void)
0395 {
0396     WARN_ON(!list_empty(&transactions));
0397     fw_core_remove_address_handler(&response_register_handler);
0398 }
0399 
0400 module_init(fcp_module_init);
0401 module_exit(fcp_module_exit);