static int open_interface(struct olimex_transport *tr, struct usb_device *dev, int ino) { #if defined(__linux__) int drv; char drName[256]; #endif printc(__FILE__": Trying to open interface %d on %s\n", ino, dev->filename); tr->int_number = ino; tr->handle = usb_open(dev); if (!tr->handle) { pr_error(__FILE__": can't open device"); return -1; } #if defined(__linux__) drv = usb_get_driver_np(tr->handle, tr->int_number, drName, sizeof(drName)); printc(__FILE__" : driver %d\n", drv); if (drv >= 0) { if (usb_detach_kernel_driver_np(tr->handle, tr->int_number) < 0) pr_error(__FILE__": warning: can't detach " "kernel driver"); } #endif if (usb_claim_interface(tr->handle, tr->int_number) < 0) { pr_error(__FILE__": can't claim interface"); usb_close(tr->handle); return -1; } int ret = usb_control_msg(tr->handle, CP210x_REQTYPE_HOST_TO_DEVICE, CP210X_IFC_ENABLE, 0x1, 0, NULL, 0, 300); #ifdef DEBUG_OLIMEX printc(__FILE__": %s : Sending control message ret %d\n", __FUNCTION__, ret); #endif /* Set the baud rate to 500000 bps */ ret = usb_control_msg(tr->handle, CP210x_REQTYPE_HOST_TO_DEVICE, CP210X_SET_BAUDDIV, 0x7, 0, NULL, 0, 300); #ifdef DEBUG_OLIMEX printc(__FILE__": %s : Sending control message ret %d\n", __FUNCTION__, ret); #endif /* Set the modem control settings. * Set RTS, DTR and WRITE_DTR, WRITE_RTS */ ret = usb_control_msg(tr->handle, CP210x_REQTYPE_HOST_TO_DEVICE, CP210X_SET_MHS, 0x303, 0, NULL, 0, 300); #ifdef DEBUG_OLIMEX printc(__FILE__": %s : Sending control message ret %d\n", __FUNCTION__, ret); #endif return 0; }
static nfc_device * pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; struct pn53x_usb_descriptor desc = { NULL, NULL }; int connstring_decode_level = connstring_decode(connstring, PN53X_USB_DRIVER_NAME, "usb", &desc.dirname, &desc.filename); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d element(s) have been decoded from \"%s\"", connstring_decode_level, connstring); if (connstring_decode_level < 1) { goto free_mem; } struct pn53x_usb_data data = { .pudh = NULL, .uiEndPointIn = 0, .uiEndPointOut = 0, }; struct usb_bus *bus; struct usb_device *dev; usb_prepare(); for (bus = usb_get_busses(); bus; bus = bus->next) { if (connstring_decode_level > 1) { // A specific bus have been specified if (0 != strcmp(bus->dirname, desc.dirname)) continue; } for (dev = bus->devices; dev; dev = dev->next) { if (connstring_decode_level > 2) { // A specific dev have been specified if (0 != strcmp(dev->filename, desc.filename)) continue; } // Open the USB device if ((data.pudh = usb_open(dev)) == NULL) continue; // Retrieve end points pn53x_usb_get_end_points(dev, &data); // Set configuration int res = usb_set_configuration(data.pudh, 1); if (res < 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror(res)); if (EPERM == -res) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: Please double check USB permissions for device %04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); } usb_close(data.pudh); // we failed to use the specified device goto free_mem; } res = usb_claim_interface(data.pudh, 0); if (res < 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror(res)); usb_close(data.pudh); // we failed to use the specified device goto free_mem; } data.model = pn53x_usb_get_device_model(dev->descriptor.idVendor, dev->descriptor.idProduct); // Allocate memory for the device info and specification, fill it and return the info pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); goto error; } pn53x_usb_get_usb_device_name(dev, data.pudh, pnd->name, sizeof(pnd->name)); pnd->driver_data = malloc(sizeof(struct pn53x_usb_data)); if (!pnd->driver_data) { perror("malloc"); goto error; } *DRIVER_DATA(pnd) = data; // Alloc and init chip's data if (pn53x_data_new(pnd, &pn53x_usb_io) == NULL) { perror("malloc"); goto error; } switch (DRIVER_DATA(pnd)->model) { // empirical tuning case ASK_LOGO: CHIP_DATA(pnd)->timer_correction = 50; break; case SCM_SCL3711: case NXP_PN533: CHIP_DATA(pnd)->timer_correction = 46; break; case NXP_PN531: CHIP_DATA(pnd)->timer_correction = 50; break; case SONY_PN531: CHIP_DATA(pnd)->timer_correction = 54; break; case SONY_RCS360: case UNKNOWN: CHIP_DATA(pnd)->timer_correction = 0; // TODO: allow user to know if timed functions are available break; } pnd->driver = &pn53x_usb_driver; // HACK1: Send first an ACK as Abort command, to reset chip before talking to it: pn53x_usb_ack(pnd); // HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device // in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do if (pn53x_usb_init(pnd) < 0) { usb_close(data.pudh); goto error; } DRIVER_DATA(pnd)->abort_flag = false; goto free_mem; } } // We ran out of devices before the index required goto free_mem; error: // Free allocated structure on error. nfc_device_free(pnd); pnd = NULL; free_mem: free(desc.dirname); free(desc.filename); return pnd; } static void pn53x_usb_close(nfc_device *pnd) { pn53x_usb_ack(pnd); if (DRIVER_DATA(pnd)->model == ASK_LOGO) { /* Set P30, P31, P32, P33, P35 to logic 1 and P34 to 0 logic */ /* ie. Switch all LEDs off and turn off progressive field */ pn53x_write_register(pnd, PN53X_SFR_P3, 0xFF, _BV(P30) | _BV(P31) | _BV(P32) | _BV(P33) | _BV(P35)); } pn53x_idle(pnd); int res; if ((res = usb_release_interface(DRIVER_DATA(pnd)->pudh, 0)) < 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to release USB interface (%s)", _usb_strerror(res)); } if ((res = usb_close(DRIVER_DATA(pnd)->pudh)) < 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to close USB connection (%s)", _usb_strerror(res)); } pn53x_data_free(pnd); nfc_device_free(pnd); }
void garmin_usb_start(struct usb_device *dev, libusb_unit_data *lud) { int i; if (udev) return; udev = usb_open(dev); atexit(gusb_atexit_teardown); if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } /* * Hrmph. No iManufacturer or iProduct headers.... */ #if __APPLE__ // On Leopard, if we don't do an explicit set_configuration, some // devices will work only the first time after a reset. if (usb_set_configuration(udev, 1) < 0) { fatal("usb_set_configuration failed: %s\n", usb_strerror()); }; #endif #if 0 if (usb_set_configuration(udev, 1) < 0) { #if __linux__ char drvnm[128]; drvnm[0] = 0; /* * Most Linux distributions ship a slightly broken * kernel driver that bonds with the hardware. */ usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); #else fatal("usb_set_configuration failed: %s\n", usb_strerror()); #endif } #endif if (usb_claim_interface(udev, 0) < 0) { fatal("Claim interfaced failed: %s\n", usb_strerror()); } libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; /* * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac * with Venture HC) we get a dev with a valid vendor ID, but no * associated configuration. I was unable to see a single instance * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading * me to think this is some kind of bug in the Venture HC. * * Rather than crash, we at least print * a nastygram. Experiments with retrying various USB ops brought * no joy, so just call fatal and move on. */ if (!dev->config) { fatal("Found USB device with no configuration.\n"); } for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { struct usb_endpoint_descriptor * ep; ep = &dev->config->interface->altsetting->endpoint[i]; switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK case USB_ENDPOINT_TYPE_BULK: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; else gusb_bulk_out_ep = EA(ep->bEndpointAddress); break; case USB_ENDPOINT_TYPE_INTERRUPT: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; break; } } /* * Zero is the configuration endpoint, so if we made it through * that loop without non-zero values for all three, we're hosed. */ if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { lud->product_id = gusb_reset_toggles(); switch (lud->product_id) { // Search for "Venture HC" for more on this siliness.. // It's a case instead of an 'if' becuase I have a // feeling there are more affected models either // on the market or on the way. case 695: break; // Venture HC case 941: break; // Venture HC, Japanese version. case 957: break; // Legend H case 285: break; // GPSMap 276C/4.80 case 402: break; // GPSMap 396C/4.50 case 1095: break; // GPS72H/2.30 default: gusb_syncup(); } return; } fatal("Could not identify endpoints on USB device.\n" "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); }
// Open connection to a Tacx Fortius // // The Fortius handlebar controller is an EZ-USB device. This is an // embedded system using an 8051 microcontroller. Firmware must be // downloaded to it once it is connected. This firmware is obviously // copyrighted by Tacx and is not distributed with Golden Cheetah. // Instead we ask the user to tell us where it can be found when they // configure the device. (On Windows platforms the firmware is installed // by the standard Tacx software as c:\windows\system32\FortiusSWPID1942Renum.hex). // // So when we open a Fortius device we need to search for an unitialised // handlebar controller 3651:e6be and upload the firmware using the EzUsb // functions. Once that has completed the controller will represent itself // as 3651:1942. // // Firmware will need to be reloaded if the device is disconnected or the // USB controller is reset after sleep/resume. // // The EZUSB code is found in EzUsb.c, which is essentially the code used // in the 'fxload' command on Linux, some minor changes have been made to the // standard code wrt to logging errors. // // The only function we use is: // int ezusb_load_ram (usb_dev_handle *device, const char *path, int fx2, int stage) // device is a usb device handle // path is the filename of the firmware file // fx2 is non-zero to indicate an fx2 device (we pass 0, since the Fortius is fx) // stage is to control two stage loading, we load in a single stage struct usb_dev_handle* LibUsb::OpenFortius() { struct usb_bus* bus; struct usb_device* dev; struct usb_dev_handle* udev; bool programmed = false; // // Search for an UN-INITIALISED Fortius device // for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == FORTIUS_VID && dev->descriptor.idProduct == FORTIUS_INIT_PID) { if ((udev = usb_open(dev))) { // LOAD THE FIRMWARE ezusb_load_ram (udev, appsettings->value(NULL, FORTIUS_FIRMWARE, "").toString().toLatin1(), 0, 0); } // Now close the connection, our work here is done usb_close(udev); programmed = true; } } } // We need to rescan devices, since once the Fortius has // been programmed it will present itself again with a // different PID. But it takes its time, so we sleep for // 3 seconds. This may be too short on some operating // systems [XXX validate this]. On my Linux host running // a v3 kernel on an AthlonXP 2 seconds is not long enough. // // Given this is only required /the first time/ the Fortius // is connected, it can't be that bad? if (programmed == true) { #ifdef WIN32 Sleep(3000); // windows sleep is in milliseconds #else sleep(3); // do not be tempted to reduce this, it really does take that long! #endif usb_find_busses(); usb_find_devices(); } // // Now search for an INITIALISED Fortius device // for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == FORTIUS_VID && (dev->descriptor.idProduct == FORTIUS_PID || dev->descriptor.idProduct == FORTIUSVR_PID)) { //Avoid noisy output //qDebug() << "Found a Garmin USB2 ANT+ stick"; if ((udev = usb_open(dev))) { if (dev->descriptor.bNumConfigurations) { if ((intf = usb_find_interface(&dev->config[0])) != NULL) { int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); if (OperatingSystem == LINUX) { // looks like the udev rule has not been implemented qDebug()<<"check permissions on:"<<QString("/dev/bus/usb/%1/%2").arg(bus->dirname).arg(dev->filename); qDebug()<<"did you remember to setup a udev rule for this device?"; } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); if (OperatingSystem != OSX) { // fails on Mac OS X, we don't actually need it anyway rc = usb_set_altinterface(udev, alternate); if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); } return udev; } } usb_close(udev); } } } } return NULL; }
struct usb_dev_handle* LibUsb::OpenAntStick() { struct usb_bus* bus; struct usb_device* dev; struct usb_dev_handle* udev; // for Mac and Linux we do a bus reset on it first... #ifndef WIN32 for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == GARMIN_USB2_VID && dev->descriptor.idProduct == GARMIN_USB2_PID) { if ((udev = usb_open(dev))) { usb_reset(udev); usb_close(udev); } } } } #endif for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == GARMIN_USB2_VID && dev->descriptor.idProduct == GARMIN_USB2_PID) { //Avoid noisy output //qDebug() << "Found a Garmin USB2 ANT+ stick"; if ((udev = usb_open(dev))) { if (dev->descriptor.bNumConfigurations) { if ((intf = usb_find_interface(&dev->config[0])) != NULL) { int rc = usb_set_configuration(udev, 1); if (rc < 0) { qDebug()<<"usb_set_configuration Error: "<< usb_strerror(); if (OperatingSystem == LINUX) { // looks like the udev rule has not been implemented qDebug()<<"check permissions on:"<<QString("/dev/bus/usb/%1/%2").arg(bus->dirname).arg(dev->filename); qDebug()<<"did you remember to setup a udev rule for this device?"; } } rc = usb_claim_interface(udev, interface); if (rc < 0) qDebug()<<"usb_claim_interface Error: "<< usb_strerror(); if (OperatingSystem != OSX) { // fails on Mac OS X, we don't actually need it anyway rc = usb_set_altinterface(udev, alternate); if (rc < 0) qDebug()<<"usb_set_altinterface Error: "<< usb_strerror(); } return udev; } } usb_close(udev); } } } } return NULL; }
/* This function reads the Microsoft OS Descriptor and looks inside to * find if it is a MTP device. This is the similar to the way that * Windows Media Player 10 uses. * It is documented to some degree on various internet pages. */ static int gp_port_usb_match_mtp_device(struct libusb_device *dev,int *configno, int *interfaceno, int *altsettingno) { /* Marcus: Avoid this probing altogether, its too unstable on some devices */ return 0; #if 0 char buf[1000], cmd; int ret,i,i1,i2, xifaces,xnocamifaces; usb_dev_handle *devh; /* All of them are "vendor specific" device class */ #if 0 if ((desc.bDeviceClass!=0xff) && (desc.bDeviceClass!=0)) return 0; #endif if (dev->config) { xifaces = xnocamifaces = 0; for (i = 0; i < desc.bNumConfigurations; i++) { unsigned int j; for (j = 0; j < dev->config[i].bNumInterfaces; j++) { int k; xifaces++; for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) { struct usb_interface_descriptor *intf = &dev->config[i].interface[j].altsetting[k]; if ( (intf->bInterfaceClass == LIBUSB_CLASS_HID) || (intf->bInterfaceClass == LIBUSB_CLASS_PRINTER) || (intf->bInterfaceClass == LIBUSB_CLASS_AUDIO) || (intf->bInterfaceClass == LIBUSB_CLASS_HUB) || (intf->bInterfaceClass == LIBUSB_CLASS_COMM) || (intf->bInterfaceClass == 0xe0) /* wireless/bluetooth*/ ) xnocamifaces++; } } } } if (xifaces == xnocamifaces) /* only non-camera ifaces */ return 0; devh = usb_open (dev); if (!devh) return 0; /* * Loop over the device configurations and interfaces. Nokia MTP-capable * handsets (possibly others) typically have the string "MTP" in their * MTP interface descriptions, that's how they can be detected, before * we try the more esoteric "OS descriptors" (below). */ if (dev->config) { for (i = 0; i < desc.bNumConfigurations; i++) { unsigned int j; for (j = 0; j < dev->config[i].bNumInterfaces; j++) { int k; for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) { buf[0] = '\0'; ret = usb_get_string_simple(devh, dev->config[i].interface[j].altsetting[k].iInterface, (char *) buf, 1024); if (ret < 3) continue; if (strcmp((char *) buf, "MTP") == 0) { gp_log (GP_LOG_DEBUG, "mtp matcher", "Configuration %d, interface %d, altsetting %d:\n", i, j, k); gp_log (GP_LOG_DEBUG, "mtp matcher", " Interface description contains the string \"MTP\"\n"); gp_log (GP_LOG_DEBUG, "mtp matcher", " Device recognized as MTP, no further probing.\n"); goto found; } } } } } /* get string descriptor at 0xEE */ ret = usb_get_descriptor (devh, 0x03, 0xee, buf, sizeof(buf)); if (ret > 0) gp_log_data("get_MS_OSD",buf, ret); if (ret < 10) goto errout; if (!((buf[2] == 'M') && (buf[4]=='S') && (buf[6]=='F') && (buf[8]=='T'))) goto errout; cmd = buf[16]; ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|LIBUSB_REQUEST_TYPE_VENDOR, cmd, 0, 4, buf, sizeof(buf), 1000); if (ret == -1) { gp_log (GP_LOG_ERROR, "mtp matcher", "control message says %d\n", ret); goto errout; } if (buf[0] != 0x28) { gp_log (GP_LOG_ERROR, "mtp matcher", "ret is %d, buf[0] is %x\n", ret, buf[0]); goto errout; } if (ret > 0) gp_log_data("get_MS_ExtDesc",buf, ret); if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { gp_log (GP_LOG_ERROR, "mtp matcher", "buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]); goto errout; } ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|LIBUSB_REQUEST_TYPE_VENDOR, cmd, 0, 5, buf, sizeof(buf), 1000); if (ret == -1) goto errout; if (buf[0] != 0x28) { gp_log (GP_LOG_ERROR, "mtp matcher", "ret is %d, buf[0] is %x\n", ret, buf[0]); goto errout; } if (ret > 0) gp_log_data("get_MS_ExtProp",buf, ret); if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { gp_log (GP_LOG_ERROR, "mtp matcher", "buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]); goto errout; } found: usb_close (devh); /* Now chose a nice interface for us to use ... Just take the first. */ if (desc.bNumConfigurations > 1) gp_log (GP_LOG_ERROR, "mtp matcher", "The device has %d configurations!\n", desc.bNumConfigurations); for (i = 0; i < desc.bNumConfigurations; i++) { struct usb_config_descriptor *config = &dev->config[i]; if (config->bNumInterfaces > 1) gp_log (GP_LOG_ERROR, "mtp matcher", "The configuration has %d interfaces!\n", config->bNumInterfaces); for (i1 = 0; i1 < config->bNumInterfaces; i1++) { struct usb_interface *interface = &config->interface[i1]; if (interface->num_altsetting > 1) gp_log (GP_LOG_ERROR, "mtp matcher", "The interface has %d altsettings!\n", interface->num_altsetting); for (i2 = 0; i2 < interface->num_altsetting; i2++) { *configno = i; *interfaceno = i1; *altsettingno = i2; return 1; } } } return 1; errout: usb_close (devh); return 0; #endif }
usb_dev_handle *open_dev(void) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle; int rc; for(bus = usb_get_busses(); bus; bus = bus->next) { for(dev = bus->devices; dev; dev = dev->next) { #if REPORT_ALL_DEVICES dump_info(dev); #endif // // VendorID,ProductID の一致チェック. // if(dev->descriptor.idVendor == MY_VID && dev->descriptor.idProduct == MY_PID) { #if REPORT_MATCH_DEVICE if(verbose_mode) { dump_info(dev); } #endif handle = usb_open(dev); int cf=dev->config->bConfigurationValue; if((rc = usb_set_configuration(handle, cf))<0) { printf("usb_set_configuration error(1) cf=%d\n",cf); int fn=dev->config->interface->altsetting->bInterfaceNumber; if((rc = usb_detach_kernel_driver_np(handle,fn)) <0 ) { printf("usb_detach_kernel_driver_np(%d) error\n",fn); usb_close(handle); return NULL; } if((rc = usb_set_configuration(handle, dev->config->bConfigurationValue))<0) { printf("usb_set_configuration error(2)\n"); usb_close(handle); return NULL; } } if(usb_claim_interface(handle, 0) < 0) { printf("error: claiming interface 0 failed\n"); usb_close(usb_dev); return NULL; } if( open_dev_check_string(dev,handle) == 1) { return handle; //一致. } usb_close(handle); handle = NULL; } } } return NULL; }
SKYETEK_STATUS USBDevice_Open(LPSKYETEK_DEVICE device) { struct usb_bus *bus; struct usb_device *dev; LPUSB_DEVICE usbDevice; unsigned char retries; if((device == NULL) || (device->user == NULL)) return SKYETEK_INVALID_PARAMETER; if( device->readFD != 0 && device->writeFD != 0 ) return SKYETEK_SUCCESS; usbDevice = (LPUSB_DEVICE)device->user; start: for(bus = usb_busses; bus; bus = bus->next) { for(dev = bus->devices; dev; dev = dev->next) { if(strcmp(device->address, dev->filename) == 0) { usbDevice->usbDevHandle = usb_open(dev); usb_set_configuration(usbDevice->usbDevHandle, 1); retries = 3; while((usb_claim_interface(usbDevice->usbDevHandle, 0) != 0) && retries--) { /*printf("Unable to claim interface\n");*/ #ifdef LINUX if(usb_detach_kernel_driver_np(usbDevice->usbDevHandle, 0) < 0) { printf("Unable to detach kernel driver...\n"); goto done; } #else goto done; #endif } #ifdef LINUX if(retries != 3) { usb_close(usbDevice->usbDevHandle); usbDevice->usbDevHandle = NULL; goto start; } if(retries == 0) goto done; #endif /* Need this to make STPv3 happy */ device->writeFD = device->readFD = 1; #ifdef LINUX usbDevice->packetParity = 0; #endif return SKYETEK_SUCCESS; } } } done: usb_close(usbDevice->usbDevHandle); usbDevice->usbDevHandle = NULL; return SKYETEK_READER_IO_ERROR; }
//---------------------------------------------------------------------------- int usbasp_list(void) { char string[256]; char product[256]; unsigned char info[4]; struct usb_bus *bus; struct usb_device *dev; int usbasp_found; const struct usb_version *version; usb_init(); usb_find_busses(); usb_find_devices(); version = usb_get_version(); if (version) { printf("libusb-win32 : \n"); printf(" DLL(libusb0.dll) version: %d.%d.%d.%d\n", version->dll.major, version->dll.minor, version->dll.micro, version->dll.nano); printf(" Driver(libusb0.sys) version: %d.%d.%d.%d\n\n", version->driver.major, version->driver.minor, version->driver.micro, version->driver.nano); if (version->dll.major != version->driver.major || version->dll.minor != version->driver.minor || version->dll.micro != version->driver.micro // || version->dll.nano != version->driver.nano ) printf(" *** Warning : DLL, Driver Version mismatch ***\n"); } usbasp_found = 0; for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == USBDEV_VENDOR && dev->descriptor.idProduct == USBDEV_PRODUCT) { usbhandle = usb_open(dev); if (usbhandle) { /* yeah, we found something */ if (usb_get_string_simple(usbhandle, dev->descriptor.iSerialNumber, string, sizeof(string)) < 0) { strcpy(string, "[unknown]"); } if (usb_get_string_simple(usbhandle, dev->descriptor.iProduct, product, sizeof(product)) < 0) { strcpy(product, "[unnamed product]"); } if (usbasp_get_info(info) == 0) { fprintf(stdout, "%s: Found %s, Serial Number: [%s], Firmware version %X.%02X\n", progname, product, string, info[1], info[0]); // fprintf(stdout, "\t%02X %02X\n", info[2], info[3]); } else { fprintf(stdout, "%s: Found %s, Serial Number: [%s]\n", progname, product, string); } ++usbasp_found; usb_close(usbhandle); } } } } if (!usbasp_found) { fprintf(stderr, "%s: did not find any USBaspx device (VID=0x%04x, PID=0x%04x)\n", progname, USBDEV_VENDOR, USBDEV_PRODUCT); return -1; } return usbasp_found; }
/** * Initialize the driver. * \param drvthis Pointer to driver structure. * \retval 0 Success. * \retval -1 Error. */ int hd_init_lcd2usb(Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; struct usb_bus *bus; p->hd44780_functions->senddata = lcd2usb_HD44780_senddata; p->hd44780_functions->backlight = lcd2usb_HD44780_backlight; p->hd44780_functions->scankeypad = lcd2usb_HD44780_scankeypad; p->hd44780_functions->close = lcd2usb_HD44780_close; p->hd44780_functions->set_contrast = lcd2usb_HD44780_set_contrast; p->hd44780_functions->flush = lcd2usb_HD44780_flush; /* try to find USB device */ #if 0 usb_debug = 2; #endif usb_init(); usb_find_busses(); usb_find_devices(); p->usbHandle = NULL; for (bus = usb_get_busses(); bus != NULL; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev != NULL; dev = dev->next) { /* Check if this device is a LCD2USB device */ if ((dev->descriptor.idVendor == LCD2USB_VENDORID) && (dev->descriptor.idProduct == LCD2USB_PRODUCTID)) { /* * LCD2USB device found; try to find its * description */ p->usbHandle = usb_open(dev); if (p->usbHandle == NULL) { report(RPT_WARNING, "hd_init_lcd2usb: unable to open device"); } else { /* read firmware version */ unsigned char buffer[2]; if (usb_control_msg(p->usbHandle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, LCD2USB_GET_FWVER, 0, 0, (char *)buffer, sizeof(buffer), 1000) == 2) report(RPT_INFO, "hd_init_lcd2usb: device with firmware version %d.%02d found", buffer[0], buffer[1]); } } } } if (p->usbHandle != NULL) { debug(RPT_DEBUG, "hd_init_lcd2usb: opening device succeeded"); } else { report(RPT_ERR, "hd_init_lcd2usb: no (matching) LCD2USB device found"); return -1; } /* allocate and initialize send buffer */ if ((p->tx_buf.buffer = malloc(LCD2USB_MAX_CMD)) == NULL) { report(RPT_ERR, "hd_init_lcd2usb: could not allocate send buffer"); lcd2usb_HD44780_close(p); return -1; } p->tx_buf.type = -1; p->tx_buf.use_count = 0; common_init(p, IF_4BIT); /* replace uPause with empty one after initialization */ p->hd44780_functions->uPause = lcd2usb_HD44780_uPause; return 0; }
int main(int argc, char **argv) { struct usb_vendprod vendprod; struct dfu_if _rt_dif, _dif, *dif = &_dif; int num_devs; int num_ifs; unsigned int transfer_size = 0; enum mode mode = MODE_NONE; struct dfu_status status; int quirks_auto_detect = 1; dfu_quirks manual_quirks; dfu_handle handle; char *filename = NULL; char *alt_name = NULL; /* query alt name if non-NULL */ char *end; int final_reset = 0; int page_size = getpagesize(); int ret; printf("dfu-util - (C) 2007-2008 by OpenMoko Inc.\n" "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n"); dfu_quirks_clear(&manual_quirks); memset(dif, 0, sizeof(*dif)); usb_init(); //usb_set_debug(255); usb_find_busses(); usb_find_devices(); while (1) { int c, option_index = 0; c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:C:S:RQNq:", opts, &option_index); if (c == -1) break; switch (c) { case 'h': help(); exit(0); break; case 'V': print_version(); exit(0); break; case 'v': verbose = 1; break; case 'l': list_dfu_interfaces(); exit(0); break; case 'd': /* Parse device */ if (parse_vendprod(&vendprod, optarg) < 0) { fprintf(stderr, "unable to parse `%s'\n", optarg); exit(2); } dif->vendor = vendprod.vendor; dif->product = vendprod.product; dif->flags |= (DFU_IFF_VENDOR | DFU_IFF_PRODUCT); break; case 'p': /* Parse device path */ dif->path = optarg; dif->flags |= DFU_IFF_PATH; ret = resolve_device_path(dif); if (ret < 0) { fprintf(stderr, "unable to parse `%s'\n", optarg); exit(2); } if (!ret) { fprintf(stderr, "cannot find `%s'\n", optarg); exit(1); } break; case 'c': /* Configuration */ dif->configuration = atoi(optarg); dif->flags |= DFU_IFF_CONFIG; break; case 'i': /* Interface */ dif->interface = atoi(optarg); dif->flags |= DFU_IFF_IFACE; break; case 'a': /* Interface Alternate Setting */ dif->altsetting = strtoul(optarg, &end, 0); if (*end) alt_name = optarg; dif->flags |= DFU_IFF_ALT; break; case 't': transfer_size = atoi(optarg); break; case 'U': mode = MODE_UPLOAD; filename = optarg; break; case 'D': mode = MODE_DOWNLOAD; filename = optarg; break; case 'C': mode = MODE_COMPARE; /* TODO: verify firmware */ filename = optarg; break; case 'S': filename = optarg; add_file_suffix(filename); exit(0); break; case 'R': final_reset = 1; break; case 'Q': dfu_quirks_print(); exit(0); break; case 'N': quirks_auto_detect = 0; break; case 'q': quirks_auto_detect = 0; dfu_quirk_set(&manual_quirks, atoi(optarg)); break; default: help(); exit(2); } } if (mode == MODE_NONE) { fprintf(stderr, "You need to specify one of -D or -U\n"); help(); exit(2); } if (!filename) { fprintf(stderr, "You need to specify a filename to -D -r -U\n"); help(); exit(2); } dfu_init(&handle, 5000); num_devs = count_dfu_devices(dif); if (num_devs == 0) { fprintf(stderr, "No DFU capable USB device found\n"); exit(1); } else if (num_devs > 1) { /* We cannot safely support more than one DFU capable device * with same vendor/product ID, since during DFU we need to do * a USB bus reset, after which the target device will get a * new address */ fprintf(stderr, "More than one DFU capable USB device found, " "you might try `--list' and then disconnect all but one " "device\n"); exit(3); } if (!get_first_dfu_device(dif)) exit(3); /* We have exactly one device. It's usb_device is now in dif->dev */ printf("Opening USB Device 0x%04x:0x%04x...\n", dif->vendor, dif->product); dif->dev_handle = usb_open(dif->dev); if (!dif->dev_handle) { fprintf(stderr, "Cannot open device: %s\n", usb_strerror()); exit(1); } /* try to find first DFU interface of device */ memcpy(&_rt_dif, dif, sizeof(_rt_dif)); if (!get_first_dfu_if(&_rt_dif)) exit(1); handle.device = _rt_dif.dev_handle; handle.interface = _rt_dif.interface; /* automatic quirk detection */ if(quirks_auto_detect) { /* TODO: let the detection be influenced by bcdDFU, bcdDevice */ handle.quirk_flags = dfu_quirks_detect(0, dif->vendor, dif->product, 0); } /* merge with manual quirks */ dfu_quirks_insert(&handle.quirk_flags, &manual_quirks); if(!dfu_quirks_is_empty(&handle.quirk_flags)) { printf("Selected quirks: "); dfu_quirks_print_set(&handle.quirk_flags); printf("\n"); } if (!_rt_dif.flags & DFU_IFF_DFU) { /* In the 'first round' during runtime mode, there can only be one * DFU Interface descriptor according to the DFU Spec. */ /* FIXME: check if the selected device really has only one */ printf("Claiming USB DFU Runtime Interface %d...\n", _rt_dif.interface); if (usb_claim_interface(_rt_dif.dev_handle, _rt_dif.interface) < 0) { fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); exit(1); } /* DFU 1.0, Table 4.1: in runtime-mode, alternate interface setting must be zero. therefore we can assume, '0' is correct. the reason we use usb_set_altinterface() here: switch devices to the interface set using usb_claim_interface() above - for some reason this isn't done there. is the only libusb API which issues the SET_INTERFACE USB standard request is usb_set_altinterface() */ if (usb_set_altinterface(_rt_dif.dev_handle, 0) < 0) { fprintf(stderr, "Cannot set alternate interface %d: %s\n", 0, usb_strerror()); exit(1); } printf("Determining device state: "); int state = -1; if ( (state = dfu_get_state(&handle)) < 0) { exit(1); } printf("state = %s\n", dfu_state_to_string(state)); dfu_sm_set_state_unchecked(&handle, state); printf("Determining device status: "); if (dfu_get_status(&handle, &status ) < 0) { exit(1); } printf("state = %s, status = %d = \"%s\"\n", dfu_state_to_string(status.bState), status.bStatus, dfu_status_to_string(status.bStatus) ); switch (status.bState) { case DFU_STATE_appIDLE: case DFU_STATE_appDETACH: printf("Device really in Runtime Mode, send DFU " "detach request...\n"); if(status.bState == DFU_STATE_appDETACH) { printf("Device is already in state %s, skipping DFU_DETACH request\n", dfu_state_to_string(status.bState)); } else { if (dfu_detach(&handle, 1000) < 0) { exit(1); break; } } /* handle bitWillDetach (DFU 1.1) */ if(handle.dfu_ver == DFU_VERSION_1_1 && handle.func_dfu.bmAttributes & USB_DFU_WILL_DETACH) { /* TODO: test this with a real DFU 1.1 device */ printf("Waiting for USB device's own detach (bitWillDetach=1)...\n"); dfu_sm_set_state_checked(&handle, DFU_STATE_dfuIDLE); } else { printf("Resetting USB...\n"); ret = dfu_usb_reset(&handle); if (ret < 0 && ret != -ENODEV) { /* do nothing; error msg is output in dfu_usb_reset. */ } } sleep(2); break; case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); if (dfu_clear_status(&handle) < 0) { exit(1); break; } break; default: fprintf(stderr, "WARNING: Runtime device already " "in DFU state ?!?\n"); goto dfustate; break; } /* now we need to re-scan the bus and locate our device */ if (usb_find_devices() < 2) printf("not at least 2 device changes found ?!?\n"); if (dif->flags & DFU_IFF_PATH) { ret = resolve_device_path(dif); if (ret < 0) { fprintf(stderr, "internal error: cannot re-parse `%s'\n", dif->path); abort(); } if (!ret) { fprintf(stderr, "Can't resolve path after RESET?\n"); exit(1); } } num_devs = count_dfu_devices(dif); if (num_devs == 0) { fprintf(stderr, "Lost device after RESET?\n"); exit(1); } else if (num_devs > 1) { fprintf(stderr, "More than one DFU capable USB " "device found, you might try `--list' and " "then disconnect all but one device\n"); exit(1); } if (!get_first_dfu_device(dif)) exit(3); printf("Opening USB Device...\n"); dif->dev_handle = usb_open(dif->dev); if (!dif->dev_handle) { fprintf(stderr, "Cannot open device: %s\n", usb_strerror()); exit(1); } } else { /* we're already in DFU mode, so we can skip the detach/reset * procedure */ } dfustate: if (alt_name) { int n; n = find_dfu_if(dif->dev, &alt_by_name, alt_name); if (!n) { fprintf(stderr, "No such Alternate Setting: \"%s\"\n", alt_name); exit(1); } if (n < 0) { fprintf(stderr, "Error %d in name lookup\n", n); exit(1); } dif->altsetting = n-1; } print_dfu_if(dif, NULL); num_ifs = count_dfu_interfaces(dif->dev); if (num_ifs < 0) { fprintf(stderr, "No DFU Interface after RESET?!?\n"); exit(1); } else if (num_ifs == 1) { if (!get_first_dfu_if(dif)) { fprintf(stderr, "Can't find the single available " "DFU IF\n"); exit(1); } } else if (num_ifs > 1 && (!dif->flags) & (DFU_IFF_IFACE|DFU_IFF_ALT)) { fprintf(stderr, "We have %u DFU Interfaces/Altsettings, " "you have to specify one via --intf / --alt options\n", num_ifs); exit(1); } #if 0 printf("Setting Configuration %u...\n", dif->configuration); if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) { fprintf(stderr, "Cannot set configuration: %s\n", usb_strerror()); exit(1); } #endif printf("Claiming USB DFU Interface...\n"); if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) { fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror()); exit(1); } printf("Setting Alternate Setting ...\n"); if (usb_set_altinterface(dif->dev_handle, dif->altsetting) < 0) { fprintf(stderr, "Cannot set alternate interface: %s\n", usb_strerror()); exit(1); } /* update the handle to point to the dfu-mode descriptor */ handle.device = dif->dev_handle; handle.interface = dif->interface; status_again: printf("Determining device status: "); if (dfu_get_status(&handle, &status ) < 0) { fprintf(stderr, "error get_status: %s\n", usb_strerror()); exit(1); } printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus); /* force the statemachine into current status */ dfu_sm_set_state_unchecked(&handle, status.bState); switch (status.bState) { case DFU_STATE_appIDLE: case DFU_STATE_appDETACH: fprintf(stderr, "Device still in Runtime Mode!\n"); exit(1); break; case DFU_STATE_dfuERROR: printf("dfuERROR, clearing status\n"); if (dfu_clear_status(&handle) < 0) { fprintf(stderr, "error clear_status: %s\n", usb_strerror()); exit(1); } goto status_again; break; case DFU_STATE_dfuDNLOAD_IDLE: case DFU_STATE_dfuUPLOAD_IDLE: printf("aborting previous incomplete transfer\n"); if (dfu_abort(&handle) < 0) { fprintf(stderr, "can't send DFU_ABORT: %s\n", usb_strerror()); exit(1); } goto status_again; break; case DFU_STATE_dfuIDLE: printf("dfuIDLE, continuing\n"); break; } /* Obtain DFU functional descriptor */ ret = usb_get_descriptor(dif->dev_handle, 0x21, dif->interface, &(handle.func_dfu), sizeof(handle.func_dfu)); if (ret < 0) { fprintf(stderr, "Error obtaining DFU functional " "descriptor: %s\n", usb_strerror()); if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_IGNORE_INVALID_FUNCTIONAL_DESCRIPTOR)) { handle.func_dfu.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_MANIFEST_TOL; handle.func_dfu.wTransferSize = cpu_to_le16(transfer_size); if(!transfer_size) transfer_size = page_size; handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0; fprintf(stderr, " Still, try to continue with default flags/manual settings.\n"); } else { exit(1); } } else { transfer_size = le16_to_cpu(handle.func_dfu.wTransferSize); } /* why is this limited to page_size, a host-dependent value? (sgiessl) */ if (transfer_size > page_size) transfer_size = page_size; /* quirk overwriting DFU version */ if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_0)) { handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0; } else if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_1)) { handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_1; } /* read DFU version */ switch(handle.func_dfu.bcdDFUVersion) { case USB_DFU_VER_1_1: handle.dfu_ver = DFU_VERSION_1_1; break; default: printf("WARNING: device specifies unknown DFU version 0x%.2x, defaulting to DFU 1.0\n", handle.func_dfu.bcdDFUVersion); /* fall through intended */ case USB_DFU_VER_1_0: handle.dfu_ver = DFU_VERSION_1_0; break; } printf("Transfer Size = 0x%04x\n", transfer_size); printf("Device functional descriptor: %s\n", dfu_func_descriptor_to_string(&handle.func_dfu)); if (DFU_STATUS_OK != status.bStatus ) { printf("WARNING: DFU Status: '%s'\n", dfu_status_to_string(status.bStatus)); /* Clear our status & try again. */ dfu_clear_status(&handle); dfu_get_status(&handle, &status); if (DFU_STATUS_OK != status.bStatus) { fprintf(stderr, "Error: %d\n", status.bStatus); exit(1); } } switch (mode) { case MODE_UPLOAD: if (sam7dfu_do_upload(&handle, transfer_size, filename) < 0) exit(1); break; case MODE_DOWNLOAD: if (sam7dfu_do_dnload(&handle, transfer_size, filename) < 0) exit(1); break; default: fprintf(stderr, "Unsupported mode: %u\n", mode); exit(1); } if (final_reset) { if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET)) { /* DFU_DETACH is only allowed in appIDLE, so this is non-standard (as of DFU 1.0, and 1.1). */ printf("Initiating reset by sending DFU_DETACH (QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET)\n"); if (dfu_detach(&handle, 1000) < 0) { fprintf(stderr, "can't detach: %s\n", usb_strerror()); } } printf("Resetting USB to switch back to runtime mode\n"); ret = usb_reset(dif->dev_handle); if (ret < 0 && ret != -ENODEV) { fprintf(stderr, "error resetting after download: %s\n", usb_strerror()); } } exit(0); }
int device_init(void) { struct usb_bus *usb_bus; struct usb_device *dev; usb_init(); int n=0; usb_find_busses(); usb_find_devices(); ret = hid_init(); if (ret != HID_RET_SUCCESS) { fprintf(stderr, "hid_init failed with return code %d \n", ret); return 1; } for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) { for (dev = usb_bus->devices; dev; dev = dev->next) { if ((dev->descriptor.idVendor == VENDOR_ID) && (dev->descriptor.idProduct == PRODUCT_ID)) { /////////////////////////////////////////////// n++; usb_handle = usb_open(dev); int drstatus = usb_get_driver_np(usb_handle, 0, kdname,sizeof(kdname)); if (kdname != NULL && strlen(kdname) > 0) usb_detach_kernel_driver_np(usb_handle, 0); usb_reset(usb_handle); usb_close(usb_handle); HIDInterfaceMatcher matcher = { VENDOR_ID, PRODUCT_ID, NULL, NULL, 0 }; if (n==1) { hid1 = hid_new_HIDInterface(); if (hid1 != 0) { ret = hid_force_open(hid1, 0, &matcher, 3); if (ret != HID_RET_SUCCESS) { fprintf(stderr, "hid_force_open failed with return code %d\n", ret); } } ////////////////////////////////////////////// } else // n=2 { hid2 = hid_new_HIDInterface(); if (hid2 != 0) { ret = hid_force_open(hid2, 0, &matcher, 3); if (ret != HID_RET_SUCCESS) { fprintf(stderr, "hid_force_open failed with return code %d\n", ret); } ////////////////////////////////////////////// } } } } } return 0; }
int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) { struct usb_device *found = NULL; struct usb_device *dev; struct usb_bus *bus; /* At last, we reach out through the USB bus to the part. There are three * ways to specify the part: by USB address, by USB vendor and product id, * and by part name. To specify the part by USB address, the user specifies * a port parameter in the form "usb:BUS:DEV" (see dfu_open()). To specify * the part by vendor and product, the user must specify a usbvid and usbpid * in the configuration file. Finally, if the user specifies the part only, * we use the default vendor and product id. */ if (pid == 0 && dfu->dev_name == NULL) { fprintf(stderr, "%s: Error: No DFU support for part; " "specify PID in config or USB address (via -P) to override.\n", progname); return -1; } /* Scan through all the devices for the part. The matching rules are: * * 1. If the user specified a USB bus name, it must match. * 2. If the user specified a USB device name, it must match. * 3. If the user didn't specify a USB device name and specified a vendor * id, the vendor id must match. * 4. If the user didn't specify a USB device name and specified a product * id, the product id must match. */ for (bus = usb_busses; !found && bus != NULL; bus = bus->next) { for (dev = bus->devices; !found && dev != NULL; dev = dev->next) { if (dfu->bus_name != NULL && strcmp(bus->dirname, dfu->bus_name)) continue; if (dfu->dev_name != NULL) { if (strcmp(dev->filename, dfu->dev_name)) continue; } else if (vid != dev->descriptor.idVendor) continue; else if (pid != 0 && pid != dev->descriptor.idProduct) continue; found = dev; } } if (found == NULL) { /* We could try to be more informative here. For example, we could report * why the match failed, and if we came across another DFU-capable part. */ fprintf(stderr, "%s: Error: No matching USB device found\n", progname); return -1; } if(verbose) fprintf(stderr, "%s: Found VID=0x%04x PID=0x%04x at %s:%s\n", progname, found->descriptor.idVendor, found->descriptor.idProduct, found->bus->dirname, found->filename); dfu->dev_handle = usb_open(found); if (dfu->dev_handle == NULL) { fprintf(stderr, "%s: Error: USB device at %s:%s: %s\n", progname, found->bus->dirname, found->filename, usb_strerror()); return -1; } /* Save device, configuration, interface and endpoint descriptors. */ memcpy(&dfu->dev_desc, &found->descriptor, sizeof(dfu->dev_desc)); memcpy(&dfu->conf_desc, found->config, sizeof(dfu->conf_desc)); dfu->conf_desc.interface = NULL; memcpy(&dfu->intf_desc, found->config->interface->altsetting, sizeof(dfu->intf_desc)); dfu->intf_desc.endpoint = &dfu->endp_desc; if (found->config->interface->altsetting->endpoint != 0) memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint, sizeof(dfu->endp_desc)); /* Get strings. */ dfu->manf_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iManufacturer); dfu->prod_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iProduct); dfu->serno_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iSerialNumber); return 0; }
Xbox360Controller::Xbox360Controller(struct usb_device* dev_, bool is_guitar_, bool try_detach) : dev(dev_), is_guitar(is_guitar_), dev_type(), handle(), endpoint_in(1), endpoint_out(2), read_thread() { find_endpoints(); if (0) { std::cout << "EP(IN): " << endpoint_in << std::endl; std::cout << "EP(OUT): " << endpoint_out << std::endl; } handle = usb_open(dev); if (0) { int err; if ((err = usb_set_configuration(handle, 0)) < 0) { std::ostringstream out; out << "Error set USB configuration: " << usb_strerror() << std::endl << "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver."; throw std::runtime_error(out.str()); } } if (!handle) { throw std::runtime_error("Error opening Xbox360 controller"); } else { // FIXME: bInterfaceNumber shouldn't be hardcoded int err = usb_claim_n_detach_interface(handle, 0, try_detach); if (err != 0) { std::ostringstream out; out << " Error couldn't claim the USB interface: " << usb_strerror() << std::endl << "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver."; throw std::runtime_error(out.str()); } } if (0) { unsigned char arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 255 }; for (int len = 3; len <= 8; ++len) { // Sending random data: for (int front = 0; front < 256; ++front) { for (size_t i = 0; i < sizeof(arr); ++i) { char ledcmd[] = { front, len, arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i], arr[i] }; printf("%d %d %d\n", len, front, arr[i]); usb_interrupt_write(handle, endpoint_out, ledcmd, len, 0); uint8_t data[32]; int ret = usb_interrupt_read(handle, endpoint_in, reinterpret_cast<char*>(data), sizeof(data), 20); print_raw_data(std::cout, data, ret); } } } } read_thread = std::auto_ptr<USBReadThread>(new USBReadThread(handle, endpoint_in, 32)); read_thread->start_thread(); }
static int probe_device_descriptor(struct usb_device *dev, FILE *dumpfile) { usb_dev_handle *devh; unsigned char buf[1024], cmd; int i; int ret; if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) { return 0; } devh = usb_open(dev); if (devh == NULL) { return 0; } if (dev->config) { for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { uint8_t j; for (j = 0; j < dev->config[i].bNumInterfaces; j++) { int k; for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) { struct usb_interface_descriptor *intf = &dev->config[i].interface[j].altsetting[k]; buf[0] = '\0'; ret = usb_get_string_simple(devh, dev->config[i].interface[j].altsetting[k].iInterface, (char *) buf, 1024); if (ret < 3) continue; if (strcmp((char *) buf, "MTP") == 0) { if (dumpfile != NULL) { fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k); fprintf(dumpfile, " Interface description contains the string \"MTP\"\n"); fprintf(dumpfile, " Device recognized as MTP, no further probing.\n"); } usb_close(devh); return 1; } #ifdef LIBUSB_HAS_GET_DRIVER_NP { char devname[0x10]; devname[0] = '\0'; ret = usb_get_driver_np(devh, dev->config[i].interface[j].altsetting[k].iInterface, devname, sizeof(devname)); if (devname[0] != '\0' && strcmp(devname, "usb-storage")) { printf("avoid probing device using kernel interface \"%s\"\n", devname); return 0; } } #endif } } } } else { if (dev->descriptor.bNumConfigurations) printf("dev->config is NULL in probe_device_descriptor yet dev->descriptor.bNumConfigurations > 0\n"); } ret = usb_get_descriptor(devh, 0x03, 0xee, buf, sizeof(buf)); if (dumpfile != NULL && ret > 0) { fprintf(dumpfile, "Microsoft device descriptor 0xee:\n"); data_dump_ascii(dumpfile, buf, ret, 16); } if (ret < 10) { usb_close(devh); return 0; } if (!((buf[2] == 'M') && (buf[4] == 'S') && (buf[6] == 'F') && (buf[8] == 'T'))) { usb_close(devh); return 0; } cmd = buf[16]; ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, cmd, 0, 4, (char *) buf, sizeof(buf), USB_TIMEOUT_DEFAULT); if (dumpfile != NULL && ret > 0) { fprintf(dumpfile, "Microsoft device response to control message 1, CMD 0x%02x:\n", cmd); data_dump_ascii(dumpfile, buf, ret, 16); } if (ret <= 0x15) { usb_close(devh); return 0; } if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { usb_close(devh); return 0; } ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, cmd, 0, 5, (char *) buf, sizeof(buf), USB_TIMEOUT_DEFAULT); if (dumpfile != NULL && ret > 0) { fprintf(dumpfile, "Microsoft device response to control message 2, CMD 0x%02x:\n", cmd); data_dump_ascii(dumpfile, buf, ret, 16); } if (ret == -1) { fprintf(stderr, "Potential MTP Device with VendorID:%04x and " "ProductID:%04x encountered an error responding to " "control message 2.\n" "Problems may arrise but continuing\n", dev->descriptor.idVendor, dev->descriptor.idProduct); } else if (ret <= 0x15) { fprintf(stderr, "Potential MTP Device with VendorID:%04x and " "ProductID:%04x responded to control message 2 with a " "response that was too short. Problems may arrise but " "continuing\n", dev->descriptor.idVendor, dev->descriptor.idProduct); } else if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { fprintf(stderr, "Potential MTP Device with VendorID:%04x and " "ProductID:%04x encountered an error responding to " "control message 2\n" "Problems may arrise but continuing\n", dev->descriptor.idVendor, dev->descriptor.idProduct); } usb_close(devh); return 1; }
//---------------------------------------------------------------------------- int usbasp_open(char *SerialNumber) { struct usb_bus *bus; struct usb_device *dev; char string[256]; char serial[USB_CFG_SERIAL_NUMBER_LEN+1]; #ifdef __GNUC__ int old_fd, nul_fd; #endif setup_serial(serial, SerialNumber); /* * libusb-win32-0.1.10.1 で usb_find_busses() を実行したときに * "found N busses"がstdoutに出力されるため一時的にstdoutをnulに切換 * libusb-win32-0.1.10.2/ libusb-win32-0.1.12.0で修正されている * とりあえずgccのみ (bcc/bcb6/vc8では正常に動作しない) */ #ifdef __GNUC__ old_fd = dup(fileno(stdout)); // 標準出力のバックアップを作成 nul_fd = open("nul", O_WRONLY); // 標準出力用に"nul"を開く dup2(nul_fd, fileno(stdout)); // ファイルのディスクリプタのコピーを1番に作成 #endif usb_init(); usb_find_busses(); // この中で不要な printf がある usb_find_devices(); #ifdef __GNUC__ fflush(stdout); dup2(old_fd, fileno(stdout)); // 標準出力を元に戻す close(old_fd); // 標準出力のバックアップを閉じる close(nul_fd); #endif for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == USBDEV_VENDOR && dev->descriptor.idProduct == USBDEV_PRODUCT) { usbhandle = usb_open(dev); if (usbhandle) { if (SerialNumber == NULL) return 0; // findfirst // check serial number if (usb_get_string_simple(usbhandle, dev->descriptor.iSerialNumber, string, sizeof(string)) < 0) { // cannot read serial number if (!SerialNumber[0]) return 0; } if (strnicmp(serial, string, USB_CFG_SERIAL_NUMBER_LEN) == 0) return 0; usb_close(usbhandle); } } } } fprintf(stderr, "%s: usb_open(): did not find any%s USB device \"%.4s\"\n", progname, SerialNumber ? " (matching)": "", serial); return 1; }
/** @brief detect devices based on usb pid / vid. * @return list with usb VID / PID values. */ QMap<uint32_t, QString> System::listUsbDevices(void) { QMap<uint32_t, QString> usbids; // usb pid detection qDebug() << "[System] Searching for USB devices"; #if defined(Q_OS_LINUX) #if defined(LIBUSB1) libusb_device **devs; if(libusb_init(NULL) != 0) { qDebug() << "[System] Initializing libusb-1 failed."; return usbids; } if(libusb_get_device_list(NULL, &devs) < 1) { qDebug() << "[System] Error getting device list."; return usbids; } libusb_device *dev; int i = 0; while((dev = devs[i++]) != NULL) { QString name; unsigned char buf[256]; uint32_t id; struct libusb_device_descriptor descriptor; if(libusb_get_device_descriptor(dev, &descriptor) == 0) { id = descriptor.idVendor << 16 | descriptor.idProduct; libusb_device_handle *dh; if(libusb_open(dev, &dh) == 0) { libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256); name += QString::fromLatin1((char*)buf) + " "; libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256); name += QString::fromLatin1((char*)buf); libusb_close(dh); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insert(id, name); qDebug("[System] USB: 0x%08x, %s", id, name.toLocal8Bit().data()); } } } libusb_free_device_list(devs, 1); libusb_exit(NULL); #else usb_init(); usb_find_busses(); usb_find_devices(); struct usb_bus *b; b = usb_busses; while(b) { if(b->devices) { struct usb_device *u; u = b->devices; while(u) { uint32_t id; id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; // get identification strings usb_dev_handle *dev; QString name; char string[256]; int res; dev = usb_open(u); if(dev) { if(u->descriptor.iManufacturer) { res = usb_get_string_simple(dev, u->descriptor.iManufacturer, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string) + " "; } if(u->descriptor.iProduct) { res = usb_get_string_simple(dev, u->descriptor.iProduct, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string); } usb_close(dev); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insert(id, name); qDebug() << "[System] USB:" << QString("0x%1").arg(id, 8, 16) << name; } u = u->next; } } b = b->next; } #endif #endif #if defined(Q_OS_MACX) kern_return_t result = KERN_FAILURE; CFMutableDictionaryRef usb_matching_dictionary; io_iterator_t usb_iterator = IO_OBJECT_NULL; usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName); result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary, &usb_iterator); if(result) { qDebug() << "[System] USB: IOKit: Could not get matching services."; return usbids; } io_object_t usbCurrentObj; while((usbCurrentObj = IOIteratorNext(usb_iterator))) { uint32_t id; QString name; /* get vendor ID */ CFTypeRef vidref = NULL; int vid = 0; vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid); CFRelease(vidref); /* get product ID */ CFTypeRef pidref = NULL; int pid = 0; pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid); CFRelease(pidref); id = vid << 16 | pid; /* get product vendor */ char vendor_buf[256]; CFIndex vendor_buflen = 256; CFTypeRef vendor_name_ref = NULL; vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Vendor Name"), kCFAllocatorDefault, 0); if(vendor_name_ref != NULL) { CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(vendor_buf) + " "; CFRelease(vendor_name_ref); } else { name += QObject::tr("(unknown vendor name) "); } /* get product name */ char product_buf[256]; CFIndex product_buflen = 256; CFTypeRef product_name_ref = NULL; product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Product Name"), kCFAllocatorDefault, 0); if(product_name_ref != NULL) { CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(product_buf); CFRelease(product_name_ref); } else { name += QObject::tr("(unknown product name)"); } if(id) { usbids.insert(id, name); qDebug() << "[System] USB:" << QString("0x%1").arg(id, 8, 16) << name; } } IOObjectRelease(usb_iterator); #endif #if defined(Q_OS_WIN32) HDEVINFO deviceInfo; SP_DEVINFO_DATA infoData; DWORD i; // Iterate over all devices // by doing it this way it's unneccessary to use GUIDs which might be not // present in current MinGW. It also seemed to be more reliably than using // a GUID. // See KB259695 for an example. deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); infoData.cbSize = sizeof(SP_DEVINFO_DATA); for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { DWORD data; LPTSTR buffer = NULL; DWORD buffersize = 0; QString description; // get device desriptor first // for some reason not doing so results in bad things (tm) while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } description = QString::fromWCharArray(buffer); // now get the hardware id, which contains PID and VID. while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } unsigned int vid, pid; // convert buffer text to upper case to avoid depending on the case of // the keys (W7 uses different casing than XP at least). int len = _tcslen(buffer); while(len--) buffer[len] = _totupper(buffer[len]); if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) { uint32_t id; id = vid << 16 | pid; usbids.insert(id, description); qDebug("[System] USB VID: %04x, PID: %04x", vid, pid); } if(buffer) free(buffer); } SetupDiDestroyDeviceInfoList(deviceInfo); #endif return usbids; }
/* * Open SUB device */ sub_handle sub_open( sub_device dev ) { #ifndef _MSC_VER /* Determine Debug Level */ { char* level_env = getenv("SUB_DEBUG"); if( level_env ) sub_debug_level = atoi(level_env); } #endif /*_MSC_VER*/ #ifdef LIBUSB_1_0 libusb_device_handle* handle; int config; /* Open Device */ if( !dev ) { if( init_required ) { if( libusb_init(&usb_context) ) { sub_errno = SE_INIT; return 0; } init_required = 0; list = 0; } handle = libusb_open_device_with_vid_pid(usb_context,SUB_VID,SUB_PID); if( !handle ) { sub_errno = SE_NODEV; return 0; } } else { if( libusb_open( dev, &handle ) ) { sub_errno = SE_OPEN; return 0; } } /* Set Configuration */ if( libusb_get_configuration(handle, &config) ) { sub_errno = SE_SETCONF; goto fin; } if( config!=1 ) { if( libusb_set_configuration(handle,1) ) { sub_errno = SE_SETCONF; goto fin; } } /* Claim Interface */ if( libusb_claim_interface(handle,0) ) { sub_errno = SE_CLAIM; goto fin; } return handle; fin: libusb_close( handle ); return 0; #else /* Libusb 0.1 Compatible Implementation */ usb_dev_handle* handle; if( !dev ) { dev = sub_find_devices( 0 ); if( !dev ) return 0; } handle = usb_open( dev ); if( !handle ) { sub_errno = SE_OPEN; return 0; } if( usb_set_configuration(handle,1) < 0 ) { sub_errno = SE_SETCONF; goto fin; } if( usb_claim_interface(handle,0) < 0 ) { sub_errno = SE_CLAIM; goto fin; } return handle; fin: usb_close( handle ); return 0; #endif /*LIBUSB_1_0*/ }
void UDMXDevice::open() { if (m_device != NULL && m_handle == NULL) m_handle = usb_open(m_device); start(); }
/** * Initialize the driver. * \param drvthis Pointer to driver structure. * \retval 0 Success. * \retval <0 Error. */ MODULE_EXPORT int IOWarrior_init(Driver *drvthis) { char serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO; char size[LCD_MAX_WIDTH+1] = DEFAULT_SIZE; struct usb_bus *busses; struct usb_bus *bus; int w; int h; PrivateData *p; /* Allocate and store private data */ p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) return -1; if (drvthis->store_private_ptr(drvthis, p)) return -1; /* Initialize the PrivateData structure */ p->cellwidth = CELLWIDTH; p->cellheight = CELLHEIGHT; p->backlight = DEFAULT_BACKLIGHT; debug(RPT_INFO, "%s: init(%p)", drvthis->name, drvthis); /* Read config file */ /* What IO-Warrior device should be used */ strncpy(serial, drvthis->config_get_string(drvthis->name, "SerialNumber", 0, DEFAULT_SERIALNO), sizeof(serial)); serial[sizeof(serial)-1] = '\0'; if (*serial != '\0') { report(RPT_INFO, "%s: using serial number: %s", drvthis->name, serial); } /* Which size */ strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); size[sizeof(size) - 1] = '\0'; if ((sscanf(size, "%dx%d", &w, &h) != 2) || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report(RPT_WARNING, "%s: cannot read Size: %s; using default %s", drvthis->name, size, DEFAULT_SIZE); sscanf(DEFAULT_SIZE, "%dx%d", &w, &h); } p->width = w; p->height = h; /* special options for displays with some incompatibilities */ p->lastline = drvthis->config_get_bool(drvthis->name, "lastline", 0, 1); p->ext_mode = drvthis->config_get_bool(drvthis->name, "extendedmode", 0, 0); /* Contrast of the LCD can be changed by adjusting a trimpot */ /* End of config file parsing */ /* Allocate framebuffer memory */ p->framebuf = (unsigned char *) calloc(p->width * p->height, 1); if (p->framebuf == NULL) { report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name); return -1; } /* Allocate and clear the buffer for incremental updates */ p->backingstore = (unsigned char *) calloc(p->width * p->height, 1); if (p->backingstore == NULL) { report(RPT_ERR, "%s: unable to create backingstore", drvthis->name); return -1; } /* set mode for custom chracter cache */ p->ccmode = standard; /* initialize output stuff */ p->output_mask = 0; /* not yet supported */ p->output_state = -1; /* find USB device */ usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); /* on all busses look for IO-Warriors */ p->udh = NULL; for (bus = busses; bus != NULL; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev; dev = dev->next) { /* Check if this device is a Code Mercenaries IO-Warrior */ if ((dev->descriptor.idVendor == iowVendor) && ((dev->descriptor.idProduct == iowProd24) || (dev->descriptor.idProduct == iowProd40) || (dev->descriptor.idProduct == iowProd56))) { /* IO-Warrior found; try to find it's description and serial number */ p->udh = usb_open(dev); if (p->udh == NULL) { report(RPT_WARNING, "%s: unable to open device", drvthis->name); // return -1; /* it's better to continue */ } else { /* get device information & check for serial number */ p->productID = dev->descriptor.idProduct; if (usb_get_string_simple(p->udh, dev->descriptor.iManufacturer, p->manufacturer, LCD_MAX_WIDTH) <= 0) *p->manufacturer = '\0'; p->manufacturer[p->width] = '\0'; if (usb_get_string_simple(p->udh, dev->descriptor.iProduct, p->product, LCD_MAX_WIDTH) <= 0) *p->product = '\0'; p->product[p->width] = '\0'; if (usb_get_string_simple(p->udh, dev->descriptor.iSerialNumber, p->serial, LCD_MAX_WIDTH) <= 0) *p->serial = '\0'; p->serial[sizeof(p->serial)-1] = '\0'; if ((*serial != '\0') && (*p->serial == '\0')) { report(RPT_ERR, "%s: unable to get device's serial number", drvthis->name); usb_close(p->udh); return -1; } /* succeed if no serial was given in the config or the 2 numbers match */ if ((!*serial) || (strcmp(serial, p->serial) == 0)) goto done; usb_close(p->udh); p->udh = NULL; } } } } done: if (p->udh != NULL) { debug(RPT_DEBUG, "%s: opening device succeeded", drvthis->name); errno = 0; if (usb_set_configuration(p->udh, 1) < 0) { report(RPT_WARNING, "%s: unable to set configuration: %s", drvthis->name, strerror(errno)); } errno = 0; if (usb_claim_interface(p->udh, 1) < 0) { #if defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) report(RPT_WARNING, "%s: interface may be claimed by kernel driver, attempting to detach it", drvthis->name); errno = 0; if ((usb_detach_kernel_driver_np(p->udh, 1) < 0) || (usb_claim_interface(p->udh, 1) < 0)) { report(RPT_ERR, "%s: unable to re-claim interface: %s", drvthis->name, strerror(errno)); usb_close(p->udh); return -1; } #else report(RPT_ERR, "%s: unable to claim interface: %s", drvthis->name, strerror(errno)); usb_close(p->udh); return -1; #endif } } else { report(RPT_ERR, "%s: no (matching) IO-Warrior device found", drvthis->name); return -1; } /* enable LCD in IOW */ if (iowlcd_enable(p) == IOW_ERROR) return -1; if (p->ext_mode) { if (iowlcd_set_function(p, 1, 1, 1) == IOW_ERROR) return -1; if (iowlcd_display_on_off(p, 0, 0, 1) == IOW_ERROR) return -1; } /* enable 8bit transfer mode */ if (iowlcd_set_function(p, 1, 1, 0) == IOW_ERROR) return -1; /* enable display, disable cursor+blinking */ if (iowlcd_display_on_off(p, 1, 0, 0) == IOW_ERROR) return -1; report(RPT_DEBUG, "%s: init() done", drvthis->name); /* clear screen */ IOWarrior_clear(drvthis); /* display information about the driver */ { int y = 1; if (p->height > 2) IOWarrior_string(drvthis, 1, y++, p->manufacturer); IOWarrior_string(drvthis, 1, y++, p->product); if (p->height > 1) { IOWarrior_string(drvthis, 1, y, "# "); IOWarrior_string(drvthis, 3, y, p->serial); } IOWarrior_flush(drvthis); sleep(2); } return 0; }