Example #1
0
/**
 *	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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
/*
 * 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;
}
Example #7
0
/*******************************************************************************
 * 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;
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
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;
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
0
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);
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #18
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;
}
Example #20
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;
}
Example #21
0
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);
}
Example #23
0
/**
 *	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;
}