/** * ld_usb_write */ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct ld_usb *dev; size_t bytes_to_write; int retval = 0; dev = file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* lock this object */ if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } /* wait until previous transfer is finished */ if (dev->interrupt_out_busy) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); if (retval < 0) { goto unlock_exit; } } /* write the data into interrupt_out_buffer from userspace */ bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write); dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __FUNCTION__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; goto unlock_exit; } if (dev->interrupt_out_endpoint == NULL) { /* try HID_REQ_SET_REPORT=9 on control_endpoint instead of interrupt_out_endpoint */ retval = usb_control_msg(interface_to_usbdev(dev->intf), usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0), 9, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 1 << 8, 0, dev->interrupt_out_buffer, bytes_to_write, USB_CTRL_SET_TIMEOUT * HZ); if (retval < 0) err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval); goto unlock_exit; } /* send off the urb */ usb_fill_int_urb(dev->interrupt_out_urb, interface_to_usbdev(dev->intf), usb_sndintpipe(interface_to_usbdev(dev->intf), dev->interrupt_out_endpoint->bEndpointAddress), dev->interrupt_out_buffer, bytes_to_write, ld_usb_interrupt_out_callback, dev, dev->interrupt_out_interval); dev->interrupt_out_busy = 1; wmb(); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; err("Couldn't submit interrupt_out_urb %d\n", retval); goto unlock_exit; } retval = bytes_to_write; unlock_exit: /* unlock the device */ up(&dev->sem); exit: return retval; }
struct ara_board_info *ara_board_init(void) { int i; enum hwid hwid = board_get_hwid(); board_info = NULL; /* Check HWID, assign board_info struct and the Switch ES revision */ switch (hwid) { case HWID_DB3_0_1: board_info = &db3_board_info; dbg_info("HWID found as DB3.0/3.1\n"); break; case HWID_DB3_2: /* DB3.0/1 with ES3 Switch */ board_info = &db3_board_info; board_info->sw_data.rev = SWITCH_REV_ES3; dbg_info("HWID found as DB3.2\n"); break; case HWID_DB3_5: /* EVT1.5 + DB3.5 pwrmon + specific mapping of physical interfaces */ board_info = &evt1_5_board_info; board_info->pwrmon = &db3_5_pwrmon; board_info->interfaces = db3_5_interfaces; board_info->nr_interfaces = db3_5_nr_interfaces; dbg_info("HWID found as DB3.5\n"); break; case HWID_EVT1: board_info = &evt1_board_info; dbg_info("HWID found as EVT1\n"); break; case HWID_EVT1_5: board_info = &evt1_5_board_info; dbg_info("HWID found as EVT1.5\n"); break; case HWID_EVT1_6: board_info = &evt1_5_board_info; board_info->sw_data.rev = SWITCH_REV_ES2; dbg_info("HWID found as EVT1.6\n"); break; default: return NULL; } /* Disable the I/O Expanders for now */ for (i = 0; i < board_info->nr_io_expanders; i++) { struct io_expander_info *io_exp = &board_info->io_expanders[i]; stm32_configgpio(io_exp->reset); stm32_gpiowrite(io_exp->reset, false); } /* * Register the STM32 GPIOs to Gpio Chip * * This needs to happen before the I/O Expanders registration, which * uses some STM32 pins */ stm32_gpio_init(); /* Register the TCA64xx I/O Expanders GPIOs to Gpio Chip */ for (i = 0; i < board_info->nr_io_expanders; i++) { struct io_expander_info *io_exp = &board_info->io_expanders[i]; io_exp->i2c_dev = up_i2cinitialize(io_exp->i2c_bus); if (!io_exp->i2c_dev) { dbg_error("%s(): Failed to get I/O Expander I2C bus %u\n", __func__, io_exp->i2c_bus); goto err_deinit_gpio; } else { if (tca64xx_init(&io_exp->io_exp_driver_data, io_exp->part, io_exp->i2c_dev, io_exp->i2c_addr, io_exp->reset, io_exp->irq, io_exp->gpio_base) < 0) { dbg_error("%s(): Failed to register I/O Expander(0x%02x)\n", __func__, io_exp->i2c_addr); goto err_uninit_i2c; } } } /* Run the board specific code */ if (board_info->board_init) { if (board_info->board_init(board_info)) { dbg_error("%s(): Failed to initalize board\n", __func__); goto err_uninit_i2c; } } /* Return the board specific info */ return board_info; err_uninit_i2c: /* Done in reverse order to account for possible IRQ chaining. */ for (i = board_info->nr_io_expanders - 1; i >= 0; i--) { struct io_expander_info *io_exp = &board_info->io_expanders[i]; if (io_exp->i2c_dev) { up_i2cuninitialize(io_exp->i2c_dev); } } err_deinit_gpio: stm32_gpio_deinit(); /* Leave the I/O expanders in reset here. */ return NULL; }
int spi_flash_recovery(struct spi_flash *flash) { const struct spi_flash_erase_map *map = &flash->erase_map; const struct spi_flash_erase_region *cur_region, *region = NULL; const struct spi_flash_erase_command *cur_erase, *erase = NULL; int i, ret; /* * If Recovery Button is pressed during boot sequence, * erase dataflash page0 */ dbg_info("SF: Press the recovery button (%s) to recovery\n", RECOVERY_BUTTON_NAME); if ((pio_get_value(CONFIG_SYS_RECOVERY_BUTTON_PIN)) == 0) { dbg_info("SF: The recovery button (%s) has been pressed,\n", RECOVERY_BUTTON_NAME); dbg_info("SF: The page 0 is erasing...\n"); /* Get the erase region for offset 0. */ for (i = 0; i < map->num_regions; i++) { cur_region = &map->regions[i]; if (!(cur_region->offset & ~SFLASH_CMD_ERASE_MASK)) { region = cur_region; break; } } if (!region) { dbg_info("SF: Can't find erase region for offset 0\n"); return -1; } /* Get the smallest erase size of the region. */ for (i = 0; i < SFLASH_CMD_ERASE_MAX; i++) { cur_erase = &map->commands[i]; if (!(region->offset & (0x1UL << i))) continue; if (!erase || erase->size > cur_erase->size) erase = cur_erase; } if (!erase) { dbg_info("SF: Can't find erase command for offset 0\n"); return -1; } /* Erase the smallest sector/block at offset 0. */ ret = spi_flash_erase(flash, 0, erase->size); if (ret) { dbg_info("SF: The erasing failed\n"); return ret; } dbg_info("SF: The erasing is done\n"); return 0; } return -1; }
/* * Reset the peripheral and generate a recovery sequence on the bus. * To be used when the bus is stuck. */ inline void i2c_reset(void) { dbg_info("%s()\n", __func__); up_i2creset(sw_exp_dev); }
/** * usb_alphatrack_write */ static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct usb_alphatrack *dev; size_t bytes_to_write; int retval = 0; dev = file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* lock this object */ if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } /* wait until previous transfer is finished */ if (dev->interrupt_out_busy) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); if (retval < 0) goto unlock_exit; } /* write the data into interrupt_out_buffer from userspace */ /* FIXME - if you write more than 12 bytes this breaks */ bytes_to_write = min(count, write_buffer_size * dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count - bytes_to_write); dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; goto unlock_exit; } if (dev->interrupt_out_endpoint == NULL) { err("Endpoint should not be be null!\n"); goto unlock_exit; } /* send off the urb */ usb_fill_int_urb(dev->interrupt_out_urb, interface_to_usbdev(dev->intf), usb_sndintpipe(interface_to_usbdev(dev->intf), dev->interrupt_out_endpoint-> bEndpointAddress), dev->interrupt_out_buffer, bytes_to_write, usb_alphatrack_interrupt_out_callback, dev, dev->interrupt_out_interval); dev->interrupt_out_busy = 1; atomic_inc(&dev->writes_pending); wmb(); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; err("Couldn't submit interrupt_out_urb %d\n", retval); atomic_dec(&dev->writes_pending); goto unlock_exit; } retval = bytes_to_write; unlock_exit: /* unlock the device */ mutex_unlock(&dev->mtx); exit: return retval; }
/* MAXIM App. Note #187 */ static int ds24xx_search_rom() { int id_bit_number; int last_zero, rom_byte_number, search_result; int id_bit, cmp_id_bit; unsigned char rom_byte_mask, search_direction; unsigned char crc8 = 0; /* initialize for search */ id_bit_number = 1; last_zero = 0; rom_byte_number = 0; rom_byte_mask = 1; search_result = 0; /* if the last call was not the last one */ if (!LastDeviceFlag) { /* 1-Wire reset */ if (!ds24xx_reset()) { /* reset the search*/ dbg_info("1-Wire: reset fail\n"); LastDiscrepancy = 0; LastDeviceFlag = 0; LastFamilyDiscrepancy = 0; return 0; } /* issue the search command */ ds24xx_write_byte(ROM_COMMAND_SEARCH); /* loop to do the search */ do { /* read a bit and its complement */ id_bit = ds24xx_read_bit(); cmp_id_bit = ds24xx_read_bit(); /* check for no devices on 1-Wire */ if ((id_bit == 1) && (cmp_id_bit == 1)) break; else { /* all devices coupled have 0 or 1 */ if (id_bit != cmp_id_bit) search_direction = id_bit; else { /* * if this discrepancy if before * the Last Discrepancy on a previous * next then pick the same as last time */ if (id_bit_number < LastDiscrepancy) search_direction = ((buf[rom_byte_number] & rom_byte_mask) > 0); else /* * if equal to last pick 1, * if not then pick 0 */ search_direction = (id_bit_number == LastDiscrepancy); /* * if 0 was picked then record its * position in LastZero */ if (search_direction == 0) { last_zero = id_bit_number; /* * check for Last discrepancy * in family */ if (last_zero < 9) LastFamilyDiscrepancy = last_zero; } } /* * set or clear the bit in the ROM byte * rom_byte_number with mask rom_byte_mask */ if (search_direction == 1) buf[rom_byte_number] |= rom_byte_mask; else buf[rom_byte_number] &= ~rom_byte_mask; /* serial number search direction write bit */ if (search_direction == 1) ds24xx_write_bit(1); else ds24xx_write_bit(0); /* * increment the byte counter id_bit_number * and shift the mask rom_byte_mask */ id_bit_number++; rom_byte_mask <<= 1; /* * if the mask is 0 then go to new SerialNum * byte rom_byte_number and reset mask */ if (rom_byte_mask == 0) { crc8 = docrc8(crc8, buf[rom_byte_number]); rom_byte_number++; rom_byte_mask = 1; } } } while(rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ /* if the search was successful then */ if (!((id_bit_number < 65) || (crc8 != 0))) { /* search successful so set LastDiscrepancy,LastDeviceFlag,search_result */ LastDiscrepancy = last_zero; /* check for last device */ if (LastDiscrepancy == 0) LastDeviceFlag = 1; search_result = 1; } } /* if no device found then reset counters so next 'search' will be like a first */ if (!search_result || !buf[0]) { LastDiscrepancy = 0; LastDeviceFlag = 0; LastFamilyDiscrepancy = 0; search_result = 0; } return search_result; }
/******************************************************************************* * SN layout * * 31 30 25 20 15 10 5 0 * ----------------------------------------------------------------------- * | | Vendor ID| Board ID | Vendor ID| Board ID | Vendor ID| Board ID | * ----------------------------------------------------------------------- * | EK | DM | CPU | * * Rev layout * * 31 24 21 18 15 10 5 0 * ----------------------------------------------------------------------- * | | EK | DM | CPU | EK | DM | CPU | * ----------------------------------------------------------------------- * | Revision id | Revision Code | * ******************************************************************************* */ void load_1wire_info(void) { int i, j; unsigned int cnt; unsigned int size = LEN_ONE_WIRE_INFO; struct board_info board_info; struct board_info *bd_info; #if defined(CONFIG_SAMA5D4EK) int missing = BOARD_TYPE_EK_MASK | BOARD_TYPE_DM_MASK; #else int missing = BOARD_TYPE_MASK; #endif unsigned char *tmp = buf; memset(&board_info, 0, sizeof(board_info)); bd_info= &board_info; dbg_info("1-Wire: Loading 1-Wire information ...\n"); sn = rev = 0; cnt = enumerate_all_rom(); if (!cnt) { dbg_info("WARNING: 1-Wire: No 1-Wire chip found\n "); goto err; } dbg_info("1-Wire: BoardName | [Revid] | VendorName\n"); for (i = 0; i < cnt; i++) { if (ds24xx_read_memory(i, 0, 0, size, buf) < 0) { dbg_info("WARNING: 1-Wire: Failed to read from 1-Wire chip!\n"); goto err; } dbg_loud("board: #%d: ", i); for (j = 0; j < size; j++) dbg_loud("%d ", *tmp++); dbg_loud("\n"); if (get_board_info(buf, i, bd_info)) { continue; } switch (bd_info->board_type) { case BOARD_TYPE_CPU: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_CPU_MASK); sn |= (bd_info->board_id & SN_MASK); sn |= ((bd_info->vendor_id & VENDOR_MASK) << CM_VENDOR_OFFSET); rev |= ((bd_info->revision_code - 'A') & REV_MASK); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << CM_REV_ID_OFFSET); break; case BOARD_TYPE_DM: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_DM_MASK); sn |= ((bd_info->board_id & SN_MASK) << DM_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << DM_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << DM_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << DM_REV_ID_OFFSET); break; case BOARD_TYPE_EK: missing &= (BOARD_TYPE_MASK & ~BOARD_TYPE_EK_MASK); sn |= ((bd_info->board_id & SN_MASK) << EK_SN_OFFSET); sn |= ((bd_info->vendor_id & VENDOR_MASK) << EK_VENDOR_OFFSET); rev |= (((bd_info->revision_code - 'A') & REV_MASK) << EK_REV_OFFSET); rev |= (((bd_info->revision_id - '0') & REV_ID_MASK) << EK_REV_ID_OFFSET); break; default: dbg_info("WARNING: 1-Wire: Unknown board type\n"); goto err; } } if (missing & BOARD_TYPE_CPU_MASK) dbg_info("1-Wire: Failed to read CM board information\n"); if (missing & BOARD_TYPE_DM_MASK) dbg_info("1-Wire: Failed to read DM board information\n"); if (missing & BOARD_TYPE_EK_MASK) dbg_info("1-Wire: Failed to read EK board information\n"); goto save_info; err: dbg_info("\n1-Wire: Using defalt information\n"); sn = set_default_sn(); rev = set_default_rev(); save_info: #ifdef AT91C_BASE_GPBR /* save to GPBR #2 and #3 */ dbg_info("\n1-Wire: SYS_GPBR2: %d, SYS_GPBR3: %d\n\n", sn, rev); writel(sn, AT91C_BASE_GPBR + 4 * 2); writel(rev, AT91C_BASE_GPBR + 4 * 3); #else dbg_info("\n1-Wire: Board sn: %d, revsion: %d\n\n", sn, rev); #endif return; }
static int parse_board_hw_info(unsigned char *buff, board_info_t *bd_info) { char board_name[BOARD_NAME_LEN + 1]; char vendor_name[VENDOR_NAME_LEN + 1]; int i; hw_info_map_t *p = (hw_info_map_t *)buff; if (p->total_bytes != HW_INFO_TOTAL_SIZE) { dbg_info("HW Info: The total size isn't correct\n"); return -1; } for (i = 0; i < ARRAY_SIZE(board_list); i++) { if (strncmp(board_list[i].board_name, (const char *)p->board_name, strlen(board_list[i].board_name)) == 0) break; } if (i == ARRAY_SIZE(board_list)) goto fail_to_search_board; bd_info->board_type = board_list[i].board_type; bd_info->board_id = board_list[i].board_id; bd_info->revision_code = normalize_rev_code(p->revision_code); if (p->revision_mapping == 'B') { bd_info->revision_id = normalize_rev_id_map_b(p->revision_id); bd_info->bom_revision = normalize_bom_revision(p->bom_revision); } else { bd_info->revision_id = normalize_rev_id(p->revision_id); } bd_info->board_name = board_list[i].board_name; for (i = 0; i < ARRAY_SIZE(vendor_list); i++) { if (strncmp(vendor_list[i].vendor_name, (const char *)p->vendor_name, strlen(vendor_list[i].vendor_name)) == 0) break; } if (i == ARRAY_SIZE(vendor_list)) goto fail_to_search_vendor; bd_info->vendor_id = vendor_list[i].vendor_id; bd_info->vendor_name = vendor_list[i].vendor_name; return 0; fail_to_search_board: for (i = 0; i < BOARD_NAME_LEN; i++) board_name[i] = p->board_name[i]; board_name[i] = 0; dbg_info("Failed to parse the board name: %s\n", board_name); return -1; fail_to_search_vendor: for (i = 0; i < VENDOR_NAME_LEN; i++) vendor_name[i] = p->vendor_name[i]; vendor_name[i] = 0; dbg_info("Failed to parse the vendor name: %s\n", vendor_name); return -1; }
static int macronix_set_dummy_cycles(qspi_flash_t *flash, unsigned char num_dummy_cycles) { int ret, sr, cr, mask, val; unsigned char dc, sr_cr[2]; /* Convert the numver of dummy cycles into Macronix DC volatile bits. */ ret = macronix_dummy2code(flash->read_opcode, num_dummy_cycles, &dc); if (ret) return ret; mask = 0xc0; val = (dc << 6) & mask; cr = qspi_flash_read_macronix_config_reg(flash); if (cr < 0) { dbg_info("QSPI Flash: error while reading CR register\n"); return cr; } if ((cr & mask) == val) goto updated; sr = qspi_flash_read_status_reg(flash); if (sr < 0) { dbg_info("QSPI Flash: error while reading SR register\n"); return sr; } ret = qspi_flash_write_enable(flash); if (ret) return ret; cr = (cr & ~mask) | val; sr_cr[0] = sr & 0xff; sr_cr[1] = cr & 0xff; ret = qspi_flash_write_status_and_config_regs(flash, sr_cr); if (ret) { dbg_info("QSPI Flash: error while writing SR and CR registers\n"); return ret; } ret = qspi_flash_wait_ready(flash); if (ret) return ret; cr = qspi_flash_read_macronix_config_reg(flash); if (cr < 0 || (cr & mask) != val) { dbg_info("QSPI Flash: Macronix Dummy Cycle bits not updated\n"); return -1; } updated: if (num_dummy_cycles) { flash->num_mode_cycles = 2; flash->num_dummy_cycles = num_dummy_cycles - 2; } else { flash->num_mode_cycles = 0; flash->num_dummy_cycles = 0; } /* mode cycles: bit[0:3] = ~bit[4:7]: continuous read, normal read otherwise */ flash->normal_mode = 0x00; flash->continuous_read_mode = 0xf0; return 0; }
static int get_board_info(unsigned char *buffer, unsigned char bd_sn, struct board_info *bd_info) { int i; char tmp[20]; struct one_wire_info one_wire; struct one_wire_info *p = &one_wire; unsigned char *pbuf = buffer; char *boardname; char *vendorname; p->total_bytes = (unsigned char)*pbuf; pbuf = buffer + 1; for (i = 0; i < VENDOR_NAME_LEN; i++) p->vendor_name[i] = *pbuf++; pbuf = buffer + 11; for (i = 0; i < VENDOR_COUNTRY_LEN; i++) p->vendor_country[i] = *pbuf++; pbuf = buffer + 13; for (i = 0; i < BOARD_NAME_LEN; i++) p->board_name[i] = *pbuf++; p->year = *pbuf++; p->week = *pbuf++; p->revision_code = *pbuf++; p->revision_id = *pbuf++; p->bom_revision = *pbuf++; p->revision_mapping = *pbuf++; memset(tmp, 0, sizeof(tmp)); for (i = 0; i < BOARD_NAME_LEN; i++) { if (p->board_name[i] == 0x20) break; tmp[i] = p->board_name[i]; } for (i = 0; i < ARRAY_SIZE(board_list); i++) { if (strncmp(board_list[i].board_name, tmp, strlen(board_list[i].board_name)) == 0) { bd_info->board_type = board_list[i].board_type; bd_info->board_id = board_list[i].board_id; bd_info->revision_code = normalize_rev_code(p->revision_code); if (p->revision_mapping == 'B') { bd_info->revision_id = normalize_rev_id_map_b(p->revision_id); bd_info->bom_revision = normalize_bom_revision(p->bom_revision); } else { bd_info->revision_id = normalize_rev_id(p->revision_id); } break; } } if (i == ARRAY_SIZE(board_list)) { return -1; } boardname = board_list[i].board_name; dbg_loud("board: #%d: boardname: %s\n", bd_sn, boardname); memset(tmp, 0, sizeof(tmp)); for (i = 0; i < VENDOR_NAME_LEN; i++) { if (p->vendor_name[i] == 0x20) break; tmp[i] = p->vendor_name[i]; } for (i = 0; i < ARRAY_SIZE(vendor_list); i++) { if (strncmp(vendor_list[i].vendor_name, tmp, strlen(vendor_list[i].vendor_name)) == 0) { bd_info->vendor_id = vendor_list[i].vendor_id; break; } } if (i == ARRAY_SIZE(vendor_list)) { return -1; } vendorname = vendor_list[i].vendor_name; dbg_loud("board: #%d: vendorname: %s\n", bd_sn, vendorname); dbg_info(" #%d", bd_sn); if (p->revision_mapping == 'B') { dbg_info(" %s [%c%c%c] %s\n", boardname, bd_info->revision_code, bd_info->revision_id, bd_info->bom_revision, vendorname); } else { dbg_info(" %s [%c%c] %s\n", boardname, bd_info->revision_code, bd_info->revision_id, vendorname); } return 0; }
static ssize_t ld_usb_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct ld_usb *dev; size_t bytes_to_write; int retval = 0; dev = file->private_data; if (count == 0) goto exit; if (mutex_lock_interruptible(&dev->mutex)) { retval = -ERESTARTSYS; goto exit; } if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } if (dev->interrupt_out_busy) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); if (retval < 0) { goto unlock_exit; } } bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write); dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; goto unlock_exit; } if (dev->interrupt_out_endpoint == NULL) { retval = usb_control_msg(interface_to_usbdev(dev->intf), usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0), 9, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 1 << 8, 0, dev->interrupt_out_buffer, bytes_to_write, USB_CTRL_SET_TIMEOUT * HZ); if (retval < 0) err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval); goto unlock_exit; } usb_fill_int_urb(dev->interrupt_out_urb, interface_to_usbdev(dev->intf), usb_sndintpipe(interface_to_usbdev(dev->intf), dev->interrupt_out_endpoint->bEndpointAddress), dev->interrupt_out_buffer, bytes_to_write, ld_usb_interrupt_out_callback, dev, dev->interrupt_out_interval); dev->interrupt_out_busy = 1; wmb(); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; err("Couldn't submit interrupt_out_urb %d\n", retval); goto unlock_exit; } retval = bytes_to_write; unlock_exit: mutex_unlock(&dev->mutex); exit: return retval; }
static char *__curl_do_operation(curl_context *cc, struct curl_slist* headers, int curl_opt, char *url, char *fields, char *data, curl_response **ret_data) { CURL *curl = NULL; CURLcode res; char *endpoint; char *tmpptr; long tmplong; long send_len; *ret_data = init_curl_response(); if (!(*ret_data)) { goto error_exit; } if (data) { send_len = strlen(data); } else { send_len = 0; } if (url) { endpoint = url; } else { endpoint = cc->url; } struct curl_http_data send_data = { .ptr = data, .len = send_len }; struct curl_http_data recv_data = { .ptr = NULL, .len = 0 }; if (cc->curl_persist) { curl = cc->curl; } else { curl = curl_easy_init(); if (!curl) { dbg_info(ERROR, "Could not initialize CURL\n"); goto error_exit; } if (cc->use_ssl) { __init_curl_ssl(curl, 0); __set_curl_ssl_certificates(curl, cc->cacerts, cc->certfile, cc->keypass, cc->keyfile); } } //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_URL, endpoint); curl_easy_setopt(curl, curl_opt, 1L); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(curl, CURLOPT_READDATA, &send_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &recv_data); if (cc->follow_redirect) { curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); } if (cc->use_cookies) { curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cc->cookiejar); curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cc->cookiejar); } if (headers) { curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); } if (fields && (curl_opt & CURLOPT_HTTPPOST)) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields); } else if (curl_opt & CURLOPT_HTTPPOST) { curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, send_len); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); } res = curl_easy_perform(curl); if (res != CURLE_OK) { dbg_info(ERROR, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); goto error_exit; } if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &tmplong) == CURLE_OK) (*ret_data)->status = tmplong; if (curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &tmpptr) == CURLE_OK){ if(tmpptr != NULL){ asprintf(&((*ret_data)->redirect_url), "%s", tmpptr); } } if (curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &tmpptr) == CURLE_OK){ if(tmpptr != NULL){ (*ret_data)->content_type = malloc(strlen(tmpptr) + 1); strncpy((*ret_data)->content_type, tmpptr, strlen(tmpptr) + 1); //asprintf(&((*ret_data)->content_type), "%s", tmpptr); } } if (recv_data.len) { (*ret_data)->data = malloc(recv_data.len+1 * sizeof(char)); memcpy((*ret_data)->data, recv_data.ptr, recv_data.len); (*ret_data)->data[recv_data.len] = '\0'; } if (headers) { curl_slist_free_all(headers); } if (!(cc->curl_persist)) { curl_easy_cleanup(curl); } return (*ret_data)->data; error_exit: if (headers) curl_slist_free_all(headers); if (!(cc->curl_persist)) curl_easy_cleanup(curl); free_curl_response(*ret_data); *ret_data = NULL; return NULL; } static size_t read_cb(void *ptr, size_t size, size_t nmemb, void *userp) { struct curl_http_data *data = (struct curl_http_data *) userp; if (size * nmemb < 1) { return 0; } if (data->len) { *(char *) ptr = data->ptr[0]; data->ptr++; data->len--; return 1; } return 0; } static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *userp) { struct curl_http_data *s = (struct curl_http_data *) userp; size_t new_len = s->len + size*nmemb; s->ptr = realloc(s->ptr, new_len+1); if (s->ptr == NULL) { fprintf(stderr, "realloc() failed\n"); exit(EXIT_FAILURE); } memcpy(s->ptr+s->len, ptr, size*nmemb); s->ptr[new_len] = '\0'; s->len = new_len; return size*nmemb; }
int spi_flash_loadimage(struct spi_flash *flash, struct image_info *image) { #if defined(CONFIG_LOAD_LINUX) || defined(CONFIG_LOAD_ANDROID) int length; #endif int ret = 0; #ifdef CONFIG_DATAFLASH_RECOVERY if (!spi_flash_recovery(flash)) { ret = -2; goto err_exit; } #endif /* CONFIG_DATAFLASH_RECOVERY */ #ifdef CONFIG_OF_LIBFDT length = update_image_length(flash, image->of_offset, image->of_dest, DT_BLOB); if (length == -1) { ret = -1; goto err_exit; } image->of_length = length; dbg_info("SF: dt blob: Copy %x bytes from %x to %x\n", image->of_length, image->of_offset, image->of_dest); ret = spi_flash_read(flash, image->of_offset, image->of_length, image->of_dest); if (ret) { dbg_info("** SF: DT: Serial flash read error**\n"); ret = -1; goto err_exit; } #endif /* CONFIG_OF_LIBFDT */ #ifdef CONFIG_QSPI_XIP ret = qspi_xip(flash, (void **)&image->dest); if (ret) { dbg_info("** SF: XIP error**\n"); ret = -1; goto err_exit; } image->dest += image->offset; return 0; #else /* CONFIG_QSPI_XIP */ #if defined(CONFIG_LOAD_LINUX) || defined(CONFIG_LOAD_ANDROID) length = update_image_length(flash, image->offset, image->dest, KERNEL_IMAGE); if (length == -1) { ret = -1; goto err_exit; } image->length = length; #endif dbg_info("SF: Copy %x bytes from %x to %x\n", image->length, image->offset, image->dest); ret = spi_flash_read(flash, image->offset, image->length, image->dest); if (ret) { dbg_info("** SF: Serial flash read error**\n"); ret = -1; goto err_exit; } #endif /* !CONFIG_QSPI_XIP */ err_exit: spi_flash_cleanup(flash); return ret; }
static void usb_alphatrack_interrupt_in_callback(struct urb *urb) { struct usb_alphatrack *dev = urb->context; unsigned int next_ring_head; int retval = -1; if (urb->status) { if (urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) { goto exit; } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", __func__, urb->status); goto resubmit; } } if (urb->actual_length != INPUT_CMD_SIZE) { dev_warn(&dev->intf->dev, "Urb length was %d bytes!!" "Do something intelligent \n", urb->actual_length); } else { alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", "bla"); if (memcmp (dev->interrupt_in_buffer, dev->oldi_buffer, INPUT_CMD_SIZE) == 0) { goto resubmit; } memcpy(dev->oldi_buffer, dev->interrupt_in_buffer, INPUT_CMD_SIZE); #if SUPPRESS_EXTRA_OFFLINE_EVENTS if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) goto resubmit; if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; } if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) dev->offline = 0; if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) dev->offline = 1; #endif dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__, dev->ring_head, dev->ring_tail); next_ring_head = (dev->ring_head + 1) % ring_buffer_size; if (next_ring_head != dev->ring_tail) { memcpy(&((*dev->ring_buffer)[dev->ring_head]), dev->interrupt_in_buffer, urb->actual_length); dev->ring_head = next_ring_head; retval = 0; memset(dev->interrupt_in_buffer, 0, urb->actual_length); } else { dev_warn(&dev->intf->dev, "Ring buffer overflow, %d bytes dropped\n", urb->actual_length); memset(dev->interrupt_in_buffer, 0, urb->actual_length); } } resubmit: if (dev->interrupt_in_running && dev->intf) { retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); if (retval) dev_err(&dev->intf->dev, "usb_submit_urb failed (%d)\n", retval); } exit: dev->interrupt_in_done = 1; wake_up_interruptible(&dev->read_wait); }
void parse_announce_request(client_socket_data *data) { tracker_announce_data *announce_data = calloc(1, sizeof(tracker_announce_data)); announce_data->socket_data = data; announce_data->port = -1; announce_data->left = -1; announce_data->event = -1; announce_data->ip = -1; int beginning_of_token = strlen(announce_base_url), middle_of_token = -1, error = 0, pos; for(pos = strlen(announce_base_url); pos <= data->url->size; pos++) { if(pos == data->url->size || data->url->str[pos] == '&') { // end of string or new param int end_of_token = pos; if(beginning_of_token == end_of_token) { dbg_info("No param"); error = 1; } if(!error & (middle_of_token == -1)) { dbg_info("Missing ="); error = 1; } if(!error & (beginning_of_token == middle_of_token || middle_of_token == end_of_token - 1)) { dbg_info("Missing either field or value"); error = 1; } if(!error) { // All good char *field = data->url->str + beginning_of_token; int field_size = middle_of_token - beginning_of_token; char *value = data->url->str + middle_of_token + 1; int value_size = end_of_token - middle_of_token - 1; if(strlen(info_hash_str) == field_size && strncmp(info_hash_str, field, strlen(info_hash_str)) == 0) { int parsing_succeeded = parse_info_hash(announce_data->info_hash, 40, value, value_size); if (parsing_succeeded == 0) { dbg_info("Info hash: %.*s", 40, announce_data->info_hash); } else { simple_error(announce_data->socket_data, "Invalid info hash."); dbg_warn("Invalid hash: %s", value); goto error; } } else if(strlen(left_str) == field_size && strncmp(left_str, field, strlen(left_str)) == 0) { announce_data->left = read_int(value, value_size, 10); dbg_info("Left: %lld", announce_data->left); } else if(strlen(port_str) == field_size && strncmp(port_str, field, strlen(port_str)) == 0) { long long temp = read_int(value, value_size, 10); announce_data->port = (int)temp; if(announce_data->port < 0 || announce_data->port > 0xffff) { simple_error(announce_data->socket_data, "Invalid port."); dbg_warn("Invalid port: %.*s -> %d", value_size, value, announce_data->port); goto error; } dbg_info("Port: %d", announce_data->port); } else if(strlen(ip_str) == field_size && strncmp(ip_str, field, strlen(ip_str)) == 0) { inet_pton(AF_INET, value, &(announce_data->ip)); dbg_info("IP: %d", announce_data->ip); } else if(strlen(peer_id_str) == field_size && strncmp(peer_id_str, field, strlen(peer_id_str)) == 0) { parse_peer_id(announce_data->peer_id,value,value_size); } else if(strlen(compact_str) == field_size && strncmp(compact_str, field, strlen(compact_str)) == 0) { announce_data->compact = read_int(value, value_size, 10); dbg_info("compact: %d", announce_data->compact); } else if(strlen(event_str) == field_size && strncmp(event_str, field, strlen(event_str)) == 0) { const static char *started = "started"; const static char *completed = "completed"; if(value_size == 7 && strncmp(started, value, 7) == 0) { announce_data->event = 0; // 0 for started } else if(value_size == 9 && strncmp(completed, value, 9) == 0) { announce_data->event = 1; // 1 for completed } else { /* stopped, assuming clients don't send other events I don't know about. probably would be good to remove the peer from the sorted set, but that would require effort. */ simple_error(announce_data->socket_data, "Bye."); goto error; } } } // Reset beginning_of_token = pos + 1; middle_of_token = -1; error = 0; } else if(data->url->str[pos] == '=') { if(middle_of_token != -1) { dbg_info("Double ="); error = 1; } middle_of_token = pos; } } if (announce_data->info_hash[0] == 0) { simple_error(announce_data->socket_data, "No info_hash specified."); dbg_warn("No info_hash."); goto error; } if (announce_data->port == -1) { simple_error(announce_data->socket_data, "No port specified."); dbg_warn("No port."); goto error; } if (announce_data->ip == -1) { announce_data->ip = data->peer_ip; } announce(announce_data); return; error: if (announce_data) free(announce_data); return; }
static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct usb_alphatrack *dev; size_t bytes_to_write; int retval = 0; dev = file->private_data; if (count == 0) goto exit; if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } if (dev->interrupt_out_busy) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); if (retval < 0) goto unlock_exit; } bytes_to_write = min(count, write_buffer_size * dev->interrupt_out_endpoint_size); if (bytes_to_write < count) dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count - bytes_to_write); dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { retval = -EFAULT; goto unlock_exit; } if (dev->interrupt_out_endpoint == NULL) { err("Endpoint should not be be null! \n"); goto unlock_exit; } usb_fill_int_urb(dev->interrupt_out_urb, interface_to_usbdev(dev->intf), usb_sndintpipe(interface_to_usbdev(dev->intf), dev->interrupt_out_endpoint-> bEndpointAddress), dev->interrupt_out_buffer, bytes_to_write, usb_alphatrack_interrupt_out_callback, dev, dev->interrupt_out_interval); dev->interrupt_out_busy = 1; atomic_inc(&dev->writes_pending); wmb(); retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); if (retval) { dev->interrupt_out_busy = 0; err("Couldn't submit interrupt_out_urb %d\n", retval); atomic_dec(&dev->writes_pending); goto unlock_exit; } retval = bytes_to_write; unlock_exit: up(&dev->sem); exit: return retval; }
int SiI9022_enter_power_state_D3_Cold(void) { unsigned char power_state = 0; unsigned char device_id = 0; unsigned int timeout = 10; int ret; /* * D3 cold Note:It is necessary to unplug the HDMI connector, * otherwise would not go to D3 cold. */ /* 1. Clear any pending interrupts via TPI 0x3D */ ret = SiI9022_write(TPI_INTERRUPT_STATUS_REG, 0xFF); if (ret) { dbg_info("SiI9022: Failed to clear any pending interrupts\n"); return -1; } /* 2. Reset SiI9022A Tx via HW */ ret = SiI9022_TxHW_Reset(); if (ret) { dbg_info("SiI9022: Failed to reset\n"); return -1; } do { /* 3. Write device register 0xC7 = 0x00 to enter TPI mode */ ret = SiI9022_write(TPI_ENABLE, 0x00); if (ret) dbg_info("SiI9022: Failed to enter TPI mode\n"); mdelay(100); power_state = TX_POWER_STATE_D0; ret = SiI9022_write(TPI_DEVICE_POWER_STATE_CTRL_REG, power_state); if (ret) { dbg_info("SiI9022: Failed to write TPI 0x1E\n"); return -1; } ret = SiI9022_read(TPI_DEVICE_ID, &device_id); if (ret) dbg_info("SiI9022: Failed to 0x1b\n"); } while ((--timeout) && (device_id == 0x0)); if (device_id != SiI9022_DEVICE_ID) { dbg_info("SiI9022: Not found\n"); return -1; } /* 4. Set INT# source to Hotplug via TPI 0x3C[0] = 1b */ ret = SiI9022_write(TPI_INTERRUPT_ENABLE_REG, HOT_PLUG_EVENT | 0x08); if (ret) { dbg_info("SiI9022: Failed to Set INT# source to Hotplug\n"); return -1; } /* 5. Clear any pending interrupts via TPI 0x3D*/ ret = SiI9022_write(TPI_INTERRUPT_STATUS_REG, 0xFF); if (ret) { dbg_info("SiI9022: Failed to clear any pending interrupts\n"); return -1; } /* 6. Enter D3 Cold mode via TPI 0x1E[1:0] = 11b */ power_state = 0x04; ret = SiI9022_write(TPI_DEVICE_POWER_STATE_CTRL_REG, power_state); if (ret) { dbg_info("SiI9022: Failed to write TPI 0x1E\n"); return -1; } power_state &= ~TX_POWER_STATE_MASK; power_state |= TX_POWER_STATE_D3; ret = SiI9022_write(TPI_DEVICE_POWER_STATE_CTRL_REG, power_state); if (ret) { dbg_info("SiI9022: Failed to write TPI 0x1E\n"); return -1; } dbg_info("HDMI SiI9022: Enter D3 Cold mode\n"); return 0; }
/** * usb_alphatrack_read */ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct usb_alphatrack *dev; int retval = 0; int c = 0; dev = file->private_data; /* verify that we actually have some data to read */ if (count == 0) goto exit; /* lock this object */ if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } while (dev->ring_head == dev->ring_tail) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } dev->interrupt_in_done = 0; retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; } alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", ": copying to userspace"); c = 0; while ((c < count) && (dev->ring_tail != dev->ring_head)) { if (copy_to_user (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], INPUT_CMD_SIZE)) { retval = -EFAULT; goto unlock_exit; } dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; c += INPUT_CMD_SIZE; dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__, dev->ring_head, dev->ring_tail); } retval = c; unlock_exit: /* unlock the device */ mutex_unlock(&dev->mtx); exit: return retval; }
int at91_board_act8865_set_reg_voltage(void) { unsigned char reg, value; int ret; /* Check ACT8865 I2C interface */ if (act8865_check_i2c_disabled()) return 0; /* Enable REG2 output 1.2V */ reg = REG2_1; value = ACT8865_1V2; ret = act8865_set_reg_voltage(reg, value); if (ret) { dbg_loud("ACT8865: Failed to make REG2 output 1200mV\n"); return -1; } dbg_info("ACT8865: The REG2 output 1200mV\n"); /* Enable REG4 output 2.5V */ reg = REG4_0; value = ACT8865_2V5; ret = act8865_set_reg_voltage(reg, value); if (ret) { dbg_loud("ACT8865: Failed to make REG4 output 2500mV\n"); return -1; } dbg_info("ACT8865: The REG4 output 2500mV\n"); /* Enable REG5 output 3.3V */ reg = REG5_0; value = ACT8865_3V3; ret = act8865_set_reg_voltage(reg, value); if (ret) { dbg_loud("ACT8865: Failed to make REG5 output 3300mV\n"); return -1; } dbg_info("ACT8865: The REG5 output 3300mV\n"); /* Enable REG6 output 2.5V */ reg = REG6_0; value = ACT8865_2V5; ret = act8865_set_reg_voltage(reg, value); if (ret) { dbg_loud("ACT8865: Failed to make REG6 output 2500mV\n"); return -1; } dbg_info("ACT8865: The REG6 output 2500mV\n"); /* Enable REG7 output 1.8V */ reg = REG7_0; value = ACT8865_1V8; ret = act8865_set_reg_voltage(reg, value); if (ret) { dbg_loud("ACT8865: Failed to make REG7 output 1800mV\n"); return -1; } dbg_info("ACT8865: The REG7 output 1800mV\n"); return 0; }
static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct usb_tranzport *dev; int retval = 0; #if BUFFERED_READS int c = 0; #endif #if COMPRESS_WHEEL_EVENTS signed char oldwheel; signed char newwheel; int cancompress = 1; int next_tail; #endif /* do I have such a thing as a null event? */ dev = file->private_data; /* verify that we actually have some data to read */ if (count == 0) goto exit; /* lock this object */ if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } while (dev->ring_head == dev->ring_tail) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } /* tiny race - FIXME: make atomic? */ /* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */ dev->interrupt_in_done = 0; retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; } dbg_info(&dev->intf->dev, "%s: copying to userspace: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0], (*dev->ring_buffer)[dev->ring_tail].cmd[1], (*dev->ring_buffer)[dev->ring_tail].cmd[2], (*dev->ring_buffer)[dev->ring_tail].cmd[3], (*dev->ring_buffer)[dev->ring_tail].cmd[4], (*dev->ring_buffer)[dev->ring_tail].cmd[5], (*dev->ring_buffer)[dev->ring_tail].cmd[6], (*dev->ring_buffer)[dev->ring_tail].cmd[7]); #if BUFFERED_READS c = 0; while ((c < count) && (dev->ring_tail != dev->ring_head)) { #if COMPRESS_WHEEL_EVENTS next_tail = (dev->ring_tail+1) % ring_buffer_size; if (dev->compress_wheel) cancompress = 1; while (dev->ring_head != next_tail && cancompress == 1) { newwheel = (*dev->ring_buffer)[next_tail].cmd[6]; oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6]; /* if both are wheel events, and no buttons have changes (FIXME, do I have to check?), and we are the same sign, we can compress +- 7F */ dbg_info(&dev->intf->dev, "%s: trying to compress: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0], (*dev->ring_buffer)[dev->ring_tail].cmd[1], (*dev->ring_buffer)[dev->ring_tail].cmd[2], (*dev->ring_buffer)[dev->ring_tail].cmd[3], (*dev->ring_buffer)[dev->ring_tail].cmd[4], (*dev->ring_buffer)[dev->ring_tail].cmd[5], (*dev->ring_buffer)[dev->ring_tail].cmd[6], (*dev->ring_buffer)[dev->ring_tail].cmd[7]); if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 && (*dev->ring_buffer)[next_tail].cmd[6] != 0) && ((newwheel > 0 && oldwheel > 0) || (newwheel < 0 && oldwheel < 0)) && ((*dev->ring_buffer)[dev->ring_tail].cmd[2] == (*dev->ring_buffer)[next_tail].cmd[2]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[3] == (*dev->ring_buffer)[next_tail].cmd[3]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[4] == (*dev->ring_buffer)[next_tail].cmd[4]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[5] == (*dev->ring_buffer)[next_tail].cmd[5])) { dbg_info(&dev->intf->dev, "%s: should compress: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", __func__, (*dev->ring_buffer)[dev->ring_tail]. cmd[0], (*dev->ring_buffer)[dev->ring_tail]. cmd[1], (*dev->ring_buffer)[dev->ring_tail]. cmd[2], (*dev->ring_buffer)[dev->ring_tail]. cmd[3], (*dev->ring_buffer)[dev->ring_tail]. cmd[4], (*dev->ring_buffer)[dev->ring_tail]. cmd[5], (*dev->ring_buffer)[dev->ring_tail]. cmd[6], (*dev->ring_buffer)[dev->ring_tail]. cmd[7]); newwheel += oldwheel; if (oldwheel > 0 && !(newwheel > 0)) { newwheel = 0x7f; cancompress = 0; } if (oldwheel < 0 && !(newwheel < 0)) { newwheel = 0x80; cancompress = 0; } (*dev->ring_buffer)[next_tail].cmd[6] = newwheel; dev->ring_tail = next_tail; next_tail = (dev->ring_tail + 1) % ring_buffer_size; } else { cancompress = 0; } } #endif /* COMPRESS_WHEEL_EVENTS */ if (copy_to_user( &buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 8)) { retval = -EFAULT; goto unlock_exit; } dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; c += 8; dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__, dev->ring_head, dev->ring_tail); } retval = c; #else /* if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */ retval = -EFAULT; goto unlock_exit; }
void_t vt_inclined_plane(virtualtouch_s* vt) { dbg_function(); int tmp; int_t alpha = mm_alpha(vt->countalpha); int_t ahpla = 1000 - mm_alpha(vt->countalpha); tmp = (vt->distance.dx + vt->distance.sx + vt->distance.dw + vt->distance.up) / 4; if ( vt->eamflags & VT_EAMF_PLANE ) vt->p3d.z = (alpha * tmp + ahpla * vt->p3d.z)/1000; else vt->p3d.z = tmp; dbg_info("plane: [z=%3d]", vt->p3d.z); int_t h, f, l; int_t b = vt->vxdistance.x; if (vt->distance.sx > vt->distance.dx) { h = vt->distance.sx - vt->distance.dx; f = 1; } else { h = vt->distance.dx - vt->distance.sx; f = -1; } l = sqrt32(b*b + h*h); tmp = ((vt->peso.x * h) / l) * f; if ( vt->eamflags & VT_EAMF_PLANE ) vt->p3d.x = (alpha * tmp + ahpla * vt->p3d.x)/1000; else vt->p3d.x = tmp; dbg_info("plane: [p=%3d z=%3d h=%3d b=%3d l=%3d f=%3d][px=%3d]", vt->peso.x, vt->p3d.z, h, b, l, f, vt->p3d.x); b = vt->vxdistance.y; if (vt->distance.up > vt->distance.dw) { h = vt->distance.up - vt->distance.dw; f = -1; } else { h = vt->distance.dw - vt->distance.up; f = 1; } l = sqrt32(b*b + h*h); tmp = ((vt->peso.y * h) / l) * f; if ( vt->eamflags & VT_EAMF_PLANE ) vt->p3d.y = (alpha * tmp + ahpla * vt->p3d.y)/1000; else vt->p3d.y = tmp; dbg_info("plane: [p=%3d z=%3d h=%3d b=%3d l=%3d f=%3d][px=%3d]", vt->peso.y, vt->p3d.z, h, b, l, f, vt->p3d.y); dbg_return(0); }
static void usb_tranzport_interrupt_in_callback(struct urb *urb) { struct usb_tranzport *dev = urb->context; unsigned int next_ring_head; int retval = -1; if (urb->status) { if (urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) { goto exit; } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", __func__, urb->status); goto resubmit; /* maybe we can recover */ } } if (urb->actual_length != 8) { dev_warn(&dev->intf->dev, "Urb length was %d bytes!!" "Do something intelligent \n", urb->actual_length); } else { dbg_info(&dev->intf->dev, "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n", __func__, dev->interrupt_in_buffer[0], dev->interrupt_in_buffer[1], dev->interrupt_in_buffer[2], dev->interrupt_in_buffer[3], dev->interrupt_in_buffer[4], dev->interrupt_in_buffer[5], dev->interrupt_in_buffer[6], dev->interrupt_in_buffer[7]); #if SUPPRESS_EXTRA_OFFLINE_EVENTS if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) goto resubmit; if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; } /* Always pass one offline event up the stack */ if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) dev->offline = 0; if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) dev->offline = 1; #endif /* SUPPRESS_EXTRA_OFFLINE_EVENTS */ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__, dev->ring_head, dev->ring_tail); next_ring_head = (dev->ring_head + 1) % ring_buffer_size; if (next_ring_head != dev->ring_tail) { memcpy(&((*dev->ring_buffer)[dev->ring_head]), dev->interrupt_in_buffer, urb->actual_length); dev->ring_head = next_ring_head; retval = 0; memset(dev->interrupt_in_buffer, 0, urb->actual_length); } else { dev_warn(&dev->intf->dev, "Ring buffer overflow, %d bytes dropped\n", urb->actual_length); memset(dev->interrupt_in_buffer, 0, urb->actual_length); } } resubmit: /* resubmit if we're still running */ if (dev->interrupt_in_running && dev->intf) { retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); if (retval) dev_err(&dev->intf->dev, "usb_submit_urb failed (%d)\n", retval); } exit: dev->interrupt_in_done = 1; wake_up_interruptible(&dev->read_wait); }
/** * usb_tranzport_read */ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct usb_tranzport *dev; size_t bytes_to_read; int retval = 0; #if BUFFERED_READS int c = 0; #endif #if COMPRESS_WHEEL_EVENTS signed char oldwheel; signed char newwheel; int cancompress = 1; int next_tail; #endif /* do I have such a thing as a null event? */ dev = file->private_data; /* verify that we actually have some data to read */ if (count == 0) goto exit; /* lock this object */ if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } /* verify that the device wasn't unplugged */ if (dev->intf == NULL) { retval = -ENODEV; err("No device or device unplugged %d\n", retval); goto unlock_exit; } while (dev->ring_head == dev->ring_tail) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto unlock_exit; } // atomic_cmp_exchange(&dev->interrupt_in_done,0,0); dev->interrupt_in_done = 0 ; /* tiny race - FIXME: make atomic? */ retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) { goto unlock_exit; } } dbg_info(&dev->intf->dev, "%s: copying to userspace: %02x%02x%02x%02x%02x%02x%02x%02x\n", __FUNCTION__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]); #if BUFFERED_READS c = 0; while((c < count) && (dev->ring_tail != dev->ring_head)) { /* This started off in the lower level service routine, and I moved it here. Then my brain died. Not done yet. */ #if COMPRESS_WHEEL_EVENTS next_tail = (dev->ring_tail+1) % ring_buffer_size; if(dev->compress_wheel) cancompress = 1; while(dev->ring_head != next_tail && cancompress == 1 ) { newwheel = (*dev->ring_buffer)[next_tail].cmd[6]; oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6]; // if both are wheel events, and no buttons have changes (FIXME, do I have to check?), // and we are the same sign, we can compress +- 7F // FIXME: saner check for overflow! - max of +- 7F // FIXME the math is wrong for going in reverse, actually, as the midi spec doesn't allow signed chars dbg_info(&dev->intf->dev, "%s: trying to compress: %02x%02x%02x%02x%02x %02x %02x %02x\n", __FUNCTION__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]); if(((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 && (*dev->ring_buffer)[next_tail].cmd[6] != 0 ) && ((newwheel > 0 && oldwheel > 0) || (newwheel < 0 && oldwheel < 0)) && ((*dev->ring_buffer)[dev->ring_tail].cmd[2] == (*dev->ring_buffer)[next_tail].cmd[2]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[3] == (*dev->ring_buffer)[next_tail].cmd[3]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[4] == (*dev->ring_buffer)[next_tail].cmd[4]) && ((*dev->ring_buffer)[dev->ring_tail].cmd[5] == (*dev->ring_buffer)[next_tail].cmd[5])) { dbg_info(&dev->intf->dev, "%s: should compress: %02x%02x%02x%02x%02x%02x%02x%02x\n", __FUNCTION__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]); newwheel += oldwheel; if(oldwheel > 0 && !(newwheel > 0)) { newwheel = 0x7f; cancompress = 0; } if(oldwheel < 0 && !(newwheel < 0)) { newwheel = 0x80; cancompress = 0; } (*dev->ring_buffer)[next_tail].cmd[6] = newwheel; dev->ring_tail = next_tail; next_tail = (dev->ring_tail+1) % ring_buffer_size; } else { cancompress = 0; } } #endif /* COMPRESS_WHEEL_EVENTS */ if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 8)) { retval = -EFAULT; goto unlock_exit; } dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; c+=8; dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __FUNCTION__,dev->ring_head,dev->ring_tail); } retval = c; #else if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { retval = -EFAULT; goto unlock_exit; } dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __FUNCTION__,dev->ring_head,dev->ring_tail); retval = 8; #endif /* BUFFERED_READS */ unlock_exit: /* unlock the device */ up(&dev->sem); exit: return retval; }