Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eadc21f5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull staging / IIO fixes from Greg KH:
 "Here are some IIO driver fixes to resolve reported issues, some ozwpan
  fixes for some reported CVE problems, and a rtl8712 driver fix for a
  reported regression.

  All have been in linux-next successfully"

* tag 'staging-4.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: rtl8712: fix stack dump
  ozwpan: unchecked signed subtraction leads to DoS
  ozwpan: divide-by-zero leading to panic
  ozwpan: Use unsigned ints to prevent heap overflow
  ozwpan: Use proper check to prevent heap overflow
  iio: adc: twl6030-gpadc: Fix modalias
  iio: adis16400: Fix burst transfer for adis16448
  iio: adis16400: Fix burst mode
  iio: adis16400: Compute the scan mask from channel indices
  iio: adis16400: Use != channel indices for the two voltage channels
  iio: adis16400: Report pressure channel scale
parents b334b773 39a6e737
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@
#define ADIS16400_NO_BURST		BIT(1)
#define ADIS16400_HAS_SLOW_MODE		BIT(2)
#define ADIS16400_HAS_SERIAL_NUMBER	BIT(3)
#define ADIS16400_BURST_DIAG_STAT	BIT(4)

struct adis16400_state;

@@ -165,6 +166,7 @@ struct adis16400_state {
	int				filt_int;

	struct adis adis;
	unsigned long avail_scan_mask[2];
};

/* At the moment triggers are only used for ring buffer
+18 −8
Original line number Diff line number Diff line
@@ -18,7 +18,8 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev,
{
	struct adis16400_state *st = iio_priv(indio_dev);
	struct adis *adis = &st->adis;
	uint16_t *tx;
	unsigned int burst_length;
	u8 *tx;

	if (st->variant->flags & ADIS16400_NO_BURST)
		return adis_update_scan_mode(indio_dev, scan_mask);
@@ -26,26 +27,29 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev,
	kfree(adis->xfer);
	kfree(adis->buffer);

	/* All but the timestamp channel */
	burst_length = (indio_dev->num_channels - 1) * sizeof(u16);
	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
		burst_length += sizeof(u16);

	adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
	if (!adis->xfer)
		return -ENOMEM;

	adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
		GFP_KERNEL);
	adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL);
	if (!adis->buffer)
		return -ENOMEM;

	tx = adis->buffer + indio_dev->scan_bytes;

	tx = adis->buffer + burst_length;
	tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
	tx[1] = 0;

	adis->xfer[0].tx_buf = tx;
	adis->xfer[0].bits_per_word = 8;
	adis->xfer[0].len = 2;
	adis->xfer[1].tx_buf = tx;
	adis->xfer[1].rx_buf = adis->buffer;
	adis->xfer[1].bits_per_word = 8;
	adis->xfer[1].len = indio_dev->scan_bytes;
	adis->xfer[1].len = burst_length;

	spi_message_init(&adis->msg);
	spi_message_add_tail(&adis->xfer[0], &adis->msg);
@@ -61,6 +65,7 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
	struct adis16400_state *st = iio_priv(indio_dev);
	struct adis *adis = &st->adis;
	u32 old_speed_hz = st->adis.spi->max_speed_hz;
	void *buffer;
	int ret;

	if (!adis->buffer)
@@ -81,7 +86,12 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
		spi_setup(st->adis.spi);
	}

	iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
	if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
		buffer = adis->buffer + sizeof(u16);
	else
		buffer = adis->buffer;

	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
		pf->timestamp);

	iio_trigger_notify_done(indio_dev->trig);
+29 −12
Original line number Diff line number Diff line
@@ -405,6 +405,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
			*val = st->variant->temp_scale_nano / 1000000;
			*val2 = (st->variant->temp_scale_nano % 1000000);
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_PRESSURE:
			/* 20 uBar = 0.002kPascal */
			*val = 0;
			*val2 = 2000;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
@@ -454,10 +459,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
	}
}

#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \
#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si, chn) { \
	.type = IIO_VOLTAGE, \
	.indexed = 1, \
	.channel = 0, \
	.channel = chn, \
	.extend_name = name, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
		BIT(IIO_CHAN_INFO_SCALE), \
@@ -474,10 +479,10 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
}

#define ADIS16400_SUPPLY_CHAN(addr, bits) \
	ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY)
	ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY, 0)

#define ADIS16400_AUX_ADC_CHAN(addr, bits) \
	ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC)
	ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC, 1)

#define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
	.type = IIO_ANGL_VEL, \
@@ -773,7 +778,8 @@ static struct adis16400_chip_info adis16400_chips[] = {
		.channels = adis16448_channels,
		.num_channels = ARRAY_SIZE(adis16448_channels),
		.flags = ADIS16400_HAS_PROD_ID |
				ADIS16400_HAS_SERIAL_NUMBER,
				ADIS16400_HAS_SERIAL_NUMBER |
				ADIS16400_BURST_DIAG_STAT,
		.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */
		.accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */
		.temp_scale_nano = 73860000, /* 0.07386 C */
@@ -791,11 +797,6 @@ static const struct iio_info adis16400_info = {
	.debugfs_reg_access = adis_debugfs_reg_access,
};

static const unsigned long adis16400_burst_scan_mask[] = {
	~0UL,
	0,
};

static const char * const adis16400_status_error_msgs[] = {
	[ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
	[ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
@@ -843,6 +844,20 @@ static const struct adis_data adis16400_data = {
		BIT(ADIS16400_DIAG_STAT_POWER_LOW),
};

static void adis16400_setup_chan_mask(struct adis16400_state *st)
{
	const struct adis16400_chip_info *chip_info = st->variant;
	unsigned i;

	for (i = 0; i < chip_info->num_channels; i++) {
		const struct iio_chan_spec *ch = &chip_info->channels[i];

		if (ch->scan_index >= 0 &&
		    ch->scan_index != ADIS16400_SCAN_TIMESTAMP)
			st->avail_scan_mask[0] |= BIT(ch->scan_index);
	}
}

static int adis16400_probe(struct spi_device *spi)
{
	struct adis16400_state *st;
@@ -866,8 +881,10 @@ static int adis16400_probe(struct spi_device *spi)
	indio_dev->info = &adis16400_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	if (!(st->variant->flags & ADIS16400_NO_BURST))
		indio_dev->available_scan_masks = adis16400_burst_scan_mask;
	if (!(st->variant->flags & ADIS16400_NO_BURST)) {
		adis16400_setup_chan_mask(st);
		indio_dev->available_scan_masks = st->avail_scan_mask;
	}

	ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
	if (ret)
+4 −4
Original line number Diff line number Diff line
@@ -746,8 +746,8 @@ void oz_hcd_pd_reset(void *hpd, void *hport)
/*
 * Context: softirq
 */
void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc,
			int length, int offset, int total_size)
void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status, const u8 *desc,
			u8 length, u16 offset, u16 total_size)
{
	struct oz_port *port = hport;
	struct urb *urb;
@@ -759,8 +759,8 @@ void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status, const u8 *desc,
	if (!urb)
		return;
	if (status == 0) {
		int copy_len;
		int required_size = urb->transfer_buffer_length;
		unsigned int copy_len;
		unsigned int required_size = urb->transfer_buffer_length;

		if (required_size > total_size)
			required_size = total_size;
+2 −2
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ void oz_usb_request_heartbeat(void *hpd);

/* Confirmation functions.
 */
void oz_hcd_get_desc_cnf(void *hport, u8 req_id, int status,
	const u8 *desc, int length, int offset, int total_size);
void oz_hcd_get_desc_cnf(void *hport, u8 req_id, u8 status,
	const u8 *desc, u8 length, u16 offset, u16 total_size);
void oz_hcd_control_cnf(void *hport, u8 req_id, u8 rcode,
	const u8 *data, int data_len);

Loading