/* * Execute a Radio Control Command * * Command data has to be in i1480->cmd_buf. * * @returns size of the reply data filled in i1480->evt_buf or < 0 errno * code on error. */ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size, size_t reply_size) { ssize_t result; struct uwb_rceb *reply = i1480->evt_buf; struct uwb_rccb *cmd = i1480->cmd_buf; u16 expected_event = reply->wEvent; u8 expected_type = reply->bEventType; u8 context; init_completion(&i1480->evt_complete); i1480->evt_result = -EINPROGRESS; do { get_random_bytes(&context, 1); } while (context == 0x00 || context == 0xff); cmd->bCommandContext = context; result = i1480->cmd(i1480, cmd_name, cmd_size); if (result < 0) goto error; /* wait for the callback to report a event was received */ result = wait_for_completion_interruptible_timeout( &i1480->evt_complete, HZ); if (result == 0) { result = -ETIMEDOUT; goto error; } if (result < 0) goto error; result = i1480->evt_result; if (result < 0) { dev_err(i1480->dev, "%s: command reply reception failed: %zd\n", cmd_name, result); goto error; } /* * Firmware versions >= 1.4.12224 for IOGear GUWA100U generate a * spurious notification after firmware is downloaded. So check whether * the receibed RCEB is such notification before assuming that the * command has failed. */ if (i1480_rceb_check(i1480, i1480->evt_buf, NULL, 0, 0xfd, 0x0022) == 0) { /* Now wait for the actual RCEB for this command. */ result = i1480->wait_init_done(i1480); if (result < 0) goto error; result = i1480->evt_result; } if (result != reply_size) { dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n", cmd_name, result, reply_size); result = -EINVAL; goto error; } /* Verify we got the right event in response */ result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context, expected_type, expected_event); error: return result; }
ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size, size_t reply_size) { ssize_t result; struct uwb_rceb *reply = i1480->evt_buf; struct uwb_rccb *cmd = i1480->cmd_buf; u16 expected_event = reply->wEvent; u8 expected_type = reply->bEventType; u8 context; init_completion(&i1480->evt_complete); i1480->evt_result = -EINPROGRESS; do { get_random_bytes(&context, 1); } while (context == 0x00 || context == 0xff); cmd->bCommandContext = context; result = i1480->cmd(i1480, cmd_name, cmd_size); if (result < 0) goto error; result = wait_for_completion_interruptible_timeout( &i1480->evt_complete, HZ); if (result == 0) { result = -ETIMEDOUT; goto error; } if (result < 0) goto error; result = i1480->evt_result; if (result < 0) { dev_err(i1480->dev, "%s: command reply reception failed: %zd\n", cmd_name, result); goto error; } if (i1480_rceb_check(i1480, i1480->evt_buf, NULL, 0, 0xfd, 0x0022) == 0) { result = i1480->wait_init_done(i1480); if (result < 0) goto error; result = i1480->evt_result; } if (result != reply_size) { dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n", cmd_name, result, reply_size); result = -EINVAL; goto error; } result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context, expected_type, expected_event); error: return result; }
/** * Upload MAC firmware, wait for it to start * * @i1480: Device instance * @fw_name: Name of the file that contains the firmware * * This has to be called after the pre fw has been uploaded (if * there is any). */ int i1480_mac_fw_upload(struct i1480 *i1480) { int result = 0, deprecated_name = 0; struct i1480_rceb *rcebe = (void *) i1480->evt_buf; result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC"); if (result == -ENOENT) { result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate, "MAC"); deprecated_name = 1; } if (result < 0) return result; if (deprecated_name == 1) dev_warn(i1480->dev, "WARNING: firmware file name %s is deprecated, " "please rename to %s\n", i1480->mac_fw_name_deprecate, i1480->mac_fw_name); result = i1480_fw_is_running_q(i1480); if (result < 0) goto error_fw_not_running; result = i1480->rc_setup ? i1480->rc_setup(i1480) : 0; if (result < 0) { dev_err(i1480->dev, "Cannot setup after MAC fw upload: %d\n", result); goto error_setup; } result = i1480->wait_init_done(i1480); /* wait init'on */ if (result < 0) { dev_err(i1480->dev, "MAC fw '%s': Initialization timed out " "(%d)\n", i1480->mac_fw_name, result); goto error_init_timeout; } /* verify we got the right initialization done event */ if (i1480->evt_result != sizeof(*rcebe)) { dev_err(i1480->dev, "MAC fw '%s': initialization event returns " "wrong size (%zu bytes vs %zu needed)\n", i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe)); goto error_size; } result = -EIO; if (i1480_rceb_check(i1480, &rcebe->rceb, NULL, 0, i1480_CET_VS1, i1480_EVT_RM_INIT_DONE) < 0) { dev_err(i1480->dev, "wrong initialization event 0x%02x/%04x/%02x " "received; expected 0x%02x/%04x/00\n", rcebe->rceb.bEventType, le16_to_cpu(rcebe->rceb.wEvent), rcebe->rceb.bEventContext, i1480_CET_VS1, i1480_EVT_RM_INIT_DONE); goto error_init_timeout; } result = i1480_cmd_reset(i1480); if (result < 0) dev_err(i1480->dev, "MAC fw '%s': MBOA reset failed (%d)\n", i1480->mac_fw_name, result); error_fw_not_running: error_init_timeout: error_size: error_setup: return result; }