Changes for 1.12 release
[platform/adaptation/npu/intel-libmvnc.git] / api / src / usb_link_vsc.c
1 /*
2 * Copyright 2017 Intel Corporation.
3 * The source code, information and material ("Material") contained herein is
4 * owned by Intel Corporation or its suppliers or licensors, and title to such
5 * Material remains with Intel Corporation or its suppliers or licensors.
6 * The Material contains proprietary information of Intel or its suppliers and
7 * licensors. The Material is protected by worldwide copyright laws and treaty
8 * provisions.
9 * No part of the Material may be used, copied, reproduced, modified, published,
10 * uploaded, posted, transmitted, distributed or disclosed in any way without
11 * Intel's prior express written permission. No license under any patent,
12 * copyright or other intellectual property rights in the Material is granted to
13 * or conferred upon you, either expressly, by implication, inducement, estoppel
14 * or otherwise.
15 * Any license under such intellectual property rights must be express and
16 * approved by Intel in writing.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/file.h>
26 #include <fcntl.h>
27 #include <sys/wait.h>
28 #include <sys/timeb.h>
29 #include <sys/un.h>
30 #include <errno.h>
31 #include <sys/ioctl.h>
32 #include <time.h>
33 #include <termios.h>
34 #include <libusb.h>
35
36 #include "usb_link.h"
37 #include "usb_boot.h"
38 #include "common.h"
39
40 #define USB_ENDPOINT_IN         0x81
41 #define USB_ENDPOINT_OUT        0x01
42 #define USB_TIMEOUT             10000
43 #define USB_MAX_PACKET_SIZE     1024 * 1024 * 10
44
45 #define SLEEP_MS        100
46 #define ITERATIONS      50
47
48 static int usb_write(void *f, const void *data, size_t size)
49 {
50         while (size > 0) {
51                 int bt, ss = size;
52                 if (ss > USB_MAX_PACKET_SIZE)
53                         ss = USB_MAX_PACKET_SIZE;
54                 if (libusb_bulk_transfer(f, USB_ENDPOINT_OUT, (unsigned char *) data, ss, &bt,
55                      USB_TIMEOUT))
56                         return -1;
57                 data = (char *) data + bt;
58                 size -= bt;
59         }
60         return 0;
61 }
62
63 static int usb_read(void *f, void *data, size_t size)
64 {
65         while (size > 0) {
66                 int bt, ss = size;
67                 if (ss > USB_MAX_PACKET_SIZE)
68                         ss = USB_MAX_PACKET_SIZE;
69                 if (libusb_bulk_transfer(f, USB_ENDPOINT_IN, data, ss, &bt, USB_TIMEOUT))
70                         return -1;
71                 data = (char *) data + bt;
72                 size -= bt;
73         }
74         return 0;
75 }
76
77 void *usblink_open(const char *path)
78 {
79         int rc;
80         libusb_device_handle *h = NULL;
81         libusb_device *dev;
82
83         rc = usb_find_device(0, (char *) path, 0, (void **) &dev,
84                              DEFAULT_OPEN_VID, DEFAULT_OPEN_PID);
85         if (rc < 0)
86                 return 0;
87
88         rc = libusb_open(dev, &h);
89         if (rc < 0) {
90                 libusb_unref_device(dev);
91                 return 0;
92         }
93
94         libusb_unref_device(dev);
95         rc = libusb_claim_interface(h, 0);
96         if (rc < 0) {
97                 libusb_close(h);
98                 return 0;
99         }
100         return h;
101 }
102
103 void usblink_close(void *f)
104 {
105         libusb_release_interface(f, 0);
106         libusb_close(f);
107 }
108
109 void usblink_resetall()
110 {
111         libusb_device **devs;
112         libusb_device *dev;
113         struct libusb_device_descriptor desc;
114         libusb_device_handle *h;
115         size_t i;
116         int rc, iters = 0, cnt_bootrom = 0, cnt_runtime = 0, cnt_after = 0;
117
118         if ((rc = libusb_get_device_list(NULL, &devs)) < 0)
119                 return;
120         i = 0;
121         while ((dev = devs[i++]) != NULL) {
122                 if (libusb_get_device_descriptor(dev, &desc) < 0)
123                         continue;
124                 if (desc.idVendor == DEFAULT_VID &&
125                         desc.idProduct == DEFAULT_PID)
126                         cnt_bootrom++;
127                 // If Runtime device found, reset it
128                 if (desc.idVendor == DEFAULT_OPEN_VID &&
129                     desc.idProduct == DEFAULT_OPEN_PID) {
130                         cnt_runtime++;
131                         rc = libusb_open(dev, &h);
132                         if (rc < -1)
133                                 continue;
134                         rc = libusb_claim_interface(h, 0);
135                         if (rc < 0) {
136                                 libusb_close(h);
137                                 continue;
138                         }
139                         PRINT_DEBUG(stderr, "Found stale device, resetting\n");
140                         usblink_resetmyriad(h);
141                         usblink_close(h);
142                 }
143         }
144         // If some devices needed reset
145         if(cnt_runtime > 0){
146                 iters = 0;
147                 // Wait until all devices re-enumerate, or timeout occurs
148                 while((cnt_after < cnt_bootrom + cnt_runtime) && (iters < ITERATIONS)){
149                         usleep(SLEEP_MS*1000);
150                         cnt_after = 0;
151                         if ((rc = libusb_get_device_list(NULL, &devs)) < 0)
152                                 return;
153                         i = 0;
154                         while ((dev = devs[i++]) != NULL) {
155                                 if ((rc = libusb_get_device_descriptor(dev, &desc)) < 0)
156                                         continue;
157                                 if (desc.idVendor == DEFAULT_VID &&
158                                         desc.idProduct == DEFAULT_PID)
159                                         cnt_after++;
160                         }
161                         iters++;
162                 }
163         }
164         libusb_free_device_list(devs, 1);
165 }
166
167 int usblink_setdata(void *f, const char *name, const void *data,
168                     unsigned int length, int host_ready)
169 {
170         usbHeader_t header;
171         memset(&header, 0, sizeof(header));
172         header.cmd = USB_LINK_HOST_SET_DATA;
173         header.hostready = host_ready;
174         strcpy(header.name, name);
175         header.dataLength = length;
176         if (usb_write(f, &header, sizeof(header)))
177                 return -1;
178
179         unsigned int operation_permit = 0xFFFF;
180         if (usb_read(f, &operation_permit, sizeof(operation_permit)))
181                 return -1;
182
183         if (operation_permit != 0xABCD)
184                 return -1;
185         int rc = usb_write(f, data, length);
186         return rc;
187 }
188
189 int usblink_getdata(void *f, const char *name, void *data, unsigned int length,
190                     unsigned int offset, int host_ready)
191 {
192         usbHeader_t header;
193         memset(&header, 0, sizeof(header));
194         header.cmd = USB_LINK_HOST_GET_DATA;
195         header.hostready = host_ready;
196         strcpy(header.name, name);
197         header.dataLength = length;
198         header.offset = offset;
199         if (usb_write(f, &header, sizeof(header)))
200                 return -1;
201
202         unsigned int operation_permit = 0xFFFF;
203         if (usb_read(f, &operation_permit, sizeof(operation_permit)))
204                 return -1;
205
206         if (operation_permit != 0xABCD)
207                 return -1;
208         return usb_read(f, data, length);
209 }
210
211 int usblink_resetmyriad(void *f)
212 {
213         usbHeader_t header;
214         memset(&header, 0, sizeof(header));
215         header.cmd = USB_LINK_RESET_REQUEST;
216         if (usb_write(f, &header, sizeof(header)))
217                 return -1;
218         return 0;
219 }
220
221 int usblink_getmyriadstatus(void *f, myriadStatus_t* myriad_state)
222 {
223         usbHeader_t header;
224         memset(&header, 0, sizeof(header));
225         header.cmd = USB_LINK_GET_MYRIAD_STATUS;
226         if (usb_write(f, &header, sizeof(header)))
227                 return -1;
228         return usb_read(f, myriad_state, sizeof(*myriad_state));
229 }