Commit 6c7247f6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging/IIO driver fixes from Greg KH:
 "Here are a number of staging and IIO driver fixes for 5.9-rc5.

  The majority of these are IIO driver fixes, to resolve a timestamp
  issue that was recently found to affect a bunch of IIO drivers.

  The other fixes in here are:

   - small IIO driver fixes

   - greybus driver fix

   - counter driver fix (came in through the IIO fixes tree)

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'staging-5.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (23 commits)
  iio: adc: mcp3422: fix locking on error path
  iio: adc: mcp3422: fix locking scope
  iio: adc: meson-saradc: Use the parent device to look up the calib data
  iio:adc:max1118 Fix alignment of timestamp and data leak issues
  iio:adc:ina2xx Fix timestamp alignment issue.
  iio:adc:ti-adc084s021 Fix alignment and data leak issues.
  iio:adc:ti-adc081c Fix alignment and data leak issues
  iio:magnetometer:ak8975 Fix alignment and data leak issues.
  iio:light:ltr501 Fix timestamp alignment issue.
  iio:light:max44000 Fix timestamp alignment and prevent data leak.
  iio:chemical:ccs811: Fix timestamp alignment and prevent data leak.
  iio:proximity:mb1232: Fix timestamp alignment and prevent data leak.
  iio:accel:mma7455: Fix timestamp alignment and prevent data leak.
  iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak.
  iio:accel:mma8452: Fix timestamp alignment and prevent data leak.
  iio: accel: kxsd9: Fix alignment of local buffer.
  iio: adc: rockchip_saradc: select IIO_TRIGGERED_BUFFER
  iio: adc: ti-ads1015: fix conversion when CONFIG_PM is not set
  counter: microchip-tcb-capture: check the correct variable
  iio: cros_ec: Set Gyroscope default frequency to 25Hz
  ...
parents 20a7b6be a139ffa4
......@@ -320,8 +320,8 @@ static int mchp_tc_probe(struct platform_device *pdev)
}
regmap = syscon_node_to_regmap(np->parent);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
/* max. channels number is 2 when in QDEC mode */
priv->num_channels = of_property_count_u32_elems(np, "reg");
......
......@@ -189,6 +189,14 @@ struct bmc150_accel_data {
struct mutex mutex;
u8 fifo_mode, watermark;
s16 buffer[8];
/*
* Ensure there is sufficient space and correct alignment for
* the timestamp if enabled
*/
struct {
__le16 channels[3];
s64 ts __aligned(8);
} scan;
u8 bw_bits;
u32 slope_dur;
u32 slope_thres;
......@@ -922,15 +930,16 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
* now.
*/
for (i = 0; i < count; i++) {
u16 sample[8];
int j, bit;
j = 0;
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength)
memcpy(&sample[j++], &buffer[i * 3 + bit], 2);
memcpy(&data->scan.channels[j++], &buffer[i * 3 + bit],
sizeof(data->scan.channels[0]));
iio_push_to_buffers_with_timestamp(indio_dev, sample, tstamp);
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
tstamp);
tstamp += sample_period;
}
......
......@@ -209,14 +209,20 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
const struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct kxsd9_state *st = iio_priv(indio_dev);
/*
* Ensure correct positioning and alignment of timestamp.
* No need to zero initialize as all elements written.
*/
struct {
__be16 chan[4];
s64 ts __aligned(8);
} hw_values;
int ret;
/* 4 * 16bit values AND timestamp */
__be16 hw_values[8];
ret = regmap_bulk_read(st->map,
KXSD9_REG_X,
&hw_values,
8);
hw_values.chan,
sizeof(hw_values.chan));
if (ret) {
dev_err(st->dev,
"error reading data\n");
......@@ -224,7 +230,7 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
}
iio_push_to_buffers_with_timestamp(indio_dev,
hw_values,
&hw_values,
iio_get_time_ns(indio_dev));
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -52,6 +52,14 @@
struct mma7455_data {
struct regmap *regmap;
/*
* Used to reorganize data. Will ensure correct alignment of
* the timestamp if present
*/
struct {
__le16 channels[3];
s64 ts __aligned(8);
} scan;
};
static int mma7455_drdy(struct mma7455_data *mma7455)
......@@ -82,19 +90,19 @@ static irqreturn_t mma7455_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct mma7455_data *mma7455 = iio_priv(indio_dev);
u8 buf[16]; /* 3 x 16-bit channels + padding + ts */
int ret;
ret = mma7455_drdy(mma7455);
if (ret)
goto done;
ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf,
sizeof(__le16) * 3);
ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL,
mma7455->scan.channels,
sizeof(mma7455->scan.channels));
if (ret)
goto done;
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &mma7455->scan,
iio_get_time_ns(indio_dev));
done:
......
......@@ -110,6 +110,12 @@ struct mma8452_data {
int sleep_val;
struct regulator *vdd_reg;
struct regulator *vddio_reg;
/* Ensure correct alignment of time stamp when present */
struct {
__be16 channels[3];
s64 ts __aligned(8);
} buffer;
};
/**
......@@ -1091,14 +1097,13 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct mma8452_data *data = iio_priv(indio_dev);
u8 buffer[16]; /* 3 16-bit channels + padding + ts */
int ret;
ret = mma8452_read(data, (__be16 *)buffer);
ret = mma8452_read(data, data->buffer.channels);
if (ret < 0)
goto done;
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
iio_get_time_ns(indio_dev));
done:
......
......@@ -865,6 +865,8 @@ config ROCKCHIP_SARADC
tristate "Rockchip SARADC driver"
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
depends on RESET_CONTROLLER
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the SARADC found in SoCs from
Rockchip.
......
......@@ -146,6 +146,11 @@ struct ina2xx_chip_info {
int range_vbus; /* Bus voltage maximum in V */
int pga_gain_vshunt; /* Shunt voltage PGA gain */
bool allow_async_readout;
/* data buffer needs space for channel data and timestamp */
struct {
u16 chan[4];
u64 ts __aligned(8);
} scan;
};
static const struct ina2xx_config ina2xx_config[] = {
......@@ -738,8 +743,6 @@ static int ina2xx_conversion_ready(struct iio_dev *indio_dev)
static int ina2xx_work_buffer(struct iio_dev *indio_dev)
{
struct ina2xx_chip_info *chip = iio_priv(indio_dev);
/* data buffer needs space for channel data and timestap */
unsigned short data[4 + sizeof(s64)/sizeof(short)];
int bit, ret, i = 0;
s64 time;
......@@ -758,10 +761,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
if (ret < 0)
return ret;
data[i++] = val;
chip->scan.chan[i++] = val;
}
iio_push_to_buffers_with_timestamp(indio_dev, data, time);
iio_push_to_buffers_with_timestamp(indio_dev, &chip->scan, time);
return 0;
};
......
......@@ -36,6 +36,11 @@ struct max1118 {
struct spi_device *spi;
struct mutex lock;
struct regulator *reg;
/* Ensure natural alignment of buffer elements */
struct {
u8 channels[2];
s64 ts __aligned(8);
} scan;
u8 data ____cacheline_aligned;
};
......@@ -166,7 +171,6 @@ static irqreturn_t max1118_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct max1118 *adc = iio_priv(indio_dev);
u8 data[16] = { }; /* 2x 8-bit ADC data + padding + 8 bytes timestamp */
int scan_index;
int i = 0;
......@@ -184,10 +188,10 @@ static irqreturn_t max1118_trigger_handler(int irq, void *p)
goto out;
}
data[i] = ret;
adc->scan.channels[i] = ret;
i++;
}
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
iio_get_time_ns(indio_dev));
out:
mutex_unlock(&adc->lock);
......
......@@ -96,16 +96,12 @@ static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
{
int ret;
mutex_lock(&adc->lock);
ret = i2c_master_send(adc->i2c, &newconfig, 1);
if (ret > 0) {
adc->config = newconfig;
ret = 0;
}
mutex_unlock(&adc->lock);
return ret;
}
......@@ -138,6 +134,8 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
u8 config;
u8 req_channel = channel->channel;
mutex_lock(&adc->lock);
if (req_channel != MCP3422_CHANNEL(adc->config)) {
config = adc->config;
config &= ~MCP3422_CHANNEL_MASK;
......@@ -145,12 +143,18 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
config &= ~MCP3422_PGA_MASK;
config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
ret = mcp3422_update_config(adc, config);
if (ret < 0)
if (ret < 0) {
mutex_unlock(&adc->lock);
return ret;
}
msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
}
return mcp3422_read(adc, value, &config);
ret = mcp3422_read(adc, value, &config);
mutex_unlock(&adc->lock);
return ret;
}
static int mcp3422_read_raw(struct iio_dev *iio,
......
......@@ -707,7 +707,7 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
size_t read_len;
int ret;
temperature_calib = devm_nvmem_cell_get(&indio_dev->dev,
temperature_calib = devm_nvmem_cell_get(indio_dev->dev.parent,
"temperature_calib");
if (IS_ERR(temperature_calib)) {
ret = PTR_ERR(temperature_calib);
......
......@@ -33,6 +33,12 @@ struct adc081c {
/* 8, 10 or 12 */
int bits;
/* Ensure natural alignment of buffer elements */
struct {
u16 channel;
s64 ts __aligned(8);
} scan;
};
#define REG_CONV_RES 0x00
......@@ -128,14 +134,13 @@ static irqreturn_t adc081c_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc081c *data = iio_priv(indio_dev);
u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
int ret;
ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES);
if (ret < 0)
goto out;
buf[0] = ret;
iio_push_to_buffers_with_timestamp(indio_dev, buf,
data->scan.channel = ret;
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -26,6 +26,11 @@ struct adc084s021 {
struct spi_transfer spi_trans;
struct regulator *reg;
struct mutex lock;
/* Buffer used to align data */
struct {
__be16 channels[4];
s64 ts __aligned(8);
} scan;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache line.
......@@ -141,14 +146,13 @@ static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc)
struct iio_poll_func *pf = pollfunc;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc084s021 *adc = iio_priv(indio_dev);
__be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */
mutex_lock(&adc->lock);
if (adc084s021_adc_conversion(adc, &data) < 0)
if (adc084s021_adc_conversion(adc, adc->scan.channels) < 0)
dev_err(&adc->spi->dev, "Failed to read data\n");
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
iio_get_time_ns(indio_dev));
mutex_unlock(&adc->lock);
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -316,6 +316,7 @@ static const struct iio_chan_spec ads1115_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
};
#ifdef CONFIG_PM
static int ads1015_set_power_state(struct ads1015_data *data, bool on)
{
int ret;
......@@ -333,6 +334,15 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on)
return ret < 0 ? ret : 0;
}
#else /* !CONFIG_PM */
static int ads1015_set_power_state(struct ads1015_data *data, bool on)
{
return 0;
}
#endif /* !CONFIG_PM */
static
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
{
......
......@@ -78,6 +78,11 @@ struct ccs811_data {
struct iio_trigger *drdy_trig;
struct gpio_desc *wakeup_gpio;
bool drdy_trig_on;
/* Ensures correct alignment of timestamp if present */
struct {
s16 channels[2];
s64 ts __aligned(8);
} scan;
};
static const struct iio_chan_spec ccs811_channels[] = {
......@@ -327,17 +332,17 @@ static irqreturn_t ccs811_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct ccs811_data *data = iio_priv(indio_dev);
struct i2c_client *client = data->client;
s16 buf[8]; /* s16 eCO2 + s16 TVOC + padding + 8 byte timestamp */
int ret;
ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA, 4,
(u8 *)&buf);
ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA,
sizeof(data->scan.channels),
(u8 *)data->scan.channels);
if (ret != 4) {
dev_err(&client->dev, "cannot read sensor data\n");
goto err;
}
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
err:
......
......@@ -72,10 +72,13 @@ static void get_default_min_max_freq(enum motionsensor_type type,
switch (type) {
case MOTIONSENSE_TYPE_ACCEL:
case MOTIONSENSE_TYPE_GYRO:
*min_freq = 12500;
*max_freq = 100000;
break;
case MOTIONSENSE_TYPE_GYRO:
*min_freq = 25000;
*max_freq = 100000;
break;
case MOTIONSENSE_TYPE_MAG:
*min_freq = 5000;
*max_freq = 25000;
......
......@@ -1243,13 +1243,16 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ltr501_data *data = iio_priv(indio_dev);
u16 buf[8];
struct {
u16 channels[3];
s64 ts __aligned(8);
} scan;
__le16 als_buf[2];
u8 mask = 0;
int j = 0;
int ret, psdata;
memset(buf, 0, sizeof(buf));
memset(&scan, 0, sizeof(scan));
/* figure out which data needs to be ready */
if (test_bit(0, indio_dev->active_scan_mask) ||
......@@ -1268,9 +1271,9 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
if (ret < 0)
return ret;
if (test_bit(0, indio_dev->active_scan_mask))
buf[j++] = le16_to_cpu(als_buf[1]);
scan.channels[j++] = le16_to_cpu(als_buf[1]);
if (test_bit(1, indio_dev->active_scan_mask))
buf[j++] = le16_to_cpu(als_buf[0]);
scan.channels[j++] = le16_to_cpu(als_buf[0]);
}
if (mask & LTR501_STATUS_PS_RDY) {
......@@ -1278,10 +1281,10 @@ static irqreturn_t ltr501_trigger_handler(int irq, void *p)
&psdata, 2);
if (ret < 0)
goto done;
buf[j++] = psdata & LTR501_PS_DATA_MASK;
scan.channels[j++] = psdata & LTR501_PS_DATA_MASK;
}
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &scan,
iio_get_time_ns(indio_dev));
done:
......
......@@ -75,6 +75,11 @@
struct max44000_data {
struct mutex lock;
struct regmap *regmap;
/* Ensure naturally aligned timestamp */
struct {
u16 channels[2];
s64 ts __aligned(8);
} scan;
};
/* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */
......@@ -488,7 +493,6 @@ static irqreturn_t max44000_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct max44000_data *data = iio_priv(indio_dev);
u16 buf[8]; /* 2x u16 + padding + 8 bytes timestamp */
int index = 0;
unsigned int regval;
int ret;
......@@ -498,17 +502,17 @@ static irqreturn_t max44000_trigger_handler(int irq, void *p)
ret = max44000_read_alsval(data);
if (ret < 0)
goto out_unlock;
buf[index++] = ret;
data->scan.channels[index++] = ret;
}
if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) {
ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, &regval);
if (ret < 0)
goto out_unlock;
buf[index] = regval;
data->scan.channels[index] = regval;
}
mutex_unlock(&data->lock);
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
......
......@@ -366,6 +366,12 @@ struct ak8975_data {
struct iio_mount_matrix orientation;
struct regulator *vdd;
struct regulator *vid;
/* Ensure natural alignment of timestamp */
struct {
s16 channels[3];
s64 ts __aligned(8);
} scan;
};
/* Enable attached power regulator if any. */
......@@ -793,7 +799,6 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
const struct i2c_client *client = data->client;
const struct ak_def *def = data->def;
int ret;
s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
__le16 fval[3];
mutex_lock(&data->lock);
......@@ -816,12 +821,13 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
mutex_unlock(&data->lock);
/* Clamp to valid range. */
buff[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
buff[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
buff[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
data->scan.channels[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
data->scan.channels[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
data->scan.channels[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
iio_push_to_buffers_with_timestamp(indio_dev, buff,
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
return;
unlock:
......
......@@ -40,6 +40,11 @@ struct mb1232_data {
*/
struct completion ranging;
int irqnr;
/* Ensure correct alignment of data to push to IIO buffer */
struct {
s16 distance;
s64 ts __aligned(8);
} scan;
};
static irqreturn_t mb1232_handle_irq(int irq, void *dev_id)
......@@ -113,17 +118,13 @@ static irqreturn_t mb1232_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct mb1232_data *data = iio_priv(indio_dev);
/*
* triggered buffer
* 16-bit channel + 48-bit padding + 64-bit timestamp
*/
s16 buffer[8] = { 0 };
buffer[0] = mb1232_read_distance(data);
if (buffer[0] < 0)
data->scan.distance = mb1232_read_distance(data);
if (data->scan.distance < 0)
goto err;
iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
pf->timestamp);
err:
iio_trigger_notify_done(indio_dev->trig);
......
......@@ -173,8 +173,7 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev,
id.index = control->index;
kctl = snd_ctl_find_id(card, &id);
if (!kctl) {
dev_err(dev, "%d: Failed to find %s\n", err,
control->name);
dev_err(dev, "Failed to find %s\n", control->name);
continue;
}
err = snd_ctl_remove(card, kctl);
......
......@@ -456,6 +456,15 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
val = ucontrol->value.integer.value[0] & mask;
connect = !!val;
ret = gb_pm_runtime_get_sync(bundle);
if (ret)
return ret;
ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
GB_AUDIO_INVALID_INDEX, &gbvalue);
if (ret)
goto exit;
/* update ucontrol */
if (gbvalue.value.integer_value[0] != val) {
for (wi = 0; wi < wlist->num_widgets; wi++) {
......@@ -466,25 +475,17 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
gbvalue.value.integer_value[0] =
cpu_to_le32(ucontrol->value.integer.value[0]);
ret = gb_pm_runtime_get_sync(bundle);
if (ret)
return ret;
ret = gb_audio_gb_set_control(module->mgmt_connection,
data->ctl_id,
GB_AUDIO_INVALID_INDEX, &gbvalue);
}
exit:
gb_pm_runtime_put_autosuspend(bundle);
if (ret) {
dev_err_ratelimited(codec_dev,
"%d:Error in %s for %s\n", ret,
if (ret)
dev_err_ratelimited(codec_dev, "%d:Error in %s for %s\n", ret,
__func__, kcontrol->id.name);
return ret;
}
}
return 0;
}
#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
......
......@@ -524,13 +524,8 @@ static void hfa384x_usb_defer(struct work_struct *data)
*/
void hfa384x_create(struct hfa384x *hw, struct usb_device *usb)
{
memset(hw, 0, sizeof(*hw));
hw->usb = usb;
/* set up the endpoints */
hw->endp_in = usb_rcvbulkpipe(usb, 1);
hw->endp_out = usb_sndbulkpipe(usb, 2);
/* Set up the waitq */
init_waitqueue_head(&hw->cmdq);
......
......@@ -61,23 +61,14 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct usb_device *dev;
const struct usb_endpoint_descriptor *epd;
const struct usb_host_interface *iface_desc = interface->cur_altsetting;
struct usb_endpoint_descriptor *bulk_in, *bulk_out;
struct usb_host_interface *iface_desc = interface->cur_altsetting;
struct wlandevice *wlandev = NULL;
struct hfa384x *hw = NULL;
int result = 0;
if (iface_desc->desc.bNumEndpoints != 2) {
result = -ENODEV;
goto failed;
}
result = -EINVAL;
epd = &iface_desc->endpoint[1].desc;
if (!usb_endpoint_is_bulk_in(epd))
goto failed;
epd = &iface_desc->endpoint[2].desc;
if (!usb_endpoint_is_bulk_out(epd))
result = usb_find_common_endpoints(iface_desc, &bulk_in, &bulk_out, NULL, NULL);
if (result)
goto failed;
dev = interface_to_usbdev(interface);
......@@ -96,6 +87,8 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
}
/* Initialize the hw data */
hw->endp_in = usb_rcvbulkpipe(dev, bulk_in->bEndpointAddress);
hw->endp_out = usb_sndbulkpipe(dev, bulk_out->bEndpointAddress);
hfa384x_create(hw, dev);
hw->wlandev = wlandev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment