Revision 50b7963e usb-linux.c

b/usb-linux.c
54 54
    void *data;
55 55
};
56 56

  
57
struct usb_ctrlrequest {
58
    uint8_t bRequestType;
59
    uint8_t bRequest;
60
    uint16_t wValue;
61
    uint16_t wIndex;
62
    uint16_t wLength;
63
};
64

  
65 57
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int devpath,
66 58
                        int class_id, int vendor_id, int product_id,
67 59
                        const char *product_name, int speed);
......
108 100
    int max_packet_size;
109 101
};
110 102

  
111
enum {
112
    CTRL_STATE_IDLE = 0,
113
    CTRL_STATE_SETUP,
114
    CTRL_STATE_DATA,
115
    CTRL_STATE_ACK
116
};
117

  
118
/*
119
 * Control transfer state.
120
 * Note that 'buffer' _must_ follow 'req' field because
121
 * we need contiguous buffer when we submit control URB.
122
 */
123
struct ctrl_struct {
124
    uint16_t len;
125
    uint16_t offset;
126
    uint8_t  state;
127
    struct   usb_ctrlrequest req;
128
    uint8_t  buffer[8192];
129
};
130

  
131 103
struct USBAutoFilter {
132 104
    uint32_t bus_num;
133 105
    uint32_t addr;
......
146 118
    int       closing;
147 119
    Notifier  exit;
148 120

  
149
    struct ctrl_struct ctrl;
150 121
    struct endp_data endp_table[MAX_ENDPOINTS];
151 122

  
152 123
    /* Host side address */
......
269 240
    qemu_free(aurb);
270 241
}
271 242

  
272
static void async_complete_ctrl(USBHostDevice *s, USBPacket *p)
273
{
274
    switch(s->ctrl.state) {
275
    case CTRL_STATE_SETUP:
276
        if (p->len < s->ctrl.len)
277
            s->ctrl.len = p->len;
278
        s->ctrl.state = CTRL_STATE_DATA;
279
        p->len = 8;
280
        break;
281

  
282
    case CTRL_STATE_ACK:
283
        s->ctrl.state = CTRL_STATE_IDLE;
284
        p->len = 0;
285
        break;
286

  
287
    default:
288
        break;
289
    }
290
}
291

  
292 243
static void async_complete(void *opaque)
293 244
{
294 245
    USBHostDevice *s = opaque;
......
333 284
            switch (aurb->urb.status) {
334 285
            case 0:
335 286
                p->len = aurb->urb.actual_length;
336
                if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
337
                    async_complete_ctrl(s, p);
338
                }
339 287
                break;
340 288

  
341 289
            case -EPIPE:
......
348 296
                break;
349 297
            }
350 298

  
351
            usb_packet_complete(&s->dev, p);
299
            if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
300
                usb_generic_async_ctrl_complete(&s->dev, p);
301
            } else {
302
                usb_packet_complete(&s->dev, p);
303
            }
352 304
        }
353 305

  
354 306
        async_free(aurb);
......
675 627
    return len;
676 628
}
677 629

  
678
static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
630
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
679 631
{
632
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
680 633
    struct usbdevfs_urb *urb;
681 634
    AsyncURB *aurb;
682 635
    int ret;
......
796 749
    return 0;
797 750
}
798 751

  
799
static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
752
static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
753
               int request, int value, int index, int length, uint8_t *data)
800 754
{
755
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
801 756
    struct usbdevfs_urb *urb;
802 757
    AsyncURB *aurb;
803
    int ret, value, index;
804
    int buffer_len;
758
    int ret;
805 759

  
806 760
    /*
807 761
     * Process certain standard device requests.
808 762
     * These are infrequent and are processed synchronously.
809 763
     */
810
    value = le16_to_cpu(s->ctrl.req.wValue);
811
    index = le16_to_cpu(s->ctrl.req.wIndex);
812 764

  
765
    /* Note request is (bRequestType << 8) | bRequest */
813 766
    DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
814
            s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index,
815
            s->ctrl.len);
767
            request >> 8, request & 0xff, value, index, length);
816 768

  
817
    if (s->ctrl.req.bRequestType == 0) {
818
        switch (s->ctrl.req.bRequest) {
819
        case USB_REQ_SET_ADDRESS:
820
            return usb_host_set_address(s, value);
769
    switch (request) {
770
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
771
        return usb_host_set_address(s, value);
821 772

  
822
        case USB_REQ_SET_CONFIGURATION:
823
            return usb_host_set_config(s, value & 0xff);
824
        }
825
    }
773
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
774
        return usb_host_set_config(s, value & 0xff);
826 775

  
827
    if (s->ctrl.req.bRequestType == 1 &&
828
                  s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE) {
776
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
829 777
        return usb_host_set_interface(s, index, value);
830 778
    }
831 779

  
832 780
    /* The rest are asynchronous */
833 781

  
834
    buffer_len = 8 + s->ctrl.len;
835
    if (buffer_len > sizeof(s->ctrl.buffer)) {
836
        fprintf(stderr, "husb: ctrl buffer too small (%u > %zu)\n",
837
                buffer_len, sizeof(s->ctrl.buffer));
782
    if (length > sizeof(dev->data_buf)) {
783
        fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
784
                length, sizeof(dev->data_buf));
838 785
        return USB_RET_STALL;
839 786
    }
840 787

  
......
853 800
    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
854 801
    urb->endpoint = p->devep;
855 802

  
856
    urb->buffer        = &s->ctrl.req;
857
    urb->buffer_length = buffer_len;
803
    urb->buffer        = &dev->setup_buf;
804
    urb->buffer_length = length + 8;
858 805

  
859 806
    urb->usercontext = s;
860 807

  
......
879 826
    return USB_RET_ASYNC;
880 827
}
881 828

  
882
static int do_token_setup(USBDevice *dev, USBPacket *p)
883
{
884
    USBHostDevice *s = (USBHostDevice *) dev;
885
    int ret = 0;
886

  
887
    if (p->len != 8) {
888
        return USB_RET_STALL;
889
    }
890

  
891
    memcpy(&s->ctrl.req, p->data, 8);
892
    s->ctrl.len    = le16_to_cpu(s->ctrl.req.wLength);
893
    s->ctrl.offset = 0;
894
    s->ctrl.state  = CTRL_STATE_SETUP;
895

  
896
    if (s->ctrl.req.bRequestType & USB_DIR_IN) {
897
        ret = usb_host_handle_control(s, p);
898
        if (ret < 0) {
899
            return ret;
900
        }
901

  
902
        if (ret < s->ctrl.len) {
903
            s->ctrl.len = ret;
904
        }
905
        s->ctrl.state = CTRL_STATE_DATA;
906
    } else {
907
        if (s->ctrl.len == 0) {
908
            s->ctrl.state = CTRL_STATE_ACK;
909
        } else {
910
            s->ctrl.state = CTRL_STATE_DATA;
911
        }
912
    }
913

  
914
    return ret;
915
}
916

  
917
static int do_token_in(USBDevice *dev, USBPacket *p)
918
{
919
    USBHostDevice *s = (USBHostDevice *) dev;
920
    int ret = 0;
921

  
922
    if (p->devep != 0) {
923
        return usb_host_handle_data(s, p);
924
    }
925

  
926
    switch(s->ctrl.state) {
927
    case CTRL_STATE_ACK:
928
        if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
929
            ret = usb_host_handle_control(s, p);
930
            if (ret == USB_RET_ASYNC) {
931
                return USB_RET_ASYNC;
932
            }
933
            s->ctrl.state = CTRL_STATE_IDLE;
934
            return ret > 0 ? 0 : ret;
935
        }
936

  
937
        return 0;
938

  
939
    case CTRL_STATE_DATA:
940
        if (s->ctrl.req.bRequestType & USB_DIR_IN) {
941
            int len = s->ctrl.len - s->ctrl.offset;
942
            if (len > p->len) {
943
                len = p->len;
944
            }
945
            memcpy(p->data, s->ctrl.buffer + s->ctrl.offset, len);
946
            s->ctrl.offset += len;
947
            if (s->ctrl.offset >= s->ctrl.len) {
948
                s->ctrl.state = CTRL_STATE_ACK;
949
            }
950
            return len;
951
        }
952

  
953
        s->ctrl.state = CTRL_STATE_IDLE;
954
        return USB_RET_STALL;
955

  
956
    default:
957
        return USB_RET_STALL;
958
    }
959
}
960

  
961
static int do_token_out(USBDevice *dev, USBPacket *p)
962
{
963
    USBHostDevice *s = (USBHostDevice *) dev;
964

  
965
    if (p->devep != 0) {
966
        return usb_host_handle_data(s, p);
967
    }
968

  
969
    switch(s->ctrl.state) {
970
    case CTRL_STATE_ACK:
971
        if (s->ctrl.req.bRequestType & USB_DIR_IN) {
972
            s->ctrl.state = CTRL_STATE_IDLE;
973
            /* transfer OK */
974
        } else {
975
            /* ignore additional output */
976
        }
977
        return 0;
978

  
979
    case CTRL_STATE_DATA:
980
        if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
981
            int len = s->ctrl.len - s->ctrl.offset;
982
            if (len > p->len) {
983
                len = p->len;
984
            }
985
            memcpy(s->ctrl.buffer + s->ctrl.offset, p->data, len);
986
            s->ctrl.offset += len;
987
            if (s->ctrl.offset >= s->ctrl.len) {
988
                s->ctrl.state = CTRL_STATE_ACK;
989
            }
990
            return len;
991
        }
992

  
993
        s->ctrl.state = CTRL_STATE_IDLE;
994
        return USB_RET_STALL;
995

  
996
    default:
997
        return USB_RET_STALL;
998
    }
999
}
1000

  
1001
/*
1002
 * Packet handler.
1003
 * Called by the HC (host controller).
1004
 *
1005
 * Returns length of the transaction or one of the USB_RET_XXX codes.
1006
 */
1007
static int usb_host_handle_packet(USBDevice *s, USBPacket *p)
1008
{
1009
    switch(p->pid) {
1010
    case USB_MSG_ATTACH:
1011
        s->state = USB_STATE_ATTACHED;
1012
        return 0;
1013

  
1014
    case USB_MSG_DETACH:
1015
        s->state = USB_STATE_NOTATTACHED;
1016
        return 0;
1017

  
1018
    case USB_MSG_RESET:
1019
        s->remote_wakeup = 0;
1020
        s->addr = 0;
1021
        s->state = USB_STATE_DEFAULT;
1022
        s->info->handle_reset(s);
1023
        return 0;
1024
    }
1025

  
1026
    /* Rest of the PIDs must match our address */
1027
    if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr) {
1028
        return USB_RET_NODEV;
1029
    }
1030

  
1031
    switch (p->pid) {
1032
    case USB_TOKEN_SETUP:
1033
        return do_token_setup(s, p);
1034

  
1035
    case USB_TOKEN_IN:
1036
        return do_token_in(s, p);
1037

  
1038
    case USB_TOKEN_OUT:
1039
        return do_token_out(s, p);
1040

  
1041
    default:
1042
        return USB_RET_STALL;
1043
    }
1044
}
1045

  
1046 829
static int usb_linux_get_configuration(USBHostDevice *s)
1047 830
{
1048 831
    uint8_t configuration;
......
1368 1151
    .qdev.name      = "usb-host",
1369 1152
    .qdev.size      = sizeof(USBHostDevice),
1370 1153
    .init           = usb_host_initfn,
1371
    .handle_packet  = usb_host_handle_packet,
1154
    .handle_packet  = usb_generic_handle_packet,
1155
    .handle_data    = usb_host_handle_data,
1156
    .handle_control = usb_host_handle_control,
1372 1157
    .handle_reset   = usb_host_handle_reset,
1373 1158
    .handle_destroy = usb_host_handle_destroy,
1374 1159
    .usbdevice_name = "host",

Also available in: Unified diff