carlu: support testing async commands
authorChristian Lamparter <chunkeey@googlemail.com>
Fri, 15 Oct 2010 21:14:30 +0000 (23:14 +0200)
committerChristian Lamparter <chunkeey@googlemail.com>
Fri, 15 Oct 2010 21:14:30 +0000 (23:14 +0200)
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
tools/carlu/src/cmd.c
tools/carlu/src/rx.c
tools/carlu/src/usb.c
tools/carlu/src/usb.h

index a6c9020d3a2b587862e00b6932745e59953b2a73..e7759dcb563abb3983fa04a707055bb94c3b2d66 100644 (file)
@@ -56,17 +56,34 @@ int carlu_cmd_echo(struct carlu *ar, const uint32_t message)
        return ret;
 }
 
+struct carl9170_cmd *carlu_cmd_buf(struct carlu *ar,
+       const enum carl9170_cmd_oids cmd, const unsigned int len)
+{
+       struct carl9170_cmd *tmp;
+
+       if (len % 4 || (sizeof(struct carl9170_cmd_head) + len > 64))
+               return ERR_PTR(-EINVAL);
+
+       tmp = malloc(sizeof(struct carl9170_cmd_head) + len);
+       if (tmp) {
+               tmp->hdr.cmd = cmd;
+               tmp->hdr.len = len;
+       }
+       return tmp;
+}
+
 int carlu_cmd_reboot(struct carlu *ar)
 {
+       struct carl9170_cmd *reboot;
        int err;
 
-       err = carlusb_cmd(ar, CARL9170_CMD_REBOOT,
-                         NULL, 0, NULL, 0);
+       /* sure, we could put the struct on the stack too. */
+       reboot = carlu_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0);
+       if (IS_ERR_OR_NULL(reboot))
+               return reboot ? PTR_ERR(reboot) : -ENOMEM;
 
-       if (err == -ETIMEDOUT)
-               return 0;
-
-       return err ? err : -1;
+       err = carlusb_cmd_async(ar, reboot, true);
+       return err;
 }
 
 int carlu_cmd_mem_dump(struct carlu *ar, const uint32_t start,
index 4a8f24e8cad7b4128efffea963365d3f44042354..bda8d2d7da1738e84dc67d8b2b8669e1618dc711 100644 (file)
@@ -57,7 +57,9 @@ void carlu_handle_command(struct carlu *ar, void *buf,
 
        cmd = (void *) buf;
 
-       if ((cmd->hdr.cmd & 0xc0) != 0xc0) {
+       if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) {
+               if ((cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG))
+                       return;
 
                SDL_mutexP(ar->resp_lock);
                if (ar->resp_buf && ar->resp_len && ar->resp_len >= (len - 4)) {
index c99dbc13994ae9aa4dcb87606194c6ce416ee3aa..72d08ea6d20295c8a77fb860ec70c10427a002ab 100644 (file)
@@ -609,6 +609,35 @@ static int carlusb_upload_firmware(struct carlusb *ar, bool boot)
        return 0;
 }
 
+int carlusb_cmd_async(struct carlu *_ar, struct carl9170_cmd *cmd,
+                     const bool free_buf)
+{
+       struct carlusb *ar = (void *)_ar;
+       struct libusb_transfer *urb;
+       int ret, send;
+
+       if (cmd->hdr.len > (CARL9170_MAX_CMD_LEN - 4)) {
+               err("|-> too much payload\n");
+               return -EINVAL;
+       }
+
+       if (cmd->hdr.len % 4) {
+               err("|-> invalid command length\n");
+               return -EINVAL;
+       }
+
+       ret = libusb_interrupt_transfer(ar->dev, AR9170_EP_CMD, (void *) cmd, cmd->hdr.len + 4, &send, 32);
+       if (ret != 0) {
+               err("OID:0x%.2x failed due to (%d) (%d).\n", cmd->hdr.cmd, ret, send);
+               print_hex_dump_bytes(ERROR, "CMD:", cmd, cmd->hdr.len);
+       }
+
+       if (free_buf)
+               free((void *)cmd);
+
+       return ret;
+}
+
 int carlusb_cmd(struct carlu *_ar, uint8_t oid,
                      uint8_t *cmd, size_t clen,
                      uint8_t *rsp, size_t rlen)
@@ -624,23 +653,23 @@ int carlusb_cmd(struct carlu *_ar, uint8_t oid,
        ret = SDL_mutexP(ar->common.resp_lock);
        if (ret != 0) {
                err("failed to acquire resp_lock.\n");
-               print_hex_dump_bytes(ERROR, "CMD:", ar->cmd_buf, clen);
+               print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
                return -1;
        }
 
-       ar->cmd_buf[0] = clen;
-       ar->cmd_buf[1] = oid;
+       ar->cmd.cmd.hdr.len = clen;
+       ar->cmd.cmd.hdr.cmd = oid;
        /* buf[2] & buf[3] are padding */
-       if (clen && cmd != (uint8_t *)(&ar->cmd_buf[4]))
-               memcpy(&ar->cmd_buf[4], cmd, clen);
+       if (clen && cmd != (uint8_t *)(&ar->cmd.cmd.data))
+               memcpy(&ar->cmd.cmd.data, cmd, clen);
 
        ar->common.resp_buf = (uint8_t *)rsp;
        ar->common.resp_len = rlen;
 
-       ret = libusb_interrupt_transfer(ar->dev, AR9170_EP_CMD, ar->cmd_buf, clen + 4, &send, 32);
+       ret = carlusb_cmd_async(_ar, &ar->cmd.cmd, false);
        if (ret != 0) {
                err("OID:0x%.2x failed due to (%d) (%d).\n", oid, ret, send);
-               print_hex_dump_bytes(ERROR, "CMD:", ar->cmd_buf, clen);
+               print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
                SDL_mutexV(ar->common.resp_lock);
                return ret;
        }
index 298e82d14ad76048328ab9b89e134401925bf4ee..00e1467b935c76f650f2cbaa7b4446e5bc755351 100644 (file)
@@ -60,7 +60,11 @@ struct carlusb {
        struct libusb_transfer *rx_interrupt;
        unsigned char irq_buf[AR9170_RX_BULK_IRQ_SIZE];
 
-       unsigned char cmd_buf[CARL9170_MAX_CMD_LEN];
+       union {
+               unsigned char buf[CARL9170_MAX_CMD_LEN];
+               struct carl9170_cmd cmd;
+               struct carl9170_rsp rsp;
+       } cmd;
 
        struct list_head tx_queue;
        SDL_mutex *tx_queue_lock;