uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void **const DescriptorAddress, uint8_t *DescriptorMemorySpace) { uint32_t snum; const uint8_t DescriptorType = (wValue >> 8); const uint8_t DescriptorNumber = (wValue & 0xFF); const void *Address = NULL; uint16_t Size = NO_DESCRIPTOR; *DescriptorMemorySpace = MEMSPACE_FLASH; switch (DescriptorType) { case DTYPE_Device: Address = &BlueBox_DeviceDescriptor; Size = sizeof(USB_Descriptor_Device_t); break; case DTYPE_Configuration: Address = &BlueBox_ConfigurationDescriptor; Size = sizeof(USB_Descriptor_Configuration_t); break; case DTYPE_String: switch (DescriptorNumber) { case 0x00: Address = &BlueBox_LanguageString; Size = pgm_read_byte(&BlueBox_LanguageString.Header.Size); break; case 0x01: Address = &BlueBox_ManufacturerString; Size = pgm_read_byte(&BlueBox_ManufacturerString.Header.Size); break; case 0x02: Address = &BlueBox_ProductString; Size = pgm_read_byte(&BlueBox_ProductString.Header.Size); break; case 0x03: Address = &BlueBox_SerialString; Size = BlueBox_SerialString.Header.Size; snum = eeprom_read_dword(&serialno); format_serial(snum, ((uint16_t *) &BlueBox_SerialString.UnicodeString)); *DescriptorMemorySpace = MEMSPACE_RAM; break; } break; } *DescriptorAddress = Address; return Size; }
/* * scsi_id: try to get an id, if one is found, printf it to stdout. * returns a value passed to exit() - 0 if printed an id, else 1. This * could be expanded, for example, if we want to report a failure like no * memory etc. return 2, and return 1 for expected cases (like broken * device found) that do not print an id. */ static int scsi_id(const char *devpath, char *maj_min_dev) { int retval; int dev_type = 0; char *serial, *unaligned_buf; struct sysfs_device *dev; struct sysfs_device *dev_scsi; int good_dev; int page_code; dbg("devpath %s\n", devpath); dev = sysfs_device_get(devpath); if (dev == NULL) { err("unable to access '%s'", devpath); return 1; } if (strcmp(dev->subsystem, "block") == 0) dev_type = S_IFBLK; else dev_type = S_IFCHR; /* get scsi parent device */ dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); if (dev_scsi == NULL) { err("unable to access parent device of '%s'", devpath); return 1; } /* mknod a temp dev to communicate with the device */ if (!dev_specified && create_tmp_dev(dev->devpath, maj_min_dev, dev_type)) { dbg("create_tmp_dev failed\n"); return 1; } /* get per device (vendor + model) options from the config file */ retval = per_dev_options(dev_scsi, &good_dev, &page_code); dbg("per dev options: good %d; page code 0x%x", good_dev, page_code); #define ALIGN 512 unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN); serial = (char*) (((unsigned long) unaligned_buf + (ALIGN - 1)) & ~(ALIGN - 1)); dbg("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); #undef ALIGN if (!good_dev) { retval = 1; } else if (scsi_get_serial(dev_scsi, maj_min_dev, page_code, serial, MAX_SERIAL_LEN)) { retval = always_info?0:1; } else { retval = 0; } if (!retval) { if (export) { static char serial_str[64]; printf("ID_VENDOR=%s\n", vendor_str); printf("ID_MODEL=%s\n", model_str); printf("ID_REVISION=%s\n", revision_str); set_str(serial_str, serial, sizeof(serial_str)); printf("ID_SERIAL=%s\n", serial_str); printf("ID_TYPE=%s\n", type_str); printf("ID_BUS=scsi\n"); } else { if (reformat_serial) format_serial(serial); if (display_bus_id) printf("%s: ", dev_scsi->kernel); printf("%s\n", serial); } dbg("%s\n", serial); retval = 0; }