Commit edf6d6c5 authored by Bernhard Nortmann's avatar Bernhard Nortmann
Browse files

fel: Eliminate 'global' vars, switching to their handle counterparts



We move USB endpoint detection into the feldev_claim() routine, so
higher level code is no longer involved with that. Also make use of
the "detached" flag within feldev_handle, instead of relying on an
isolated variable.
Signed-off-by: default avatarBernhard Nortmann <bernhard.nortmann@web.de>
parent 1c8f81aa
...@@ -77,8 +77,6 @@ struct aw_usb_request { ...@@ -77,8 +77,6 @@ struct aw_usb_request {
static const int AW_USB_READ = 0x11; static const int AW_USB_READ = 0x11;
static const int AW_USB_WRITE = 0x12; static const int AW_USB_WRITE = 0x12;
static int AW_USB_FEL_BULK_EP_OUT;
static int AW_USB_FEL_BULK_EP_IN;
static int timeout = 10000; /* 10 seconds */ static int timeout = 10000; /* 10 seconds */
static bool verbose = false; /* If set, makes the 'fel' tool more talkative */ static bool verbose = false; /* If set, makes the 'fel' tool more talkative */
...@@ -193,14 +191,14 @@ static void aw_send_usb_request(feldev_handle *dev, int type, int length) ...@@ -193,14 +191,14 @@ static void aw_send_usb_request(feldev_handle *dev, int type, int length)
.unknown1 = htole32(0x0c000000) .unknown1 = htole32(0x0c000000)
}; };
req.length2 = req.length; req.length2 = req.length;
usb_bulk_send(dev->usb->handle, AW_USB_FEL_BULK_EP_OUT, usb_bulk_send(dev->usb->handle, dev->usb->endpoint_out,
&req, sizeof(req), false); &req, sizeof(req), false);
} }
static void aw_read_usb_response(feldev_handle *dev) static void aw_read_usb_response(feldev_handle *dev)
{ {
char buf[13]; char buf[13];
usb_bulk_recv(dev->usb->handle, AW_USB_FEL_BULK_EP_IN, usb_bulk_recv(dev->usb->handle, dev->usb->endpoint_in,
buf, sizeof(buf)); buf, sizeof(buf));
assert(strcmp(buf, "AWUS") == 0); assert(strcmp(buf, "AWUS") == 0);
} }
...@@ -209,7 +207,7 @@ static void aw_usb_write(feldev_handle *dev, const void *data, size_t len, ...@@ -209,7 +207,7 @@ static void aw_usb_write(feldev_handle *dev, const void *data, size_t len,
bool progress) bool progress)
{ {
aw_send_usb_request(dev, AW_USB_WRITE, len); aw_send_usb_request(dev, AW_USB_WRITE, len);
usb_bulk_send(dev->usb->handle, AW_USB_FEL_BULK_EP_OUT, usb_bulk_send(dev->usb->handle, dev->usb->endpoint_out,
data, len, progress); data, len, progress);
aw_read_usb_response(dev); aw_read_usb_response(dev);
} }
...@@ -217,7 +215,7 @@ static void aw_usb_write(feldev_handle *dev, const void *data, size_t len, ...@@ -217,7 +215,7 @@ static void aw_usb_write(feldev_handle *dev, const void *data, size_t len,
static void aw_usb_read(feldev_handle *dev, const void *data, size_t len) static void aw_usb_read(feldev_handle *dev, const void *data, size_t len)
{ {
aw_send_usb_request(dev, AW_USB_READ, len); aw_send_usb_request(dev, AW_USB_READ, len);
usb_bulk_send(dev->usb->handle, AW_USB_FEL_BULK_EP_IN, usb_bulk_send(dev->usb->handle, dev->usb->endpoint_in,
data, len, false); data, len, false);
aw_read_usb_response(dev); aw_read_usb_response(dev);
} }
...@@ -1229,7 +1227,7 @@ void pass_fel_information(feldev_handle *dev, ...@@ -1229,7 +1227,7 @@ void pass_fel_information(feldev_handle *dev,
} }
} }
static int aw_fel_get_endpoint(feldev_handle *dev) static int feldev_get_endpoint(feldev_handle *dev)
{ {
struct libusb_device *usb = libusb_get_device(dev->usb->handle); struct libusb_device *usb = libusb_get_device(dev->usb->handle);
struct libusb_config_descriptor *config; struct libusb_config_descriptor *config;
...@@ -1257,16 +1255,16 @@ static int aw_fel_get_endpoint(feldev_handle *dev) ...@@ -1257,16 +1255,16 @@ static int aw_fel_get_endpoint(feldev_handle *dev)
if ((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == if ((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
LIBUSB_ENDPOINT_IN) LIBUSB_ENDPOINT_IN)
AW_USB_FEL_BULK_EP_IN = ep->bEndpointAddress; dev->usb->endpoint_in = ep->bEndpointAddress;
else else
AW_USB_FEL_BULK_EP_OUT = ep->bEndpointAddress; dev->usb->endpoint_out = ep->bEndpointAddress;
} }
} }
} }
libusb_free_config_descriptor(config); libusb_free_config_descriptor(config);
return 0; return LIBUSB_SUCCESS;
} }
/* /*
...@@ -1364,6 +1362,33 @@ static unsigned int file_upload(feldev_handle *dev, size_t count, ...@@ -1364,6 +1362,33 @@ static unsigned int file_upload(feldev_handle *dev, size_t count,
return i; /* return number of files that were processed */ return i; /* return number of files that were processed */
} }
void feldev_claim(feldev_handle *dev)
{
int rc = libusb_claim_interface(dev->usb->handle, 0);
#if defined(__linux__)
if (rc != LIBUSB_SUCCESS) {
libusb_detach_kernel_driver(dev->usb->handle, 0);
dev->usb->iface_detached = true;
rc = libusb_claim_interface(dev->usb->handle, 0);
}
#endif
if (rc)
usb_error(rc, "libusb_claim_interface()", 1);
rc = feldev_get_endpoint(dev);
if (rc)
usb_error(rc, "FAILED to get FEL mode endpoint addresses!", 1);
}
void feldev_release(feldev_handle *dev)
{
libusb_release_interface(dev->usb->handle, 0);
#if defined(__linux__)
if (dev->usb->iface_detached)
libusb_attach_kernel_driver(dev->usb->handle, 0);
#endif
}
/* open handle to desired FEL device */ /* open handle to desired FEL device */
static feldev_handle *open_fel_device(int busnum, int devnum, static feldev_handle *open_fel_device(int busnum, int devnum,
uint16_t vendor_id, uint16_t product_id) uint16_t vendor_id, uint16_t product_id)
...@@ -1451,9 +1476,6 @@ int main(int argc, char **argv) ...@@ -1451,9 +1476,6 @@ int main(int argc, char **argv)
bool pflag_active = false; /* -p switch, causing "write" to output progress */ bool pflag_active = false; /* -p switch, causing "write" to output progress */
feldev_handle *handle; feldev_handle *handle;
int busnum = -1, devnum = -1; int busnum = -1, devnum = -1;
#if defined(__linux__)
int iface_detached = -1;
#endif
if (argc <= 1) { if (argc <= 1) {
puts("sunxi-fel " VERSION "\n"); puts("sunxi-fel " VERSION "\n");
...@@ -1527,20 +1549,7 @@ int main(int argc, char **argv) ...@@ -1527,20 +1549,7 @@ int main(int argc, char **argv)
assert(rc == 0); assert(rc == 0);
handle = open_fel_device(busnum, devnum, AW_USB_VENDOR_ID, AW_USB_PRODUCT_ID); handle = open_fel_device(busnum, devnum, AW_USB_VENDOR_ID, AW_USB_PRODUCT_ID);
assert(handle != NULL); assert(handle != NULL);
rc = libusb_claim_interface(handle->usb->handle, 0); feldev_claim(handle);
#if defined(__linux__)
if (rc != LIBUSB_SUCCESS) {
libusb_detach_kernel_driver(handle->usb->handle, 0);
iface_detached = 0;
rc = libusb_claim_interface(handle->usb->handle, 0);
}
#endif
assert(rc == 0);
if (aw_fel_get_endpoint(handle)) {
fprintf(stderr, "ERROR: Failed to get FEL mode endpoint addresses!\n");
exit(1);
}
while (argc > 1 ) { while (argc > 1 ) {
int skip = 1; int skip = 1;
...@@ -1636,11 +1645,7 @@ int main(int argc, char **argv) ...@@ -1636,11 +1645,7 @@ int main(int argc, char **argv)
aw_fel_execute(handle, uboot_entry); aw_fel_execute(handle, uboot_entry);
} }
libusb_release_interface(handle->usb->handle, 0); feldev_release(handle);
#if defined(__linux__)
if (iface_detached >= 0)
libusb_attach_kernel_driver(handle->usb->handle, iface_detached);
#endif
feldev_close(handle); feldev_close(handle);
free(handle); free(handle);
libusb_exit(NULL); libusb_exit(NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment