diff options
Diffstat (limited to 'drivers')
536 files changed, 42709 insertions, 16573 deletions
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 1cae4e920c9b..3dcdbad65456 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -262,6 +262,18 @@ static int accel_3d_parse_report(struct platform_device *pdev, st->accel[1].index, st->accel[1].report_id, st->accel[2].index, st->accel[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ACCELERATION, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } + return ret; } diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index c8c1baaec6c1..47dcb34ff44c 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -362,7 +362,7 @@ static int mcp3422_probe(struct i2c_client *client, | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); mcp3422_update_config(adc, config); - err = iio_device_register(indio_dev); + err = devm_iio_device_register(&client->dev, indio_dev); if (err < 0) return err; @@ -371,12 +371,6 @@ static int mcp3422_probe(struct i2c_client *client, return 0; } -static int mcp3422_remove(struct i2c_client *client) -{ - iio_device_unregister(i2c_get_clientdata(client)); - return 0; -} - static const struct i2c_device_id mcp3422_id[] = { { "mcp3422", 2 }, { "mcp3423", 3 }, @@ -400,7 +394,6 @@ static struct i2c_driver mcp3422_driver = { .of_match_table = of_match_ptr(mcp3422_of_match), }, .probe = mcp3422_probe, - .remove = mcp3422_remove, .id_table = mcp3422_id, }; module_i2c_driver(mcp3422_driver); diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index 09727a71e9fa..d0add8f9416b 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -42,12 +42,6 @@ struct vprbrd_adc { .indexed = 1, \ .channel = _index, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .scan_index = _index, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 8, \ - .storagebits = 8, \ - }, \ } static struct iio_chan_spec const vprbrd_adc_iio_channels[] = { @@ -73,7 +67,7 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev, mutex_lock(&vb->lock); admsg->cmd = VPRBRD_ADC_CMD_GET; - admsg->chan = chan->scan_index; + admsg->chan = chan->channel; admsg->val = 0x00; ret = usb_control_msg(vb->usb_dev, @@ -139,7 +133,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev) indio_dev->channels = vprbrd_adc_iio_channels; indio_dev->num_channels = ARRAY_SIZE(vprbrd_adc_iio_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret) { dev_err(&pdev->dev, "could not register iio (adc)"); return ret; @@ -150,22 +144,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev) return 0; } -static int vprbrd_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - - iio_device_unregister(indio_dev); - - return 0; -} - static struct platform_driver vprbrd_adc_driver = { .driver = { .name = "viperboard-adc", .owner = THIS_MODULE, }, .probe = vprbrd_adc_probe, - .remove = vprbrd_adc_remove, }; module_platform_driver(vprbrd_adc_driver); diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 3eeaa82075f7..7d1e90811c71 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -514,16 +514,7 @@ static int ad5421_probe(struct spi_device *spi) return ret; } - return iio_device_register(indio_dev); -} - -static int ad5421_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver ad5421_driver = { @@ -532,7 +523,6 @@ static struct spi_driver ad5421_driver = { .owner = THIS_MODULE, }, .probe = ad5421_probe, - .remove = ad5421_remove, }; module_spi_driver(ad5421_driver); diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 9a78d5abb2f6..ee1e95a3a0c3 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -589,16 +589,7 @@ static int ad5755_probe(struct spi_device *spi) if (ret) return ret; - return iio_device_register(indio_dev); -} - -static int ad5755_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad5755_id[] = { @@ -617,7 +608,6 @@ static struct spi_driver ad5755_driver = { .owner = THIS_MODULE, }, .probe = ad5755_probe, - .remove = ad5755_remove, .id_table = ad5755_id, }; module_spi_driver(ad5755_driver); diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index 445c2aecfadd..8d08c7ed1ea6 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -161,13 +161,7 @@ static int adis16130_probe(struct spi_device *spi) indio_dev->info = &adis16130_info; indio_dev->modes = INDIO_DIRECT_MODE; - return iio_device_register(indio_dev); -} - -static int adis16130_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16130_driver = { @@ -176,7 +170,6 @@ static struct spi_driver adis16130_driver = { .owner = THIS_MODULE, }, .probe = adis16130_probe, - .remove = adis16130_remove, }; module_spi_driver(adis16130_driver); diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index 1e546ba7ba45..eb0e08ec9e20 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -434,23 +434,14 @@ static int adxrs450_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels); indio_dev->name = spi->dev.driver->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; /* Get the device into a sane initial state */ ret = adxrs450_initial_setup(indio_dev); if (ret) - goto error_initial; - return 0; -error_initial: - iio_device_unregister(indio_dev); - return ret; -} - -static int adxrs450_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); + return ret; return 0; } @@ -468,7 +459,6 @@ static struct spi_driver adxrs450_driver = { .owner = THIS_MODULE, }, .probe = adxrs450_probe, - .remove = adxrs450_remove, .id_table = adxrs450_id, }; module_spi_driver(adxrs450_driver); diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index e54f0f4959d3..59d6bc3e04df 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -262,6 +262,17 @@ static int gyro_3d_parse_report(struct platform_device *pdev, st->gyro[1].index, st->gyro[1].report_id, st->gyro[2].index, st->gyro[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ANGL_VELOCITY, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } return ret; } diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 18f72e3d0ed6..2fe88c189f74 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -107,6 +107,11 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_INT_TIME] = "integration_time", }; +/** + * iio_find_channel_from_si() - get channel from its scan index + * @indio_dev: device + * @si: scan index to match + */ const struct iio_chan_spec *iio_find_channel_from_si(struct iio_dev *indio_dev, int si) { @@ -922,6 +927,10 @@ struct device_type iio_device_type = { .release = iio_dev_release, }; +/** + * iio_device_alloc() - allocate an iio_dev from a driver + * @sizeof_priv: Space to allocate for private structure. + **/ struct iio_dev *iio_device_alloc(int sizeof_priv) { struct iio_dev *dev; @@ -962,6 +971,10 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) } EXPORT_SYMBOL(iio_device_alloc); +/** + * iio_device_free() - free an iio_dev from a driver + * @dev: the iio_dev associated with the device + **/ void iio_device_free(struct iio_dev *dev) { if (dev) @@ -984,6 +997,20 @@ static int devm_iio_device_match(struct device *dev, void *res, void *data) return *r == data; } +/** + * devm_iio_device_alloc - Resource-managed iio_device_alloc() + * @dev: Device to allocate iio_dev for + * @sizeof_priv: Space to allocate for private structure. + * + * Managed iio_device_alloc. iio_dev allocated with this function is + * automatically freed on driver detach. + * + * If an iio_dev allocated with this function needs to be freed separately, + * devm_iio_device_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_dev on success, NULL on failure. + */ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) { struct iio_dev **ptr, *iio_dev; @@ -1006,6 +1033,13 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) } EXPORT_SYMBOL_GPL(devm_iio_device_alloc); +/** + * devm_iio_device_free - Resource-managed iio_device_free() + * @dev: Device this iio_dev belongs to + * @iio_dev: the iio_dev associated with the device + * + * Free iio_dev allocated with devm_iio_device_alloc(). + */ void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev) { int rc; @@ -1080,6 +1114,10 @@ static const struct file_operations iio_buffer_fileops = { static const struct iio_buffer_setup_ops noop_ring_setup_ops; +/** + * iio_device_register() - register a device with the IIO subsystem + * @indio_dev: Device structure filled by the device driver + **/ int iio_device_register(struct iio_dev *indio_dev) { int ret; @@ -1141,6 +1179,10 @@ error_ret: } EXPORT_SYMBOL(iio_device_register); +/** + * iio_device_unregister() - unregister a device from the IIO subsystem + * @indio_dev: Device structure representing the device. + **/ void iio_device_unregister(struct iio_dev *indio_dev) { mutex_lock(&indio_dev->info_exist_lock); @@ -1161,6 +1203,65 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_unlock(&indio_dev->info_exist_lock); } EXPORT_SYMBOL(iio_device_unregister); + +static void devm_iio_device_unreg(struct device *dev, void *res) +{ + iio_device_unregister(*(struct iio_dev **)res); +} + +/** + * devm_iio_device_register - Resource-managed iio_device_register() + * @dev: Device to allocate iio_dev for + * @indio_dev: Device structure filled by the device driver + * + * Managed iio_device_register. The IIO device registered with this + * function is automatically unregistered on driver detach. This function + * calls iio_device_register() internally. Refer to that function for more + * information. + * + * If an iio_dev registered with this function needs to be unregistered + * separately, devm_iio_device_unregister() must be used. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev) +{ + struct iio_dev **ptr; + int ret; + + ptr = devres_alloc(devm_iio_device_unreg, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + *ptr = indio_dev; + ret = iio_device_register(indio_dev); + if (!ret) + devres_add(dev, ptr); + else + devres_free(ptr); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_iio_device_register); + +/** + * devm_iio_device_unregister - Resource-managed iio_device_unregister() + * @dev: Device this iio_dev belongs to + * @indio_dev: the iio_dev associated with the device + * + * Unregister iio_dev registered with devm_iio_device_register(). + */ +void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev) +{ + int rc; + + rc = devres_release(dev, devm_iio_device_unreg, + devm_iio_device_match, indio_dev); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_iio_device_unregister); + subsys_initcall(iio_init); module_exit(iio_exit); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index c10eab64bc05..bc043fab4cd1 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -42,6 +42,12 @@ struct iio_event_interface { struct attribute_group group; }; +/** + * iio_push_event() - try to add event to the list for userspace reading + * @indio_dev: IIO device structure + * @ev_code: What event + * @timestamp: When the event occurred + **/ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) { struct iio_event_interface *ev_int = indio_dev->event_interface; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index bf5e70a32d3f..7ba2f002ffca 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -318,7 +318,7 @@ static ssize_t iio_trigger_read_current(struct device *dev, * iio_trigger_write_current() - trigger consumer sysfs set current trigger * * For trigger consumers the current_trigger interface allows the trigger - * used for this device to be specified at run time based on the triggers + * used for this device to be specified at run time based on the trigger's * name. **/ static ssize_t iio_trigger_write_current(struct device *dev, @@ -356,7 +356,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, indio_dev->trig = trig; - if (oldtrig && indio_dev->trig != oldtrig) + if (oldtrig) iio_trigger_put(oldtrig); if (indio_dev->trig) iio_trigger_get(indio_dev->trig); @@ -506,6 +506,23 @@ static int devm_iio_trigger_match(struct device *dev, void *res, void *data) return *r == data; } +/** + * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc() + * @dev: Device to allocate iio_trigger for + * @fmt: trigger name format. If it includes format + * specifiers, the additional arguments following + * format are formatted and inserted in the resulting + * string replacing their respective specifiers. + * + * Managed iio_trigger_alloc. iio_trigger allocated with this function is + * automatically freed on driver detach. + * + * If an iio_trigger allocated with this function needs to be freed separately, + * devm_iio_trigger_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_trigger on success, NULL on failure. + */ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, const char *fmt, ...) { @@ -532,6 +549,13 @@ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, } EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc); +/** + * devm_iio_trigger_free - Resource-managed iio_trigger_free() + * @dev: Device this iio_dev belongs to + * @iio_trig: the iio_trigger associated with the device + * + * Free iio_trigger allocated with devm_iio_trigger_alloc(). + */ void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig) { int rc; diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 8e8b9d722853..621541fb10a9 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -229,6 +229,17 @@ static int als_parse_report(struct platform_device *pdev, dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index, st->als_illum.report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_LIGHT, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } return ret; } diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 5e5d9dea22c5..0c6e459c86b1 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -714,6 +714,7 @@ static int tsl2563_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct tsl2563_chip *chip; struct tsl2563_platform_data *pdata = client->dev.platform_data; + struct device_node *np = client->dev.of_node; int err = 0; u8 id = 0; @@ -750,6 +751,9 @@ static int tsl2563_probe(struct i2c_client *client, if (pdata) chip->cover_comp_gain = pdata->cover_comp_gain; + else if (np) + of_property_read_u32(np, "amstaos,cover-comp-gain", + &chip->cover_comp_gain); else chip->cover_comp_gain = 1; diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index ecb3341ef9c0..384ac23f576f 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -179,13 +179,7 @@ static int vcnl4000_probe(struct i2c_client *client, indio_dev->name = VCNL4000_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - return iio_device_register(indio_dev); -} - -static int vcnl4000_remove(struct i2c_client *client) -{ - iio_device_unregister(i2c_get_clientdata(client)); - return 0; + return devm_iio_device_register(&client->dev, indio_dev); } static struct i2c_driver vcnl4000_driver = { @@ -194,7 +188,6 @@ static struct i2c_driver vcnl4000_driver = { .owner = THIS_MODULE, }, .probe = vcnl4000_probe, - .remove = vcnl4000_remove, .id_table = vcnl4000_id, }; diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index b26e1028a0a0..6d162b7e7af5 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -263,6 +263,18 @@ static int magn_3d_parse_report(struct platform_device *pdev, st->magn[1].index, st->magn[1].report_id, st->magn[2].index, st->magn[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ORIENTATION, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } + return ret; } diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 4f2e0f9bad8c..a8b9cae5c173 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -5,6 +5,18 @@ menu "Pressure sensors" +config MPL3115 + tristate "Freescale MPL3115A2 pressure sensor driver" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for the Freescale MPL3115A2 + pressure sensor / altimeter. + + To compile this driver as a module, choose M here: the module + will be called mpl3115. + config IIO_ST_PRESS tristate "STMicroelectronics pressure sensor Driver" depends on (I2C || SPI_MASTER) && SYSFS diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index be71464c2752..42bb9fcf5436 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -3,6 +3,7 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_MPL3115) += mpl3115.o obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o st_pressure-y := st_pressure_core.o st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c new file mode 100644 index 000000000000..ac8c8ab723e5 --- /dev/null +++ b/drivers/iio/pressure/mpl3115.c @@ -0,0 +1,329 @@ +/* + * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor + * + * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net> + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * (7-bit I2C slave address 0x60) + * + * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode, + * interrupts, user offset correction, raw mode + */ + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/buffer.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/delay.h> + +#define MPL3115_STATUS 0x00 +#define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */ +#define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */ +#define MPL3115_WHO_AM_I 0x0c +#define MPL3115_CTRL_REG1 0x26 + +#define MPL3115_DEVICE_ID 0xc4 + +#define MPL3115_STATUS_PRESS_RDY BIT(2) +#define MPL3115_STATUS_TEMP_RDY BIT(1) + +#define MPL3115_CTRL_RESET BIT(2) /* software reset */ +#define MPL3115_CTRL_OST BIT(1) /* initiate measurement */ +#define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */ +#define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */ + +struct mpl3115_data { + struct i2c_client *client; + struct mutex lock; + u8 ctrl_reg1; +}; + +static int mpl3115_request(struct mpl3115_data *data) +{ + int ret, tries = 15; + + /* trigger measurement */ + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1 | MPL3115_CTRL_OST); + if (ret < 0) + return ret; + + while (tries-- > 0) { + ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1); + if (ret < 0) + return ret; + /* wait for data ready, i.e. OST cleared */ + if (!(ret & MPL3115_CTRL_OST)) + break; + msleep(20); + } + + if (tries < 0) { + dev_err(&data->client->dev, "data not ready\n"); + return -EIO; + } + + return 0; +} + +static int mpl3115_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct mpl3115_data *data = iio_priv(indio_dev); + s32 tmp = 0; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + switch (chan->type) { + case IIO_PRESSURE: /* in 0.25 pascal / LSB */ + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_PRESS, 3, (u8 *) &tmp); + mutex_unlock(&data->lock); + if (ret < 0) + return ret; + *val = sign_extend32(be32_to_cpu(tmp) >> 12, 23); + return IIO_VAL_INT; + case IIO_TEMP: /* in 0.0625 celsius / LSB */ + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_TEMP, 2, (u8 *) &tmp); + mutex_unlock(&data->lock); + if (ret < 0) + return ret; + *val = sign_extend32(be32_to_cpu(tmp) >> 20, 15); + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_PRESSURE: + *val = 0; + *val2 = 250; /* want kilopascal */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_TEMP: + *val = 0; + *val2 = 62500; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + } + return -EINVAL; +} + +static irqreturn_t mpl3115_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct mpl3115_data *data = iio_priv(indio_dev); + u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */ + int ret, pos = 0; + + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + + memset(buffer, 0, sizeof(buffer)); + if (test_bit(0, indio_dev->active_scan_mask)) { + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_PRESS, 3, &buffer[pos]); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + pos += 4; + } + + if (test_bit(1, indio_dev->active_scan_mask)) { + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_TEMP, 2, &buffer[pos]); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + } + mutex_unlock(&data->lock); + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_get_time_ns()); + +done: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static const struct iio_chan_spec mpl3115_channels[] = { + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 20, + .storagebits = 32, + .shift = 12, + .endianness = IIO_BE, + } + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .shift = 4, + .endianness = IIO_BE, + } + }, + IIO_CHAN_SOFT_TIMESTAMP(2), +}; + +static const struct iio_info mpl3115_info = { + .read_raw = &mpl3115_read_raw, + .driver_module = THIS_MODULE, +}; + +static int mpl3115_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mpl3115_data *data; + struct iio_dev *indio_dev; + int ret; + + ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I); + if (ret < 0) + return ret; + if (ret != MPL3115_DEVICE_ID) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = client; + mutex_init(&data->lock); + + i2c_set_clientdata(client, indio_dev); + indio_dev->info = &mpl3115_info; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mpl3115_channels; + indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels); + + /* software reset, I2C transfer is aborted (fails) */ + i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, + MPL3115_CTRL_RESET); + msleep(50); + + data->ctrl_reg1 = MPL3115_CTRL_OS_258MS; + ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, + data->ctrl_reg1); + if (ret < 0) + return ret; + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + mpl3115_trigger_handler, NULL); + if (ret < 0) + return ret; + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto buffer_cleanup; + return 0; + +buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + return ret; +} + +static int mpl3115_standby(struct mpl3115_data *data) +{ + return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE); +} + +static int mpl3115_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + mpl3115_standby(iio_priv(indio_dev)); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int mpl3115_suspend(struct device *dev) +{ + return mpl3115_standby(iio_priv(i2c_get_clientdata( + to_i2c_client(dev)))); +} + +static int mpl3115_resume(struct device *dev) +{ + struct mpl3115_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1); +} + +static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume); +#define MPL3115_PM_OPS (&mpl3115_pm_ops) +#else +#define MPL3115_PM_OPS NULL +#endif + +static const struct i2c_device_id mpl3115_id[] = { + { "mpl3115", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mpl3115_id); + +static struct i2c_driver mpl3115_driver = { + .driver = { + .name = "mpl3115", + .pm = MPL3115_PM_OPS, + }, + .probe = mpl3115_probe, + .remove = mpl3115_remove, + .id_table = mpl3115_id, +}; +module_i2c_driver(mpl3115_driver); + +MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); +MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 3bfdaa8d80a9..d2beb07f2403 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -54,6 +54,8 @@ source "drivers/staging/rtl8188eu/Kconfig" source "drivers/staging/rts5139/Kconfig" +source "drivers/staging/rts5208/Kconfig" + source "drivers/staging/frontier/Kconfig" source "drivers/staging/phison/Kconfig" @@ -142,8 +144,6 @@ source "drivers/staging/dwc2/Kconfig" source "drivers/staging/lustre/Kconfig" -source "drivers/staging/btmtk_usb/Kconfig" - source "drivers/staging/xillybus/Kconfig" source "drivers/staging/dgnc/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index b0d3303b4680..bf62386d6259 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_R8188EU) += rtl8188eu/ obj-$(CONFIG_RTS5139) += rts5139/ +obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ @@ -62,7 +63,6 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_GOLDFISH) += goldfish/ obj-$(CONFIG_USB_DWC2) += dwc2/ obj-$(CONFIG_LUSTRE_FS) += lustre/ -obj-$(CONFIG_USB_BTMTK) += btmtk_usb/ obj-$(CONFIG_XILLYBUS) += xillybus/ obj-$(CONFIG_DGNC) += dgnc/ obj-$(CONFIG_DGAP) += dgap/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 1e9ab6dfc90d..b91c758883bf 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -100,6 +100,8 @@ config SW_SYNC_USER *WARNING* improper use of this can result in deadlocking kernel drivers from userspace. +source "drivers/staging/android/ion/Kconfig" + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index c136299e05af..0a01e1914905 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,5 +1,7 @@ ccflags-y += -I$(src) # needed for trace events +obj-y += ion/ + obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 647694f43dcf..2fc7cdd4c4e3 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -68,11 +68,10 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; */ static int is_wakeup(enum android_alarm_type type) { - return (type == ANDROID_ALARM_RTC_WAKEUP || - type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); + return type == ANDROID_ALARM_RTC_WAKEUP || + type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP; } - static void devalarm_start(struct devalarm *alrm, ktime_t exp) { if (is_wakeup(alrm->type)) @@ -111,7 +110,6 @@ static void alarm_clear(enum android_alarm_type alarm_type) } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); - } static void alarm_set(enum android_alarm_type alarm_type, @@ -280,6 +278,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return 0; } + #ifdef CONFIG_COMPAT static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -371,7 +370,6 @@ static void devalarm_triggered(struct devalarm *alarm) spin_unlock_irqrestore(&alarm_slock, flags); } - static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) { struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig new file mode 100644 index 000000000000..b95281eef2aa --- /dev/null +++ b/drivers/staging/android/ion/Kconfig @@ -0,0 +1,24 @@ +menuconfig ION + bool "Ion Memory Manager" + select GENERIC_ALLOCATOR + select DMA_SHARED_BUFFER + ---help--- + Chose this option to enable the ION Memory Manager, + used by Android to efficiently allocate buffers + from userspace that can be shared between drivers. + If you're not using Android its probably safe to + say N here. + +config ION_TEST + tristate "Ion Test Device" + depends on ION + help + Choose this option to create a device that can be used to test the + kernel and device side ION functions. + +config ION_TEGRA + tristate "Ion for Tegra" + depends on ARCH_TEGRA && ION + help + Choose this option if you wish to use ion on an nVidia Tegra. + diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile new file mode 100644 index 000000000000..75039b98eebb --- /dev/null +++ b/drivers/staging/android/ion/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_ION) += ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \ + ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o +obj-$(CONFIG_ION_TEST) += ion_test.o +ifdef CONFIG_COMPAT +obj-$(CONFIG_ION) += compat_ion.o +endif +obj-$(CONFIG_ION_TEGRA) += tegra/ diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c new file mode 100644 index 000000000000..af6cd370b30f --- /dev/null +++ b/drivers/staging/android/ion/compat_ion.c @@ -0,0 +1,177 @@ +/* + * drivers/staging/android/ion/compat_ion.c + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/compat.h> +#include <linux/fs.h> +#include <linux/uaccess.h> + +#include "ion.h" +#include "compat_ion.h" + +/* See drivers/staging/android/uapi/ion.h for the definition of these structs */ +struct compat_ion_allocation_data { + compat_size_t len; + compat_size_t align; + compat_uint_t heap_id_mask; + compat_uint_t flags; + compat_int_t handle; +}; + +struct compat_ion_custom_data { + compat_uint_t cmd; + compat_ulong_t arg; +}; + +#define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct compat_ion_allocation_data) +#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ + struct compat_ion_custom_data) + +static int compat_get_ion_allocation_data( + struct compat_ion_allocation_data __user *data32, + struct ion_allocation_data __user *data) +{ + compat_size_t s; + compat_uint_t u; + compat_int_t i; + int err; + + err = get_user(s, &data32->len); + err |= put_user(s, &data->len); + err |= get_user(s, &data32->align); + err |= put_user(s, &data->align); + err |= get_user(u, &data32->heap_id_mask); + err |= put_user(u, &data->heap_id_mask); + err |= get_user(u, &data32->flags); + err |= put_user(u, &data->flags); + err |= get_user(i, &data32->handle); + err |= put_user(i, &data->handle); + + return err; +} + +static int compat_put_ion_allocation_data( + struct compat_ion_allocation_data __user *data32, + struct ion_allocation_data __user *data) +{ + compat_size_t s; + compat_uint_t u; + compat_int_t i; + int err; + + err = get_user(s, &data->len); + err |= put_user(s, &data32->len); + err |= get_user(s, &data->align); + err |= put_user(s, &data32->align); + err |= get_user(u, &data->heap_id_mask); + err |= put_user(u, &data32->heap_id_mask); + err |= get_user(u, &data->flags); + err |= put_user(u, &data32->flags); + err |= get_user(i, &data->handle); + err |= put_user(i, &data32->handle); + + return err; +} + +static int compat_get_ion_custom_data( + struct compat_ion_custom_data __user *data32, + struct ion_custom_data __user *data) +{ + compat_uint_t cmd; + compat_ulong_t arg; + int err; + + err = get_user(cmd, &data32->cmd); + err |= put_user(cmd, &data->cmd); + err |= get_user(arg, &data32->arg); + err |= put_user(arg, &data->arg); + + return err; +}; + +long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + + switch (cmd) { + case COMPAT_ION_IOC_ALLOC: + { + struct compat_ion_allocation_data __user *data32; + struct ion_allocation_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_allocation_data(data32, data); + if (err) + return err; + ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC, + (unsigned long)data); + err = compat_put_ion_allocation_data(data32, data); + return ret ? ret : err; + } + case COMPAT_ION_IOC_FREE: + { + struct compat_ion_allocation_data __user *data32; + struct ion_allocation_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_allocation_data(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE, + (unsigned long)data); + } + case COMPAT_ION_IOC_CUSTOM: { + struct compat_ion_custom_data __user *data32; + struct ion_custom_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_custom_data(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM, + (unsigned long)data); + } + case ION_IOC_SHARE: + case ION_IOC_MAP: + case ION_IOC_IMPORT: + case ION_IOC_SYNC: + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + default: + return -ENOIOCTLCMD; + } +} diff --git a/drivers/staging/android/ion/compat_ion.h b/drivers/staging/android/ion/compat_ion.h new file mode 100644 index 000000000000..c2ad5893dfda --- /dev/null +++ b/drivers/staging/android/ion/compat_ion.h @@ -0,0 +1,30 @@ +/* + + * drivers/staging/android/ion/compat_ion.h + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_COMPAT_ION_H +#define _LINUX_COMPAT_ION_H + +#if IS_ENABLED(CONFIG_COMPAT) + +long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + +#else + +#define compat_ion_ioctl NULL + +#endif /* CONFIG_COMPAT */ +#endif /* _LINUX_COMPAT_ION_H */ diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c new file mode 100644 index 000000000000..574066ff73f8 --- /dev/null +++ b/drivers/staging/android/ion/ion.c @@ -0,0 +1,1549 @@ +/* + + * drivers/staging/android/ion/ion.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/device.h> +#include <linux/file.h> +#include <linux/freezer.h> +#include <linux/fs.h> +#include <linux/anon_inodes.h> +#include <linux/kthread.h> +#include <linux/list.h> +#include <linux/memblock.h> +#include <linux/miscdevice.h> +#include <linux/export.h> +#include <linux/mm.h> +#include <linux/mm_types.h> +#include <linux/rbtree.h> +#include <linux/slab.h> +#include <linux/seq_file.h> +#include <linux/uaccess.h> +#include <linux/vmalloc.h> +#include <linux/debugfs.h> +#include <linux/dma-buf.h> +#include <linux/idr.h> + +#include "ion.h" +#include "ion_priv.h" +#include "compat_ion.h" + +/** + * struct ion_device - the metadata of the ion device node + * @dev: the actual misc device + * @buffers: an rb tree of all the existing buffers + * @buffer_lock: lock protecting the tree of buffers + * @lock: rwsem protecting the tree of heaps and clients + * @heaps: list of all the heaps in the system + * @user_clients: list of all the clients created from userspace + */ +struct ion_device { + struct miscdevice dev; + struct rb_root buffers; + struct mutex buffer_lock; + struct rw_semaphore lock; + struct plist_head heaps; + long (*custom_ioctl) (struct ion_client *client, unsigned int cmd, + unsigned long arg); + struct rb_root clients; + struct dentry *debug_root; +}; + +/** + * struct ion_client - a process/hw block local address space + * @node: node in the tree of all clients + * @dev: backpointer to ion device + * @handles: an rb tree of all the handles in this client + * @idr: an idr space for allocating handle ids + * @lock: lock protecting the tree of handles + * @name: used for debugging + * @task: used for debugging + * + * A client represents a list of buffers this client may access. + * The mutex stored here is used to protect both handles tree + * as well as the handles themselves, and should be held while modifying either. + */ +struct ion_client { + struct rb_node node; + struct ion_device *dev; + struct rb_root handles; + struct idr idr; + struct mutex lock; + const char *name; + struct task_struct *task; + pid_t pid; + struct dentry *debug_root; +}; + +/** + * ion_handle - a client local reference to a buffer + * @ref: reference count + * @client: back pointer to the client the buffer resides in + * @buffer: pointer to the buffer + * @node: node in the client's handle rbtree + * @kmap_cnt: count of times this client has mapped to kernel + * @id: client-unique id allocated by client->idr + * + * Modifications to node, map_cnt or mapping should be protected by the + * lock in the client. Other fields are never changed after initialization. + */ +struct ion_handle { + struct kref ref; + struct ion_client *client; + struct ion_buffer *buffer; + struct rb_node node; + unsigned int kmap_cnt; + int id; +}; + +bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer) +{ + return (buffer->flags & ION_FLAG_CACHED) && + !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC); +} + +bool ion_buffer_cached(struct ion_buffer *buffer) +{ + return !!(buffer->flags & ION_FLAG_CACHED); +} + +static inline struct page *ion_buffer_page(struct page *page) +{ + return (struct page *)((unsigned long)page & ~(1UL)); +} + +static inline bool ion_buffer_page_is_dirty(struct page *page) +{ + return !!((unsigned long)page & 1UL); +} + +static inline void ion_buffer_page_dirty(struct page **page) +{ + *page = (struct page *)((unsigned long)(*page) | 1UL); +} + +static inline void ion_buffer_page_clean(struct page **page) +{ + *page = (struct page *)((unsigned long)(*page) & ~(1UL)); +} + +/* this function should only be called while dev->lock is held */ +static void ion_buffer_add(struct ion_device *dev, + struct ion_buffer *buffer) +{ + struct rb_node **p = &dev->buffers.rb_node; + struct rb_node *parent = NULL; + struct ion_buffer *entry; + + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_buffer, node); + + if (buffer < entry) { + p = &(*p)->rb_left; + } else if (buffer > entry) { + p = &(*p)->rb_right; + } else { + pr_err("%s: buffer already found.", __func__); + BUG(); + } + } + + rb_link_node(&buffer->node, parent, p); + rb_insert_color(&buffer->node, &dev->buffers); +} + +/* this function should only be called while dev->lock is held */ +static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, + struct ion_device *dev, + unsigned long len, + unsigned long align, + unsigned long flags) +{ + struct ion_buffer *buffer; + struct sg_table *table; + struct scatterlist *sg; + int i, ret; + + buffer = kzalloc(sizeof(struct ion_buffer), GFP_KERNEL); + if (!buffer) + return ERR_PTR(-ENOMEM); + + buffer->heap = heap; + buffer->flags = flags; + kref_init(&buffer->ref); + + ret = heap->ops->allocate(heap, buffer, len, align, flags); + + if (ret) { + if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) + goto err2; + + ion_heap_freelist_drain(heap, 0); + ret = heap->ops->allocate(heap, buffer, len, align, + flags); + if (ret) + goto err2; + } + + buffer->dev = dev; + buffer->size = len; + + table = heap->ops->map_dma(heap, buffer); + if (WARN_ONCE(table == NULL, + "heap->ops->map_dma should return ERR_PTR on error")) + table = ERR_PTR(-EINVAL); + if (IS_ERR(table)) { + heap->ops->free(buffer); + kfree(buffer); + return ERR_PTR(PTR_ERR(table)); + } + buffer->sg_table = table; + if (ion_buffer_fault_user_mappings(buffer)) { + int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + struct scatterlist *sg; + int i, j, k = 0; + + buffer->pages = vmalloc(sizeof(struct page *) * num_pages); + if (!buffer->pages) { + ret = -ENOMEM; + goto err1; + } + + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page = sg_page(sg); + + for (j = 0; j < sg->length / PAGE_SIZE; j++) + buffer->pages[k++] = page++; + } + + if (ret) + goto err; + } + + buffer->dev = dev; + buffer->size = len; + INIT_LIST_HEAD(&buffer->vmas); + mutex_init(&buffer->lock); + /* this will set up dma addresses for the sglist -- it is not + technically correct as per the dma api -- a specific + device isn't really taking ownership here. However, in practice on + our systems the only dma_address space is physical addresses. + Additionally, we can't afford the overhead of invalidating every + allocation via dma_map_sg. The implicit contract here is that + memory comming from the heaps is ready for dma, ie if it has a + cached mapping that mapping has been invalidated */ + for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) + sg_dma_address(sg) = sg_phys(sg); + mutex_lock(&dev->buffer_lock); + ion_buffer_add(dev, buffer); + mutex_unlock(&dev->buffer_lock); + return buffer; + +err: + heap->ops->unmap_dma(heap, buffer); + heap->ops->free(buffer); +err1: + if (buffer->pages) + vfree(buffer->pages); +err2: + kfree(buffer); + return ERR_PTR(ret); +} + +void ion_buffer_destroy(struct ion_buffer *buffer) +{ + if (WARN_ON(buffer->kmap_cnt > 0)) + buffer->heap->ops->unmap_kernel(buffer->heap, buffer); + buffer->heap->ops->unmap_dma(buffer->heap, buffer); + buffer->heap->ops->free(buffer); + if (buffer->pages) + vfree(buffer->pages); + kfree(buffer); +} + +static void _ion_buffer_destroy(struct kref *kref) +{ + struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref); + struct ion_heap *heap = buffer->heap; + struct ion_device *dev = buffer->dev; + + mutex_lock(&dev->buffer_lock); + rb_erase(&buffer->node, &dev->buffers); + mutex_unlock(&dev->buffer_lock); + + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + ion_heap_freelist_add(heap, buffer); + else + ion_buffer_destroy(buffer); +} + +static void ion_buffer_get(struct ion_buffer *buffer) +{ + kref_get(&buffer->ref); +} + +static int ion_buffer_put(struct ion_buffer *buffer) +{ + return kref_put(&buffer->ref, _ion_buffer_destroy); +} + +static void ion_buffer_add_to_handle(struct ion_buffer *buffer) +{ + mutex_lock(&buffer->lock); + buffer->handle_count++; + mutex_unlock(&buffer->lock); +} + +static void ion_buffer_remove_from_handle(struct ion_buffer *buffer) +{ + /* + * when a buffer is removed from a handle, if it is not in + * any other handles, copy the taskcomm and the pid of the + * process it's being removed from into the buffer. At this + * point there will be no way to track what processes this buffer is + * being used by, it only exists as a dma_buf file descriptor. + * The taskcomm and pid can provide a debug hint as to where this fd + * is in the system + */ + mutex_lock(&buffer->lock); + buffer->handle_count--; + BUG_ON(buffer->handle_count < 0); + if (!buffer->handle_count) { + struct task_struct *task; + + task = current->group_leader; + get_task_comm(buffer->task_comm, task); + buffer->pid = task_pid_nr(task); + } + mutex_unlock(&buffer->lock); +} + +static struct ion_handle *ion_handle_create(struct ion_client *client, + struct ion_buffer *buffer) +{ + struct ion_handle *handle; + + handle = kzalloc(sizeof(struct ion_handle), GFP_KERNEL); + if (!handle) + return ERR_PTR(-ENOMEM); + kref_init(&handle->ref); + RB_CLEAR_NODE(&handle->node); + handle->client = client; + ion_buffer_get(buffer); + ion_buffer_add_to_handle(buffer); + handle->buffer = buffer; + + return handle; +} + +static void ion_handle_kmap_put(struct ion_handle *); + +static void ion_handle_destroy(struct kref *kref) +{ + struct ion_handle *handle = container_of(kref, struct ion_handle, ref); + struct ion_client *client = handle->client; + struct ion_buffer *buffer = handle->buffer; + + mutex_lock(&buffer->lock); + while (handle->kmap_cnt) + ion_handle_kmap_put(handle); + mutex_unlock(&buffer->lock); + + idr_remove(&client->idr, handle->id); + if (!RB_EMPTY_NODE(&handle->node)) + rb_erase(&handle->node, &client->handles); + + ion_buffer_remove_from_handle(buffer); + ion_buffer_put(buffer); + + kfree(handle); +} + +struct ion_buffer *ion_handle_buffer(struct ion_handle *handle) +{ + return handle->buffer; +} + +static void ion_handle_get(struct ion_handle *handle) +{ + kref_get(&handle->ref); +} + +static int ion_handle_put(struct ion_handle *handle) +{ + struct ion_client *client = handle->client; + int ret; + + mutex_lock(&client->lock); + ret = kref_put(&handle->ref, ion_handle_destroy); + mutex_unlock(&client->lock); + + return ret; +} + +static struct ion_handle *ion_handle_lookup(struct ion_client *client, + struct ion_buffer *buffer) +{ + struct rb_node *n = client->handles.rb_node; + + while (n) { + struct ion_handle *entry = rb_entry(n, struct ion_handle, node); + if (buffer < entry->buffer) + n = n->rb_left; + else if (buffer > entry->buffer) + n = n->rb_right; + else + return entry; + } + return ERR_PTR(-EINVAL); +} + +static struct ion_handle *ion_handle_get_by_id(struct ion_client *client, + int id) +{ + struct ion_handle *handle; + + mutex_lock(&client->lock); + handle = idr_find(&client->idr, id); + if (handle) + ion_handle_get(handle); + mutex_unlock(&client->lock); + + return handle ? handle : ERR_PTR(-EINVAL); +} + +static bool ion_handle_validate(struct ion_client *client, + struct ion_handle *handle) +{ + WARN_ON(!mutex_is_locked(&client->lock)); + return (idr_find(&client->idr, handle->id) == handle); +} + +static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) +{ + int id; + struct rb_node **p = &client->handles.rb_node; + struct rb_node *parent = NULL; + struct ion_handle *entry; + + id = idr_alloc(&client->idr, handle, 1, 0, GFP_KERNEL); + if (id < 0) + return id; + + handle->id = id; + + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_handle, node); + + if (handle->buffer < entry->buffer) + p = &(*p)->rb_left; + else if (handle->buffer > entry->buffer) + p = &(*p)->rb_right; + else + WARN(1, "%s: buffer already found.", __func__); + } + + rb_link_node(&handle->node, parent, p); + rb_insert_color(&handle->node, &client->handles); + + return 0; +} + +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags) +{ + struct ion_handle *handle; + struct ion_device *dev = client->dev; + struct ion_buffer *buffer = NULL; + struct ion_heap *heap; + int ret; + + pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__, + len, align, heap_id_mask, flags); + /* + * traverse the list of heaps available in this system in priority + * order. If the heap type is supported by the client, and matches the + * request of the caller allocate from it. Repeat until allocate has + * succeeded or all heaps have been tried + */ + len = PAGE_ALIGN(len); + + if (!len) + return ERR_PTR(-EINVAL); + + down_read(&dev->lock); + plist_for_each_entry(heap, &dev->heaps, node) { + /* if the caller didn't specify this heap id */ + if (!((1 << heap->id) & heap_id_mask)) + continue; + buffer = ion_buffer_create(heap, dev, len, align, flags); + if (!IS_ERR(buffer)) + break; + } + up_read(&dev->lock); + + if (buffer == NULL) + return ERR_PTR(-ENODEV); + + if (IS_ERR(buffer)) + return ERR_PTR(PTR_ERR(buffer)); + + handle = ion_handle_create(client, buffer); + + /* + * ion_buffer_create will create a buffer with a ref_cnt of 1, + * and ion_handle_create will take a second reference, drop one here + */ + ion_buffer_put(buffer); + + if (IS_ERR(handle)) + return handle; + + mutex_lock(&client->lock); + ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); + if (ret) { + ion_handle_put(handle); + handle = ERR_PTR(ret); + } + + return handle; +} +EXPORT_SYMBOL(ion_alloc); + +void ion_free(struct ion_client *client, struct ion_handle *handle) +{ + bool valid_handle; + + BUG_ON(client != handle->client); + + mutex_lock(&client->lock); + valid_handle = ion_handle_validate(client, handle); + + if (!valid_handle) { + WARN(1, "%s: invalid handle passed to free.\n", __func__); + mutex_unlock(&client->lock); + return; + } + mutex_unlock(&client->lock); + ion_handle_put(handle); +} +EXPORT_SYMBOL(ion_free); + +int ion_phys(struct ion_client *client, struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len) +{ + struct ion_buffer *buffer; + int ret; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + mutex_unlock(&client->lock); + return -EINVAL; + } + + buffer = handle->buffer; + + if (!buffer->heap->ops->phys) { + pr_err("%s: ion_phys is not implemented by this heap.\n", + __func__); + mutex_unlock(&client->lock); + return -ENODEV; + } + mutex_unlock(&client->lock); + ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len); + return ret; +} +EXPORT_SYMBOL(ion_phys); + +static void *ion_buffer_kmap_get(struct ion_buffer *buffer) +{ + void *vaddr; + + if (buffer->kmap_cnt) { + buffer->kmap_cnt++; + return buffer->vaddr; + } + vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); + if (WARN_ONCE(vaddr == NULL, + "heap->ops->map_kernel should return ERR_PTR on error")) + return ERR_PTR(-EINVAL); + if (IS_ERR(vaddr)) + return vaddr; + buffer->vaddr = vaddr; + buffer->kmap_cnt++; + return vaddr; +} + +static void *ion_handle_kmap_get(struct ion_handle *handle) +{ + struct ion_buffer *buffer = handle->buffer; + void *vaddr; + + if (handle->kmap_cnt) { + handle->kmap_cnt++; + return buffer->vaddr; + } + vaddr = ion_buffer_kmap_get(buffer); + if (IS_ERR(vaddr)) + return vaddr; + handle->kmap_cnt++; + return vaddr; +} + +static void ion_buffer_kmap_put(struct ion_buffer *buffer) +{ + buffer->kmap_cnt--; + if (!buffer->kmap_cnt) { + buffer->heap->ops->unmap_kernel(buffer->heap, buffer); + buffer->vaddr = NULL; + } +} + +static void ion_handle_kmap_put(struct ion_handle *handle) +{ + struct ion_buffer *buffer = handle->buffer; + + handle->kmap_cnt--; + if (!handle->kmap_cnt) + ion_buffer_kmap_put(buffer); +} + +void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle) +{ + struct ion_buffer *buffer; + void *vaddr; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + pr_err("%s: invalid handle passed to map_kernel.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + + buffer = handle->buffer; + + if (!handle->buffer->heap->ops->map_kernel) { + pr_err("%s: map_kernel is not implemented by this heap.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-ENODEV); + } + + mutex_lock(&buffer->lock); + vaddr = ion_handle_kmap_get(handle); + mutex_unlock(&buffer->lock); + mutex_unlock(&client->lock); + return vaddr; +} +EXPORT_SYMBOL(ion_map_kernel); + +void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle) +{ + struct ion_buffer *buffer; + + mutex_lock(&client->lock); + buffer = handle->buffer; + mutex_lock(&buffer->lock); + ion_handle_kmap_put(handle); + mutex_unlock(&buffer->lock); + mutex_unlock(&client->lock); +} +EXPORT_SYMBOL(ion_unmap_kernel); + +static int ion_debug_client_show(struct seq_file *s, void *unused) +{ + struct ion_client *client = s->private; + struct rb_node *n; + size_t sizes[ION_NUM_HEAP_IDS] = {0}; + const char *names[ION_NUM_HEAP_IDS] = {NULL}; + int i; + + mutex_lock(&client->lock); + for (n = rb_first(&client->handles); n; n = rb_next(n)) { + struct ion_handle *handle = rb_entry(n, struct ion_handle, + node); + unsigned int id = handle->buffer->heap->id; + + if (!names[id]) + names[id] = handle->buffer->heap->name; + sizes[id] += handle->buffer->size; + } + mutex_unlock(&client->lock); + + seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes"); + for (i = 0; i < ION_NUM_HEAP_IDS; i++) { + if (!names[i]) + continue; + seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]); + } + return 0; +} + +static int ion_debug_client_open(struct inode *inode, struct file *file) +{ + return single_open(file, ion_debug_client_show, inode->i_private); +} + +static const struct file_operations debug_client_fops = { + .open = ion_debug_client_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +struct ion_client *ion_client_create(struct ion_device *dev, + const char *name) +{ + struct ion_client *client; + struct task_struct *task; + struct rb_node **p; + struct rb_node *parent = NULL; + struct ion_client *entry; + char debug_name[64]; + pid_t pid; + + get_task_struct(current->group_leader); + task_lock(current->group_leader); + pid = task_pid_nr(current->group_leader); + /* don't bother to store task struct for kernel threads, + they can't be killed anyway */ + if (current->group_leader->flags & PF_KTHREAD) { + put_task_struct(current->group_leader); + task = NULL; + } else { + task = current->group_leader; + } + task_unlock(current->group_leader); + + client = kzalloc(sizeof(struct ion_client), GFP_KERNEL); + if (!client) { + if (task) + put_task_struct(current->group_leader); + return ERR_PTR(-ENOMEM); + } + + client->dev = dev; + client->handles = RB_ROOT; + idr_init(&client->idr); + mutex_init(&client->lock); + client->name = name; + client->task = task; + client->pid = pid; + + down_write(&dev->lock); + p = &dev->clients.rb_node; + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_client, node); + + if (client < entry) + p = &(*p)->rb_left; + else if (client > entry) + p = &(*p)->rb_right; + } + rb_link_node(&client->node, parent, p); + rb_insert_color(&client->node, &dev->clients); + + snprintf(debug_name, 64, "%u", client->pid); + client->debug_root = debugfs_create_file(debug_name, 0664, + dev->debug_root, client, + &debug_client_fops); + up_write(&dev->lock); + + return client; +} +EXPORT_SYMBOL(ion_client_create); + +void ion_client_destroy(struct ion_client *client) +{ + struct ion_device *dev = client->dev; + struct rb_node *n; + + pr_debug("%s: %d\n", __func__, __LINE__); + while ((n = rb_first(&client->handles))) { + struct ion_handle *handle = rb_entry(n, struct ion_handle, + node); + ion_handle_destroy(&handle->ref); + } + + idr_destroy(&client->idr); + + down_write(&dev->lock); + if (client->task) + put_task_struct(client->task); + rb_erase(&client->node, &dev->clients); + debugfs_remove_recursive(client->debug_root); + up_write(&dev->lock); + + kfree(client); +} +EXPORT_SYMBOL(ion_client_destroy); + +struct sg_table *ion_sg_table(struct ion_client *client, + struct ion_handle *handle) +{ + struct ion_buffer *buffer; + struct sg_table *table; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + pr_err("%s: invalid handle passed to map_dma.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + buffer = handle->buffer; + table = buffer->sg_table; + mutex_unlock(&client->lock); + return table; +} +EXPORT_SYMBOL(ion_sg_table); + +static void ion_buffer_sync_for_device(struct ion_buffer *buffer, + struct device *dev, + enum dma_data_direction direction); + +static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct dma_buf *dmabuf = attachment->dmabuf; + struct ion_buffer *buffer = dmabuf->priv; + + ion_buffer_sync_for_device(buffer, attachment->dev, direction); + return buffer->sg_table; +} + +static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ +} + +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + /* + * This is not correct - sg_dma_address needs a dma_addr_t that is valid + * for the the targeted device, but this works on the currently targeted + * hardware. + */ + sg_dma_address(&sg) = page_to_phys(page); + dma_sync_sg_for_device(dev, &sg, 1, dir); +} + +struct ion_vma_list { + struct list_head list; + struct vm_area_struct *vma; +}; + +static void ion_buffer_sync_for_device(struct ion_buffer *buffer, + struct device *dev, + enum dma_data_direction dir) +{ + struct ion_vma_list *vma_list; + int pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + int i; + + pr_debug("%s: syncing for device %s\n", __func__, + dev ? dev_name(dev) : "null"); + + if (!ion_buffer_fault_user_mappings(buffer)) + return; + + mutex_lock(&buffer->lock); + for (i = 0; i < pages; i++) { + struct page *page = buffer->pages[i]; + + if (ion_buffer_page_is_dirty(page)) + ion_pages_sync_for_device(dev, ion_buffer_page(page), + PAGE_SIZE, dir); + + ion_buffer_page_clean(buffer->pages + i); + } + list_for_each_entry(vma_list, &buffer->vmas, list) { + struct vm_area_struct *vma = vma_list->vma; + + zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, + NULL); + } + mutex_unlock(&buffer->lock); +} + +static int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct ion_buffer *buffer = vma->vm_private_data; + unsigned long pfn; + int ret; + + mutex_lock(&buffer->lock); + ion_buffer_page_dirty(buffer->pages + vmf->pgoff); + BUG_ON(!buffer->pages || !buffer->pages[vmf->pgoff]); + + pfn = page_to_pfn(ion_buffer_page(buffer->pages[vmf->pgoff])); + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); + mutex_unlock(&buffer->lock); + if (ret) + return VM_FAULT_ERROR; + + return VM_FAULT_NOPAGE; +} + +static void ion_vm_open(struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = vma->vm_private_data; + struct ion_vma_list *vma_list; + + vma_list = kmalloc(sizeof(struct ion_vma_list), GFP_KERNEL); + if (!vma_list) + return; + vma_list->vma = vma; + mutex_lock(&buffer->lock); + list_add(&vma_list->list, &buffer->vmas); + mutex_unlock(&buffer->lock); + pr_debug("%s: adding %p\n", __func__, vma); +} + +static void ion_vm_close(struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = vma->vm_private_data; + struct ion_vma_list *vma_list, *tmp; + + pr_debug("%s\n", __func__); + mutex_lock(&buffer->lock); + list_for_each_entry_safe(vma_list, tmp, &buffer->vmas, list) { + if (vma_list->vma != vma) + continue; + list_del(&vma_list->list); + kfree(vma_list); + pr_debug("%s: deleting %p\n", __func__, vma); + break; + } + mutex_unlock(&buffer->lock); +} + +static struct vm_operations_struct ion_vma_ops = { + .open = ion_vm_open, + .close = ion_vm_close, + .fault = ion_vm_fault, +}; + +static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = dmabuf->priv; + int ret = 0; + + if (!buffer->heap->ops->map_user) { + pr_err("%s: this heap does not define a method for mapping " + "to userspace\n", __func__); + return -EINVAL; + } + + if (ion_buffer_fault_user_mappings(buffer)) { + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | + VM_DONTDUMP; + vma->vm_private_data = buffer; + vma->vm_ops = &ion_vma_ops; + ion_vm_open(vma); + return 0; + } + + if (!(buffer->flags & ION_FLAG_CACHED)) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + mutex_lock(&buffer->lock); + /* now map it to userspace */ + ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); + mutex_unlock(&buffer->lock); + + if (ret) + pr_err("%s: failure mapping buffer to userspace\n", + __func__); + + return ret; +} + +static void ion_dma_buf_release(struct dma_buf *dmabuf) +{ + struct ion_buffer *buffer = dmabuf->priv; + ion_buffer_put(buffer); +} + +static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) +{ + struct ion_buffer *buffer = dmabuf->priv; + return buffer->vaddr + offset * PAGE_SIZE; +} + +static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, + void *ptr) +{ + return; +} + +static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, + size_t len, + enum dma_data_direction direction) +{ + struct ion_buffer *buffer = dmabuf->priv; + void *vaddr; + + if (!buffer->heap->ops->map_kernel) { + pr_err("%s: map kernel is not implemented by this heap.\n", + __func__); + return -ENODEV; + } + + mutex_lock(&buffer->lock); + vaddr = ion_buffer_kmap_get(buffer); + mutex_unlock(&buffer->lock); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + return 0; +} + +static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, + size_t len, + enum dma_data_direction direction) +{ + struct ion_buffer *buffer = dmabuf->priv; + + mutex_lock(&buffer->lock); + ion_buffer_kmap_put(buffer); + mutex_unlock(&buffer->lock); +} + +static struct dma_buf_ops dma_buf_ops = { + .map_dma_buf = ion_map_dma_buf, + .unmap_dma_buf = ion_unmap_dma_buf, + .mmap = ion_mmap, + .release = ion_dma_buf_release, + .begin_cpu_access = ion_dma_buf_begin_cpu_access, + .end_cpu_access = ion_dma_buf_end_cpu_access, + .kmap_atomic = ion_dma_buf_kmap, + .kunmap_atomic = ion_dma_buf_kunmap, + .kmap = ion_dma_buf_kmap, + .kunmap = ion_dma_buf_kunmap, +}; + +struct dma_buf *ion_share_dma_buf(struct ion_client *client, + struct ion_handle *handle) +{ + struct ion_buffer *buffer; + struct dma_buf *dmabuf; + bool valid_handle; + + mutex_lock(&client->lock); + valid_handle = ion_handle_validate(client, handle); + if (!valid_handle) { + WARN(1, "%s: invalid handle passed to share.\n", __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + buffer = handle->buffer; + ion_buffer_get(buffer); + mutex_unlock(&client->lock); + + dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR); + if (IS_ERR(dmabuf)) { + ion_buffer_put(buffer); + return dmabuf; + } + + return dmabuf; +} +EXPORT_SYMBOL(ion_share_dma_buf); + +int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle) +{ + struct dma_buf *dmabuf; + int fd; + + dmabuf = ion_share_dma_buf(client, handle); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + fd = dma_buf_fd(dmabuf, O_CLOEXEC); + if (fd < 0) + dma_buf_put(dmabuf); + + return fd; +} +EXPORT_SYMBOL(ion_share_dma_buf_fd); + +struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + struct ion_handle *handle; + int ret; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return ERR_PTR(PTR_ERR(dmabuf)); + /* if this memory came from ion */ + + if (dmabuf->ops != &dma_buf_ops) { + pr_err("%s: can not import dmabuf from another exporter\n", + __func__); + dma_buf_put(dmabuf); + return ERR_PTR(-EINVAL); + } + buffer = dmabuf->priv; + + mutex_lock(&client->lock); + /* if a handle exists for this buffer just take a reference to it */ + handle = ion_handle_lookup(client, buffer); + if (!IS_ERR(handle)) { + ion_handle_get(handle); + mutex_unlock(&client->lock); + goto end; + } + mutex_unlock(&client->lock); + + handle = ion_handle_create(client, buffer); + if (IS_ERR(handle)) + goto end; + + mutex_lock(&client->lock); + ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); + if (ret) { + ion_handle_put(handle); + handle = ERR_PTR(ret); + } + +end: + dma_buf_put(dmabuf); + return handle; +} +EXPORT_SYMBOL(ion_import_dma_buf); + +static int ion_sync_for_device(struct ion_client *client, int fd) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + /* if this memory came from ion */ + if (dmabuf->ops != &dma_buf_ops) { + pr_err("%s: can not sync dmabuf from another exporter\n", + __func__); + dma_buf_put(dmabuf); + return -EINVAL; + } + buffer = dmabuf->priv; + + dma_sync_sg_for_device(NULL, buffer->sg_table->sgl, + buffer->sg_table->nents, DMA_BIDIRECTIONAL); + dma_buf_put(dmabuf); + return 0; +} + +/* fix up the cases where the ioctl direction bits are incorrect */ +static unsigned int ion_ioctl_dir(unsigned int cmd) +{ + switch (cmd) { + case ION_IOC_SYNC: + case ION_IOC_FREE: + case ION_IOC_CUSTOM: + return _IOC_WRITE; + default: + return _IOC_DIR(cmd); + } +} + +static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct ion_client *client = filp->private_data; + struct ion_device *dev = client->dev; + struct ion_handle *cleanup_handle = NULL; + int ret = 0; + unsigned int dir; + + union { + struct ion_fd_data fd; + struct ion_allocation_data allocation; + struct ion_handle_data handle; + struct ion_custom_data custom; + } data; + + dir = ion_ioctl_dir(cmd); + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (dir & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + switch (cmd) { + case ION_IOC_ALLOC: + { + struct ion_handle *handle; + + handle = ion_alloc(client, data.allocation.len, + data.allocation.align, + data.allocation.heap_id_mask, + data.allocation.flags); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + data.allocation.handle = handle->id; + + cleanup_handle = handle; + break; + } + case ION_IOC_FREE: + { + struct ion_handle *handle; + + handle = ion_handle_get_by_id(client, data.handle.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ion_free(client, handle); + ion_handle_put(handle); + break; + } + case ION_IOC_SHARE: + case ION_IOC_MAP: + { + struct ion_handle *handle; + + handle = ion_handle_get_by_id(client, data.handle.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); + data.fd.fd = ion_share_dma_buf_fd(client, handle); + ion_handle_put(handle); + if (data.fd.fd < 0) + ret = data.fd.fd; + break; + } + case ION_IOC_IMPORT: + { + struct ion_handle *handle; + handle = ion_import_dma_buf(client, data.fd.fd); + if (IS_ERR(handle)) + ret = PTR_ERR(handle); + else + data.handle.handle = handle->id; + break; + } + case ION_IOC_SYNC: + { + ret = ion_sync_for_device(client, data.fd.fd); + break; + } + case ION_IOC_CUSTOM: + { + if (!dev->custom_ioctl) + return -ENOTTY; + ret = dev->custom_ioctl(client, data.custom.cmd, + data.custom.arg); + break; + } + default: + return -ENOTTY; + } + + if (dir & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { + if (cleanup_handle) + ion_free(client, cleanup_handle); + return -EFAULT; + } + } + return ret; +} + +static int ion_release(struct inode *inode, struct file *file) +{ + struct ion_client *client = file->private_data; + + pr_debug("%s: %d\n", __func__, __LINE__); + ion_client_destroy(client); + return 0; +} + +static int ion_open(struct inode *inode, struct file *file) +{ + struct miscdevice *miscdev = file->private_data; + struct ion_device *dev = container_of(miscdev, struct ion_device, dev); + struct ion_client *client; + + pr_debug("%s: %d\n", __func__, __LINE__); + client = ion_client_create(dev, "user"); + if (IS_ERR(client)) + return PTR_ERR(client); + file->private_data = client; + + return 0; +} + +static const struct file_operations ion_fops = { + .owner = THIS_MODULE, + .open = ion_open, + .release = ion_release, + .unlocked_ioctl = ion_ioctl, + .compat_ioctl = compat_ion_ioctl, +}; + +static size_t ion_debug_heap_total(struct ion_client *client, + unsigned int id) +{ + size_t size = 0; + struct rb_node *n; + + mutex_lock(&client->lock); + for (n = rb_first(&client->handles); n; n = rb_next(n)) { + struct ion_handle *handle = rb_entry(n, + struct ion_handle, + node); + if (handle->buffer->heap->id == id) + size += handle->buffer->size; + } + mutex_unlock(&client->lock); + return size; +} + +static int ion_debug_heap_show(struct seq_file *s, void *unused) +{ + struct ion_heap *heap = s->private; + struct ion_device *dev = heap->dev; + struct rb_node *n; + size_t total_size = 0; + size_t total_orphaned_size = 0; + + seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size"); + seq_printf(s, "----------------------------------------------------\n"); + + for (n = rb_first(&dev->clients); n; n = rb_next(n)) { + struct ion_client *client = rb_entry(n, struct ion_client, + node); + size_t size = ion_debug_heap_total(client, heap->id); + if (!size) + continue; + if (client->task) { + char task_comm[TASK_COMM_LEN]; + + get_task_comm(task_comm, client->task); + seq_printf(s, "%16.s %16u %16zu\n", task_comm, + client->pid, size); + } else { + seq_printf(s, "%16.s %16u %16zu\n", client->name, + client->pid, size); + } + } + seq_printf(s, "----------------------------------------------------\n"); + seq_printf(s, "orphaned allocations (info is from last known client):" + "\n"); + mutex_lock(&dev->buffer_lock); + for (n = rb_first(&dev->buffers); n; n = rb_next(n)) { + struct ion_buffer *buffer = rb_entry(n, struct ion_buffer, + node); + if (buffer->heap->id != heap->id) + continue; + total_size += buffer->size; + if (!buffer->handle_count) { + seq_printf(s, "%16.s %16u %16zu %d %d\n", + buffer->task_comm, buffer->pid, + buffer->size, buffer->kmap_cnt, + atomic_read(&buffer->ref.refcount)); + total_orphaned_size += buffer->size; + } + } + mutex_unlock(&dev->buffer_lock); + seq_printf(s, "----------------------------------------------------\n"); + seq_printf(s, "%16.s %16zu\n", "total orphaned", + total_orphaned_size); + seq_printf(s, "%16.s %16zu\n", "total ", total_size); + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + seq_printf(s, "%16.s %16zu\n", "deferred free", + heap->free_list_size); + seq_printf(s, "----------------------------------------------------\n"); + + if (heap->debug_show) + heap->debug_show(heap, s, unused); + + return 0; +} + +static int ion_debug_heap_open(struct inode *inode, struct file *file) +{ + return single_open(file, ion_debug_heap_show, inode->i_private); +} + +static const struct file_operations debug_heap_fops = { + .open = ion_debug_heap_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +#ifdef DEBUG_HEAP_SHRINKER +static int debug_shrink_set(void *data, u64 val) +{ + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + if (!val) + return 0; + + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + sc.nr_to_scan = objs; + + heap->shrinker.shrink(&heap->shrinker, &sc); + return 0; +} + +static int debug_shrink_get(void *data, u64 *val) +{ + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + *val = objs; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, + debug_shrink_set, "%llu\n"); +#endif + +void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) +{ + if (!heap->ops->allocate || !heap->ops->free || !heap->ops->map_dma || + !heap->ops->unmap_dma) + pr_err("%s: can not add heap with invalid ops struct.\n", + __func__); + + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + ion_heap_init_deferred_free(heap); + + heap->dev = dev; + down_write(&dev->lock); + /* use negative heap->id to reverse the priority -- when traversing + the list later attempt higher id numbers first */ + plist_node_init(&heap->node, -heap->id); + plist_add(&heap->node, &dev->heaps); + debugfs_create_file(heap->name, 0664, dev->debug_root, heap, + &debug_heap_fops); +#ifdef DEBUG_HEAP_SHRINKER + if (heap->shrinker.shrink) { + char debug_name[64]; + + snprintf(debug_name, 64, "%s_shrink", heap->name); + debugfs_create_file(debug_name, 0644, dev->debug_root, heap, + &debug_shrink_fops); + } +#endif + up_write(&dev->lock); +} + +struct ion_device *ion_device_create(long (*custom_ioctl) + (struct ion_client *client, + unsigned int cmd, + unsigned long arg)) +{ + struct ion_device *idev; + int ret; + + idev = kzalloc(sizeof(struct ion_device), GFP_KERNEL); + if (!idev) + return ERR_PTR(-ENOMEM); + + idev->dev.minor = MISC_DYNAMIC_MINOR; + idev->dev.name = "ion"; + idev->dev.fops = &ion_fops; + idev->dev.parent = NULL; + ret = misc_register(&idev->dev); + if (ret) { + pr_err("ion: failed to register misc device.\n"); + return ERR_PTR(ret); + } + + idev->debug_root = debugfs_create_dir("ion", NULL); + if (!idev->debug_root) + pr_err("ion: failed to create debug files.\n"); + + idev->custom_ioctl = custom_ioctl; + idev->buffers = RB_ROOT; + mutex_init(&idev->buffer_lock); + init_rwsem(&idev->lock); + plist_head_init(&idev->heaps); + idev->clients = RB_ROOT; + return idev; +} + +void ion_device_destroy(struct ion_device *dev) +{ + misc_deregister(&dev->dev); + /* XXX need to free the heaps and clients ? */ + kfree(dev); +} + +void __init ion_reserve(struct ion_platform_data *data) +{ + int i; + + for (i = 0; i < data->nr; i++) { + if (data->heaps[i].size == 0) + continue; + + if (data->heaps[i].base == 0) { + phys_addr_t paddr; + paddr = memblock_alloc_base(data->heaps[i].size, + data->heaps[i].align, + MEMBLOCK_ALLOC_ANYWHERE); + if (!paddr) { + pr_err("%s: error allocating memblock for " + "heap %d\n", + __func__, i); + continue; + } + data->heaps[i].base = paddr; + } else { + int ret = memblock_reserve(data->heaps[i].base, + data->heaps[i].size); + if (ret) + pr_err("memblock reserve of %zx@%lx failed\n", + data->heaps[i].size, + data->heaps[i].base); + } + pr_info("%s: %s reserved base %lx size %zu\n", __func__, + data->heaps[i].name, + data->heaps[i].base, + data->heaps[i].size); + } +} diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h new file mode 100644 index 000000000000..dcd2a0cdb192 --- /dev/null +++ b/drivers/staging/android/ion/ion.h @@ -0,0 +1,204 @@ +/* + * drivers/staging/android/ion/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_ION_H +#define _LINUX_ION_H + +#include <linux/types.h> + +#include "../uapi/ion.h" + +struct ion_handle; +struct ion_device; +struct ion_heap; +struct ion_mapper; +struct ion_client; +struct ion_buffer; + +/* This should be removed some day when phys_addr_t's are fully + plumbed in the kernel, and all instances of ion_phys_addr_t should + be converted to phys_addr_t. For the time being many kernel interfaces + do not accept phys_addr_t's that would have to */ +#define ion_phys_addr_t unsigned long + +/** + * struct ion_platform_heap - defines a heap in the given platform + * @type: type of the heap from ion_heap_type enum + * @id: unique identifier for heap. When allocating higher numbers + * will be allocated from first. At allocation these are passed + * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. + * @name: used for debug purposes + * @base: base address of heap in physical memory if applicable + * @size: size of the heap in bytes if applicable + * @align: required alignment in physical memory if applicable + * @priv: private info passed from the board file + * + * Provided by the board file. + */ +struct ion_platform_heap { + enum ion_heap_type type; + unsigned int id; + const char *name; + ion_phys_addr_t base; + size_t size; + ion_phys_addr_t align; + void *priv; +}; + +/** + * struct ion_platform_data - array of platform heaps passed from board file + * @nr: number of structures in the array + * @heaps: array of platform_heap structions + * + * Provided by the board file in the form of platform data to a platform device. + */ +struct ion_platform_data { + int nr; + struct ion_platform_heap *heaps; +}; + +/** + * ion_reserve() - reserve memory for ion heaps if applicable + * @data: platform data specifying starting physical address and + * size + * + * Calls memblock reserve to set aside memory for heaps that are + * located at specific memory addresses or of specfic sizes not + * managed by the kernel + */ +void ion_reserve(struct ion_platform_data *data); + +/** + * ion_client_create() - allocate a client and returns it + * @dev: the global ion device + * @heap_type_mask: mask of heaps this client can allocate from + * @name: used for debugging + */ +struct ion_client *ion_client_create(struct ion_device *dev, + const char *name); + +/** + * ion_client_destroy() - free's a client and all it's handles + * @client: the client + * + * Free the provided client and all it's resources including + * any handles it is holding. + */ +void ion_client_destroy(struct ion_client *client); + +/** + * ion_alloc - allocate ion memory + * @client: the client + * @len: size of the allocation + * @align: requested allocation alignment, lots of hardware blocks + * have alignment requirements of some kind + * @heap_id_mask: mask of heaps to allocate from, if multiple bits are set + * heaps will be tried in order from highest to lowest + * id + * @flags: heap flags, the low 16 bits are consumed by ion, the + * high 16 bits are passed on to the respective heap and + * can be heap custom + * + * Allocate memory in one of the heaps provided in heap mask and return + * an opaque handle to it. + */ +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags); + +/** + * ion_free - free a handle + * @client: the client + * @handle: the handle to free + * + * Free the provided handle. + */ +void ion_free(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_phys - returns the physical address and len of a handle + * @client: the client + * @handle: the handle + * @addr: a pointer to put the address in + * @len: a pointer to put the length in + * + * This function queries the heap for a particular handle to get the + * handle's physical address. It't output is only correct if + * a heap returns physically contiguous memory -- in other cases + * this api should not be implemented -- ion_sg_table should be used + * instead. Returns -EINVAL if the handle is invalid. This has + * no implications on the reference counting of the handle -- + * the returned value may not be valid if the caller is not + * holding a reference. + */ +int ion_phys(struct ion_client *client, struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len); + +/** + * ion_map_dma - return an sg_table describing a handle + * @client: the client + * @handle: the handle + * + * This function returns the sg_table describing + * a particular ion handle. + */ +struct sg_table *ion_sg_table(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_map_kernel - create mapping for the given handle + * @client: the client + * @handle: handle to map + * + * Map the given handle into the kernel and return a kernel address that + * can be used to access this address. + */ +void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_unmap_kernel() - destroy a kernel mapping for a handle + * @client: the client + * @handle: handle to unmap + */ +void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_share_dma_buf() - share buffer as dma-buf + * @client: the client + * @handle: the handle + */ +struct dma_buf *ion_share_dma_buf(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd + * @client: the client + * @handle: the handle + */ +int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle + * @client: the client + * @fd: the dma-buf fd + * + * Given an dma-buf fd that was allocated through ion via ion_share_dma_buf, + * import that fd and return a handle representing it. If a dma-buf from + * another exporter is passed in this function will return ERR_PTR(-EINVAL) + */ +struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd); + +#endif /* _LINUX_ION_H */ diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c new file mode 100644 index 000000000000..3cb05b9b0e93 --- /dev/null +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -0,0 +1,194 @@ +/* + * drivers/staging/android/ion/ion_carveout_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include <linux/spinlock.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/genalloc.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include "ion.h" +#include "ion_priv.h" + +struct ion_carveout_heap { + struct ion_heap heap; + struct gen_pool *pool; + ion_phys_addr_t base; +}; + +ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, + unsigned long size, + unsigned long align) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + unsigned long offset = gen_pool_alloc(carveout_heap->pool, size); + + if (!offset) + return ION_CARVEOUT_ALLOCATE_FAIL; + + return offset; +} + +void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, + unsigned long size) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + + if (addr == ION_CARVEOUT_ALLOCATE_FAIL) + return; + gen_pool_free(carveout_heap->pool, addr, size); +} + +static int ion_carveout_heap_phys(struct ion_heap *heap, + struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); + + *addr = paddr; + *len = buffer->size; + return 0; +} + +static int ion_carveout_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct sg_table *table; + ion_phys_addr_t paddr; + int ret; + + if (align > PAGE_SIZE) + return -EINVAL; + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto err_free; + + paddr = ion_carveout_allocate(heap, size, align); + if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) { + ret = -ENOMEM; + goto err_free_table; + } + + sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0); + buffer->priv_virt = table; + + return 0; + +err_free_table: + sg_free_table(table); +err_free: + kfree(table); + return ret; +} + +static void ion_carveout_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); + + ion_heap_buffer_zero(buffer); + + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + + ion_carveout_free(heap, paddr, buffer->size); + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops carveout_heap_ops = { + .allocate = ion_carveout_heap_allocate, + .free = ion_carveout_heap_free, + .phys = ion_carveout_heap_phys, + .map_dma = ion_carveout_heap_map_dma, + .unmap_dma = ion_carveout_heap_unmap_dma, + .map_user = ion_heap_map_user, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, +}; + +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_carveout_heap *carveout_heap; + int ret; + + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); + + carveout_heap = kzalloc(sizeof(struct ion_carveout_heap), GFP_KERNEL); + if (!carveout_heap) + return ERR_PTR(-ENOMEM); + + carveout_heap->pool = gen_pool_create(12, -1); + if (!carveout_heap->pool) { + kfree(carveout_heap); + return ERR_PTR(-ENOMEM); + } + carveout_heap->base = heap_data->base; + gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, + -1); + carveout_heap->heap.ops = &carveout_heap_ops; + carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; + carveout_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + + return &carveout_heap->heap; +} + +void ion_carveout_heap_destroy(struct ion_heap *heap) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + + gen_pool_destroy(carveout_heap->pool); + kfree(carveout_heap); + carveout_heap = NULL; +} diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c new file mode 100644 index 000000000000..d40f5f831808 --- /dev/null +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -0,0 +1,195 @@ +/* + * drivers/staging/android/ion/ion_chunk_heap.c + * + * Copyright (C) 2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/genalloc.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include "ion.h" +#include "ion_priv.h" + +struct ion_chunk_heap { + struct ion_heap heap; + struct gen_pool *pool; + ion_phys_addr_t base; + unsigned long chunk_size; + unsigned long size; + unsigned long allocated; +}; + +static int ion_chunk_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + struct sg_table *table; + struct scatterlist *sg; + int ret, i; + unsigned long num_chunks; + unsigned long allocated_size; + + if (align > chunk_heap->chunk_size) + return -EINVAL; + + allocated_size = ALIGN(size, chunk_heap->chunk_size); + num_chunks = allocated_size / chunk_heap->chunk_size; + + if (allocated_size > chunk_heap->size - chunk_heap->allocated) + return -ENOMEM; + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + ret = sg_alloc_table(table, num_chunks, GFP_KERNEL); + if (ret) { + kfree(table); + return ret; + } + + sg = table->sgl; + for (i = 0; i < num_chunks; i++) { + unsigned long paddr = gen_pool_alloc(chunk_heap->pool, + chunk_heap->chunk_size); + if (!paddr) + goto err; + sg_set_page(sg, pfn_to_page(PFN_DOWN(paddr)), + chunk_heap->chunk_size, 0); + sg = sg_next(sg); + } + + buffer->priv_virt = table; + chunk_heap->allocated += allocated_size; + return 0; +err: + sg = table->sgl; + for (i -= 1; i >= 0; i--) { + gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), + sg->length); + sg = sg_next(sg); + } + sg_free_table(table); + kfree(table); + return -ENOMEM; +} + +static void ion_chunk_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + struct sg_table *table = buffer->priv_virt; + struct scatterlist *sg; + int i; + unsigned long allocated_size; + + allocated_size = ALIGN(buffer->size, chunk_heap->chunk_size); + + ion_heap_buffer_zero(buffer); + + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + + for_each_sg(table->sgl, sg, table->nents, i) { + gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), + sg->length); + } + chunk_heap->allocated -= allocated_size; + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_chunk_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops chunk_heap_ops = { + .allocate = ion_chunk_heap_allocate, + .free = ion_chunk_heap_free, + .map_dma = ion_chunk_heap_map_dma, + .unmap_dma = ion_chunk_heap_unmap_dma, + .map_user = ion_heap_map_user, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, +}; + +struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_chunk_heap *chunk_heap; + int ret; + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); + + chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL); + if (!chunk_heap) + return ERR_PTR(-ENOMEM); + + chunk_heap->chunk_size = (unsigned long)heap_data->priv; + chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) + + PAGE_SHIFT, -1); + if (!chunk_heap->pool) { + ret = -ENOMEM; + goto error_gen_pool_create; + } + chunk_heap->base = heap_data->base; + chunk_heap->size = heap_data->size; + chunk_heap->allocated = 0; + + gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); + chunk_heap->heap.ops = &chunk_heap_ops; + chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; + chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + pr_info("%s: base %lu size %zu align %ld\n", __func__, chunk_heap->base, + heap_data->size, heap_data->align); + + return &chunk_heap->heap; + +error_gen_pool_create: + kfree(chunk_heap); + return ERR_PTR(ret); +} + +void ion_chunk_heap_destroy(struct ion_heap *heap) +{ + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + + gen_pool_destroy(chunk_heap->pool); + kfree(chunk_heap); + chunk_heap = NULL; +} diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c new file mode 100644 index 000000000000..f0f98897e4b9 --- /dev/null +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -0,0 +1,218 @@ +/* + * drivers/staging/android/ion/ion_cma_heap.c + * + * Copyright (C) Linaro 2012 + * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/dma-mapping.h> + +#include "ion.h" +#include "ion_priv.h" + +#define ION_CMA_ALLOCATE_FAILED -1 + +struct ion_cma_heap { + struct ion_heap heap; + struct device *dev; +}; + +#define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap) + +struct ion_cma_buffer_info { + void *cpu_addr; + dma_addr_t handle; + struct sg_table *table; +}; + +/* + * Create scatter-list for the already allocated DMA buffer. + * This function could be replaced by dma_common_get_sgtable + * as soon as it will avalaible. + */ +static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt, + void *cpu_addr, dma_addr_t handle, size_t size) +{ + struct page *page = virt_to_page(cpu_addr); + int ret; + + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (unlikely(ret)) + return ret; + + sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); + return 0; +} + +/* ION CMA heap operations functions */ +static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, + unsigned long len, unsigned long align, + unsigned long flags) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info; + + dev_dbg(dev, "Request buffer allocation len %ld\n", len); + + if (buffer->flags & ION_FLAG_CACHED) + return -EINVAL; + + if (align > PAGE_SIZE) + return -EINVAL; + + info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL); + if (!info) { + dev_err(dev, "Can't allocate buffer info\n"); + return ION_CMA_ALLOCATE_FAILED; + } + + info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), + GFP_HIGHUSER | __GFP_ZERO); + + if (!info->cpu_addr) { + dev_err(dev, "Fail to allocate buffer\n"); + goto err; + } + + info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!info->table) { + dev_err(dev, "Fail to allocate sg table\n"); + goto free_mem; + } + + if (ion_cma_get_sgtable + (dev, info->table, info->cpu_addr, info->handle, len)) + goto free_table; + /* keep this for memory release */ + buffer->priv_virt = info; + dev_dbg(dev, "Allocate buffer %p\n", buffer); + return 0; + +free_table: + kfree(info->table); +free_mem: + dma_free_coherent(dev, len, info->cpu_addr, info->handle); +err: + kfree(info); + return ION_CMA_ALLOCATE_FAILED; +} + +static void ion_cma_free(struct ion_buffer *buffer) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + dev_dbg(dev, "Release buffer %p\n", buffer); + /* release memory */ + dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle); + /* release sg table */ + sg_free_table(info->table); + kfree(info->table); + kfree(info); +} + +/* return physical address in addr */ +static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer, + &info->handle); + + *addr = info->handle; + *len = buffer->size; + + return 0; +} + +static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct ion_cma_buffer_info *info = buffer->priv_virt; + + return info->table; +} + +static void ion_cma_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer, + struct vm_area_struct *vma) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + return dma_mmap_coherent(dev, vma, info->cpu_addr, info->handle, + buffer->size); +} + +static void *ion_cma_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct ion_cma_buffer_info *info = buffer->priv_virt; + /* kernel memory mapping has been done at allocation time */ + return info->cpu_addr; +} + +static void ion_cma_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ +} + +static struct ion_heap_ops ion_cma_ops = { + .allocate = ion_cma_allocate, + .free = ion_cma_free, + .map_dma = ion_cma_heap_map_dma, + .unmap_dma = ion_cma_heap_unmap_dma, + .phys = ion_cma_phys, + .map_user = ion_cma_mmap, + .map_kernel = ion_cma_map_kernel, + .unmap_kernel = ion_cma_unmap_kernel, +}; + +struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) +{ + struct ion_cma_heap *cma_heap; + + cma_heap = kzalloc(sizeof(struct ion_cma_heap), GFP_KERNEL); + + if (!cma_heap) + return ERR_PTR(-ENOMEM); + + cma_heap->heap.ops = &ion_cma_ops; + /* get device from private heaps data, later it will be + * used to make the link with reserved CMA memory */ + cma_heap->dev = data->priv; + cma_heap->heap.type = ION_HEAP_TYPE_DMA; + return &cma_heap->heap; +} + +void ion_cma_heap_destroy(struct ion_heap *heap) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(heap); + + kfree(cma_heap); +} diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c new file mode 100644 index 000000000000..9cf562224386 --- /dev/null +++ b/drivers/staging/android/ion/ion_heap.c @@ -0,0 +1,314 @@ +/* + * drivers/staging/android/ion/ion_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/err.h> +#include <linux/freezer.h> +#include <linux/kthread.h> +#include <linux/mm.h> +#include <linux/rtmutex.h> +#include <linux/sched.h> +#include <linux/scatterlist.h> +#include <linux/vmalloc.h> +#include "ion.h" +#include "ion_priv.h" + +void *ion_heap_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct scatterlist *sg; + int i, j; + void *vaddr; + pgprot_t pgprot; + struct sg_table *table = buffer->sg_table; + int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + struct page **pages = vmalloc(sizeof(struct page *) * npages); + struct page **tmp = pages; + + if (!pages) + return NULL; + + if (buffer->flags & ION_FLAG_CACHED) + pgprot = PAGE_KERNEL; + else + pgprot = pgprot_writecombine(PAGE_KERNEL); + + for_each_sg(table->sgl, sg, table->nents, i) { + int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; + struct page *page = sg_page(sg); + BUG_ON(i >= npages); + for (j = 0; j < npages_this_entry; j++) + *(tmp++) = page++; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + vfree(pages); + + if (vaddr == NULL) + return ERR_PTR(-ENOMEM); + + return vaddr; +} + +void ion_heap_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + vunmap(buffer->vaddr); +} + +int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + struct vm_area_struct *vma) +{ + struct sg_table *table = buffer->sg_table; + unsigned long addr = vma->vm_start; + unsigned long offset = vma->vm_pgoff * PAGE_SIZE; + struct scatterlist *sg; + int i; + int ret; + + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page = sg_page(sg); + unsigned long remainder = vma->vm_end - addr; + unsigned long len = sg->length; + + if (offset >= sg->length) { + offset -= sg->length; + continue; + } else if (offset) { + page += offset / PAGE_SIZE; + len = sg->length - offset; + offset = 0; + } + len = min(len, remainder); + ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, + vma->vm_page_prot); + if (ret) + return ret; + addr += len; + if (addr >= vma->vm_end) + return 0; + } + return 0; +} + +static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) +{ + void *addr = vm_map_ram(pages, num, -1, pgprot); + if (!addr) + return -ENOMEM; + memset(addr, 0, PAGE_SIZE * num); + vm_unmap_ram(addr, num); + + return 0; +} + +static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, + pgprot_t pgprot) +{ + int p = 0; + int ret = 0; + struct sg_page_iter piter; + struct page *pages[32]; + + for_each_sg_page(sgl, &piter, nents, 0) { + pages[p++] = sg_page_iter_page(&piter); + if (p == ARRAY_SIZE(pages)) { + ret = ion_heap_clear_pages(pages, p, pgprot); + if (ret) + return ret; + p = 0; + } + } + if (p) + ret = ion_heap_clear_pages(pages, p, pgprot); + + return ret; +} + +int ion_heap_buffer_zero(struct ion_buffer *buffer) +{ + struct sg_table *table = buffer->sg_table; + pgprot_t pgprot; + + if (buffer->flags & ION_FLAG_CACHED) + pgprot = PAGE_KERNEL; + else + pgprot = pgprot_writecombine(PAGE_KERNEL); + + return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); +} + +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + return ion_heap_sglist_zero(&sg, 1, pgprot); +} + +void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) +{ + rt_mutex_lock(&heap->lock); + list_add(&buffer->list, &heap->free_list); + heap->free_list_size += buffer->size; + rt_mutex_unlock(&heap->lock); + wake_up(&heap->waitqueue); +} + +size_t ion_heap_freelist_size(struct ion_heap *heap) +{ + size_t size; + + rt_mutex_lock(&heap->lock); + size = heap->free_list_size; + rt_mutex_unlock(&heap->lock); + + return size; +} + +size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) +{ + struct ion_buffer *buffer, *tmp; + size_t total_drained = 0; + + if (ion_heap_freelist_size(heap) == 0) + return 0; + + rt_mutex_lock(&heap->lock); + if (size == 0) + size = heap->free_list_size; + + list_for_each_entry_safe(buffer, tmp, &heap->free_list, list) { + if (total_drained >= size) + break; + list_del(&buffer->list); + heap->free_list_size -= buffer->size; + total_drained += buffer->size; + ion_buffer_destroy(buffer); + } + rt_mutex_unlock(&heap->lock); + + return total_drained; +} + +static int ion_heap_deferred_free(void *data) +{ + struct ion_heap *heap = data; + + while (true) { + struct ion_buffer *buffer; + + wait_event_freezable(heap->waitqueue, + ion_heap_freelist_size(heap) > 0); + + rt_mutex_lock(&heap->lock); + if (list_empty(&heap->free_list)) { + rt_mutex_unlock(&heap->lock); + continue; + } + buffer = list_first_entry(&heap->free_list, struct ion_buffer, + list); + list_del(&buffer->list); + heap->free_list_size -= buffer->size; + rt_mutex_unlock(&heap->lock); + ion_buffer_destroy(buffer); + } + + return 0; +} + +int ion_heap_init_deferred_free(struct ion_heap *heap) +{ + struct sched_param param = { .sched_priority = 0 }; + + INIT_LIST_HEAD(&heap->free_list); + heap->free_list_size = 0; + rt_mutex_init(&heap->lock); + init_waitqueue_head(&heap->waitqueue); + heap->task = kthread_run(ion_heap_deferred_free, heap, + "%s", heap->name); + sched_setscheduler(heap->task, SCHED_IDLE, ¶m); + if (IS_ERR(heap->task)) { + pr_err("%s: creating thread for deferred free failed\n", + __func__); + return PTR_RET(heap->task); + } + return 0; +} + +struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_heap *heap = NULL; + + switch (heap_data->type) { + case ION_HEAP_TYPE_SYSTEM_CONTIG: + heap = ion_system_contig_heap_create(heap_data); + break; + case ION_HEAP_TYPE_SYSTEM: + heap = ion_system_heap_create(heap_data); + break; + case ION_HEAP_TYPE_CARVEOUT: + heap = ion_carveout_heap_create(heap_data); + break; + case ION_HEAP_TYPE_CHUNK: + heap = ion_chunk_heap_create(heap_data); + break; + case ION_HEAP_TYPE_DMA: + heap = ion_cma_heap_create(heap_data); + break; + default: + pr_err("%s: Invalid heap type %d\n", __func__, + heap_data->type); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR_OR_NULL(heap)) { + pr_err("%s: error creating heap %s type %d base %lu size %zu\n", + __func__, heap_data->name, heap_data->type, + heap_data->base, heap_data->size); + return ERR_PTR(-EINVAL); + } + + heap->name = heap_data->name; + heap->id = heap_data->id; + return heap; +} + +void ion_heap_destroy(struct ion_heap *heap) +{ + if (!heap) + return; + + switch (heap->type) { + case ION_HEAP_TYPE_SYSTEM_CONTIG: + ion_system_contig_heap_destroy(heap); + break; + case ION_HEAP_TYPE_SYSTEM: + ion_system_heap_destroy(heap); + break; + case ION_HEAP_TYPE_CARVEOUT: + ion_carveout_heap_destroy(heap); + break; + case ION_HEAP_TYPE_CHUNK: + ion_chunk_heap_destroy(heap); + break; + case ION_HEAP_TYPE_DMA: + ion_cma_heap_destroy(heap); + break; + default: + pr_err("%s: Invalid heap type %d\n", __func__, + heap->type); + } +} diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c new file mode 100644 index 000000000000..fa693c23681a --- /dev/null +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -0,0 +1,195 @@ +/* + * drivers/staging/android/ion/ion_mem_pool.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/debugfs.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/fs.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/slab.h> +#include "ion_priv.h" + +struct ion_page_pool_item { + struct page *page; + struct list_head list; +}; + +static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) +{ + struct page *page = alloc_pages(pool->gfp_mask, pool->order); + + if (!page) + return NULL; + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order, + DMA_BIDIRECTIONAL); + return page; +} + +static void ion_page_pool_free_pages(struct ion_page_pool *pool, + struct page *page) +{ + __free_pages(page, pool->order); +} + +static int ion_page_pool_add(struct ion_page_pool *pool, struct page *page) +{ + struct ion_page_pool_item *item; + + item = kmalloc(sizeof(struct ion_page_pool_item), GFP_KERNEL); + if (!item) + return -ENOMEM; + + mutex_lock(&pool->mutex); + item->page = page; + if (PageHighMem(page)) { + list_add_tail(&item->list, &pool->high_items); + pool->high_count++; + } else { + list_add_tail(&item->list, &pool->low_items); + pool->low_count++; + } + mutex_unlock(&pool->mutex); + return 0; +} + +static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high) +{ + struct ion_page_pool_item *item; + struct page *page; + + if (high) { + BUG_ON(!pool->high_count); + item = list_first_entry(&pool->high_items, + struct ion_page_pool_item, list); + pool->high_count--; + } else { + BUG_ON(!pool->low_count); + item = list_first_entry(&pool->low_items, + struct ion_page_pool_item, list); + pool->low_count--; + } + + list_del(&item->list); + page = item->page; + kfree(item); + return page; +} + +void *ion_page_pool_alloc(struct ion_page_pool *pool) +{ + struct page *page = NULL; + + BUG_ON(!pool); + + mutex_lock(&pool->mutex); + if (pool->high_count) + page = ion_page_pool_remove(pool, true); + else if (pool->low_count) + page = ion_page_pool_remove(pool, false); + mutex_unlock(&pool->mutex); + + if (!page) + page = ion_page_pool_alloc_pages(pool); + + return page; +} + +void ion_page_pool_free(struct ion_page_pool *pool, struct page *page) +{ + int ret; + + ret = ion_page_pool_add(pool, page); + if (ret) + ion_page_pool_free_pages(pool, page); +} + +static int ion_page_pool_total(struct ion_page_pool *pool, bool high) +{ + int total = 0; + + total += high ? (pool->high_count + pool->low_count) * + (1 << pool->order) : + pool->low_count * (1 << pool->order); + return total; +} + +int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, + int nr_to_scan) +{ + int nr_freed = 0; + int i; + bool high; + + high = !!(gfp_mask & __GFP_HIGHMEM); + + if (nr_to_scan == 0) + return ion_page_pool_total(pool, high); + + for (i = 0; i < nr_to_scan; i++) { + struct page *page; + + mutex_lock(&pool->mutex); + if (pool->low_count) { + page = ion_page_pool_remove(pool, false); + } else if (high && pool->high_count) { + page = ion_page_pool_remove(pool, true); + } else { + mutex_unlock(&pool->mutex); + break; + } + mutex_unlock(&pool->mutex); + ion_page_pool_free_pages(pool, page); + nr_freed += (1 << pool->order); + } + + return nr_freed; +} + +struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) +{ + struct ion_page_pool *pool = kmalloc(sizeof(struct ion_page_pool), + GFP_KERNEL); + if (!pool) + return NULL; + pool->high_count = 0; + pool->low_count = 0; + INIT_LIST_HEAD(&pool->low_items); + INIT_LIST_HEAD(&pool->high_items); + pool->gfp_mask = gfp_mask; + pool->order = order; + mutex_init(&pool->mutex); + plist_node_init(&pool->list, order); + + return pool; +} + +void ion_page_pool_destroy(struct ion_page_pool *pool) +{ + kfree(pool); +} + +static int __init ion_page_pool_init(void) +{ + return 0; +} + +static void __exit ion_page_pool_exit(void) +{ +} + +module_init(ion_page_pool_init); +module_exit(ion_page_pool_exit); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h new file mode 100644 index 000000000000..fc8a4c3cee5d --- /dev/null +++ b/drivers/staging/android/ion/ion_priv.h @@ -0,0 +1,360 @@ +/* + * drivers/staging/android/ion/ion_priv.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ION_PRIV_H +#define _ION_PRIV_H + +#include <linux/dma-direction.h> +#include <linux/kref.h> +#include <linux/mm_types.h> +#include <linux/mutex.h> +#include <linux/rbtree.h> +#include <linux/sched.h> +#include <linux/shrinker.h> +#include <linux/types.h> + +#include "ion.h" + +struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); + +/** + * struct ion_buffer - metadata for a particular buffer + * @ref: refernce count + * @node: node in the ion_device buffers tree + * @dev: back pointer to the ion_device + * @heap: back pointer to the heap the buffer came from + * @flags: buffer specific flags + * @size: size of the buffer + * @priv_virt: private data to the buffer representable as + * a void * + * @priv_phys: private data to the buffer representable as + * an ion_phys_addr_t (and someday a phys_addr_t) + * @lock: protects the buffers cnt fields + * @kmap_cnt: number of times the buffer is mapped to the kernel + * @vaddr: the kenrel mapping if kmap_cnt is not zero + * @dmap_cnt: number of times the buffer is mapped for dma + * @sg_table: the sg table for the buffer if dmap_cnt is not zero + * @pages: flat array of pages in the buffer -- used by fault + * handler and only valid for buffers that are faulted in + * @vmas: list of vma's mapping this buffer + * @handle_count: count of handles referencing this buffer + * @task_comm: taskcomm of last client to reference this buffer in a + * handle, used for debugging + * @pid: pid of last client to reference this buffer in a + * handle, used for debugging +*/ +struct ion_buffer { + struct kref ref; + union { + struct rb_node node; + struct list_head list; + }; + struct ion_device *dev; + struct ion_heap *heap; + unsigned long flags; + size_t size; + union { + void *priv_virt; + ion_phys_addr_t priv_phys; + }; + struct mutex lock; + int kmap_cnt; + void *vaddr; + int dmap_cnt; + struct sg_table *sg_table; + struct page **pages; + struct list_head vmas; + /* used to track orphaned buffers */ + int handle_count; + char task_comm[TASK_COMM_LEN]; + pid_t pid; +}; +void ion_buffer_destroy(struct ion_buffer *buffer); + +/** + * struct ion_heap_ops - ops to operate on a given heap + * @allocate: allocate memory + * @free: free memory + * @phys get physical address of a buffer (only define on + * physically contiguous heaps) + * @map_dma map the memory for dma to a scatterlist + * @unmap_dma unmap the memory for dma + * @map_kernel map memory to the kernel + * @unmap_kernel unmap memory to the kernel + * @map_user map memory to userspace + * + * allocate, phys, and map_user return 0 on success, -errno on error. + * map_dma and map_kernel return pointer on success, ERR_PTR on error. + */ +struct ion_heap_ops { + int (*allocate) (struct ion_heap *heap, + struct ion_buffer *buffer, unsigned long len, + unsigned long align, unsigned long flags); + void (*free) (struct ion_buffer *buffer); + int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len); + struct sg_table *(*map_dma) (struct ion_heap *heap, + struct ion_buffer *buffer); + void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer); + void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); + void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); + int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer, + struct vm_area_struct *vma); +}; + +/** + * heap flags - flags between the heaps and core ion code + */ +#define ION_HEAP_FLAG_DEFER_FREE (1 << 0) + +/** + * struct ion_heap - represents a heap in the system + * @node: rb node to put the heap on the device's tree of heaps + * @dev: back pointer to the ion_device + * @type: type of heap + * @ops: ops struct as above + * @flags: flags + * @id: id of heap, also indicates priority of this heap when + * allocating. These are specified by platform data and + * MUST be unique + * @name: used for debugging + * @shrinker: a shrinker for the heap, if the heap caches system + * memory, it must define a shrinker to return it on low + * memory conditions, this includes system memory cached + * in the deferred free lists for heaps that support it + * @free_list: free list head if deferred free is used + * @free_list_size size of the deferred free list in bytes + * @lock: protects the free list + * @waitqueue: queue to wait on from deferred free thread + * @task: task struct of deferred free thread + * @debug_show: called when heap debug file is read to add any + * heap specific debug info to output + * + * Represents a pool of memory from which buffers can be made. In some + * systems the only heap is regular system memory allocated via vmalloc. + * On others, some blocks might require large physically contiguous buffers + * that are allocated from a specially reserved heap. + */ +struct ion_heap { + struct plist_node node; + struct ion_device *dev; + enum ion_heap_type type; + struct ion_heap_ops *ops; + unsigned long flags; + unsigned int id; + const char *name; + struct shrinker shrinker; + struct list_head free_list; + size_t free_list_size; + struct rt_mutex lock; + wait_queue_head_t waitqueue; + struct task_struct *task; + int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *); +}; + +/** + * ion_buffer_cached - this ion buffer is cached + * @buffer: buffer + * + * indicates whether this ion buffer is cached + */ +bool ion_buffer_cached(struct ion_buffer *buffer); + +/** + * ion_buffer_fault_user_mappings - fault in user mappings of this buffer + * @buffer: buffer + * + * indicates whether userspace mappings of this buffer will be faulted + * in, this can affect how buffers are allocated from the heap. + */ +bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer); + +/** + * ion_device_create - allocates and returns an ion device + * @custom_ioctl: arch specific ioctl function if applicable + * + * returns a valid device or -PTR_ERR + */ +struct ion_device *ion_device_create(long (*custom_ioctl) + (struct ion_client *client, + unsigned int cmd, + unsigned long arg)); + +/** + * ion_device_destroy - free and device and it's resource + * @dev: the device + */ +void ion_device_destroy(struct ion_device *dev); + +/** + * ion_device_add_heap - adds a heap to the ion device + * @dev: the device + * @heap: the heap to add + */ +void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); + +/** + * some helpers for common operations on buffers using the sg_table + * and vaddr fields + */ +void *ion_heap_map_kernel(struct ion_heap *, struct ion_buffer *); +void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *); +int ion_heap_map_user(struct ion_heap *, struct ion_buffer *, + struct vm_area_struct *); +int ion_heap_buffer_zero(struct ion_buffer *buffer); +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); + +/** + * ion_heap_init_deferred_free -- initialize deferred free functionality + * @heap: the heap + * + * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will + * be called to setup deferred frees. Calls to free the buffer will + * return immediately and the actual free will occur some time later + */ +int ion_heap_init_deferred_free(struct ion_heap *heap); + +/** + * ion_heap_freelist_add - add a buffer to the deferred free list + * @heap: the heap + * @buffer: the buffer + * + * Adds an item to the deferred freelist. + */ +void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); + +/** + * ion_heap_freelist_drain - drain the deferred free list + * @heap: the heap + * @size: ammount of memory to drain in bytes + * + * Drains the indicated amount of memory from the deferred freelist immediately. + * Returns the total amount freed. The total freed may be higher depending + * on the size of the items in the list, or lower if there is insufficient + * total memory on the freelist. + */ +size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); + +/** + * ion_heap_freelist_size - returns the size of the freelist in bytes + * @heap: the heap + */ +size_t ion_heap_freelist_size(struct ion_heap *heap); + + +/** + * functions for creating and destroying the built in ion heaps. + * architectures can add their own custom architecture specific + * heaps as appropriate. + */ + +struct ion_heap *ion_heap_create(struct ion_platform_heap *); +void ion_heap_destroy(struct ion_heap *); +struct ion_heap *ion_system_heap_create(struct ion_platform_heap *); +void ion_system_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *); +void ion_system_contig_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *); +void ion_carveout_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *); +void ion_chunk_heap_destroy(struct ion_heap *); +struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *); +void ion_cma_heap_destroy(struct ion_heap *); + +/** + * kernel api to allocate/free from carveout -- used when carveout is + * used to back an architecture specific custom heap + */ +ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size, + unsigned long align); +void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, + unsigned long size); +/** + * The carveout heap returns physical addresses, since 0 may be a valid + * physical address, this is used to indicate allocation failed + */ +#define ION_CARVEOUT_ALLOCATE_FAIL -1 + +/** + * functions for creating and destroying a heap pool -- allows you + * to keep a pool of pre allocated memory to use from your heap. Keeping + * a pool of memory that is ready for dma, ie any cached mapping have been + * invalidated from the cache, provides a significant peformance benefit on + * many systems */ + +/** + * struct ion_page_pool - pagepool struct + * @high_count: number of highmem items in the pool + * @low_count: number of lowmem items in the pool + * @high_items: list of highmem items + * @low_items: list of lowmem items + * @shrinker: a shrinker for the items + * @mutex: lock protecting this struct and especially the count + * item list + * @alloc: function to be used to allocate pageory when the pool + * is empty + * @free: function to be used to free pageory back to the system + * when the shrinker fires + * @gfp_mask: gfp_mask to use from alloc + * @order: order of pages in the pool + * @list: plist node for list of pools + * + * Allows you to keep a pool of pre allocated pages to use from your heap. + * Keeping a pool of pages that is ready for dma, ie any cached mapping have + * been invalidated from the cache, provides a significant peformance benefit + * on many systems + */ +struct ion_page_pool { + int high_count; + int low_count; + struct list_head high_items; + struct list_head low_items; + struct mutex mutex; + gfp_t gfp_mask; + unsigned int order; + struct plist_node list; +}; + +struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); +void ion_page_pool_destroy(struct ion_page_pool *); +void *ion_page_pool_alloc(struct ion_page_pool *); +void ion_page_pool_free(struct ion_page_pool *, struct page *); + +/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool + * @pool: the pool + * @gfp_mask: the memory type to reclaim + * @nr_to_scan: number of items to shrink in pages + * + * returns the number of items freed in pages + */ +int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, + int nr_to_scan); + +/** + * ion_pages_sync_for_device - cache flush pages for use with the specified + * device + * @dev: the device the pages will be used with + * @page: the first page to be flushed + * @size: size in bytes of region to be flushed + * @dir: direction of dma transfer + */ +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir); + +#endif /* _ION_PRIV_H */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c new file mode 100644 index 000000000000..144b22727505 --- /dev/null +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -0,0 +1,483 @@ +/* + * drivers/staging/android/ion/ion_system_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <asm/page.h> +#include <linux/dma-mapping.h> +#include <linux/err.h> +#include <linux/highmem.h> +#include <linux/mm.h> +#include <linux/scatterlist.h> +#include <linux/seq_file.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include "ion.h" +#include "ion_priv.h" + +static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | + __GFP_NORETRY) & ~__GFP_WAIT; +static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); +static const unsigned int orders[] = {8, 4, 0}; +static const int num_orders = ARRAY_SIZE(orders); +static int order_to_index(unsigned int order) +{ + int i; + for (i = 0; i < num_orders; i++) + if (order == orders[i]) + return i; + BUG(); + return -1; +} + +static unsigned int order_to_size(int order) +{ + return PAGE_SIZE << order; +} + +struct ion_system_heap { + struct ion_heap heap; + struct ion_page_pool **pools; +}; + +struct page_info { + struct page *page; + unsigned int order; + struct list_head list; +}; + +static struct page *alloc_buffer_page(struct ion_system_heap *heap, + struct ion_buffer *buffer, + unsigned long order) +{ + bool cached = ion_buffer_cached(buffer); + struct ion_page_pool *pool = heap->pools[order_to_index(order)]; + struct page *page; + + if (!cached) { + page = ion_page_pool_alloc(pool); + } else { + gfp_t gfp_flags = low_order_gfp_flags; + + if (order > 4) + gfp_flags = high_order_gfp_flags; + page = alloc_pages(gfp_flags, order); + if (!page) + return NULL; + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order, + DMA_BIDIRECTIONAL); + } + if (!page) + return NULL; + + return page; +} + +static void free_buffer_page(struct ion_system_heap *heap, + struct ion_buffer *buffer, struct page *page, + unsigned int order) +{ + bool cached = ion_buffer_cached(buffer); + + if (!cached) { + struct ion_page_pool *pool = heap->pools[order_to_index(order)]; + ion_page_pool_free(pool, page); + } else { + __free_pages(page, order); + } +} + + +static struct page_info *alloc_largest_available(struct ion_system_heap *heap, + struct ion_buffer *buffer, + unsigned long size, + unsigned int max_order) +{ + struct page *page; + struct page_info *info; + int i; + + for (i = 0; i < num_orders; i++) { + if (size < order_to_size(orders[i])) + continue; + if (max_order < orders[i]) + continue; + + page = alloc_buffer_page(heap, buffer, orders[i]); + if (!page) + continue; + + info = kmalloc(sizeof(struct page_info), GFP_KERNEL); + info->page = page; + info->order = orders[i]; + return info; + } + return NULL; +} + +static int ion_system_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + struct sg_table *table; + struct scatterlist *sg; + int ret; + struct list_head pages; + struct page_info *info, *tmp_info; + int i = 0; + long size_remaining = PAGE_ALIGN(size); + unsigned int max_order = orders[0]; + + if (align > PAGE_SIZE) + return -EINVAL; + + INIT_LIST_HEAD(&pages); + while (size_remaining > 0) { + info = alloc_largest_available(sys_heap, buffer, size_remaining, + max_order); + if (!info) + goto err; + list_add_tail(&info->list, &pages); + size_remaining -= (1 << info->order) * PAGE_SIZE; + max_order = info->order; + i++; + } + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + goto err; + + ret = sg_alloc_table(table, i, GFP_KERNEL); + if (ret) + goto err1; + + sg = table->sgl; + list_for_each_entry_safe(info, tmp_info, &pages, list) { + struct page *page = info->page; + sg_set_page(sg, page, (1 << info->order) * PAGE_SIZE, 0); + sg = sg_next(sg); + list_del(&info->list); + kfree(info); + } + + buffer->priv_virt = table; + return 0; +err1: + kfree(table); +err: + list_for_each_entry_safe(info, tmp_info, &pages, list) { + free_buffer_page(sys_heap, buffer, info->page, info->order); + kfree(info); + } + return -ENOMEM; +} + +static void ion_system_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + struct sg_table *table = buffer->sg_table; + bool cached = ion_buffer_cached(buffer); + struct scatterlist *sg; + LIST_HEAD(pages); + int i; + + /* uncached pages come from the page pools, zero them before returning + for security purposes (other allocations are zerod at alloc time */ + if (!cached) + ion_heap_buffer_zero(buffer); + + for_each_sg(table->sgl, sg, table->nents, i) + free_buffer_page(sys_heap, buffer, sg_page(sg), + get_order(sg->length)); + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_system_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops system_heap_ops = { + .allocate = ion_system_heap_allocate, + .free = ion_system_heap_free, + .map_dma = ion_system_heap_map_dma, + .unmap_dma = ion_system_heap_unmap_dma, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, + .map_user = ion_heap_map_user, +}; + +static unsigned long ion_system_heap_shrink_count(struct shrinker *shrinker, + struct shrink_control *sc) +{ + struct ion_heap *heap = container_of(shrinker, struct ion_heap, + shrinker); + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int nr_total = 0; + int i; + + /* total number of items is whatever the page pools are holding + plus whatever's in the freelist */ + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + nr_total += ion_page_pool_shrink(pool, sc->gfp_mask, 0); + } + nr_total += ion_heap_freelist_size(heap) / PAGE_SIZE; + return nr_total; + +} + +static unsigned long ion_system_heap_shrink_scan(struct shrinker *shrinker, + struct shrink_control *sc) +{ + + struct ion_heap *heap = container_of(shrinker, struct ion_heap, + shrinker); + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int nr_freed = 0; + int i; + + if (sc->nr_to_scan == 0) + goto end; + + /* shrink the free list first, no point in zeroing the memory if + we're just going to reclaim it */ + nr_freed += ion_heap_freelist_drain(heap, sc->nr_to_scan * PAGE_SIZE) / + PAGE_SIZE; + + if (nr_freed >= sc->nr_to_scan) + goto end; + + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + + nr_freed += ion_page_pool_shrink(pool, sc->gfp_mask, + sc->nr_to_scan); + if (nr_freed >= sc->nr_to_scan) + break; + } + +end: + return nr_freed; + +} + +static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s, + void *unused) +{ + + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int i; + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + seq_printf(s, "%d order %u highmem pages in pool = %lu total\n", + pool->high_count, pool->order, + (1 << pool->order) * PAGE_SIZE * pool->high_count); + seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n", + pool->low_count, pool->order, + (1 << pool->order) * PAGE_SIZE * pool->low_count); + } + return 0; +} + +struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) +{ + struct ion_system_heap *heap; + int i; + + heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL); + if (!heap) + return ERR_PTR(-ENOMEM); + heap->heap.ops = &system_heap_ops; + heap->heap.type = ION_HEAP_TYPE_SYSTEM; + heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders, + GFP_KERNEL); + if (!heap->pools) + goto err_alloc_pools; + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool; + gfp_t gfp_flags = low_order_gfp_flags; + + if (orders[i] > 4) + gfp_flags = high_order_gfp_flags; + pool = ion_page_pool_create(gfp_flags, orders[i]); + if (!pool) + goto err_create_pool; + heap->pools[i] = pool; + } + + heap->heap.shrinker.scan_objects = ion_system_heap_shrink_scan; + heap->heap.shrinker.count_objects = ion_system_heap_shrink_count; + heap->heap.shrinker.seeks = DEFAULT_SEEKS; + heap->heap.shrinker.batch = 0; + register_shrinker(&heap->heap.shrinker); + heap->heap.debug_show = ion_system_heap_debug_show; + return &heap->heap; +err_create_pool: + for (i = 0; i < num_orders; i++) + if (heap->pools[i]) + ion_page_pool_destroy(heap->pools[i]); + kfree(heap->pools); +err_alloc_pools: + kfree(heap); + return ERR_PTR(-ENOMEM); +} + +void ion_system_heap_destroy(struct ion_heap *heap) +{ + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int i; + + for (i = 0; i < num_orders; i++) + ion_page_pool_destroy(sys_heap->pools[i]); + kfree(sys_heap->pools); + kfree(sys_heap); +} + +static int ion_system_contig_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long len, + unsigned long align, + unsigned long flags) +{ + int order = get_order(len); + struct page *page; + struct sg_table *table; + unsigned long i; + int ret; + + if (align > (PAGE_SIZE << order)) + return -EINVAL; + + page = alloc_pages(low_order_gfp_flags, order); + if (!page) + return -ENOMEM; + + split_page(page, order); + + len = PAGE_ALIGN(len); + for (i = len >> PAGE_SHIFT; i < (1 << order); i++) + __free_page(page + i); + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) { + ret = -ENOMEM; + goto out; + } + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_set_page(table->sgl, page, len, 0); + + buffer->priv_virt = table; + + ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL); + + return 0; + +out: + for (i = 0; i < len >> PAGE_SHIFT; i++) + __free_page(page + i); + kfree(table); + return ret; +} + +static void ion_system_contig_heap_free(struct ion_buffer *buffer) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < pages; i++) + __free_page(page + i); + sg_free_table(table); + kfree(table); +} + +static int ion_system_contig_heap_phys(struct ion_heap *heap, + struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + *addr = page_to_phys(page); + *len = buffer->size; + return 0; +} + +static struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ +} + +static struct ion_heap_ops kmalloc_ops = { + .allocate = ion_system_contig_heap_allocate, + .free = ion_system_contig_heap_free, + .phys = ion_system_contig_heap_phys, + .map_dma = ion_system_contig_heap_map_dma, + .unmap_dma = ion_system_contig_heap_unmap_dma, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, + .map_user = ion_heap_map_user, +}; + +struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) +{ + struct ion_heap *heap; + + heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL); + if (!heap) + return ERR_PTR(-ENOMEM); + heap->ops = &kmalloc_ops; + heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; + return heap; +} + +void ion_system_contig_heap_destroy(struct ion_heap *heap) +{ + kfree(heap); +} + diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c new file mode 100644 index 000000000000..3e20349baf7c --- /dev/null +++ b/drivers/staging/android/ion/ion_test.c @@ -0,0 +1,281 @@ +/* + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "ion-test: " fmt + +#include <linux/dma-buf.h> +#include <linux/dma-direction.h> +#include <linux/fs.h> +#include <linux/miscdevice.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <linux/vmalloc.h> + +#include "ion.h" +#include "../uapi/ion_test.h" + +#define u64_to_uptr(x) ((void __user *)(unsigned long)(x)) + +struct ion_test_device { + struct miscdevice misc; +}; + +struct ion_test_data { + struct dma_buf *dma_buf; + struct device *dev; +}; + +static int ion_handle_test_dma(struct device *dev, struct dma_buf *dma_buf, + void __user *ptr, size_t offset, size_t size, bool write) +{ + int ret = 0; + struct dma_buf_attachment *attach; + struct sg_table *table; + pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + struct sg_page_iter sg_iter; + unsigned long offset_page; + + attach = dma_buf_attach(dma_buf, dev); + if (IS_ERR(attach)) + return PTR_ERR(attach); + + table = dma_buf_map_attachment(attach, dir); + if (IS_ERR(table)) + return PTR_ERR(table); + + offset_page = offset >> PAGE_SHIFT; + offset %= PAGE_SIZE; + + for_each_sg_page(table->sgl, &sg_iter, table->nents, offset_page) { + struct page *page = sg_page_iter_page(&sg_iter); + void *vaddr = vmap(&page, 1, VM_MAP, pgprot); + size_t to_copy = PAGE_SIZE - offset; + + to_copy = min(to_copy, size); + if (!vaddr) { + ret = -ENOMEM; + goto err; + } + + if (write) + ret = copy_from_user(vaddr + offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + offset, to_copy); + + vunmap(vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + size -= to_copy; + if (!size) + break; + ptr += to_copy; + offset = 0; + } + +err: + dma_buf_unmap_attachment(attach, table, dir); + dma_buf_detach(dma_buf, attach); + return ret; +} + +static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr, + size_t offset, size_t size, bool write) +{ + int ret; + unsigned long page_offset = offset >> PAGE_SHIFT; + size_t copy_offset = offset % PAGE_SIZE; + size_t copy_size = size; + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + if (offset > dma_buf->size || size > dma_buf->size - offset) + return -EINVAL; + + ret = dma_buf_begin_cpu_access(dma_buf, offset, size, dir); + if (ret) + return ret; + + while (copy_size > 0) { + size_t to_copy; + void *vaddr = dma_buf_kmap(dma_buf, page_offset); + + if (!vaddr) + goto err; + + to_copy = min_t(size_t, PAGE_SIZE - copy_offset, copy_size); + + if (write) + ret = copy_from_user(vaddr + copy_offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + copy_offset, to_copy); + + dma_buf_kunmap(dma_buf, page_offset, vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + + copy_size -= to_copy; + ptr += to_copy; + page_offset++; + copy_offset = 0; + } +err: + dma_buf_end_cpu_access(dma_buf, offset, size, dir); + return ret; +} + +static long ion_test_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct ion_test_data *test_data = filp->private_data; + int ret = 0; + + union { + struct ion_test_rw_data test_rw; + } data; + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + switch (cmd) { + case ION_IOC_TEST_SET_FD: + { + struct dma_buf *dma_buf = NULL; + int fd = arg; + + if (fd >= 0) { + dma_buf = dma_buf_get((int)arg); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + } + if (test_data->dma_buf) + dma_buf_put(test_data->dma_buf); + test_data->dma_buf = dma_buf; + break; + } + case ION_IOC_TEST_DMA_MAPPING: + { + ret = ion_handle_test_dma(test_data->dev, test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + case ION_IOC_TEST_KERNEL_MAPPING: + { + ret = ion_handle_test_kernel(test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + default: + return -ENOTTY; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, sizeof(data))) + return -EFAULT; + } + return ret; +} + +static int ion_test_open(struct inode *inode, struct file *file) +{ + struct ion_test_data *data; + struct miscdevice *miscdev = file->private_data; + + data = kzalloc(sizeof(struct ion_test_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = miscdev->parent; + + file->private_data = data; + + return 0; +} + +static int ion_test_release(struct inode *inode, struct file *file) +{ + struct ion_test_data *data = file->private_data; + + kfree(data); + + return 0; +} + +static const struct file_operations ion_test_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ion_test_ioctl, + .open = ion_test_open, + .release = ion_test_release, +}; + +static int __init ion_test_probe(struct platform_device *pdev) +{ + int ret; + struct ion_test_device *testdev; + + testdev = devm_kzalloc(&pdev->dev, sizeof(struct ion_test_device), + GFP_KERNEL); + if (!testdev) + return -ENOMEM; + + testdev->misc.minor = MISC_DYNAMIC_MINOR; + testdev->misc.name = "ion-test"; + testdev->misc.fops = &ion_test_fops; + testdev->misc.parent = &pdev->dev; + ret = misc_register(&testdev->misc); + if (ret) { + pr_err("failed to register misc device.\n"); + return ret; + } + + platform_set_drvdata(pdev, testdev); + + return 0; +} + +static struct platform_driver ion_test_platform_driver = { + .driver = { + .name = "ion-test", + }, +}; + +static int __init ion_test_init(void) +{ + platform_device_register_simple("ion-test", -1, NULL, 0); + return platform_driver_probe(&ion_test_platform_driver, ion_test_probe); +} + +static void __exit ion_test_exit(void) +{ + platform_driver_unregister(&ion_test_platform_driver); +} + +module_init(ion_test_init); +module_exit(ion_test_exit); diff --git a/drivers/staging/android/ion/tegra/Makefile b/drivers/staging/android/ion/tegra/Makefile new file mode 100644 index 000000000000..11cd003fb08f --- /dev/null +++ b/drivers/staging/android/ion/tegra/Makefile @@ -0,0 +1 @@ +obj-y += tegra_ion.o diff --git a/drivers/staging/android/ion/tegra/tegra_ion.c b/drivers/staging/android/ion/tegra/tegra_ion.c new file mode 100644 index 000000000000..0849600bcc00 --- /dev/null +++ b/drivers/staging/android/ion/tegra/tegra_ion.c @@ -0,0 +1,96 @@ +/* + * drivers/gpu/tegra/tegra_ion.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include "../ion.h" +#include "../ion_priv.h" + +struct ion_device *idev; +struct ion_mapper *tegra_user_mapper; +int num_heaps; +struct ion_heap **heaps; + +int tegra_ion_probe(struct platform_device *pdev) +{ + struct ion_platform_data *pdata = pdev->dev.platform_data; + int err; + int i; + + num_heaps = pdata->nr; + + heaps = kzalloc(sizeof(struct ion_heap *) * pdata->nr, GFP_KERNEL); + + idev = ion_device_create(NULL); + if (IS_ERR_OR_NULL(idev)) { + kfree(heaps); + return PTR_ERR(idev); + } + + /* create the heaps as specified in the board file */ + for (i = 0; i < num_heaps; i++) { + struct ion_platform_heap *heap_data = &pdata->heaps[i]; + + heaps[i] = ion_heap_create(heap_data); + if (IS_ERR_OR_NULL(heaps[i])) { + err = PTR_ERR(heaps[i]); + goto err; + } + ion_device_add_heap(idev, heaps[i]); + } + platform_set_drvdata(pdev, idev); + return 0; +err: + for (i = 0; i < num_heaps; i++) { + if (heaps[i]) + ion_heap_destroy(heaps[i]); + } + kfree(heaps); + return err; +} + +int tegra_ion_remove(struct platform_device *pdev) +{ + struct ion_device *idev = platform_get_drvdata(pdev); + int i; + + ion_device_destroy(idev); + for (i = 0; i < num_heaps; i++) + ion_heap_destroy(heaps[i]); + kfree(heaps); + return 0; +} + +static struct platform_driver ion_driver = { + .probe = tegra_ion_probe, + .remove = tegra_ion_remove, + .driver = { .name = "ion-tegra" } +}; + +static int __init ion_init(void) +{ + return platform_driver_register(&ion_driver); +} + +static void __exit ion_exit(void) +{ + platform_driver_unregister(&ion_driver); +} + +module_init(ion_init); +module_exit(ion_exit); + diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 38ea986dc70f..62e2255b1c1e 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -28,7 +28,7 @@ struct sync_fence; /** * struct sync_timeline_ops - sync object implementation ops - * @driver_name: name of the implentation + * @driver_name: name of the implementation * @dup: duplicate a sync_pt * @has_signaled: returns: * 1 if pt has signaled @@ -37,12 +37,12 @@ struct sync_fence; * @compare: returns: * 1 if b will signal before a * 0 if a and b will signal at the same time - * -1 if a will signabl before b + * -1 if a will signal before b * @free_pt: called before sync_pt is freed * @release_obj: called before sync_timeline is freed * @print_obj: deprecated * @print_pt: deprecated - * @fill_driver_data: write implmentation specific driver data to data. + * @fill_driver_data: write implementation specific driver data to data. * should return an error if there is not enough room * as specified by size. This information is returned * to userspace by SYNC_IOC_FENCE_INFO. @@ -88,9 +88,9 @@ struct sync_timeline_ops { /** * struct sync_timeline - sync object * @kref: reference count on fence. - * @ops: ops that define the implementaiton of the sync_timeline + * @ops: ops that define the implementation of the sync_timeline * @name: name of the sync_timeline. Useful for debugging - * @destoryed: set when sync_timeline is destroyed + * @destroyed: set when sync_timeline is destroyed * @child_list_head: list of children sync_pts for this sync_timeline * @child_list_lock: lock protecting @child_list_head, destroyed, and * sync_pt.status @@ -119,12 +119,12 @@ struct sync_timeline { * @parent: sync_timeline to which this sync_pt belongs * @child_list: membership in sync_timeline.child_list_head * @active_list: membership in sync_timeline.active_list_head - * @signaled_list: membership in temorary signaled_list on stack + * @signaled_list: membership in temporary signaled_list on stack * @fence: sync_fence to which the sync_pt belongs * @pt_list: membership in sync_fence.pt_list_head * @status: 1: signaled, 0:active, <0: error * @timestamp: time which sync_pt status transitioned from active to - * singaled or error. + * signaled or error. */ struct sync_pt { struct sync_timeline *parent; @@ -145,9 +145,9 @@ struct sync_pt { /** * struct sync_fence - sync fence * @file: file representing this fence - * @kref: referenace count on fence. + * @kref: reference count on fence. * @name: name of sync_fence. Useful for debugging - * @pt_list_head: list of sync_pts in ths fence. immutable once fence + * @pt_list_head: list of sync_pts in the fence. immutable once fence * is created * @waiter_list_head: list of asynchronous waiters on this fence * @waiter_list_lock: lock protecting @waiter_list_head and @status @@ -201,23 +201,23 @@ static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, /** * sync_timeline_create() - creates a sync object - * @ops: specifies the implemention ops for the object + * @ops: specifies the implementation ops for the object * @size: size to allocate for this obj * @name: sync_timeline name * - * Creates a new sync_timeline which will use the implemetation specified by - * @ops. @size bytes will be allocated allowing for implemntation specific - * data to be kept after the generic sync_timeline stuct. + * Creates a new sync_timeline which will use the implementation specified by + * @ops. @size bytes will be allocated allowing for implementation specific + * data to be kept after the generic sync_timeline struct. */ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, int size, const char *name); /** - * sync_timeline_destory() - destorys a sync object + * sync_timeline_destroy() - destroys a sync object * @obj: sync_timeline to destroy * - * A sync implemntation should call this when the @obj is going away - * (i.e. module unload.) @obj won't actually be freed until all its childern + * A sync implementation should call this when the @obj is going away + * (i.e. module unload.) @obj won't actually be freed until all its children * sync_pts are freed. */ void sync_timeline_destroy(struct sync_timeline *obj); @@ -226,7 +226,7 @@ void sync_timeline_destroy(struct sync_timeline *obj); * sync_timeline_signal() - signal a status change on a sync_timeline * @obj: sync_timeline to signal * - * A sync implemntation should call this any time one of it's sync_pts + * A sync implementation should call this any time one of it's sync_pts * has signaled or has an error condition. */ void sync_timeline_signal(struct sync_timeline *obj); @@ -236,8 +236,8 @@ void sync_timeline_signal(struct sync_timeline *obj); * @parent: sync_pt's parent sync_timeline * @size: size to allocate for this pt * - * Creates a new sync_pt as a chiled of @parent. @size bytes will be - * allocated allowing for implemntation specific data to be kept after + * Creates a new sync_pt as a child of @parent. @size bytes will be + * allocated allowing for implementation specific data to be kept after * the generic sync_timeline struct. */ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size); @@ -287,7 +287,7 @@ struct sync_fence *sync_fence_merge(const char *name, struct sync_fence *sync_fence_fdget(int fd); /** - * sync_fence_put() - puts a refernnce of a sync fence + * sync_fence_put() - puts a reference of a sync fence * @fence: fence to put * * Puts a reference on @fence. If this is the last reference, the fence and @@ -297,7 +297,7 @@ void sync_fence_put(struct sync_fence *fence); /** * sync_fence_install() - installs a fence into a file descriptor - * @fence: fence to instal + * @fence: fence to install * @fd: file descriptor in which to install the fence * * Installs @fence into @fd. @fd's should be acquired through get_unused_fd(). @@ -359,10 +359,10 @@ struct sync_merge_data { * struct sync_pt_info - detailed sync_pt information * @len: length of sync_pt_info including any driver_data * @obj_name: name of parent sync_timeline - * @driver_name: name of driver implmenting the parent + * @driver_name: name of driver implementing the parent * @status: status of the sync_pt 0:active 1:signaled <0:error * @timestamp_ns: timestamp of status change in nanoseconds - * @driver_data: any driver dependant data + * @driver_data: any driver dependent data */ struct sync_pt_info { __u32 len; @@ -377,7 +377,7 @@ struct sync_pt_info { /** * struct sync_fence_info_data - data returned from fence info ioctl * @len: ioctl caller writes the size of the buffer its passing in. - * ioctl returns length of sync_fence_data reutnred to userspace + * ioctl returns length of sync_fence_data returned to userspace * including pt_info. * @name: name of fence * @status: status of fence. 1: signaled 0:active <0:error @@ -418,7 +418,7 @@ struct sync_fence_info_data { * pt_info. * * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. - * To itterate over the sync_pt_infos, use the sync_pt_info.len field. + * To iterate over the sync_pt_infos, use the sync_pt_info.len field. */ #define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ struct sync_fence_info_data) diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h new file mode 100644 index 000000000000..f09e7c154d69 --- /dev/null +++ b/drivers/staging/android/uapi/ion.h @@ -0,0 +1,196 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_ION_H +#define _UAPI_LINUX_ION_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +typedef int ion_user_handle_t; + +/** + * enum ion_heap_types - list of all possible types of heaps + * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc + * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc + * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved + * carveout heap, allocations are physically + * contiguous + * @ION_HEAP_TYPE_DMA: memory allocated via DMA API + * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask + * is used to identify the heaps, so only 32 + * total heap types are supported + */ +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CHUNK, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always + are at the end of this enum */ + ION_NUM_HEAPS = 16, +}; + +#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) +#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) +#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) + +#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 + +/** + * allocation flags - the lower 16 bits are used by core ion, the upper 16 + * bits are reserved for use by the heaps themselves. + */ +#define ION_FLAG_CACHED 1 /* mappings of this buffer should be + cached, ion will do cache + maintenance when the buffer is + mapped for dma */ +#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created + at mmap time, if this is set + caches must be managed manually */ + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @align: required alignment of the allocation + * @heap_id_mask: mask of heap ids to allocate from + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to + * refer to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_id_mask; + unsigned int flags; + ion_user_handle_t handle; +}; + +/** + * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair + * @handle: a handle + * @fd: a file descriptor representing that handle + * + * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with + * the handle returned from ion alloc, and the kernel returns the file + * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace + * provides the file descriptor and the kernel returns the handle. + */ +struct ion_fd_data { + ion_user_handle_t handle; + int fd; +}; + +/** + * struct ion_handle_data - a handle passed to/from the kernel + * @handle: a handle + */ +struct ion_handle_data { + ion_user_handle_t handle; +}; + +/** + * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl + * @cmd: the custom ioctl function to call + * @arg: additional data to pass to the custom ioctl, typically a user + * pointer to a predefined structure + * + * This works just like the regular cmd and arg fields of an ioctl. + */ +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + */ +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct ion_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + */ +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + +/** + * DOC: ION_IOC_MAP - get a file descriptor to mmap + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be used as an argument to mmap. + */ +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + */ +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + +/** + * DOC: ION_IOC_IMPORT - imports a shared file descriptor + * + * Takes an ion_fd_data struct with the fd field populated with a valid file + * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle + * filed set to the corresponding opaque handle. + */ +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) + +/** + * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory + * + * Deprecated in favor of using the dma_buf api's correctly (syncing + * will happend automatically when the buffer is mapped to a device). + * If necessary should be used after touching a cached buffer from the cpu, + * this will make the buffer in memory coherent. + */ +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) + +/** + * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl + * + * Takes the argument of the architecture specific ioctl to call and + * passes appropriate userdata for that ioctl + */ +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#endif /* _UAPI_LINUX_ION_H */ diff --git a/drivers/staging/android/uapi/ion_test.h b/drivers/staging/android/uapi/ion_test.h new file mode 100644 index 000000000000..352379a02690 --- /dev/null +++ b/drivers/staging/android/uapi/ion_test.h @@ -0,0 +1,71 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_ION_TEST_H +#define _UAPI_LINUX_ION_TEST_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +typedef int ion_user_handle_t; + +/** + * struct ion_test_rw_data - metadata passed to the kernel to read handle + * @ptr: a pointer to an area at least as large as size + * @offset: offset into the ion buffer to start reading + * @size: size to read or write + * @write: 1 to write, 0 to read + */ +struct ion_test_rw_data { + __u64 ptr; + __u64 offset; + __u64 size; + int write; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_TEST_SET_DMA_BUF - attach a dma buf to the test driver + * + * Attaches a dma buf fd to the test driver. Passing a second fd or -1 will + * release the first fd. + */ +#define ION_IOC_TEST_SET_FD \ + _IO(ION_IOC_MAGIC, 0xf0) + +/** + * DOC: ION_IOC_TEST_DMA_MAPPING - read or write memory from a handle as DMA + * + * Reads or writes the memory from a handle using an uncached mapping. Can be + * used by unit tests to emulate a DMA engine as close as possible. Only + * expected to be used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_DMA_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data) + +/** + * DOC: ION_IOC_TEST_KERNEL_MAPPING - read or write memory from a handle + * + * Reads or writes the memory from a handle using a kernel mapping. Can be + * used by unit tests to test heap map_kernel functions. Only expected to be + * used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_KERNEL_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data) + + +#endif /* _UAPI_LINUX_ION_H */ diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 87b74ca84c42..62415342ee28 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -160,7 +160,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) struct bcm_ioctl_buffer IoBuffer; int bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", + cmd, arg); if (_IOC_TYPE(cmd) != BCM_IOCTL) return -EFAULT; @@ -266,7 +268,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_3) || (uiTempVar == EEPROM_REJECT_REG_4))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } @@ -274,9 +277,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)sWrmBuffer.Data, sizeof(ULONG)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } break; @@ -291,7 +296,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Device in Idle Mode, Blocking Rdms\n"); return -EACCES; } @@ -317,7 +323,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sRdmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM Done On invalid Address : %x Access Denied.\n", (int)sRdmBuffer.Register); kfree(temp_buff); @@ -325,7 +332,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); + bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, + (PUINT)temp_buff, IoBuffer.OutputLength); if (bytes > 0) { Status = STATUS_SUCCESS; @@ -349,7 +357,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Device in Idle Mode, Blocking Wrms\n"); return -EACCES; } @@ -367,7 +376,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sWrmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM Done On invalid Address : %x Access Denied.\n", + (int)sWrmBuffer.Register); return -EINVAL; } @@ -379,17 +390,21 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_4)) && (cmd == IOCTL_BCM_REGISTER_WRITE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); + (PUINT)sWrmBuffer.Data, + sWrmBuffer.Length); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, + DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } break; @@ -405,7 +420,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "GPIO Can't be set/clear in Low power Mode"); return -EACCES; } @@ -423,7 +440,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) value = (1<<uiBit); if (IsReqGpioIsLedInNVM(Adapter, value) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", value); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", + value); Status = -EINVAL; break; } @@ -431,27 +451,42 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* Set - setting 1 */ if (uiOperation) { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); + Status = wrmaltWithLock(Adapter, + BCM_GPIO_OUTPUT_SET_REG, + (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Failed to set the %dth GPIO\n", + uiBit); break; } } else { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); + Status = wrmaltWithLock(Adapter, + BCM_GPIO_OUTPUT_CLR_REG, + (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Failed to clear the %dth GPIO\n", + uiBit); break; } } - bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, + (PUINT)ucResetValue, sizeof(UINT)); if (bytes < 0) { Status = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, @@ -467,9 +502,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)ucResetValue, sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Set the GPIO to output Mode\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Failed to put GPIO in Output Mode\n"); break; } } @@ -477,13 +516,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case BCM_LED_THREAD_STATE_CHANGE_REQ: { struct bcm_user_thread_req threadReq = {0}; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "User made LED thread InActive"); if ((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "GPIO Can't be set/clear in Low power Mode"); Status = -EACCES; break; } @@ -500,10 +542,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* if LED thread is running(Actively or Inactively) set it state to make inactive */ if (Adapter->LEDInfo.led_thread_running) { if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Activating thread req"); Adapter->DriverState = LED_THREAD_ACTIVE; } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req....."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "DeActivating Thread req....."); Adapter->DriverState = LED_THREAD_INACTIVE; } @@ -540,7 +586,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM Failed\n"); return Status; } else { Status = STATUS_SUCCESS; @@ -570,9 +617,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) return -EFAULT; if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); + pgpio_multi_info[WIMAX_IDX].uiGPIOMask, + Adapter->gpioBitMap); Status = -EINVAL; break; } @@ -590,7 +639,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)ucResetValue, sizeof(ULONG)); if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); return Status; } @@ -603,7 +653,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG)); if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); return Status; } } @@ -613,7 +664,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM to GPIO_PIN_STATE_REGISTER Failed."); return Status; } else { Status = STATUS_SUCCESS; @@ -1190,7 +1242,7 @@ cntrlEnd: break; case IOCTL_BCM_CAL_INIT: { - UINT uiSectorSize = 0 ; + UINT uiSectorSize = 0; if (Adapter->eNVMType == NVM_FLASH) { if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; @@ -1403,7 +1455,7 @@ cntrlEnd: case IOCTL_BCM_FLASH2X_SECTION_READ: { struct bcm_flash2x_readwrite sFlash2xRead = {0}; - PUCHAR pReadBuff = NULL ; + PUCHAR pReadBuff = NULL; UINT NOB = 0; UINT BuffSize = 0; UINT ReadBytes = 0; @@ -1438,7 +1490,7 @@ cntrlEnd: else BuffSize = NOB; - ReadOffset = sFlash2xRead.offset ; + ReadOffset = sFlash2xRead.offset; OutPutBuff = IoBuffer.OutputBuffer; pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); @@ -1483,7 +1535,7 @@ cntrlEnd: NOB = NOB - ReadBytes; if (NOB) { ReadOffset = ReadOffset + ReadBytes; - OutPutBuff = OutPutBuff + ReadBytes ; + OutPutBuff = OutPutBuff + ReadBytes; } } @@ -1538,7 +1590,7 @@ cntrlEnd: if (NOB > Adapter->uiSectorSize) BuffSize = Adapter->uiSectorSize; else - BuffSize = NOB ; + BuffSize = NOB; pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); @@ -1841,10 +1893,10 @@ cntrlEnd: case IOCTL_BCM_NVM_RAW_READ: { struct bcm_nvm_readwrite stNVMRead; - INT NOB ; - INT BuffSize ; + INT NOB; + INT BuffSize; INT ReadOffset = 0; - UINT ReadBytes = 0 ; + UINT ReadBytes = 0; PUCHAR pReadBuff; void __user *OutPutBuff; diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 9f7e30f637ea..6bddf723e06a 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -7,527 +7,527 @@ //DDR INIT-133Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0F000800,0x00007212}, - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00000F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = {// # DPLL Clock Setting + {0x0F000800, 0x00007212}, + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00000F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a04C,0x0000000C}, + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a04C, 0x0000000C}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020202}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101010},//ROB - 0x02101010,//0x02101018}, - {0x0F007040,0x45751200},//ROB - 0x45751200,//0x450f1200}, - {0x0F007044,0x110a0d00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x081b0306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010246c}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020202}, + {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x02101010},//ROB - 0x02101010,//0x02101018}, + {0x0F007040, 0x45751200},//ROB - 0x45751200,//0x450f1200}, + {0x0F007044, 0x110a0d00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x081b0306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010246c}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, + {0x0F007094, 0x00000104}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; //80Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07f1ffff}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a000,0x00000016}, - {0x0F00a04C,0x0000000C}, +static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = {// # DPLL Clock Setting + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07f1ffff}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a000, 0x00000016}, + {0x0F00a04C, 0x0000000C}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01000000}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, - {0x0F007020,0x04020107}, - {0x0F007024,0x00000007}, - {0x0F007028,0x02020201}, - {0x0F00702c,0x0204040a}, - {0x0F007030,0x04000000}, - {0x0F007034,0x00000002}, - {0x0F007038,0x1F060200}, - {0x0F00703C,0x1C22221F}, - {0x0F007040,0x8A006600}, - {0x0F007044,0x221a0800}, - {0x0F007048,0x02690204}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x000A15D6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00004000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007094,0x00000104}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01000000}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x02020201}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x04000000}, + {0x0F007034, 0x00000002}, + {0x0F007038, 0x1F060200}, + {0x0F00703C, 0x1C22221F}, + {0x0F007040, 0x8A006600}, + {0x0F007044, 0x221a0800}, + {0x0F007048, 0x02690204}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x000A15D6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00004000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007094, 0x00000104}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; //100Mhz #define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0F000800,0x00007008}, - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13E3F}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = {// # DPLL Clock Setting + {0x0F000800, 0x00007008}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13E3F}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL //0x0f000840,0x0FFF1800, - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a04C,0x0000000C}, + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a04C, 0x0000000C}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001}, // POP - 0x00020000 Normal 0x01020000 - {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020201}, - {0x0F00702c,0x0204040A}, - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x20080200}, - {0x0F00703C,0x02030320}, - {0x0F007040,0x6E7F1200}, - {0x0F007044,0x01190A00}, - {0x0F007048,0x06120305},//0x02690204 // 0x06120305 - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001C}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, // POP - 0x00020000 Normal 0x01020000 + {0x0F007020, 0x04020107},//Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020201}, + {0x0F00702c, 0x0204040A}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x20080200}, + {0x0F00703C, 0x02030320}, + {0x0F007040, 0x6E7F1200}, + {0x0F007044, 0x01190A00}, + {0x0F007048, 0x06120305},//0x02690204 // 0x06120305 + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001C}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, + {0x0F007094, 0x00000104}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; //Net T3B DDR Settings //DDR INIT-133Mhz static struct bcm_ddr_setting asDPLL_266MHZ[] = { - {0x0F000800,0x00007212}, - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00000F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, + {0x0F000800, 0x00007212}, + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00000F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002} + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002} }; #define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000 static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13652}, - {0x0f000840,0x0FFF0800}, + {0x0f000810, 0x00000F95}, + {0x0f000810, 0x00000F95}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13652}, + {0x0f000840, 0x0FFF0800}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, // Changed source for X-bar and MIPS clock to APLL - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020202}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101012},//ROB - 0x02101010,//0x02101018}, - {0x0F007040,0x457D1200},//ROB - 0x45751200,//0x450f1200}, - {0x0F007044,0x11130d00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x040D0306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010246c}, - {0x0F007064,0x00000012}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020202}, + {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x02101012},//ROB - 0x02101010,//0x02101018}, + {0x0F007040, 0x457D1200},//ROB - 0x45751200,//0x450f1200}, + {0x0F007044, 0x11130d00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x040D0306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010246c}, + {0x0F007064, 0x00000012}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, + {0x0F007094, 0x00000104}, //# Enable start bit within memory controller - {0x0F007018,0x01010000}, + {0x0F007018, 0x01010000}, }; #define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13FFF}, - {0x0f000840,0x0FFF1F00}, - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13FFF}, + {0x0f000840, 0x0FFF1F00}, + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a000,0x00000016}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01000000}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, - {0x0F007020,0x04020107}, - {0x0F007024,0x00000007}, - {0x0F007028,0x02020201}, - {0x0F00702c,0x0204040a}, - {0x0F007030,0x04000000}, - {0x0F007034,0x02000002}, - {0x0F007038,0x1F060202}, - {0x0F00703C,0x1C22221F}, - {0x0F007040,0x8A006600}, - {0x0F007044,0x221a0800}, - {0x0F007048,0x02690204}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x000A15D6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00004000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007094,0x00000104}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01000000}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x02020201}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x04000000}, + {0x0F007034, 0x02000002}, + {0x0F007038, 0x1F060202}, + {0x0F00703C, 0x1C22221F}, + {0x0F007040, 0x8A006600}, + {0x0F007044, 0x221a0800}, + {0x0F007048, 0x02690204}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x000A15D6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00004000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007094, 0x00000104}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; //100Mhz #define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 //index for 0x0F007000 static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F1369B}, - {0x0f000840,0x0FFF0800}, - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F1369B}, + {0x0f000840, 0x0FFF0800}, + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, // POP - 0x00020000 Normal 0x01020000 - {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020201}, - {0x0F00702c,0x0204040A}, - {0x0F007030,0x06000000}, - {0x0F007034,0x02000004}, - {0x0F007038,0x20080200}, - {0x0F00703C,0x02030320}, - {0x0F007040,0x6E7F1200}, - {0x0F007044,0x01190A00}, - {0x0F007048,0x06120305},//0x02690204 // 0x06120305 - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001C}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, // POP - 0x00020000 Normal 0x01020000 + {0x0F007020, 0x04020107},//Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020201}, + {0x0F00702c, 0x0204040A}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x02000004}, + {0x0F007038, 0x20080200}, + {0x0F00703C, 0x02030320}, + {0x0F007040, 0x6E7F1200}, + {0x0F007044, 0x01190A00}, + {0x0F007048, 0x06120305},//0x02690204 // 0x06120305 + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001C}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, + {0x0F007094, 0x00000104}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x03F1365B}, - {0x0f000810,0x00002F95}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = {// # DPLL Clock Setting + {0x0f000820, 0x03F1365B}, + {0x0f000810, 0x00002F95}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, + {0x0f000840, 0x0FFF0000}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020200}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101020},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x45711200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x110D0D00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x04080306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010245F}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020200}, + {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x02101020},//ROB - 0x02101010,//0x02101018, + {0x0F007040, 0x45711200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044, 0x110D0D00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x04080306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010245F}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00040000}, - {0x0F007098,0x00000000}, - {0x0F0070c8,0x00000104}, + {0x0F007094, 0x00040000}, + {0x0F007098, 0x00000000}, + {0x0F0070c8, 0x00000104}, //# Enable 2 ports within X-bar //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00002F95}, - {0x0f000820,0x03F1369B}, - {0x0f000840,0x0fff0000}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = {// # DPLL Clock Setting + {0x0f000810, 0x00002F95}, + {0x0f000820, 0x03F1369B}, + {0x0f000840, 0x0fff0000}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, + {0x0f000840, 0x0FFF0000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020200}, - {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x03000305}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - {0x0F007094,0x00010000}, - {0x0F007098,0x00000000}, - {0x0F0070C8,0x00000104}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04020107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020200}, + {0x0F00702c, 0x0204040a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x0203031F},//ROB - 0x02101010,//0x02101018, + {0x0F007040, 0x6e001200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044, 0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x03000305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + {0x0F007094, 0x00010000}, + {0x0F007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; #define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00002F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF1F00}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000000}, - {0x0f007008,0x01000001}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000000}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04020107}, - {0x0f007024,0x00000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0204040a}, - {0x0f007030,0x04000000}, - {0x0f007034,0x00000002}, - {0x0f007038,0x1d060200}, - {0x0f00703c,0x1c22221d}, - {0x0f007040,0x8A116600}, - {0x0f007044,0x222d0800}, - {0x0f007048,0x02690204}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0100001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x000A15D6}, - {0x0f007064,0x0000000A}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00004000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00010000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = {// # DPLL Clock Setting + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00002F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF1F00}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000000}, + {0x0f007008, 0x01000001}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000000}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04020107}, + {0x0f007024, 0x00000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0204040a}, + {0x0f007030, 0x04000000}, + {0x0f007034, 0x00000002}, + {0x0f007038, 0x1d060200}, + {0x0f00703c, 0x1c22221d}, + {0x0f007040, 0x8A116600}, + {0x0f007044, 0x222d0800}, + {0x0f007048, 0x02690204}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0100001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x000A15D6}, + {0x0f007064, 0x0000000A}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00004000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00010000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; @@ -536,246 +536,245 @@ static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting ///T3 LP-B (UMA-B) #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting - - {0x0f000820,0x03F137DB}, - {0x0f000810,0x01842795}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF0400}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},//Now dump from her in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000001}, - {0x0f007008,0x01000101}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000100}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04030107}, - {0x0f007024,0x02000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0206060a}, - {0x0f007030,0x050d0d00}, - {0x0f007034,0x00000003}, - {0x0f007038,0x170a0200}, - {0x0f00703c,0x02101012}, - {0x0f007040,0x45161200}, - {0x0f007044,0x11250c00}, - {0x0f007048,0x04da0307}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0000001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x00142bb6}, - {0x0f007064,0x20430014}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00009000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00040000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = {// # DPLL Clock Setting + {0x0f000820, 0x03F137DB}, + {0x0f000810, 0x01842795}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF0400}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084, 0x1Cffffff},//Now dump from her in internal memory + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000001}, + {0x0f007008, 0x01000101}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000100}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04030107}, + {0x0f007024, 0x02000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0206060a}, + {0x0f007030, 0x050d0d00}, + {0x0f007034, 0x00000003}, + {0x0f007038, 0x170a0200}, + {0x0f00703c, 0x02101012}, + {0x0f007040, 0x45161200}, + {0x0f007044, 0x11250c00}, + {0x0f007048, 0x04da0307}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0000001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x00142bb6}, + {0x0f007064, 0x20430014}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00009000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00040000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x03F1365B}, - {0x0f000810,0x00002F95}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = {// # DPLL Clock Setting + {0x0f000820, 0x03F1365B}, + {0x0f000810, 0x00002F95}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},//dump from here in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, + {0x0f000840, 0x0FFF0000}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084, 0x1Cffffff},//dump from here in internal memory + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020200}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101017},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x45171200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x11290D00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x04080306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010245F}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04030107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020200}, + {0x0F00702c, 0x0206060a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x02101017},//ROB - 0x02101010,//0x02101018, + {0x0F007040, 0x45171200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044, 0x11290D00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x04080306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010245F}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, //# Enable BW improvement within memory controller - {0x0F007094,0x00040000}, - {0x0F007098,0x00000000}, - {0x0F0070c8,0x00000104}, + {0x0F007094, 0x00040000}, + {0x0F007098, 0x00000000}, + {0x0F0070c8, 0x00000104}, //# Enable 2 ports within X-bar //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00002F95}, - {0x0f000820,0x03F1369B}, - {0x0f000840,0x0fff0000}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, +static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = {// # DPLL Clock Setting + {0x0f000810, 0x00002F95}, + {0x0f000820, 0x03F1369B}, + {0x0f000840, 0x0fff0000}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff}, //dump from here in internal memory - {0x0F00a080,0x1C000000}, + {0x0f000840, 0x0FFF0000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084, 0x1Cffffff}, //dump from here in internal memory + {0x0F00a080, 0x1C000000}, //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020200}, - {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x03000305}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - {0x0F007094,0x00010000}, - {0x0F007098,0x00000000}, - {0x0F0070C8,0x00000104}, + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000},// POP - 0x00020001 Normal 0x01020001 + {0x0F007020, 0x04020107}, //Normal - 0x04030107 POP - 0x05030107 + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020200}, + {0x0F00702c, 0x0204040a},//ROB- 0x0205050a,//0x0206060a + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 + {0x0F00703C, 0x0203031F},//ROB - 0x02101010,//0x02101018, + {0x0F007040, 0x6e001200},//ROB - 0x45751200,//0x450f1200, + {0x0F007044, 0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 + {0x0F007048, 0x03000305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + {0x0F007094, 0x00010000}, + {0x0F007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, + {0x0F00A000, 0x00000016}, //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F007018, 0x01010000} }; #define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00002F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF1F00}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},// dump from here in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000000}, - {0x0f007008,0x01000001}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000000}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04020107}, - {0x0f007024,0x00000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0204040a}, - {0x0f007030,0x04000000}, - {0x0f007034,0x00000002}, - {0x0f007038,0x1d060200}, - {0x0f00703c,0x1c22221d}, - {0x0f007040,0x8A116600}, - {0x0f007044,0x222d0800}, - {0x0f007048,0x02690204}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0100001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x000A15D6}, - {0x0f007064,0x0000000A}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00004000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00010000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = {// # DPLL Clock Setting + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00002F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF1F00}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz + {0x0F00a084, 0x1Cffffff},// dump from here in internal memory + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000000}, + {0x0f007008, 0x01000001}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000000}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04020107}, + {0x0f007024, 0x00000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0204040a}, + {0x0f007030, 0x04000000}, + {0x0f007034, 0x00000002}, + {0x0f007038, 0x1d060200}, + {0x0f00703c, 0x1c22221d}, + {0x0f007040, 0x8A116600}, + {0x0f007044, 0x222d0800}, + {0x0f007048, 0x02690204}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0100001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x000A15D6}, + {0x0f007064, 0x0000000A}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00004000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00010000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; int ddr_init(struct bcm_mini_adapter *Adapter) { - struct bcm_ddr_setting *psDDRSetting=NULL; - ULONG RegCount=0; + struct bcm_ddr_setting *psDDRSetting = NULL; + ULONG RegCount = 0; UINT value = 0; UINT uiResetValue = 0; UINT uiClockSetting = 0; @@ -787,20 +786,20 @@ int ddr_init(struct bcm_mini_adapter *Adapter) switch (Adapter->DDRSetting) { case DDR_80_MHZ: - psDDRSetting=asT3LP_DDRSetting80MHz; - RegCount=(sizeof(asT3LP_DDRSetting80MHz)/ + psDDRSetting = asT3LP_DDRSetting80MHz; + RegCount = (sizeof(asT3LP_DDRSetting80MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: - psDDRSetting=asT3LP_DDRSetting100MHz; - RegCount=(sizeof(asT3LP_DDRSetting100MHz)/ + psDDRSetting = asT3LP_DDRSetting100MHz; + RegCount = (sizeof(asT3LP_DDRSetting100MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: - psDDRSetting=asT3LP_DDRSetting133MHz; - RegCount=(sizeof(asT3LP_DDRSetting133MHz)/ + psDDRSetting = asT3LP_DDRSetting133MHz; + RegCount = (sizeof(asT3LP_DDRSetting133MHz)/ sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) + if (Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x03F13652; } @@ -818,47 +817,47 @@ int ddr_init(struct bcm_mini_adapter *Adapter) case BCS220_2: case BCS220_2BC: case BCS250_BC: - case BCS220_3 : + case BCS220_3: /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive * (please check current value and additionally set these bits) */ - if( (Adapter->chip_id != BCS220_2) && + if ((Adapter->chip_id != BCS220_2) && (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3) ) + (Adapter->chip_id != BCS220_3)) { - retval= rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + retval = rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue |= 0x44; retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } } - switch(Adapter->DDRSetting) + switch (Adapter->DDRSetting) { case DDR_80_MHZ: psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=(sizeof(asT3B_DDRSetting80MHz)/ + RegCount = (sizeof(asT3B_DDRSetting80MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: - psDDRSetting=asT3LPB_DDRSetting100MHz; - RegCount=(sizeof(asT3B_DDRSetting100MHz)/ + psDDRSetting = asT3LPB_DDRSetting100MHz; + RegCount = (sizeof(asT3B_DDRSetting100MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) + if (Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x03F13652; } @@ -872,7 +871,7 @@ int ddr_init(struct bcm_mini_adapter *Adapter) psDDRSetting = asT3LPB_DDRSetting160MHz; RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting); - if(Adapter->bMipsConfig == MIPS_200_MHZ) + if (Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x03F137D2; } @@ -915,30 +914,30 @@ int ddr_init(struct bcm_mini_adapter *Adapter) { case DDR_80_MHZ: psDDRSetting = asT3B_DDRSetting80MHz; - RegCount=(sizeof(asT3B_DDRSetting80MHz)/ + RegCount = (sizeof(asT3B_DDRSetting80MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_100_MHZ: - psDDRSetting=asT3B_DDRSetting100MHz; - RegCount=(sizeof(asT3B_DDRSetting100MHz)/ + psDDRSetting = asT3B_DDRSetting100MHz; + RegCount = (sizeof(asT3B_DDRSetting100MHz)/ sizeof(struct bcm_ddr_setting)); break; case DDR_133_MHZ: - if(Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected. + if (Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected. { memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, sizeof(asDPLL_266MHZ)); psDDRSetting = asT3B_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ sizeof(struct bcm_ddr_setting)); } else { psDDRSetting = asT3B_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) + if (Adapter->bMipsConfig == MIPS_200_MHZ) { uiClockSetting = 0x07F13652; } @@ -958,11 +957,11 @@ int ddr_init(struct bcm_mini_adapter *Adapter) return -EINVAL; } - value=0; + value = 0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount); - while(RegCount && !retval) + while (RegCount && !retval) { - if(uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) + if (uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) { value = uiClockSetting; } @@ -971,7 +970,7 @@ int ddr_init(struct bcm_mini_adapter *Adapter) value = psDDRSetting->ulRegValue; } retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value)); - if(STATUS_SUCCESS != retval) { + if (STATUS_SUCCESS != retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); break; } @@ -980,36 +979,36 @@ int ddr_init(struct bcm_mini_adapter *Adapter) psDDRSetting++; } - if(Adapter->chip_id >= 0xbece3300 ) + if (Adapter->chip_id >= 0xbece3300) { mdelay(3); - if( (Adapter->chip_id != BCS220_2)&& - (Adapter->chip_id != BCS220_2BC)&& + if ((Adapter->chip_id != BCS220_2) && + (Adapter->chip_id != BCS220_2BC) && (Adapter->chip_id != BCS220_3)) { /* drive MDDR to half in case of UMA-B: */ uiResetValue = 0x01010001; retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x00040020; retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x01020101; retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x01010000; retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } @@ -1022,73 +1021,73 @@ int ddr_init(struct bcm_mini_adapter *Adapter) * and since we dont have internal PMU lets do it under UMA-B chip id. * we will change this when we will have internal PMU. */ - if(Adapter->PmuMode == HYBRID_MODE_7C) + if (Adapter->PmuMode == HYBRID_MODE_7C) { retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x1322a8; retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x132296; retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } } - else if(Adapter->PmuMode == HYBRID_MODE_6 ) + else if (Adapter->PmuMode == HYBRID_MODE_6) { retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x6003229a; retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x1322a8; retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } @@ -1101,8 +1100,8 @@ int ddr_init(struct bcm_mini_adapter *Adapter) int download_ddr_settings(struct bcm_mini_adapter *Adapter) { - struct bcm_ddr_setting *psDDRSetting=NULL; - ULONG RegCount=0; + struct bcm_ddr_setting *psDDRSetting = NULL; + ULONG RegCount = 0; unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY; UINT value = 0; int retval = STATUS_SUCCESS; @@ -1116,20 +1115,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) case DDR_80_MHZ: psDDRSetting = asT3LP_DDRSetting80MHz; RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LP_DDRSetting100MHz; RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LP_DDRSetting133MHz; RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; default: @@ -1141,26 +1140,26 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) case BCS220_2: case BCS220_2BC: case BCS250_BC: - case BCS220_3 : + case BCS220_3: switch (Adapter->DDRSetting) { case DDR_80_MHZ: psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=ARRAY_SIZE(asT3LPB_DDRSetting80MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting80MHz); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LPB_DDRSetting100MHz; RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LPB_DDRSetting133MHz; RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; @@ -1182,20 +1181,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) case DDR_80_MHZ: psDDRSetting = asT3_DDRSetting80MHz; RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3_DDRSetting100MHz; RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: psDDRSetting = asT3_DDRSetting133MHz; RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; default: return -EINVAL; @@ -1208,20 +1207,20 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) case DDR_80_MHZ: psDDRSetting = asT3B_DDRSetting80MHz; RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3B_DDRSetting100MHz; RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3B_DDRSetting133MHz; RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; } @@ -1231,9 +1230,9 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) return -EINVAL; } //total number of Register that has to be dumped - value =RegCount ; + value = RegCount; retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); - if(retval) + if (retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); @@ -1241,29 +1240,29 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) } ul_ddr_setting_load_addr += sizeof(ULONG); /*signature */ - value =(0x1d1e0dd0); + value = (0x1d1e0dd0); retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); - if(retval) + if (retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); return retval; } ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount*=(sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); + RegCount *= (sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); - while(RegCount && !retval) + while (RegCount && !retval) { - value = psDDRSetting->ulRegAddress ; - retval = wrmalt( Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); + value = psDDRSetting->ulRegAddress; + retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); ul_ddr_setting_load_addr += sizeof(ULONG); - if(!retval) + if (!retval) { - if(bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) + if (bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) { value = (psDDRSetting->ulRegValue |(1<<8)); - if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr, - &value, sizeof(value))){ + if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr, + &value, sizeof(value))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); break; } @@ -1272,8 +1271,8 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) { value = psDDRSetting->ulRegValue; - if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr , - &value, sizeof(value))){ + if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr , + &value, sizeof(value))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); break; } @@ -1285,5 +1284,3 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) } return retval; } - - diff --git a/drivers/staging/btmtk_usb/Kconfig b/drivers/staging/btmtk_usb/Kconfig deleted file mode 100644 index a425ebda6c7a..000000000000 --- a/drivers/staging/btmtk_usb/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_BTMTK - tristate "Mediatek Bluetooth support" - depends on USB && BT && m - ---help--- - Say Y here if you wish to control a MTK USB Bluetooth. - - This option depends on 'USB' support being enabled - - To compile this driver as a module, choose M here: the - module will be called btmtk_usb. - diff --git a/drivers/staging/btmtk_usb/Makefile b/drivers/staging/btmtk_usb/Makefile deleted file mode 100644 index 4d6c9d764621..000000000000 --- a/drivers/staging/btmtk_usb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_USB_BTMTK) += btmtk_usb.o diff --git a/drivers/staging/btmtk_usb/README b/drivers/staging/btmtk_usb/README deleted file mode 100644 index c046c8e96b2d..000000000000 --- a/drivers/staging/btmtk_usb/README +++ /dev/null @@ -1,14 +0,0 @@ --build driver modules - make - --install driver modules - make install - --remove driver modules - make clean - --dynamic debug message - turn on CONFIG_DYNAMIC_DEBUG compiler flag for current kernel - mount -t debugfs none /sys/kernel/debug/ - echo "module module_name +p" > /sys/kernel/debug/dynamic_debug/control(turn on debug messages, module name such as btmtk_usb) - echo "module module_name -p" > /sys/kernel/debug/dynamic_debug/control(turn off debug messages, module name such as btmtk_usb) diff --git a/drivers/staging/btmtk_usb/TODO b/drivers/staging/btmtk_usb/TODO deleted file mode 100644 index a71d1297942d..000000000000 --- a/drivers/staging/btmtk_usb/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - checkpatch.pl clean - - determine if the driver should not be using a duplicate - version of the usb-bluetooth interface code, but should - be merged into the drivers/bluetooth/ directory and - infrastructure instead. - - review by the bluetooth developer community - -Please send any patches for this driver to Yu-Chen, Cho <acho@suse.com> and -jay.hung@mediatek.com diff --git a/drivers/staging/btmtk_usb/btmtk_usb.c b/drivers/staging/btmtk_usb/btmtk_usb.c deleted file mode 100644 index 9a5ebd6cc512..000000000000 --- a/drivers/staging/btmtk_usb/btmtk_usb.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * MediaTek Bluetooth USB Driver - * - * Copyright (C) 2013, MediaTek co. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * or on the worldwide web at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/errno.h> -#include <linux/skbuff.h> -#include <linux/completion.h> -#include <linux/firmware.h> -#include <linux/usb.h> -#include <net/bluetooth/bluetooth.h> -#include <net/bluetooth/hci_core.h> - -#include "btmtk_usb.h" - -#define VERSION "1.0.4" -#define MT7650_FIRMWARE "mt7650.bin" -#define MT7662_FIRMWARE "mt7662.bin" - -static struct usb_driver btmtk_usb_driver; - - -static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *); -static int btmtk_usb_load_fw(struct btmtk_usb_data *); - -static void hex_dump(char *str, u8 *src_buf, u32 src_buf_len) -{ - unsigned char *pt; - int x; - - pt = src_buf; - - BT_DBG("%s: %p, len = %d\n", str, src_buf, src_buf_len); - - for (x = 0; x < src_buf_len; x++) { - if (x % 16 == 0) - BT_DBG("0x%04x : ", x); - BT_DBG("%02x ", ((unsigned char)pt[x])); - if (x % 16 == 15) - BT_DBG("\n"); - } - - BT_DBG("\n"); -} - -static int btmtk_usb_reset(struct usb_device *udev) -{ - int ret; - - BT_DBG("%s\n", __func__); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, - DEVICE_VENDOR_REQUEST_OUT, 0x01, 0x00, - NULL, 0x00, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d)\n", __func__, ret); - return ret; - } - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_io_read32(struct btmtk_usb_data *data, u32 reg, u32 *val) -{ - u8 request = data->r_request; - struct usb_device *udev = data->udev; - int ret; - __le32 val_le; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request, - DEVICE_VENDOR_REQUEST_IN, 0x0, reg, data->io_buf, - 4, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - *val = 0xffffffff; - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, *val); - return ret; - } - - memmove(&val_le, data->io_buf, 4); - - *val = le32_to_cpu(val_le); - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val) -{ - u16 value, index; - u8 request = data->w_request; - struct usb_device *udev = data->udev; - int ret; - - index = (u16)reg; - value = val & 0x0000ffff; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, - DEVICE_VENDOR_REQUEST_OUT, value, index, - NULL, 0, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, val); - return ret; - } - - index = (u16)(reg + 2); - value = (val & 0xffff0000) >> 16; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - request, DEVICE_VENDOR_REQUEST_OUT, - value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, val); - return ret; - } - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_switch_iobase(struct btmtk_usb_data *data, int base) -{ - int ret = 0; - - switch (base) { - case SYSCTL: - data->w_request = 0x42; - data->r_request = 0x47; - break; - case WLAN: - data->w_request = 0x02; - data->r_request = 0x07; - break; - - default: - return -EINVAL; - } - - return ret; -} - -static void btmtk_usb_cap_init(struct btmtk_usb_data *data) -{ - const struct firmware *firmware; - struct usb_device *udev = data->udev; - int ret; - - btmtk_usb_io_read32(data, 0x00, &data->chip_id); - - BT_DBG("chip id = %x\n", data->chip_id); - - if (is_mt7630(data) || is_mt7650(data)) { - data->need_load_fw = 1; - data->need_load_rom_patch = 0; - ret = request_firmware(&firmware, MT7650_FIRMWARE, &udev->dev); - if (ret < 0) { - if (ret == -ENOENT) { - BT_ERR("Firmware file \"%s\" not found\n", - MT7650_FIRMWARE); - } else { - BT_ERR("Firmware file \"%s\" request failed (err=%d)\n", - MT7650_FIRMWARE, ret); - } - } else { - BT_DBG("Firmware file \"%s\" Found\n", - MT7650_FIRMWARE); - /* load firmware here */ - data->firmware = firmware; - btmtk_usb_load_fw(data); - } - release_firmware(firmware); - } else if (is_mt7632(data) || is_mt7662(data)) { - data->need_load_fw = 0; - data->need_load_rom_patch = 1; - data->rom_patch_offset = 0x90000; - ret = request_firmware(&firmware, MT7662_FIRMWARE, &udev->dev); - if (ret < 0) { - if (ret == -ENOENT) { - BT_ERR("Firmware file \"%s\" not found\n", - MT7662_FIRMWARE); - } else { - BT_ERR("Firmware file \"%s\" request failed (err=%d)\n", - MT7662_FIRMWARE, ret); - } - } else { - BT_DBG("Firmware file \"%s\" Found\n", MT7662_FIRMWARE); - /* load rom patch here */ - data->firmware = firmware; - data->rom_patch_len = firmware->size; - btmtk_usb_load_rom_patch(data); - } - release_firmware(firmware); - } else { - BT_ERR("unknow chip(%x)\n", data->chip_id); - } -} - -static u16 checksume16(u8 *pData, int len) -{ - int sum = 0; - - while (len > 1) { - sum += *((u16 *)pData); - - pData = pData + 2; - - if (sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - - len -= 2; - } - - if (len) - sum += *((u8 *)pData); - - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - return ~sum; -} - -static int btmtk_usb_chk_crc(struct btmtk_usb_data *data, u32 checksum_len) -{ - int ret = 0; - struct usb_device *udev = data->udev; - - BT_DBG("%s\n", __func__); - - memmove(data->io_buf, &data->rom_patch_offset, 4); - memmove(&data->io_buf[4], &checksum_len, 4); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, - DEVICE_VENDOR_REQUEST_IN, 0x20, 0x00, data->io_buf, - 8, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) - BT_ERR("%s error(%d)\n", __func__, ret); - - return ret; -} - -static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data) -{ - int ret = 0; - struct usb_device *udev = data->udev; - u16 crc, count = 0; - __le16 crc_le; - - BT_DBG("%s\n", __func__); - - while (1) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x01, DEVICE_VENDOR_REQUEST_IN, - 0x21, 0x00, data->io_buf, 2, - CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - crc = 0xFFFF; - BT_ERR("%s error(%d)\n", __func__, ret); - } - - memmove(&crc_le, data->io_buf, 2); - - crc = le16_to_cpu(crc_le); - - if (crc != 0xFFFF) - break; - - mdelay(100); - - if (count++ > 100) { - BT_ERR("Query CRC over %d times\n", count); - break; - } - } - - return crc; -} - -static int btmtk_usb_reset_wmt(struct btmtk_usb_data *data) -{ - int ret = 0; - - /* reset command */ - u8 cmd[8] = {0x6F, 0xFC, 0x05, 0x01, 0x07, 0x01, 0x00, 0x04}; - - memmove(data->io_buf, cmd, 8); - - BT_DBG("%s\n", __func__); - - ret = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0), 0x01, - DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00, - data->io_buf, 8, CONTROL_TIMEOUT_JIFFIES); - - if (ret) - BT_ERR("%s:(%d)\n", __func__, ret); - - return ret; -} - -static void load_rom_patch_complete(struct urb *urb) -{ - - struct completion *sent_to_mcu_done = (struct completion *)urb->context; - - complete(sent_to_mcu_done); -} - -static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *data) -{ - u32 loop = 0; - u32 value; - s32 sent_len; - int ret = 0, total_checksum = 0; - struct urb *urb; - u32 patch_len = 0; - u32 cur_len = 0; - dma_addr_t data_dma; - struct completion sent_to_mcu_done; - int first_block = 1; - unsigned char phase; - void *buf; - char *pos; - unsigned int pipe; - pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); - - if (!data->firmware) { - BT_ERR("%s:please assign a rom patch\n", __func__); - return -1; - } - -load_patch_protect: - btmtk_usb_switch_iobase(data, WLAN); - btmtk_usb_io_read32(data, SEMAPHORE_03, &value); - loop++; - - if (((value & 0x01) == 0x00) && (loop < 600)) { - mdelay(1); - goto load_patch_protect; - } - - btmtk_usb_io_write32(data, 0x1004, 0x2c); - - btmtk_usb_switch_iobase(data, SYSCTL); - - btmtk_usb_io_write32(data, 0x1c, 0x30); - - /* Enable USB_DMA_CFG */ - btmtk_usb_io_write32(data, 0x9018, 0x00c00020); - - btmtk_usb_switch_iobase(data, WLAN); - - /* check ROM patch if upgrade */ - btmtk_usb_io_read32(data, COM_REG0, &value); - - if ((value & 0x02) == 0x02) - goto error0; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - if (!urb) { - ret = -ENOMEM; - goto error0; - } - - buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT, - GFP_ATOMIC, &data_dma); - - if (!buf) { - ret = -ENOMEM; - goto error1; - } - - pos = buf; - BT_DBG("loading rom patch"); - - init_completion(&sent_to_mcu_done); - - cur_len = 0x00; - patch_len = data->rom_patch_len - PATCH_INFO_SIZE; - - /* loading rom patch */ - while (1) { - s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE; - sent_len = min_t(s32, (patch_len - cur_len), sent_len_max); - - BT_DBG("patch_len = %d\n", patch_len); - BT_DBG("cur_len = %d\n", cur_len); - BT_DBG("sent_len = %d\n", sent_len); - - if (sent_len <= 0) - break; - - if (first_block == 1) { - if (sent_len < sent_len_max) - phase = PATCH_PHASE3; - else - phase = PATCH_PHASE1; - first_block = 0; - } else if (sent_len == sent_len_max) { - phase = PATCH_PHASE2; - } else { - phase = PATCH_PHASE3; - } - - /* prepare HCI header */ - pos[0] = 0x6F; - pos[1] = 0xFC; - pos[2] = (sent_len + 5) & 0xFF; - pos[3] = ((sent_len + 5) >> 8) & 0xFF; - - /* prepare WMT header */ - pos[4] = 0x01; - pos[5] = 0x01; - pos[6] = (sent_len + 1) & 0xFF; - pos[7] = ((sent_len + 1) >> 8) & 0xFF; - - pos[8] = phase; - - memcpy(&pos[9], - data->firmware->data + PATCH_INFO_SIZE + cur_len, - sent_len); - - BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n", - sent_len + PATCH_HEADER_SIZE, phase); - - usb_fill_bulk_urb(urb, - data->udev, - pipe, - buf, - sent_len + PATCH_HEADER_SIZE, - load_rom_patch_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error2; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload rom_patch timeout\n"); - goto error2; - } - - BT_DBG("."); - - mdelay(200); - - cur_len += sent_len; - - } - - total_checksum = checksume16( - (u8 *)data->firmware->data + PATCH_INFO_SIZE, - patch_len); - - BT_DBG("Send checksum req..\n"); - - btmtk_usb_chk_crc(data, patch_len); - - mdelay(20); - - if (total_checksum != btmtk_usb_get_crc(data)) { - BT_ERR("checksum fail!, local(0x%x) <> fw(0x%x)\n", - total_checksum, btmtk_usb_get_crc(data)); - ret = -1; - goto error2; - } - - mdelay(20); - - ret = btmtk_usb_reset_wmt(data); - - mdelay(20); - -error2: - usb_free_coherent(data->udev, UPLOAD_PATCH_UNIT, buf, data_dma); -error1: - usb_free_urb(urb); -error0: - btmtk_usb_io_write32(data, SEMAPHORE_03, 0x1); - return ret; -} - - -static int load_fw_iv(struct btmtk_usb_data *data) -{ - int ret; - struct usb_device *udev = data->udev; - char *buf = kmalloc(64, GFP_ATOMIC); - - memmove(buf, data->firmware->data + 32, 64); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, - DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64, - CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d) step4\n", __func__, ret); - kfree(buf); - return ret; - } - - if (ret > 0) - ret = 0; - - kfree(buf); - - return ret; -} - -static void load_fw_complete(struct urb *urb) -{ - - struct completion *sent_to_mcu_done = (struct completion *)urb->context; - - complete(sent_to_mcu_done); -} - -static int btmtk_usb_load_fw(struct btmtk_usb_data *data) -{ - struct usb_device *udev = data->udev; - struct urb *urb; - void *buf; - u32 cur_len = 0; - u32 packet_header = 0; - __le32 packet_header_le; - u32 value; - u32 ilm_len = 0, dlm_len = 0; - u16 fw_ver, build_ver; - u32 loop = 0; - dma_addr_t data_dma; - int ret = 0, sent_len; - struct completion sent_to_mcu_done; - unsigned int pipe; - pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); - - if (!data->firmware) { - BT_ERR("%s:please assign a fw\n", __func__); - return -1; - } - - BT_DBG("bulk_tx_ep = %x\n", data->bulk_tx_ep->bEndpointAddress); - -loadfw_protect: - btmtk_usb_switch_iobase(data, WLAN); - btmtk_usb_io_read32(data, SEMAPHORE_00, &value); - loop++; - - if (((value & 0x1) == 0) && (loop < 10000)) - goto loadfw_protect; - - /* check MCU if ready */ - btmtk_usb_io_read32(data, COM_REG0, &value); - - if ((value & 0x01) == 0x01) - goto error0; - - /* Enable MPDMA TX and EP2 load FW mode */ - btmtk_usb_io_write32(data, 0x238, 0x1c000000); - - btmtk_usb_reset(udev); - mdelay(100); - - ilm_len = (*(data->firmware->data + 3) << 24) - | (*(data->firmware->data + 2) << 16) - | (*(data->firmware->data + 1) << 8) - | (*data->firmware->data); - - dlm_len = (*(data->firmware->data + 7) << 24) - | (*(data->firmware->data + 6) << 16) - | (*(data->firmware->data + 5) << 8) - | (*(data->firmware->data + 4)); - - fw_ver = (*(data->firmware->data + 11) << 8) | - (*(data->firmware->data + 10)); - - build_ver = (*(data->firmware->data + 9) << 8) | - (*(data->firmware->data + 8)); - - BT_DBG("fw version:%d.%d.%02d ", - (fw_ver & 0xf000) >> 8, - (fw_ver & 0x0f00) >> 8, - (fw_ver & 0x00ff)); - - BT_DBG("build:%x\n", build_ver); - - BT_DBG("build Time ="); - - for (loop = 0; loop < 16; loop++) - BT_DBG("%c", *(data->firmware->data + 16 + loop)); - - BT_DBG("\n"); - - BT_DBG("ILM length = %d(bytes)\n", ilm_len); - BT_DBG("DLM length = %d(bytes)\n", dlm_len); - - btmtk_usb_switch_iobase(data, SYSCTL); - - /* U2M_PDMA rx_ring_base_ptr */ - btmtk_usb_io_write32(data, 0x790, 0x400230); - - /* U2M_PDMA rx_ring_max_cnt */ - btmtk_usb_io_write32(data, 0x794, 0x1); - - /* U2M_PDMA cpu_idx */ - btmtk_usb_io_write32(data, 0x798, 0x1); - - /* U2M_PDMA enable */ - btmtk_usb_io_write32(data, 0x704, 0x44); - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - if (!urb) { - ret = -ENOMEM; - goto error1; - } - - buf = usb_alloc_coherent(udev, 14592, GFP_ATOMIC, &data_dma); - - if (!buf) { - ret = -ENOMEM; - goto error2; - } - - BT_DBG("loading fw"); - - init_completion(&sent_to_mcu_done); - - btmtk_usb_switch_iobase(data, SYSCTL); - - cur_len = 0x40; - - /* Loading ILM */ - while (1) { - sent_len = min_t(s32, (ilm_len - cur_len), 14336); - - if (sent_len > 0) { - packet_header &= ~(0xffffffff); - packet_header |= (sent_len << 16); - packet_header_le = cpu_to_le32(packet_header); - - memmove(buf, &packet_header_le, 4); - memmove(buf + 4, data->firmware->data + 32 + cur_len, - sent_len); - - /* U2M_PDMA descriptor */ - btmtk_usb_io_write32(data, 0x230, cur_len); - - while ((sent_len % 4) != 0) - sent_len++; - - /* U2M_PDMA length */ - btmtk_usb_io_write32(data, 0x234, sent_len << 16); - - usb_fill_bulk_urb(urb, - udev, - pipe, - buf, - sent_len + 4, - load_fw_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error3; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload ilm fw timeout\n"); - goto error3; - } - - BT_DBG("."); - - mdelay(200); - - cur_len += sent_len; - } else { - break; - } - } - - init_completion(&sent_to_mcu_done); - cur_len = 0x00; - - /* Loading DLM */ - while (1) { - sent_len = min_t(s32, (dlm_len - cur_len), 14336); - - if (sent_len <= 0) - break; - - packet_header &= ~(0xffffffff); - packet_header |= (sent_len << 16); - packet_header_le = cpu_to_le32(packet_header); - - memmove(buf, &packet_header_le, 4); - memmove(buf + 4, - data->firmware->data + 32 + ilm_len + cur_len, - sent_len); - - /* U2M_PDMA descriptor */ - btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len); - - while ((sent_len % 4) != 0) { - BT_DBG("sent_len is not divided by 4\n"); - sent_len++; - } - - /* U2M_PDMA length */ - btmtk_usb_io_write32(data, 0x234, sent_len << 16); - - usb_fill_bulk_urb(urb, - udev, - pipe, - buf, - sent_len + 4, - load_fw_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error3; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload dlm fw timeout\n"); - goto error3; - } - - BT_DBG("."); - - mdelay(500); - - cur_len += sent_len; - - } - - /* upload 64bytes interrupt vector */ - ret = load_fw_iv(data); - mdelay(100); - - btmtk_usb_switch_iobase(data, WLAN); - - /* check MCU if ready */ - loop = 0; - - do { - btmtk_usb_io_read32(data, COM_REG0, &value); - - if (value == 0x01) - break; - - mdelay(10); - loop++; - } while (loop <= 100); - - if (loop > 1000) { - BT_ERR("wait for 100 times\n"); - ret = -ENODEV; - } - -error3: - usb_free_coherent(udev, 14592, buf, data_dma); -error2: - usb_free_urb(urb); -error1: - /* Disbale load fw mode */ - btmtk_usb_io_read32(data, 0x238, &value); - value = value & ~(0x10000000); - btmtk_usb_io_write32(data, 0x238, value); -error0: - btmtk_usb_io_write32(data, SEMAPHORE_00, 0x1); - return ret; -} - -static int inc_tx(struct btmtk_usb_data *data) -{ - unsigned long flags; - int rv; - - spin_lock_irqsave(&data->txlock, flags); - rv = test_bit(BTUSB_SUSPENDING, &data->flags); - if (!rv) - data->tx_in_flight++; - spin_unlock_irqrestore(&data->txlock, flags); - - return rv; -} - -static void btmtk_usb_intr_complete(struct urb *urb) -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - hdev->stat.byte_rx += urb->actual_length; - - hex_dump("hci event", urb->transfer_buffer, urb->actual_length); - - if (hci_recv_fragment(hdev, HCI_EVENT_PKT, - urb->transfer_buffer, - urb->actual_length) < 0) { - BT_ERR("%s corrupted event packet", hdev->name); - hdev->stat.err_rx++; - } - } - - if (!test_bit(BTUSB_INTR_RUNNING, &data->flags)) - return; - - usb_mark_last_busy(data->udev); - usb_anchor_urb(urb, &data->intr_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static int btmtk_usb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size; - - BT_DBG("%s\n", __func__); - - if (!data->intr_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, mem_flags); - if (!urb) - return -ENOMEM; - - size = le16_to_cpu(data->intr_ep->wMaxPacketSize); - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_intr_complete, hdev, - data->intr_ep->bInterval); - - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_anchor_urb(urb, &data->intr_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; - -} - -static void btmtk_usb_bulk_in_complete(struct urb *urb) -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s:%s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - hdev->stat.byte_rx += urb->actual_length; - - if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, - urb->transfer_buffer, - urb->actual_length) < 0) { - BT_ERR("%s corrupted ACL packet", hdev->name); - hdev->stat.err_rx++; - } - } - - if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) - return; - - usb_anchor_urb(urb, &data->bulk_anchor); - usb_mark_last_busy(data->udev); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static int btmtk_usb_submit_bulk_in_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size = HCI_MAX_FRAME_SIZE; - - BT_DBG("%s:%s\n", __func__, hdev->name); - - if (!data->bulk_rx_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, mem_flags); - if (!urb) - return -ENOMEM; - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress); - - usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_bulk_in_complete, hdev); - - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_mark_last_busy(data->udev); - usb_anchor_urb(urb, &data->bulk_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; -} - -static void btmtk_usb_isoc_in_complete(struct urb *urb) - -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int i, err; - - BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int offset = urb->iso_frame_desc[i].offset; - unsigned int length; - length = urb->iso_frame_desc[i].actual_length; - - if (urb->iso_frame_desc[i].status) - continue; - - hdev->stat.byte_rx += length; - - if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, - urb->transfer_buffer + offset, - length) < 0) { - BT_ERR("%s corrupted SCO packet", hdev->name); - hdev->stat.err_rx++; - } - } - } - - if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags)) - return; - - usb_anchor_urb(urb, &data->isoc_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu) -{ - int i, offset = 0; - - BT_DBG("len %d mtu %d", len, mtu); - - for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu; - i++, offset += mtu, len -= mtu) { - urb->iso_frame_desc[i].offset = offset; - urb->iso_frame_desc[i].length = mtu; - } - - if (len && i < BTUSB_MAX_ISOC_FRAMES) { - urb->iso_frame_desc[i].offset = offset; - urb->iso_frame_desc[i].length = len; - i++; - } - - urb->number_of_packets = i; -} - -static int btmtk_usb_submit_isoc_in_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size; - - BT_DBG("%s\n", __func__); - - if (!data->isoc_rx_ep) - return -ENODEV; - - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags); - if (!urb) - return -ENOMEM; - - size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * - BTUSB_MAX_ISOC_FRAMES; - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_isoc_in_complete, hdev, - data->isoc_rx_ep->bInterval); - - urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; - - __fill_isoc_descriptor(urb, size, - le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); - - usb_anchor_urb(urb, &data->isoc_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; -} - -static int btmtk_usb_open(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s\n", __func__); - - err = usb_autopm_get_interface(data->intf); - if (err < 0) - return err; - - data->intf->needs_remote_wakeup = 1; - - if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)) - goto done; - - err = btmtk_usb_submit_intr_urb(hdev, GFP_KERNEL); - if (err < 0) - goto failed; - - err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL); - if (err < 0) { - usb_kill_anchored_urbs(&data->intr_anchor); - goto failed; - } - - set_bit(BTUSB_BULK_RUNNING, &data->flags); - btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL); - -done: - usb_autopm_put_interface(data->intf); - return 0; - -failed: - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - clear_bit(HCI_RUNNING, &hdev->flags); - usb_autopm_put_interface(data->intf); - return err; -} - -static void btmtk_usb_stop_traffic(struct btmtk_usb_data *data) -{ - BT_DBG("%s\n", __func__); - - usb_kill_anchored_urbs(&data->intr_anchor); - usb_kill_anchored_urbs(&data->bulk_anchor); - usb_kill_anchored_urbs(&data->isoc_anchor); -} - -static int btmtk_usb_close(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s\n", __func__); - - if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) - return 0; - - cancel_work_sync(&data->work); - cancel_work_sync(&data->waker); - - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - - btmtk_usb_stop_traffic(data); - - err = usb_autopm_get_interface(data->intf); - if (err < 0) - goto failed; - - data->intf->needs_remote_wakeup = 0; - usb_autopm_put_interface(data->intf); - -failed: - usb_scuttle_anchored_urbs(&data->deferred); - return 0; -} - -static int btmtk_usb_flush(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s\n", __func__); - - usb_kill_anchored_urbs(&data->tx_anchor); - - return 0; -} - -static void btmtk_usb_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct hci_dev *hdev = (struct hci_dev *)skb->dev; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (!urb->status) - hdev->stat.byte_tx += urb->transfer_buffer_length; - else - hdev->stat.err_tx++; - -done: - spin_lock(&data->txlock); - data->tx_in_flight--; - spin_unlock(&data->txlock); - - kfree(urb->setup_packet); - - kfree_skb(skb); -} - -static void btmtk_usb_isoc_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct hci_dev *hdev = (struct hci_dev *) skb->dev; - - BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (!urb->status) - hdev->stat.byte_tx += urb->transfer_buffer_length; - else - hdev->stat.err_tx++; - -done: - kfree(urb->setup_packet); - - kfree_skb(skb); -} - -static int btmtk_usb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct usb_ctrlrequest *dr; - struct urb *urb; - unsigned int pipe; - int err; - - BT_DBG("%s\n", __func__); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return -EBUSY; - - switch (bt_cb(skb)->pkt_type) { - case HCI_COMMAND_PKT: - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - dr = kmalloc(sizeof(*dr), GFP_ATOMIC); - if (!dr) { - usb_free_urb(urb); - return -ENOMEM; - } - - dr->bRequestType = data->cmdreq_type; - dr->bRequest = 0; - dr->wIndex = 0; - dr->wValue = 0; - dr->wLength = __cpu_to_le16(skb->len); - - pipe = usb_sndctrlpipe(data->udev, 0x00); - - if (test_bit(HCI_RUNNING, &hdev->flags)) { - u16 op_code; - memcpy(&op_code, skb->data, 2); - BT_DBG("ogf = %x\n", (op_code & 0xfc00) >> 10); - BT_DBG("ocf = %x\n", op_code & 0x03ff); - hex_dump("hci command", skb->data, skb->len); - - } - - usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, - skb->data, skb->len, - btmtk_usb_tx_complete, skb); - - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - if (!data->bulk_tx_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - pipe = usb_sndbulkpipe(data->udev, - data->bulk_tx_ep->bEndpointAddress); - - usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, - skb->len, btmtk_usb_tx_complete, skb); - - hdev->stat.acl_tx++; - BT_DBG("HCI_ACLDATA_PKT:\n"); - break; - - case HCI_SCODATA_PKT: - if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) - return -ENODEV; - - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - pipe = usb_sndisocpipe(data->udev, - data->isoc_tx_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, - skb->data, skb->len, btmtk_usb_isoc_tx_complete, - skb, data->isoc_tx_ep->bInterval); - - urb->transfer_flags = URB_ISO_ASAP; - - __fill_isoc_descriptor(urb, skb->len, - le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); - - hdev->stat.sco_tx++; - BT_DBG("HCI_SCODATA_PKT:\n"); - goto skip_waking; - - default: - return -EILSEQ; - } - - err = inc_tx(data); - - if (err) { - usb_anchor_urb(urb, &data->deferred); - schedule_work(&data->waker); - err = 0; - goto done; - } - -skip_waking: - usb_anchor_urb(urb, &data->tx_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - kfree(urb->setup_packet); - usb_unanchor_urb(urb); - } else { - usb_mark_last_busy(data->udev); - } - -done: - usb_free_urb(urb); - return err; -} - -static void btmtk_usb_notify(struct hci_dev *hdev, unsigned int evt) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s evt %d", hdev->name, evt); - - if (hdev->conn_hash.sco_num != data->sco_num) { - data->sco_num = hdev->conn_hash.sco_num; - schedule_work(&data->work); - } -} - -static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct usb_interface *intf = data->isoc; - struct usb_endpoint_descriptor *ep_desc; - int i, err; - - if (!data->isoc) - return -ENODEV; - - err = usb_set_interface(data->udev, 1, altsetting); - if (err < 0) { - BT_ERR("%s setting interface failed (%d)", hdev->name, -err); - return err; - } - - data->isoc_altsetting = altsetting; - - data->isoc_tx_ep = NULL; - data->isoc_rx_ep = NULL; - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { - ep_desc = &intf->cur_altsetting->endpoint[i].desc; - - if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) { - data->isoc_tx_ep = ep_desc; - continue; - } - - if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) { - data->isoc_rx_ep = ep_desc; - continue; - } - } - - if (!data->isoc_tx_ep || !data->isoc_rx_ep) { - BT_ERR("%s invalid SCO descriptors", hdev->name); - return -ENODEV; - } - - return 0; -} - -static void btmtk_usb_work(struct work_struct *work) -{ - struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, - work); - struct hci_dev *hdev = data->hdev; - int new_alts; - int err; - - BT_DBG("%s\n", __func__); - - if (hdev->conn_hash.sco_num > 0) { - if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { - err = usb_autopm_get_interface(data->isoc ? - data->isoc : data->intf); - if (err < 0) { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - return; - } - - set_bit(BTUSB_DID_ISO_RESUME, &data->flags); - } - - if (hdev->voice_setting & 0x0020) { - static const int alts[3] = { 2, 4, 5 }; - new_alts = alts[hdev->conn_hash.sco_num - 1]; - } else { - new_alts = hdev->conn_hash.sco_num; - } - - if (data->isoc_altsetting != new_alts) { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - - if (__set_isoc_interface(hdev, new_alts) < 0) - return; - } - - if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL) < 0) - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - else - btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL); - } - } else { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - - __set_isoc_interface(hdev, 0); - - if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) - usb_autopm_put_interface(data->isoc ? - data->isoc : data->intf); - } -} - -static void btmtk_usb_waker(struct work_struct *work) -{ - struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, - waker); - int err; - - err = usb_autopm_get_interface(data->intf); - - if (err < 0) - return; - - usb_autopm_put_interface(data->intf); -} - -static int btmtk_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct btmtk_usb_data *data; - struct usb_endpoint_descriptor *ep_desc; - int i, err; - struct hci_dev *hdev; - - /* interface numbers are hardcoded in the spec */ - if (intf->cur_altsetting->desc.bInterfaceNumber != 0) - return -ENODEV; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - - if (!data) - return -ENOMEM; - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { - ep_desc = &intf->cur_altsetting->endpoint[i].desc; - - if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) { - data->intr_ep = ep_desc; - continue; - } - - if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) { - data->bulk_tx_ep = ep_desc; - continue; - } - - if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) { - data->bulk_rx_ep = ep_desc; - continue; - } - } - - if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { - kfree(data); - return -ENODEV; - } - - data->cmdreq_type = USB_TYPE_CLASS; - - data->udev = interface_to_usbdev(intf); - data->intf = intf; - - spin_lock_init(&data->lock); - INIT_WORK(&data->work, btmtk_usb_work); - INIT_WORK(&data->waker, btmtk_usb_waker); - spin_lock_init(&data->txlock); - - init_usb_anchor(&data->tx_anchor); - init_usb_anchor(&data->intr_anchor); - init_usb_anchor(&data->bulk_anchor); - init_usb_anchor(&data->isoc_anchor); - init_usb_anchor(&data->deferred); - - hdev = hci_alloc_dev(); - if (!hdev) { - kfree(data); - return -ENOMEM; - } - - hdev->bus = HCI_USB; - - hci_set_drvdata(hdev, data); - - data->hdev = hdev; - - SET_HCIDEV_DEV(hdev, &intf->dev); - - hdev->open = btmtk_usb_open; - hdev->close = btmtk_usb_close; - hdev->flush = btmtk_usb_flush; - hdev->send = btmtk_usb_send_frame; - hdev->notify = btmtk_usb_notify; - - /* Interface numbers are hardcoded in the specification */ - data->isoc = usb_ifnum_to_if(data->udev, 1); - - if (data->isoc) { - err = usb_driver_claim_interface(&btmtk_usb_driver, - data->isoc, data); - if (err < 0) { - hci_free_dev(hdev); - kfree(data); - return err; - } - } - - data->io_buf = kmalloc(256, GFP_KERNEL); - if (!data->io_buf) { - hci_free_dev(hdev); - kfree(data); - return -ENOMEM; - } - - btmtk_usb_switch_iobase(data, WLAN); - - btmtk_usb_cap_init(data); - - err = hci_register_dev(hdev); - if (err < 0) { - hci_free_dev(hdev); - kfree(data); - return err; - } - - usb_set_intfdata(intf, data); - - return 0; -} - -static void btmtk_usb_disconnect(struct usb_interface *intf) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - struct hci_dev *hdev; - - BT_DBG("%s\n", __func__); - - if (!data) - return; - - hdev = data->hdev; - usb_set_intfdata(data->intf, NULL); - - if (data->isoc) - usb_set_intfdata(data->isoc, NULL); - - hci_unregister_dev(hdev); - - if (intf == data->isoc) - usb_driver_release_interface(&btmtk_usb_driver, data->intf); - else if (data->isoc) - usb_driver_release_interface(&btmtk_usb_driver, data->isoc); - - hci_free_dev(hdev); - - kfree(data->io_buf); - - kfree(data); -} - -#ifdef CONFIG_PM -static int btmtk_usb_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - - BT_DBG("%s\n", __func__); - - if (data->suspend_count++) - return 0; - - spin_lock_irq(&data->txlock); - if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) { - set_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - } else { - spin_unlock_irq(&data->txlock); - data->suspend_count--; - return -EBUSY; - } - - cancel_work_sync(&data->work); - - btmtk_usb_stop_traffic(data); - usb_kill_anchored_urbs(&data->tx_anchor); - - return 0; -} - -static void play_deferred(struct btmtk_usb_data *data) -{ - struct urb *urb; - int err; - - while ((urb = usb_get_from_anchor(&data->deferred))) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) - break; - - data->tx_in_flight++; - } - - usb_scuttle_anchored_urbs(&data->deferred); -} - -static int btmtk_usb_resume(struct usb_interface *intf) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - struct hci_dev *hdev = data->hdev; - int err = 0; - - BT_DBG("%s\n", __func__); - - if (--data->suspend_count) - return 0; - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) { - err = btmtk_usb_submit_intr_urb(hdev, GFP_NOIO); - if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - goto failed; - } - } - - if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { - err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO); - if (err < 0) { - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - goto failed; - } - - btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO); - } - - if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO) < 0) - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - else - btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO); - } - - spin_lock_irq(&data->txlock); - play_deferred(data); - clear_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - schedule_work(&data->work); - - return 0; - -failed: - usb_scuttle_anchored_urbs(&data->deferred); -done: - spin_lock_irq(&data->txlock); - clear_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - - return err; -} -#endif - -static struct usb_device_id btmtk_usb_table[] = { - /* Mediatek MT7650 */ - { USB_DEVICE(0x0e8d, 0x7650) }, - { USB_DEVICE(0x0e8d, 0x7630) }, - { USB_DEVICE(0x0e8d, 0x763e) }, - /* Mediatek MT662 */ - { USB_DEVICE(0x0e8d, 0x7662) }, - { USB_DEVICE(0x0e8d, 0x7632) }, - { } /* Terminating entry */ -}; - -static struct usb_driver btmtk_usb_driver = { - .name = "btmtk_usb", - .probe = btmtk_usb_probe, - .disconnect = btmtk_usb_disconnect, -#ifdef CONFIG_PM - .suspend = btmtk_usb_suspend, - .resume = btmtk_usb_resume, -#endif - .id_table = btmtk_usb_table, - .supports_autosuspend = 1, - .disable_hub_initiated_lpm = 1, -}; - -module_usb_driver(btmtk_usb_driver); - -MODULE_DESCRIPTION("Mediatek Bluetooth USB driver ver " VERSION); -MODULE_VERSION(VERSION); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(MT7650_FIRMWARE); -MODULE_FIRMWARE(MT7662_FIRMWARE); diff --git a/drivers/staging/btmtk_usb/btmtk_usb.h b/drivers/staging/btmtk_usb/btmtk_usb.h deleted file mode 100644 index 12f0d3b27bfe..000000000000 --- a/drivers/staging/btmtk_usb/btmtk_usb.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * MediaTek Bluetooth USB Driver - * - * Copyright (C) 2013, MediaTek co. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * or on the worldwide web at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - */ - -#ifndef __BTMTK_USB_H__ -#define __BTMTK_USB_H_ - -/* Memory map for MTK BT */ - -/* SYS Control */ -#define SYSCTL 0x400000 - -/* WLAN */ -#define WLAN 0x410000 - -/* MCUCTL */ -#define INT_LEVEL 0x0718 -#define COM_REG0 0x0730 -#define SEMAPHORE_00 0x07B0 -#define SEMAPHORE_01 0x07B4 -#define SEMAPHORE_02 0x07B8 -#define SEMAPHORE_03 0x07BC - -/* Chip definition */ - -#define CONTROL_TIMEOUT_JIFFIES ((300 * HZ) / 100) -#define DEVICE_VENDOR_REQUEST_OUT 0x40 -#define DEVICE_VENDOR_REQUEST_IN 0xc0 -#define DEVICE_CLASS_REQUEST_OUT 0x20 - -#define BTUSB_MAX_ISOC_FRAMES 10 -#define BTUSB_INTR_RUNNING 0 -#define BTUSB_BULK_RUNNING 1 -#define BTUSB_ISOC_RUNNING 2 -#define BTUSB_SUSPENDING 3 -#define BTUSB_DID_ISO_RESUME 4 - -/* ROM Patch */ -#define PATCH_HCI_HEADER_SIZE 4 -#define PATCH_WMT_HEADER_SIZE 5 -#define PATCH_HEADER_SIZE (PATCH_HCI_HEADER_SIZE + PATCH_WMT_HEADER_SIZE) -#define UPLOAD_PATCH_UNIT 2048 -#define PATCH_INFO_SIZE 30 -#define PATCH_PHASE1 1 -#define PATCH_PHASE2 2 -#define PATCH_PHASE3 3 - -struct btmtk_usb_data { - struct hci_dev *hdev; - struct usb_device *udev; - struct usb_interface *intf; - struct usb_interface *isoc; - - spinlock_t lock; - - unsigned long flags; - struct work_struct work; - struct work_struct waker; - - struct usb_anchor tx_anchor; - struct usb_anchor intr_anchor; - struct usb_anchor bulk_anchor; - struct usb_anchor isoc_anchor; - struct usb_anchor deferred; - int tx_in_flight; - spinlock_t txlock; - - struct usb_endpoint_descriptor *intr_ep; - struct usb_endpoint_descriptor *bulk_tx_ep; - struct usb_endpoint_descriptor *bulk_rx_ep; - struct usb_endpoint_descriptor *isoc_tx_ep; - struct usb_endpoint_descriptor *isoc_rx_ep; - - __u8 cmdreq_type; - - unsigned int sco_num; - int isoc_altsetting; - int suspend_count; - - /* request for different io operation */ - u8 w_request; - u8 r_request; - - /* io buffer for usb control transfer */ - char *io_buf; - - struct semaphore fw_upload_sem; - - /* unsigned char *fw_image; */ - /* unsigned char *rom_patch; */ - const struct firmware *firmware; - u32 chip_id; - u8 need_load_fw; - u8 need_load_rom_patch; - u32 rom_patch_offset; - u32 rom_patch_len; -}; - -static inline int is_mt7630(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76300000); -} - -static inline int is_mt7650(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76500000); -} - -static inline int is_mt7632(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76320000); -} - -static inline int is_mt7662(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76620000); -} - -#endif diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 62efd74b8c04..043a93230e82 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -630,7 +630,7 @@ int ClearArea(DEVICE_EXTENSION *pdx, int nArea) } spin_unlock_irq(&pdx->stagedLock); - if (pPages) { /* if we decided to release the memory */ + if (pPages) { /* if we decided to release the memory */ /* Now we must undo the pinning down of the pages. We will assume the worst and mark */ /* all the pages as dirty. Don't be tempted to move this up above as you must not be */ /* holding a spin lock to do this stuff as it is not atomic. */ diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index e6dfc98f8c8e..fae2d9090006 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -1,3 +1,5 @@ +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG + comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 4e26bd7fc84f..924fce977985 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -16,6 +16,7 @@ */ #include <linux/vmalloc.h> +#include <linux/slab.h> #include "comedidev.h" #include "comedi_internal.h" @@ -26,31 +27,21 @@ #define COMEDI_PAGE_PROTECTION PAGE_KERNEL #endif -static void __comedi_buf_free(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned n_pages) +static void comedi_buf_map_kref_release(struct kref *kref) { - struct comedi_async *async = s->async; + struct comedi_buf_map *bm = + container_of(kref, struct comedi_buf_map, refcount); struct comedi_buf_page *buf; - unsigned i; - - if (async->prealloc_buf) { - vunmap(async->prealloc_buf); - async->prealloc_buf = NULL; - async->prealloc_bufsz = 0; - } + unsigned int i; - if (!async->buf_page_list) - return; - - for (i = 0; i < n_pages; ++i) { - buf = &async->buf_page_list[i]; - if (buf->virt_addr) { + if (bm->page_list) { + for (i = 0; i < bm->n_pages; i++) { + buf = &bm->page_list[i]; clear_bit(PG_reserved, &(virt_to_page(buf->virt_addr)->flags)); - if (s->async_dma_dir != DMA_NONE) { + if (bm->dma_dir != DMA_NONE) { #ifdef CONFIG_HAS_DMA - dma_free_coherent(dev->hw_dev, + dma_free_coherent(bm->dma_hw_dev, PAGE_SIZE, buf->virt_addr, buf->dma_addr); @@ -59,10 +50,26 @@ static void __comedi_buf_free(struct comedi_device *dev, free_page((unsigned long)buf->virt_addr); } } + vfree(bm->page_list); } - vfree(async->buf_page_list); - async->buf_page_list = NULL; - async->n_buf_pages = 0; + if (bm->dma_dir != DMA_NONE) + put_device(bm->dma_hw_dev); + kfree(bm); +} + +static void __comedi_buf_free(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct comedi_async *async = s->async; + + if (async->prealloc_buf) { + vunmap(async->prealloc_buf); + async->prealloc_buf = NULL; + async->prealloc_bufsz = 0; + } + + comedi_buf_map_put(async->buf_map); + async->buf_map = NULL; } static void __comedi_buf_alloc(struct comedi_device *dev, @@ -71,6 +78,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, { struct comedi_async *async = s->async; struct page **pages = NULL; + struct comedi_buf_map *bm; struct comedi_buf_page *buf; unsigned i; @@ -80,18 +88,29 @@ static void __comedi_buf_alloc(struct comedi_device *dev, return; } - async->buf_page_list = vzalloc(sizeof(*buf) * n_pages); - if (async->buf_page_list) + bm = kzalloc(sizeof(*async->buf_map), GFP_KERNEL); + if (!bm) + return; + + async->buf_map = bm; + kref_init(&bm->refcount); + bm->dma_dir = s->async_dma_dir; + if (bm->dma_dir != DMA_NONE) + /* Need ref to hardware device to free buffer later. */ + bm->dma_hw_dev = get_device(dev->hw_dev); + + bm->page_list = vzalloc(sizeof(*buf) * n_pages); + if (bm->page_list) pages = vmalloc(sizeof(struct page *) * n_pages); if (!pages) return; for (i = 0; i < n_pages; i++) { - buf = &async->buf_page_list[i]; - if (s->async_dma_dir != DMA_NONE) + buf = &bm->page_list[i]; + if (bm->dma_dir != DMA_NONE) #ifdef CONFIG_HAS_DMA - buf->virt_addr = dma_alloc_coherent(dev->hw_dev, + buf->virt_addr = dma_alloc_coherent(bm->dma_hw_dev, PAGE_SIZE, &buf->dma_addr, GFP_KERNEL | @@ -108,6 +127,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, pages[i] = virt_to_page(buf->virt_addr); } + bm->n_pages = i; /* vmap the prealloc_buf if all the pages were allocated */ if (i == n_pages) @@ -117,6 +137,26 @@ static void __comedi_buf_alloc(struct comedi_device *dev, vfree(pages); } +void comedi_buf_map_get(struct comedi_buf_map *bm) +{ + if (bm) + kref_get(&bm->refcount); +} + +int comedi_buf_map_put(struct comedi_buf_map *bm) +{ + if (bm) + return kref_put(&bm->refcount, comedi_buf_map_kref_release); + return 1; +} + +bool comedi_buf_is_mmapped(struct comedi_async *async) +{ + struct comedi_buf_map *bm = async->buf_map; + + return bm && (atomic_read(&bm->refcount.refcount) > 1); +} + int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { @@ -130,7 +170,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, return 0; /* deallocate old buffer */ - __comedi_buf_free(dev, s, async->n_buf_pages); + __comedi_buf_free(dev, s); /* allocate new buffer */ if (new_size) { @@ -140,10 +180,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, if (!async->prealloc_buf) { /* allocation failed */ - __comedi_buf_free(dev, s, n_pages); + __comedi_buf_free(dev, s); return -ENOMEM; } - async->n_buf_pages = n_pages; } async->prealloc_bufsz = new_size; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f3d59e2a1152..cdaef09c8993 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -16,8 +16,6 @@ GNU General Public License for more details. */ -#undef DEBUG - #include "comedi_compat32.h" #include <linux/module.h> @@ -47,15 +45,6 @@ #define COMEDI_NUM_SUBDEVICE_MINORS \ (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS) -#ifdef CONFIG_COMEDI_DEBUG -int comedi_debug; -EXPORT_SYMBOL_GPL(comedi_debug); -module_param(comedi_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(comedi_debug, - "enable comedi core and driver debugging if non-zero (default 0)" - ); -#endif - static int comedi_num_legacy_minors; module_param(comedi_num_legacy_minors, int, S_IRUGO); MODULE_PARM_DESC(comedi_num_legacy_minors, @@ -89,11 +78,37 @@ static struct cdev comedi_cdev; static void comedi_device_init(struct comedi_device *dev) { + kref_init(&dev->refcount); spin_lock_init(&dev->spinlock); mutex_init(&dev->mutex); + init_rwsem(&dev->attach_lock); dev->minor = -1; } +static void comedi_dev_kref_release(struct kref *kref) +{ + struct comedi_device *dev = + container_of(kref, struct comedi_device, refcount); + + mutex_destroy(&dev->mutex); + kfree(dev); +} + +int comedi_dev_put(struct comedi_device *dev) +{ + if (dev) + return kref_put(&dev->refcount, comedi_dev_kref_release); + return 1; +} +EXPORT_SYMBOL_GPL(comedi_dev_put); + +static struct comedi_device *comedi_dev_get(struct comedi_device *dev) +{ + if (dev) + kref_get(&dev->refcount); + return dev; +} + static void comedi_device_cleanup(struct comedi_device *dev) { struct module *driver_module = NULL; @@ -111,7 +126,6 @@ static void comedi_device_cleanup(struct comedi_device *dev) dev->use_count--; } mutex_unlock(&dev->mutex); - mutex_destroy(&dev->mutex); } static bool comedi_clear_board_dev(struct comedi_device *dev) @@ -147,12 +161,12 @@ static void comedi_free_board_dev(struct comedi_device *dev) MKDEV(COMEDI_MAJOR, dev->minor)); } comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); } } static struct comedi_subdevice -*comedi_subdevice_from_minor(unsigned minor) +*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned minor) { struct comedi_subdevice *s; unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; @@ -160,37 +174,45 @@ static struct comedi_subdevice BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS); mutex_lock(&comedi_subdevice_minor_table_lock); s = comedi_subdevice_minor_table[i]; + if (s && s->device != dev) + s = NULL; mutex_unlock(&comedi_subdevice_minor_table_lock); return s; } -static struct comedi_device *comedi_dev_from_board_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor) { struct comedi_device *dev; BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); mutex_lock(&comedi_board_minor_table_lock); - dev = comedi_board_minor_table[minor]; + dev = comedi_dev_get(comedi_board_minor_table[minor]); mutex_unlock(&comedi_board_minor_table_lock); return dev; } -static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor) { + struct comedi_device *dev; struct comedi_subdevice *s; + unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; - s = comedi_subdevice_from_minor(minor); - return s ? s->device : NULL; + BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS); + mutex_lock(&comedi_subdevice_minor_table_lock); + s = comedi_subdevice_minor_table[i]; + dev = comedi_dev_get(s ? s->device : NULL); + mutex_unlock(&comedi_subdevice_minor_table_lock); + return dev; } -struct comedi_device *comedi_dev_from_minor(unsigned minor) +struct comedi_device *comedi_dev_get_from_minor(unsigned minor) { if (minor < COMEDI_NUM_BOARD_MINORS) - return comedi_dev_from_board_minor(minor); + return comedi_dev_get_from_board_minor(minor); else - return comedi_dev_from_subdevice_minor(minor); + return comedi_dev_get_from_subdevice_minor(minor); } -EXPORT_SYMBOL_GPL(comedi_dev_from_minor); +EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor); static struct comedi_subdevice * comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) @@ -198,10 +220,8 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_READ) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_READ)) return s; } return dev->read_subdev; @@ -213,10 +233,8 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_WRITE) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_WRITE)) return s; } return dev->write_subdev; @@ -232,11 +250,13 @@ static int resize_async_buffer(struct comedi_device *dev, return -EPERM; if (s->busy) { - DPRINTK("subdevice is busy, cannot resize buffer\n"); + dev_dbg(dev->class_dev, + "subdevice is busy, cannot resize buffer\n"); return -EBUSY; } - if (async->mmap_count) { - DPRINTK("subdevice is mmapped, cannot resize buffer\n"); + if (comedi_buf_is_mmapped(async)) { + dev_dbg(dev->class_dev, + "subdevice is mmapped, cannot resize buffer\n"); return -EBUSY; } @@ -254,8 +274,8 @@ static int resize_async_buffer(struct comedi_device *dev, return retval; } - DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", - dev->minor, s->index, async->prealloc_bufsz); + dev_dbg(dev->class_dev, "subd %d buffer resized to %i bytes\n", + s->index, async->prealloc_bufsz); return 0; } @@ -269,7 +289,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -279,6 +299,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev, size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -299,7 +320,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -311,6 +332,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(max_read_buffer_kb); @@ -323,7 +345,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -333,6 +355,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev, size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -353,7 +376,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -365,6 +388,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(read_buffer_kb); @@ -378,7 +402,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -388,6 +412,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev, size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -408,7 +433,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -420,6 +445,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(max_write_buffer_kb); @@ -432,7 +458,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -442,6 +468,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev, size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -462,7 +489,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -474,6 +501,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(write_buffer_kb); @@ -562,12 +590,13 @@ static void do_become_nonbusy(struct comedi_device *dev, async->inttrig = NULL; kfree(async->cmd.chanlist); async->cmd.chanlist = NULL; + s->busy = NULL; + wake_up_interruptible_all(&s->async->wait_head); } else { dev_err(dev->class_dev, "BUG: (?) do_become_nonbusy called with async=NULL\n"); + s->busy = NULL; } - - s->busy = NULL; } static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) @@ -582,6 +611,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } +void comedi_device_cancel_all(struct comedi_device *dev) +{ + struct comedi_subdevice *s; + int i; + + if (!dev->attached) + return; + + for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; + if (s->async) + do_cancel(dev, s); + } +} + static int is_device_busy(struct comedi_device *dev) { struct comedi_subdevice *s; @@ -594,7 +638,7 @@ static int is_device_busy(struct comedi_device *dev) s = &dev->subdevices[i]; if (s->busy) return 1; - if (s->async && s->async->mmap_count) + if (s->async && comedi_buf_is_mmapped(s->async)) return 1; } @@ -684,7 +728,8 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, async = s->async; if (!async) { - DPRINTK("subdevice does not have async capability\n"); + dev_dbg(dev->class_dev, + "subdevice does not have async capability\n"); bc.size = 0; bc.maximum_size = 0; goto copyback; @@ -931,7 +976,8 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, async = s->async; if (!async) { - DPRINTK("subdevice does not have async capability\n"); + dev_dbg(dev->class_dev, + "subdevice does not have async capability\n"); bi.buf_write_ptr = 0; bi.buf_read_ptr = 0; bi.buf_write_count = 0; @@ -1083,19 +1129,20 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, break; } if (insn->subdev >= dev->n_subdevices) { - DPRINTK("%d not usable subdevice\n", + dev_dbg(dev->class_dev, + "%d not usable subdevice\n", insn->subdev); ret = -EINVAL; break; } s = &dev->subdevices[insn->subdev]; if (!s->async) { - DPRINTK("no async\n"); + dev_dbg(dev->class_dev, "no async\n"); ret = -EINVAL; break; } if (!s->async->inttrig) { - DPRINTK("no inttrig\n"); + dev_dbg(dev->class_dev, "no inttrig\n"); ret = -EAGAIN; break; } @@ -1104,7 +1151,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = 1; break; default: - DPRINTK("invalid insn\n"); + dev_dbg(dev->class_dev, "invalid insn\n"); ret = -EINVAL; break; } @@ -1113,21 +1160,23 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int maxdata; if (insn->subdev >= dev->n_subdevices) { - DPRINTK("subdevice %d out of range\n", insn->subdev); + dev_dbg(dev->class_dev, "subdevice %d out of range\n", + insn->subdev); ret = -EINVAL; goto out; } s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not usable subdevice\n", insn->subdev); + dev_dbg(dev->class_dev, "%d not usable subdevice\n", + insn->subdev); ret = -EIO; goto out; } /* are we locked? (ioctl lock) */ if (s->lock && s->lock != file) { - DPRINTK("device locked\n"); + dev_dbg(dev->class_dev, "device locked\n"); ret = -EACCES; goto out; } @@ -1135,7 +1184,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { ret = -EINVAL; - DPRINTK("bad chanspec\n"); + dev_dbg(dev->class_dev, "bad chanspec\n"); goto out; } @@ -1156,7 +1205,8 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, for (i = 0; i < insn->n; ++i) { if (data[i] > maxdata) { ret = -EINVAL; - DPRINTK("bad data value(s)\n"); + dev_dbg(dev->class_dev, + "bad data value(s)\n"); break; } } @@ -1238,35 +1288,35 @@ static int do_insnlist_ioctl(struct comedi_device *dev, data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL); if (!data) { - DPRINTK("kmalloc failed\n"); ret = -ENOMEM; goto error; } insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL); if (!insns) { - DPRINTK("kmalloc failed\n"); ret = -ENOMEM; goto error; } if (copy_from_user(insns, insnlist.insns, sizeof(*insns) * insnlist.n_insns)) { - DPRINTK("copy_from_user failed\n"); + dev_dbg(dev->class_dev, "copy_from_user failed\n"); ret = -EFAULT; goto error; } for (i = 0; i < insnlist.n_insns; i++) { if (insns[i].n > MAX_SAMPLES) { - DPRINTK("number of samples too large\n"); + dev_dbg(dev->class_dev, + "number of samples too large\n"); ret = -EINVAL; goto error; } if (insns[i].insn & INSN_MASK_WRITE) { if (copy_from_user(data, insns[i].data, insns[i].n * sizeof(unsigned int))) { - DPRINTK("copy_from_user failed\n"); + dev_dbg(dev->class_dev, + "copy_from_user failed\n"); ret = -EFAULT; goto error; } @@ -1277,7 +1327,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev, if (insns[i].insn & INSN_MASK_READ) { if (copy_to_user(insns[i].data, data, insns[i].n * sizeof(unsigned int))) { - DPRINTK("copy_to_user failed\n"); + dev_dbg(dev->class_dev, + "copy_to_user failed\n"); ret = -EFAULT; goto error; } @@ -1367,14 +1418,14 @@ static int do_cmd_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev); return -ENODEV; } @@ -1382,38 +1433,38 @@ static int do_cmd_ioctl(struct comedi_device *dev, async = s->async; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest || !s->async) { - DPRINTK("subdevice %i does not support commands\n", - cmd.subdev); + dev_dbg(dev->class_dev, + "subdevice %i does not support commands\n", cmd.subdev); return -EIO; } /* are we locked? (ioctl lock) */ if (s->lock && s->lock != file) { - DPRINTK("subdevice locked\n"); + dev_dbg(dev->class_dev, "subdevice locked\n"); return -EACCES; } /* are we busy? */ if (s->busy) { - DPRINTK("subdevice busy\n"); + dev_dbg(dev->class_dev, "subdevice busy\n"); return -EBUSY; } /* make sure channel/gain list isn't too long */ if (cmd.chanlist_len > s->len_chanlist) { - DPRINTK("channel/gain list too long %u > %d\n", + dev_dbg(dev->class_dev, "channel/gain list too long %u > %d\n", cmd.chanlist_len, s->len_chanlist); return -EINVAL; } /* make sure channel/gain list isn't too short */ if (cmd.chanlist_len < 1) { - DPRINTK("channel/gain list too short %u < 1\n", + dev_dbg(dev->class_dev, "channel/gain list too short %u < 1\n", cmd.chanlist_len); return -EINVAL; } @@ -1425,7 +1476,8 @@ static int do_cmd_ioctl(struct comedi_device *dev, async->cmd.chanlist_len * sizeof(int)); if (IS_ERR(async->cmd.chanlist)) { ret = PTR_ERR(async->cmd.chanlist); - DPRINTK("memdup_user failed with code %d\n", ret); + dev_dbg(dev->class_dev, "memdup_user failed with code %d\n", + ret); goto cleanup; } @@ -1434,20 +1486,20 @@ static int do_cmd_ioctl(struct comedi_device *dev, async->cmd.chanlist_len, async->cmd.chanlist); if (ret < 0) { - DPRINTK("bad chanlist\n"); + dev_dbg(dev->class_dev, "bad chanlist\n"); goto cleanup; } ret = s->do_cmdtest(dev, s, &async->cmd); if (async->cmd.flags & TRIG_BOGUS || ret) { - DPRINTK("test returned %d\n", ret); + dev_dbg(dev->class_dev, "test returned %d\n", ret); cmd = async->cmd; /* restore chanlist pointer before copying back */ cmd.chanlist = (unsigned int __force *)user_chanlist; cmd.data = NULL; if (copy_to_user(arg, &cmd, sizeof(cmd))) { - DPRINTK("fault writing cmd\n"); + dev_dbg(dev->class_dev, "fault writing cmd\n"); ret = -EFAULT; goto cleanup; } @@ -1457,7 +1509,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (!async->prealloc_bufsz) { ret = -ENOMEM; - DPRINTK("no buffer (?)\n"); + dev_dbg(dev->class_dev, "no buffer (?)\n"); goto cleanup; } @@ -1469,8 +1521,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (async->cmd.flags & TRIG_WAKE_EOS) async->cb_mask |= COMEDI_CB_EOS; - comedi_set_subdevice_runflags(s, SRF_USER | SRF_ERROR | SRF_RUNNING, - SRF_USER | SRF_RUNNING); + comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING); /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with * comedi_read() or comedi_write() */ @@ -1510,32 +1561,32 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev); return -ENODEV; } s = &dev->subdevices[cmd.subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest) { - DPRINTK("subdevice %i does not support commands\n", - cmd.subdev); + dev_dbg(dev->class_dev, + "subdevice %i does not support commands\n", cmd.subdev); return -EIO; } /* make sure channel/gain list isn't too long */ if (cmd.chanlist_len > s->len_chanlist) { - DPRINTK("channel/gain list too long %d > %d\n", + dev_dbg(dev->class_dev, "channel/gain list too long %d > %d\n", cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; @@ -1547,14 +1598,15 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, cmd.chanlist_len * sizeof(int)); if (IS_ERR(chanlist)) { ret = PTR_ERR(chanlist); - DPRINTK("memdup_user exited with code %d", ret); + dev_dbg(dev->class_dev, + "memdup_user exited with code %d", ret); goto cleanup; } /* make sure each element in channel/gain list is valid */ ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist); if (ret < 0) { - DPRINTK("bad chanlist\n"); + dev_dbg(dev->class_dev, "bad chanlist\n"); goto cleanup; } @@ -1567,7 +1619,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, cmd.chanlist = (unsigned int __force *)user_chanlist; if (copy_to_user(arg, &cmd, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); ret = -EFAULT; goto cleanup; } @@ -1700,8 +1752,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, return -EBUSY; ret = do_cancel(dev, s); - if (comedi_get_subdevice_runflags(s) & SRF_USER) - wake_up_interruptible(&s->async->wait_head); return ret; } @@ -1748,12 +1798,9 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; int rc; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); /* Device config is special, because it must work on @@ -1782,7 +1829,7 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, } if (!dev->attached) { - DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); rc = -ENODEV; goto done; } @@ -1852,28 +1899,18 @@ done: static void comedi_vm_open(struct vm_area_struct *area) { - struct comedi_async *async; - struct comedi_device *dev; + struct comedi_buf_map *bm; - async = area->vm_private_data; - dev = async->subdevice->device; - - mutex_lock(&dev->mutex); - async->mmap_count++; - mutex_unlock(&dev->mutex); + bm = area->vm_private_data; + comedi_buf_map_get(bm); } static void comedi_vm_close(struct vm_area_struct *area) { - struct comedi_async *async; - struct comedi_device *dev; - - async = area->vm_private_data; - dev = async->subdevice->device; + struct comedi_buf_map *bm; - mutex_lock(&dev->mutex); - async->mmap_count--; - mutex_unlock(&dev->mutex); + bm = area->vm_private_data; + comedi_buf_map_put(bm); } static struct vm_operations_struct comedi_vm_ops = { @@ -1884,22 +1921,20 @@ static struct vm_operations_struct comedi_vm_ops = { static int comedi_mmap(struct file *file, struct vm_area_struct *vma) { const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; struct comedi_async *async; + struct comedi_buf_map *bm; unsigned long start = vma->vm_start; unsigned long size; int n_pages; int i; int retval; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); retval = -ENODEV; goto done; } @@ -1920,7 +1955,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } if (vma->vm_pgoff != 0) { - DPRINTK("comedi: mmap() offset must be 0.\n"); + dev_dbg(dev->class_dev, "mmap() offset must be 0.\n"); retval = -EINVAL; goto done; } @@ -1936,8 +1971,13 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } n_pages = size >> PAGE_SHIFT; + bm = async->buf_map; + if (!bm || n_pages > bm->n_pages) { + retval = -EINVAL; + goto done; + } for (i = 0; i < n_pages; ++i) { - struct comedi_buf_page *buf = &async->buf_page_list[i]; + struct comedi_buf_page *buf = &bm->page_list[i]; if (remap_pfn_range(vma, start, page_to_pfn(virt_to_page(buf->virt_addr)), @@ -1949,9 +1989,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } vma->vm_ops = &comedi_vm_ops; - vma->vm_private_data = async; + vma->vm_private_data = bm; - async->mmap_count++; + vma->vm_ops->open(vma); retval = 0; done: @@ -1963,16 +2003,13 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); goto done; } @@ -2008,39 +2045,75 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; + bool on_wait_queue = false; + bool attach_locked; + unsigned int old_detach_count; - if (!dev) - return -ENODEV; + /* Protect against device detachment during operation. */ + down_read(&dev->attach_lock); + attach_locked = true; + old_detach_count = dev->detach_count; if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); - return -ENODEV; + dev_dbg(dev->class_dev, "no driver attached\n"); + retval = -ENODEV; + goto out; } s = comedi_write_subdevice(dev, minor); - if (!s || !s->async) - return -EIO; + if (!s || !s->async) { + retval = -EIO; + goto out; + } async = s->async; if (!s->busy || !nbytes) - return 0; - if (s->busy != file) - return -EACCES; + goto out; + if (s->busy != file) { + retval = -EACCES; + goto out; + } add_wait_queue(&async->wait_head, &wait); + on_wait_queue = true; while (nbytes > 0 && !retval) { set_current_state(TASK_INTERRUPTIBLE); if (!comedi_is_subdevice_running(s)) { if (count == 0) { - mutex_lock(&dev->mutex); + struct comedi_subdevice *new_s; + if (comedi_is_subdevice_in_error(s)) retval = -EPIPE; else retval = 0; - do_become_nonbusy(dev, s); + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. Need to + * remove task from the async wait queue before + * releasing dev->attach_lock, as it might not + * be valid afterwards. + */ + remove_wait_queue(&async->wait_head, &wait); + on_wait_queue = false; + up_read(&dev->attach_lock); + attach_locked = false; + mutex_lock(&dev->mutex); + /* + * Become non-busy unless things have changed + * behind our back. Checking dev->detach_count + * is unchanged ought to be sufficient (unless + * there have been 2**32 detaches in the + * meantime!), but check the subdevice pointer + * as well just in case. + */ + new_s = comedi_write_subdevice(dev, minor); + if (dev->attached && + old_detach_count == dev->detach_count && + s == new_s && new_s->async == async) + do_become_nonbusy(dev, s); mutex_unlock(&dev->mutex); } break; @@ -2090,8 +2163,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, buf += n; break; /* makes device work like a pipe */ } +out: + if (on_wait_queue) + remove_wait_queue(&async->wait_head, &wait); set_current_state(TASK_RUNNING); - remove_wait_queue(&async->wait_head, &wait); + if (attach_locked) + up_read(&dev->attach_lock); return count ? count : retval; } @@ -2104,25 +2181,35 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; + unsigned int old_detach_count; + bool become_nonbusy = false; + bool attach_locked; - if (!dev) - return -ENODEV; + /* Protect against device detachment during operation. */ + down_read(&dev->attach_lock); + attach_locked = true; + old_detach_count = dev->detach_count; if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); - return -ENODEV; + dev_dbg(dev->class_dev, "no driver attached\n"); + retval = -ENODEV; + goto out; } s = comedi_read_subdevice(dev, minor); - if (!s || !s->async) - return -EIO; + if (!s || !s->async) { + retval = -EIO; + goto out; + } async = s->async; if (!s->busy || !nbytes) - return 0; - if (s->busy != file) - return -EACCES; + goto out; + if (s->busy != file) { + retval = -EACCES; + goto out; + } add_wait_queue(&async->wait_head, &wait); while (nbytes > 0 && !retval) { @@ -2140,13 +2227,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, if (n == 0) { if (!comedi_is_subdevice_running(s)) { - mutex_lock(&dev->mutex); - do_become_nonbusy(dev, s); if (comedi_is_subdevice_in_error(s)) retval = -EPIPE; else retval = 0; - mutex_unlock(&dev->mutex); + become_nonbusy = true; break; } if (file->f_flags & O_NONBLOCK) { @@ -2184,14 +2269,37 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, buf += n; break; /* makes device work like a pipe */ } - if (comedi_is_subdevice_idle(s)) { + remove_wait_queue(&async->wait_head, &wait); + set_current_state(TASK_RUNNING); + if (become_nonbusy || comedi_is_subdevice_idle(s)) { + struct comedi_subdevice *new_s; + + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. + */ + up_read(&dev->attach_lock); + attach_locked = false; mutex_lock(&dev->mutex); - if (async->buf_read_count - async->buf_write_count == 0) - do_become_nonbusy(dev, s); + /* + * Check device hasn't become detached behind our back. + * Checking dev->detach_count is unchanged ought to be + * sufficient (unless there have been 2**32 detaches in the + * meantime!), but check the subdevice pointer as well just in + * case. + */ + new_s = comedi_read_subdevice(dev, minor); + if (dev->attached && old_detach_count == dev->detach_count && + s == new_s && new_s->async == async) { + if (become_nonbusy || + async->buf_read_count - async->buf_write_count == 0) + do_become_nonbusy(dev, s); + } mutex_unlock(&dev->mutex); } - set_current_state(TASK_RUNNING); - remove_wait_queue(&async->wait_head, &wait); +out: + if (attach_locked) + up_read(&dev->attach_lock); return count ? count : retval; } @@ -2199,10 +2307,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, static int comedi_open(struct inode *inode, struct file *file) { const unsigned minor = iminor(inode); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = comedi_dev_get_from_minor(minor); + int rc; if (!dev) { - DPRINTK("invalid minor number\n"); + pr_debug("invalid minor number\n"); return -ENODEV; } @@ -2223,9 +2332,9 @@ static int comedi_open(struct inode *inode, struct file *file) if (dev->attached) goto ok; if (!capable(CAP_NET_ADMIN) && dev->in_request_module) { - DPRINTK("in request module\n"); - mutex_unlock(&dev->mutex); - return -ENODEV; + dev_dbg(dev->class_dev, "in request module\n"); + rc = -ENODEV; + goto out; } if (capable(CAP_NET_ADMIN) && dev->in_request_module) goto ok; @@ -2241,9 +2350,9 @@ static int comedi_open(struct inode *inode, struct file *file) dev->in_request_module = false; if (!dev->attached && !capable(CAP_NET_ADMIN)) { - DPRINTK("not attached and not CAP_NET_ADMIN\n"); - mutex_unlock(&dev->mutex); - return -ENODEV; + dev_dbg(dev->class_dev, "not attached and not CAP_NET_ADMIN\n"); + rc = -ENODEV; + goto out; } ok: __module_get(THIS_MODULE); @@ -2251,49 +2360,44 @@ ok: if (dev->attached) { if (!try_module_get(dev->driver->module)) { module_put(THIS_MODULE); - mutex_unlock(&dev->mutex); - return -ENOSYS; + rc = -ENOSYS; + goto out; } } if (dev->attached && dev->use_count == 0 && dev->open) { - int rc = dev->open(dev); + rc = dev->open(dev); if (rc < 0) { module_put(dev->driver->module); module_put(THIS_MODULE); - mutex_unlock(&dev->mutex); - return rc; + goto out; } } dev->use_count++; + file->private_data = dev; + rc = 0; +out: mutex_unlock(&dev->mutex); - - return 0; + if (rc) + comedi_dev_put(dev); + return rc; } static int comedi_fasync(int fd, struct file *file, int on) { - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); - - if (!dev) - return -ENODEV; + struct comedi_device *dev = file->private_data; return fasync_helper(fd, file, on, &dev->async_queue); } static int comedi_close(struct inode *inode, struct file *file) { - const unsigned minor = iminor(inode); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s = NULL; int i; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (dev->subdevices) { @@ -2316,6 +2420,7 @@ static int comedi_close(struct inode *inode, struct file *file) dev->use_count--; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return 0; } @@ -2346,8 +2451,6 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) unsigned runflags = 0; unsigned runflags_mask = 0; - /* DPRINTK("comedi_event 0x%x\n",mask); */ - if (!comedi_is_subdevice_running(s)) return; @@ -2368,16 +2471,11 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) } if (async->cb_mask & s->async->events) { - if (comedi_get_subdevice_runflags(s) & SRF_USER) { - wake_up_interruptible(&async->wait_head); - if (s->subdev_flags & SDF_CMD_READ) - kill_fasync(&dev->async_queue, SIGIO, POLL_IN); - if (s->subdev_flags & SDF_CMD_WRITE) - kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); - } else { - if (async->cb_func) - async->cb_func(s->async->events, async->cb_arg); - } + wake_up_interruptible(&async->wait_head); + if (s->subdev_flags & SDF_CMD_READ) + kill_fasync(&dev->async_queue, SIGIO, POLL_IN); + if (s->subdev_flags & SDF_CMD_WRITE) + kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); } s->async->events = 0; } @@ -2408,7 +2506,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) if (i == COMEDI_NUM_BOARD_MINORS) { mutex_unlock(&dev->mutex); comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return ERR_PTR(-EBUSY); } diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index fda1a7ba0e16..9a746570f161 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -16,7 +16,11 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); void comedi_buf_reset(struct comedi_async *async); +bool comedi_buf_is_mmapped(struct comedi_async *async); +void comedi_buf_map_get(struct comedi_buf_map *bm); +int comedi_buf_map_put(struct comedi_buf_map *bm); unsigned int comedi_buf_write_n_allocated(struct comedi_async *async); +void comedi_device_cancel_all(struct comedi_device *dev); extern unsigned int comedi_default_buf_size_kb; extern unsigned int comedi_default_buf_maxsize_kb; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 143be8076a2e..f00b43c955f4 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -20,14 +20,13 @@ #define _COMEDIDEV_H #include <linux/dma-mapping.h> +#include <linux/mutex.h> +#include <linux/spinlock_types.h> +#include <linux/rwsem.h> +#include <linux/kref.h> #include "comedi.h" -#define DPRINTK(format, args...) do { \ - if (comedi_debug) \ - pr_debug("comedi: " format, ## args); \ -} while (0) - #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) #define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \ COMEDI_MINORVERSION, COMEDI_MICROVERSION) @@ -100,18 +99,22 @@ struct comedi_buf_page { dma_addr_t dma_addr; }; +struct comedi_buf_map { + struct device *dma_hw_dev; + struct comedi_buf_page *page_list; + unsigned int n_pages; + enum dma_data_direction dma_dir; + struct kref refcount; +}; + struct comedi_async { struct comedi_subdevice *subdevice; void *prealloc_buf; /* pre-allocated buffer */ unsigned int prealloc_bufsz; /* buffer size, in bytes */ - /* virtual and dma address of each page */ - struct comedi_buf_page *buf_page_list; - unsigned n_buf_pages; /* num elements in buf_page_list */ + struct comedi_buf_map *buf_map; /* map of buffer pages */ unsigned int max_bufsize; /* maximum buffer size, bytes */ - /* current number of mmaps of prealloc_buf */ - unsigned int mmap_count; /* byte count for writer (write completed) */ unsigned int buf_write_count; @@ -141,10 +144,7 @@ struct comedi_async { wait_queue_head_t wait_head; - /* callback stuff */ unsigned int cb_mask; - int (*cb_func) (unsigned int flags, void *); - void *cb_arg; int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x); @@ -173,6 +173,7 @@ struct comedi_device { struct device *class_dev; int minor; + unsigned int detach_count; /* hw_dev is passed to dma_alloc_coherent when allocating async buffers * for subdevices that have async_dma_dir set to something other than * DMA_NONE */ @@ -185,6 +186,8 @@ struct comedi_device { bool ioenabled:1; spinlock_t spinlock; struct mutex mutex; + struct rw_semaphore attach_lock; + struct kref refcount; int n_subdevices; struct comedi_subdevice *subdevices; @@ -208,12 +211,6 @@ static inline const void *comedi_board(const struct comedi_device *dev) return dev->board_ptr; } -#ifdef CONFIG_COMEDI_DEBUG -extern int comedi_debug; -#else -static const int comedi_debug; -#endif - /* * function prototypes */ @@ -231,7 +228,8 @@ enum comedi_minor_bits { static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4; static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; -struct comedi_device *comedi_dev_from_minor(unsigned minor); +struct comedi_device *comedi_dev_get_from_minor(unsigned minor); +int comedi_dev_put(struct comedi_device *dev); void init_polling(void); void cleanup_polling(void); @@ -240,7 +238,6 @@ void stop_polling(struct comedi_device *); /* subdevice runflags */ enum subdevice_runflags { - SRF_USER = 0x00000001, SRF_RT = 0x00000002, /* indicates an COMEDI_CB_ERROR event has occurred since the last * command was started */ diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 8f02bf66e20b..a5d03b9c3717 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -95,7 +95,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) } EXPORT_SYMBOL_GPL(comedi_alloc_subdevices); -static void cleanup_device(struct comedi_device *dev) +static void comedi_device_detach_cleanup(struct comedi_device *dev) { int i; struct comedi_subdevice *s; @@ -133,10 +133,14 @@ static void cleanup_device(struct comedi_device *dev) void comedi_device_detach(struct comedi_device *dev) { + comedi_device_cancel_all(dev); + down_write(&dev->attach_lock); dev->attached = false; + dev->detach_count++; if (dev->driver) dev->driver->detach(dev); - cleanup_device(dev); + comedi_device_detach_cleanup(dev); + up_write(&dev->attach_lock); } static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s) @@ -355,8 +359,9 @@ static int comedi_device_postconfig(struct comedi_device *dev) ret = __comedi_device_postconfig(dev); if (ret < 0) return ret; - smp_wmb(); + down_write(&dev->attach_lock); dev->attached = true; + up_write(&dev->attach_lock); return 0; } @@ -657,7 +662,7 @@ void comedi_driver_unregister(struct comedi_driver *driver) /* check for devices using this driver */ for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { - struct comedi_device *dev = comedi_dev_from_minor(i); + struct comedi_device *dev = comedi_dev_get_from_minor(i); if (!dev) continue; @@ -671,6 +676,7 @@ void comedi_driver_unregister(struct comedi_driver *driver) comedi_device_detach(dev); } mutex_unlock(&dev->mutex); + comedi_dev_put(dev); } } EXPORT_SYMBOL_GPL(comedi_driver_unregister); diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 432e3f9c3301..ec14acb653c2 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -257,7 +257,7 @@ static int pci_8255_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { +static const struct pci_device_id pci_8255_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 }, { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 }, { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 }, diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 94cbd2618fc8..a16e674e2a2b 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -1,5 +1,6 @@ # Makefile for individual comedi drivers # +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG # Comedi "helper" modules diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3c9eec84f0eb..bd05857b82f2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1414,7 +1414,7 @@ static void v_APCI3120_InterruptDma(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int next_dma_buf, samplesinbuf; unsigned long low_word, high_word, var; unsigned int ui_Tmp; @@ -1568,8 +1568,8 @@ static void v_APCI3120_InterruptDma(int irq, void *d) static int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; int n_chan, i; - struct comedi_subdevice *s = &dev->subdevices[0]; int err = 1; n_chan = devpriv->ui_AiNbrofChannels; @@ -1593,11 +1593,11 @@ static void v_APCI3120_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; unsigned short int_daq; unsigned int int_amcc, ui_Check, i; unsigned short us_TmpValue; unsigned char b_DummyRead; - struct comedi_subdevice *s = &dev->subdevices[0]; ui_Check = 1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index dc73d4d348ed..8c85a09d1c66 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -2590,8 +2590,8 @@ static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; unsigned int ui_StatusRegister = 0; - struct comedi_subdevice *s = &dev->subdevices[0]; /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ /* comedi_async *async = s->async; */ diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 8d229b2f0973..ccd49211ea17 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -58,7 +58,7 @@ static int apci035_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = { +static const struct pci_device_id apci035_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 34ab0679e992..af2306c1b649 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -364,7 +364,7 @@ static int apci1032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1032_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = { +static const struct pci_device_id apci1032_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index ae9ded63dcec..74f7ace8adbc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -57,7 +57,7 @@ static int apci1500_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = { +static const struct pci_device_id apci1500_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 9d1b1425c60b..e9c5291c77cd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -206,7 +206,7 @@ static int apci1516_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1516_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { +static const struct pci_device_id apci1516_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x1000), BOARD_APCI1016 }, { PCI_VDEVICE(ADDIDATA, 0x1001), BOARD_APCI1516 }, { PCI_VDEVICE(ADDIDATA, 0x1002), BOARD_APCI2016 }, diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index c5717d63e16a..6248284caaf5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -55,7 +55,7 @@ static int apci1564_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = { +static const struct pci_device_id apci1564_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 5ee204bcbeef..28df4b50b87a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -168,7 +168,7 @@ static int apci16xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci16xx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { +static const struct pci_device_id apci16xx_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x1009), BOARD_APCI1648 }, { PCI_VDEVICE(ADDIDATA, 0x100a), BOARD_APCI1696 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index c77ee8732d38..c9b933cb5987 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -359,7 +359,7 @@ static int apci2032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2032_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { +static const struct pci_device_id apci2032_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 7fb32e778d8b..e1a916546d18 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -134,7 +134,7 @@ static int apci2200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2200_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = { +static const struct pci_device_id apci2200_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 67d09e8afb2e..1e6fa56c516e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -230,7 +230,7 @@ static int apci3120_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { +static const struct pci_device_id apci3120_pci_table[] = { { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 }, { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 1213d5aa6bea..9868a5369aff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -109,7 +109,7 @@ static int apci3200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { +static const struct pci_device_id apci3200_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 }, { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 6138440b919e..4cb69ec54c9b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -428,7 +428,7 @@ static int apci3501_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { +static const struct pci_device_id apci3501_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 761cbf8f964b..ceadf8eff47f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -915,7 +915,7 @@ static int apci3xxx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { +static const struct pci_device_id apci3xxx_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 }, { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 }, { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 }, diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index dd092c7954a9..5c1413abc52d 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -242,7 +242,7 @@ static int adl_pci6208_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { +static const struct pci_device_id adl_pci6208_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 }, { PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 }, { 0 } diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 5617f5ca384a..6f622b4de698 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -259,7 +259,7 @@ static int adl_pci7x3x_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = { +static const struct pci_device_id adl_pci7x3x_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 }, { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 }, { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 }, diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index b3d009285ed4..300df55a2802 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -145,7 +145,7 @@ static int adl_pci8164_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { +static const struct pci_device_id adl_pci8164_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index eab8da2c3d66..de763ec4ce21 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -470,11 +470,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct pci9111_private_data *dev_private = dev->private; struct comedi_cmd *async_cmd = &s->async->cmd; - if (!dev->irq) { - comedi_error(dev, - "no irq assigned for PCI9111, cannot do hardware conversion"); - return -1; - } /* Set channel scan limit */ /* PCI9111 allows only scanning from channel 0 to channel n */ /* TODO: handle the case of an external multiplexer */ @@ -858,12 +853,11 @@ static int pci9111_auto_attach(struct comedi_device *dev, pci9111_reset(dev); - if (pcidev->irq > 0) { - ret = request_irq(dev->irq, pci9111_interrupt, + if (pcidev->irq) { + ret = request_irq(pcidev->irq, pci9111_interrupt, IRQF_SHARED, dev->board_name, dev); - if (ret) - return ret; - dev->irq = pcidev->irq; + if (ret == 0) + dev->irq = pcidev->irq; } ret = comedi_alloc_subdevices(dev, 4); @@ -871,18 +865,21 @@ static int pci9111_auto_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_COMMON; s->n_chan = 16; s->maxdata = 0xffff; - s->len_chanlist = 16; s->range_table = &pci9111_ai_range; - s->cancel = pci9111_ai_cancel; s->insn_read = pci9111_ai_insn_read; - s->do_cmdtest = pci9111_ai_do_cmd_test; - s->do_cmd = pci9111_ai_do_cmd; - s->munge = pci9111_ai_munge; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmdtest = pci9111_ai_do_cmd_test; + s->do_cmd = pci9111_ai_do_cmd; + s->cancel = pci9111_ai_cancel; + s->munge = pci9111_ai_munge; + } s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -938,7 +935,7 @@ static int pci9111_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { +static const struct pci_device_id pci9111_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ { 0 } diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 986489641ed7..a1de96356e30 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1126,7 +1126,7 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) } } - (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat, + (devpriv->int_ai_func) (dev, dev->read_subdev, int_adstat, int_amcc, int_daq); } @@ -1965,7 +1965,6 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret, pages, i; - unsigned int irq; u16 u16w; dev->board_name = this_board->name; @@ -2036,12 +2035,18 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ + if (!disable_irq && pcidev->irq) { + ret = request_irq(pcidev->irq, interrupt_pci9118, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; if (devpriv->usemux) @@ -2050,11 +2055,17 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, s->n_chan = this_board->n_aichan; s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->n_aichanlist; s->range_table = this_board->rangelist_ai; - s->cancel = pci9118_ai_cancel; s->insn_read = pci9118_insn_read_ai; - s->munge = pci9118_ai_munge; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = this_board->n_aichanlist; + s->do_cmdtest = pci9118_ai_cmdtest; + s->do_cmd = pci9118_ai_cmd; + s->cancel = pci9118_ai_cancel; + s->munge = pci9118_ai_munge; + } s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -2100,27 +2111,7 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, break; } - if (disable_irq) - irq = 0; - else - irq = pcidev->irq; - if (irq > 0) { - if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - dev->board_name, dev)) { - dev_warn(dev->class_dev, - "unable to allocate IRQ %u, DISABLING IT\n", - irq); - } else { - dev->irq = irq; - /* Enable AI commands */ - s = &dev->subdevices[0]; - s->subdev_flags |= SDF_CMD_READ; - s->do_cmdtest = pci9118_ai_cmdtest; - s->do_cmd = pci9118_ai_cmd; - } - } - - pci9118_report_attach(dev, irq); + pci9118_report_attach(dev, dev->irq); return 0; } @@ -2217,7 +2208,7 @@ static int adl_pci9118_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = { +static const struct pci_device_id adl_pci9118_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 8150a67cd1fb..79e06b9b6bc9 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -162,8 +162,6 @@ static int adq12b_ai_rinsn(struct comedi_device *dev, hi = inb(dev->iobase + ADQ12B_ADHIG); lo = inb(dev->iobase + ADQ12B_ADLOW); - /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", - channel, range, status, hi, lo); */ data[n] = (hi << 8) | lo; } diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index c3fdcabe9aec..3957da5500e2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -731,7 +731,7 @@ static void interrupt_pci1710_every_sample(void *d) { struct comedi_device *dev = d; struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int m; #ifdef PCI171x_PARANOIDCHECK const struct boardtype *this_board = comedi_board(dev); @@ -740,16 +740,15 @@ static void interrupt_pci1710_every_sample(void *d) m = inw(dev->iobase + PCI171x_STATUS); if (m & Status_FE) { - printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m); + dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); return; } if (m & Status_FF) { - printk - ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, + "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -825,12 +824,12 @@ static int move_block_from_fifo(struct comedi_device *dev, sampl = inw(dev->iobase + PCI171x_AD_DATA); if (this_board->cardtype != TYPE_PCI1713) if ((sampl & 0xf000) != devpriv->act_chanlist[j]) { - printk - ("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n", - dev->minor, (sampl & 0xf000) >> 12, - (devpriv->act_chanlist[j] & 0xf000) >> 12, - i, j, devpriv->ai_act_scan, n, turn, - sampl); + dev_dbg(dev->class_dev, + "A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n", + (sampl & 0xf000) >> 12, + (devpriv->act_chanlist[j] & 0xf000) >> 12, + i, j, devpriv->ai_act_scan, n, turn, + sampl); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; @@ -860,22 +859,20 @@ static void interrupt_pci1710_half_fifo(void *d) struct comedi_device *dev = d; const struct boardtype *this_board = comedi_board(dev); struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int m, samplesinbuf; m = inw(dev->iobase + PCI171x_STATUS); if (!(m & Status_FH)) { - printk("comedi%d: A/D FIFO not half full! (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); return; } if (m & Status_FF) { - printk - ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, + "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -1267,21 +1264,21 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_aichan) { s = &dev->subdevices[subdev]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; if (this_board->n_aichand) s->subdev_flags |= SDF_DIFF; s->n_chan = this_board->n_aichan; s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->n_aichan; s->range_table = this_board->rangelist_ai; - s->cancel = pci171x_ai_cancel; s->insn_read = pci171x_insn_read_ai; if (dev->irq) { + dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; s->do_cmdtest = pci171x_ai_cmdtest; s->do_cmd = pci171x_ai_cmd; + s->cancel = pci171x_ai_cancel; } devpriv->i8254_osc_base = I8254_OSC_BASE_10MHZ; subdev++; @@ -1374,7 +1371,7 @@ static int adv_pci1710_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { +static const struct pci_device_id adv_pci1710_pci_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index bd4f781b4b24..72394267ddfe 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -306,7 +306,7 @@ static int adv_pci1723_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1723_pci_table) = { +static const struct pci_device_id adv_pci1723_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index 009a3039fc4f..56f2d97b3a46 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -381,7 +381,7 @@ static int adv_pci1724_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1724_pci_table) = { +static const struct pci_device_id adv_pci1724_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1724) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 6bac665261f8..d4bd61d84daf 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1188,7 +1188,7 @@ static int adv_pci_dio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { +static const struct pci_device_id adv_pci_dio_pci_table[] = { { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 }, { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 }, { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 }, diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 2e4bf284d52c..9c9559ffc643 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -513,7 +513,7 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, int event = 0; spin_lock_irqsave(&subpriv->spinlock, flags); - subpriv->active = 1; + subpriv->active = true; /* Set up end of acquisition. */ switch (cmd->stop_src) { diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index a810a2416443..e0367380b37a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -439,7 +439,7 @@ static struct comedi_driver dio200_pci_comedi_driver = { .detach = dio200_pci_detach, }; -static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { +static const struct pci_device_id dio200_pci_table[] = { { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215), pci215_model diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 98075f999c9f..31734e1142fd 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -356,7 +356,7 @@ static int pc236_intr_cancel(struct comedi_device *dev, static irqreturn_t pc236_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[1]; + struct comedi_subdevice *s = dev->read_subdev; int handled; handled = pc236_intr_check(dev); @@ -567,7 +567,7 @@ static struct comedi_driver amplc_pc236_driver = { }; #if DO_PCI -static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { +static const struct pci_device_id pc236_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} }; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 810e397d8fd7..f16b4724632c 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -909,16 +909,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } if (errors) { if (errors & dupchan_err) { - DPRINTK("comedi%d: " DRIVER_NAME - ": ao_cmdtest: " - "entries in chanlist must contain no " - "duplicate channels\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: entries in chanlist must contain no duplicate channels\n", + __func__); } if (errors & range_err) { - DPRINTK("comedi%d: " DRIVER_NAME - ": ao_cmdtest: " - "entries in chanlist must all have " - "the same range index\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: entries in chanlist must all have the same range index\n", + __func__); } err++; } @@ -1142,7 +1140,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct pci224_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->write_subdev; struct comedi_cmd *cmd; unsigned char intstat, valid_intstat; unsigned char curenab; @@ -1498,7 +1496,7 @@ static int amplc_pci224_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = { +static const struct pci_device_id amplc_pci224_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) }, { 0 } diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a97bbd6ca3db..48a0f527b431 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -818,9 +818,9 @@ static int pci230_ai_rinsn(struct comedi_device *dev, if (aref == AREF_DIFF) { /* Differential. */ if (chan >= s->n_chan / 2) { - DPRINTK("comedi%d: amplc_pci230: ai_rinsn: " - "differential channel number out of range " - "0 to %u\n", dev->minor, (s->n_chan / 2) - 1); + dev_dbg(dev->class_dev, + "%s: differential channel number out of range 0 to %u\n", + __func__, (s->n_chan / 2) - 1); return -EINVAL; } } @@ -1092,14 +1092,14 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if (errors != 0) { err++; if ((errors & seq_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: " - "channel numbers must increase\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel numbers must increase\n", + __func__); } if ((errors & range_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: " - "channels must have the same range\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channels must have the same range\n", + __func__); } } } @@ -1835,33 +1835,29 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if (errors != 0) { err++; if ((errors & seq_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel numbers must increase or " - "sequence must repeat exactly\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel numbers must increase or sequence must repeat exactly\n", + __func__); } if ((errors & rangepair_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "single-ended channel pairs must " - "have the same range\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: single-ended channel pairs must have the same range\n", + __func__); } if ((errors & polarity_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel sequence ranges must be all " - "bipolar or all unipolar\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel sequence ranges must be all bipolar or all unipolar\n", + __func__); } if ((errors & aref_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel sequence analogue references " - "must be all the same (single-ended " - "or differential)\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: channel sequence analogue references must be all the same (single-ended or differential)\n", + __func__); } if ((errors & diffchan_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "differential channel number out of " - "range 0 to %u\n", dev->minor, - (s->n_chan / 2) - 1); + dev_dbg(dev->class_dev, + "%s: differential channel number out of range 0 to %u\n", + __func__, (s->n_chan / 2) - 1); } if ((errors & buggy_chan0_err) != 0) { dev_info(dev->class_dev, @@ -2637,7 +2633,7 @@ static int pci230_attach_common(struct comedi_device *dev, struct comedi_subdevice *s; unsigned long iobase1, iobase2; /* PCI230's I/O spaces 1 and 2 respectively. */ - int irq_hdl, rc; + int rc; comedi_set_hw_dev(dev, &pci_dev->dev); @@ -2709,16 +2705,12 @@ static int pci230_attach_common(struct comedi_device *dev, outw(devpriv->adcg, dev->iobase + PCI230_ADCG); outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON); - /* Register the interrupt handler. */ - irq_hdl = request_irq(pci_dev->irq, pci230_interrupt, - IRQF_SHARED, "amplc_pci230", dev); - if (irq_hdl < 0) { - dev_warn(dev->class_dev, - "unable to register irq %u, commands will not be available\n", - pci_dev->irq); - } else { - dev->irq = pci_dev->irq; - dev_dbg(dev->class_dev, "registered irq %u\n", pci_dev->irq); + + if (pci_dev->irq) { + rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (rc == 0) + dev->irq = pci_dev->irq; } rc = comedi_alloc_subdevices(dev, 3); @@ -2734,14 +2726,14 @@ static int pci230_attach_common(struct comedi_device *dev, s->range_table = &pci230_ai_range; s->insn_read = &pci230_ai_rinsn; s->len_chanlist = 256; /* but there are restrictions. */ - /* Only register commands if the interrupt handler is installed. */ - if (irq_hdl == 0) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->do_cmd = &pci230_ai_cmd; s->do_cmdtest = &pci230_ai_cmdtest; s->cancel = pci230_ai_cancel; } + s = &dev->subdevices[1]; /* analog output subdevice */ if (thisboard->ao_chans > 0) { @@ -2753,9 +2745,7 @@ static int pci230_attach_common(struct comedi_device *dev, s->insn_write = &pci230_ao_winsn; s->insn_read = &pci230_ao_rinsn; s->len_chanlist = thisboard->ao_chans; - /* Only register commands if the interrupt handler is - * installed. */ - if (irq_hdl == 0) { + if (dev->irq) { dev->write_subdev = s; s->subdev_flags |= SDF_CMD_WRITE; s->do_cmd = &pci230_ao_cmd; @@ -2765,6 +2755,7 @@ static int pci230_attach_common(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } + s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->have_dio) { @@ -2856,7 +2847,7 @@ static int amplc_pci230_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = { +static const struct pci_device_id amplc_pci230_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) }, { 0 } diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index 4bd4ef8e88cd..be28e6cbea20 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -96,7 +96,7 @@ static struct comedi_driver amplc_pci263_driver = { .detach = comedi_pci_disable, }; -static DEFINE_PCI_DEVICE_TABLE(pci263_pci_table) = { +static const struct pci_device_id pci263_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} }; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 217aa19cdc32..5034f663eec9 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -94,8 +94,6 @@ static void C6X_pwmInit(unsigned long baseAddr) { int timeout = 0; -/* printk("Inside C6X_pwmInit\n"); */ - WriteByteToHwPort(baseAddr, 0x70); while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { @@ -132,8 +130,6 @@ static void C6X_pwmOutput(unsigned long baseAddr, unsigned channel, int value) int timeout = 0; unsigned tmp; - /* printk("Inside C6X_pwmOutput\n"); */ - pwm.cmd = value; if (pwm.cmd > 498) pwm.cmd = 498; @@ -200,8 +196,6 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel) int timeout = 0; int tmp; - /* printk("Inside C6X_encInput\n"); */ - enc.value = 0; if (channel == 0) ppcmd = 0x48; @@ -295,8 +289,6 @@ static void C6X_encResetAll(unsigned long baseAddr) { unsigned timeout = 0; -/* printk("Inside C6X_encResetAll\n"); */ - WriteByteToHwPort(baseAddr, 0x68); while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { @@ -322,14 +314,6 @@ static void C6X_encResetAll(unsigned long baseAddr) } } -static int c6xdigio_pwmo_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - printk(KERN_DEBUG "c6xdigio_pwmo_insn_read %x\n", insn->n); - return insn->n; -} - static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -338,7 +322,6 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, int i; int chan = CR_CHAN(insn->chanspec); - /* printk("c6xdigio_pwmo_insn_write %x\n", insn->n); */ for (i = 0; i < insn->n; i++) { C6X_pwmOutput(dev->iobase, chan, data[i]); /* devpriv->ao_readback[chan] = data[i]; */ @@ -346,31 +329,10 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, return i; } -/* static int c6xdigio_ei_init_insn_read(struct comedi_device *dev, */ -/* struct comedi_subdevice *s, */ -/* struct comedi_insn *insn, */ -/* unsigned int *data) */ -/* { */ -/* printk("c6xdigio_ei_init_insn_read %x\n", insn->n); */ -/* return insn->n; */ -/* } */ - -/* static int c6xdigio_ei_init_insn_write(struct comedi_device *dev, */ -/* struct comedi_subdevice *s, */ -/* struct comedi_insn *insn, */ -/* unsigned int *data) */ -/* { */ -/* int i; */ -/* int chan = CR_CHAN(insn->chanspec); */ - /* *//* C6X_encResetAll( dev->iobase ); */ - /* *//* return insn->n; */ -/* } */ - static int c6xdigio_ei_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - /* printk("c6xdigio_ei__insn_read %x\n", insn->n); */ int n; int chan = CR_CHAN(insn->chanspec); @@ -382,12 +344,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev, static void board_init(struct comedi_device *dev) { - - /* printk("Inside board_init\n"); */ - C6X_pwmInit(dev->iobase); C6X_encResetAll(dev->iobase); - } static const struct pnp_device_id c6xdigio_pnp_tbl[] = { @@ -426,7 +384,6 @@ static int c6xdigio_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE; s->n_chan = 2; /* s->trig[0] = c6xdigio_pwmo; */ - s->insn_read = c6xdigio_pwmo_insn_read; s->insn_write = c6xdigio_pwmo_insn_write; s->maxdata = 500; s->range_table = &range_bipolar10; /* A suitable lie */ @@ -441,17 +398,6 @@ static int c6xdigio_attach(struct comedi_device *dev, s->maxdata = 0xffffff; s->range_table = &range_unknown; - /* s = &dev->subdevices[2]; */ - /* pwm output subdevice */ - /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ - /* s->subdev_flags = SDF_WRITEABLE; */ - /* s->n_chan = 1; */ - /* s->trig[0] = c6xdigio_ei_init; */ - /* s->insn_read = c6xdigio_ei_init_insn_read; */ - /* s->insn_write = c6xdigio_ei_init_insn_write; */ - /* s->maxdata = 0xFFFF; // Really just a don't care */ - /* s->range_table = &range_unknown; // Not sure what to put here */ - /* I will call this init anyway but more than likely the DSP board */ /* will not be connected when device driver is loaded. */ board_init(dev); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e72a403db17c..22c1623c048b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1614,7 +1614,7 @@ static int cb_pcidas_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { +static const struct pci_device_id cb_pcidas_pci_table[] = { { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 }, { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 }, { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 }, diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index ff5206536be3..0fcedd050425 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -94,15 +94,6 @@ TODO: #include "plx9080.h" #include "comedi_fc.h" -#undef PCIDAS64_DEBUG /* disable debugging code */ -/* #define PCIDAS64_DEBUG enable debugging code */ - -#ifdef PCIDAS64_DEBUG -#define DEBUG_PRINT(format, args...) pr_debug(format, ## args) -#else -#define DEBUG_PRINT(format, args...) no_printk(format, ## args) -#endif - #define TIMER_BASE 25 /* 40MHz master clock */ /* 100kHz 'prescaled' clock for slow acquisition, * maybe I'll support this someday */ @@ -1252,8 +1243,6 @@ static void disable_ai_interrupts(struct comedi_device *dev) writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); } static void enable_ai_interrupts(struct comedi_device *dev, @@ -1277,7 +1266,6 @@ static void enable_ai_interrupts(struct comedi_device *dev, devpriv->intr_enable_bits |= bits; writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -1292,38 +1280,6 @@ static void init_plx9080(struct comedi_device *dev) devpriv->plx_control_bits = readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); - /* plx9080 dump */ - DEBUG_PRINT(" plx interrupt status 0x%x\n", - readl(plx_iobase + PLX_INTRCS_REG)); - DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits); - DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n", - readl(plx_iobase + PLX_MARB_REG)); - DEBUG_PRINT(" plx region0 reg 0x%x\n", - readl(plx_iobase + PLX_REGION0_REG)); - DEBUG_PRINT(" plx region1 reg 0x%x\n", - readl(plx_iobase + PLX_REGION1_REG)); - - DEBUG_PRINT(" plx revision 0x%x\n", - readl(plx_iobase + PLX_REVISION_REG)); - DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n", - readl(plx_iobase + PLX_DMA0_MODE_REG)); - DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n", - readl(plx_iobase + PLX_DMA1_MODE_REG)); - DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n", - readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n", - readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n", - readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG)); - DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n", - readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n", - readb(plx_iobase + PLX_DMA0_CS_REG)); - DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n", - readl(plx_iobase + PLX_DMA0_THRESHOLD_REG)); - DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG)); - #ifdef __BIG_ENDIAN bits = BIGEND_DMA0 | BIGEND_DMA1; #else @@ -1417,9 +1373,6 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, devpriv->ai_fifo_segment_length = num_increments * increment_size; - DEBUG_PRINT("set hardware fifo segment length to %i\n", - devpriv->ai_fifo_segment_length); - return devpriv->ai_fifo_segment_length; } @@ -1441,8 +1394,6 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; - DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); - return num_samples; } @@ -1538,8 +1489,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) if (devpriv->ai_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(thisboard)) { devpriv->ao_dma_desc = pci_alloc_consistent(pcidev, @@ -1548,9 +1497,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) &devpriv->ao_dma_desc_bus_addr); if (devpriv->ao_dma_desc == NULL) return -ENOMEM; - - DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ for (i = 0; i < ai_dma_ring_count(thisboard); i++) { @@ -1650,8 +1596,6 @@ static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) uint8_t bit; unsigned int num_bits = 8; - DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); - for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { i2c_set_scl(dev, 0); if ((byte & bit)) @@ -1738,7 +1682,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; static const int timeout = 100; - DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec); channel = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); aref = CR_AREF(insn->chanspec); @@ -1766,7 +1709,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (insn->chanspec & CR_ALT_SOURCE) { unsigned int cal_en_bit; - DEBUG_PRINT("reading calibration source\n"); if (thisboard->layout == LAYOUT_60XX) cal_en_bit = CAL_EN_60XX_BIT; else @@ -1800,7 +1742,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; if (insn->chanspec & CR_ALT_SOURCE) { - DEBUG_PRINT("reading calibration source\n"); devpriv->i2c_cal_range_bits |= adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ @@ -1839,7 +1780,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* wait for data */ for (i = 0; i < timeout; i++) { bits = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); if (thisboard->layout == LAYOUT_4020) { if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) @@ -1850,7 +1790,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } udelay(1); } - DEBUG_PRINT(" looped %i times waiting for data\n", i); if (i == timeout) { comedi_error(dev, " analog input read insn timed out"); dev_info(dev->class_dev, "status 0x%x\n", bits); @@ -1884,7 +1823,6 @@ static int ai_config_calibration_source(struct comedi_device *dev, return -EINVAL; } - DEBUG_PRINT("setting calibration source to %i\n", source); devpriv->calibration_source = source; return 2; @@ -2368,7 +2306,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load lower 16 bits of convert interval */ writew(convert_counter & 0xffff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); - DEBUG_PRINT("convert counter 0x%x\n", convert_counter); /* load upper 8 bits of convert interval */ writew((convert_counter >> 16) & 0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); @@ -2378,7 +2315,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load upper 8 bits of scan delay */ writew((scan_counter >> 16) & 0xff, devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); - DEBUG_PRINT("scan counter 0x%x\n", scan_counter); } static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) @@ -2469,9 +2405,6 @@ static int setup_channel_queue(struct comedi_device *dev, writew(bits, devpriv->main_iobase + ADC_QUEUE_FIFO_REG); - DEBUG_PRINT( - "wrote 0x%x to external channel queue\n", - bits); } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ @@ -2593,7 +2526,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } writew(devpriv->adc_control1_bits, devpriv->main_iobase + ADC_CONTROL1_REG); - DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits); spin_unlock_irqrestore(&dev->spinlock, flags); /* clear adc buffer */ @@ -2645,17 +2577,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (use_hw_sample_counter(cmd)) bits |= ADC_SAMPLE_COUNTER_EN_BIT; writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG); - DEBUG_PRINT("control0 bits 0x%x\n", bits); devpriv->ai_cmd_running = 1; spin_unlock_irqrestore(&dev->spinlock, flags); /* start acquisition */ - if (cmd->start_src == TRIG_NOW) { + if (cmd->start_src == TRIG_NOW) writew(0, devpriv->main_iobase + ADC_START_REG); - DEBUG_PRINT("soft trig\n"); - } return 0; } @@ -2690,10 +2619,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) read_segment = adc_upper_read_ptr_code(prepost_bits); write_segment = adc_upper_write_ptr_code(prepost_bits); - DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n", - read_segment, write_segment, read_index, - write_index); - if (read_segment != write_segment) num_samples = devpriv->ai_fifo_segment_length - read_index; @@ -2715,8 +2640,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) break; } - DEBUG_PRINT(" read %i samples from fifo\n", num_samples); - for (i = 0; i < num_samples; i++) { cfc_write_to_buffer(s, readw(devpriv->main_iobase + @@ -2812,11 +2735,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) num_samples * sizeof(uint16_t)); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % ai_dma_ring_count(thisboard); - - DEBUG_PRINT("next buffer addr 0x%lx\n", - (unsigned long)devpriv-> - ai_buffer_bus_addr[devpriv->ai_dma_index]); - DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } /* XXX check for dma ring buffer overrun * (use end-of-chain bit to mark last unused buffer) */ @@ -2845,24 +2763,17 @@ static void handle_ai_interrupt(struct comedi_device *dev, if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA1_CS_REG); - DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); if (dma1_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 1); - - DEBUG_PRINT(" cleared dma ch1 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); - if (status & ADC_DONE_BIT) - DEBUG_PRINT("adc done interrupt\n"); - /* drain fifo with pio */ if ((status & ADC_DONE_BIT) || ((cmd->flags & TRIG_WAKE_EOS) && (status & ADC_INTR_PENDING_BIT) && (thisboard->layout != LAYOUT_4020))) { - DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->ai_cmd_running) { spin_unlock_irqrestore(&dev->spinlock, flags); @@ -2947,7 +2858,6 @@ static void restart_ao_dma(struct comedi_device *dev) dma_desc_bits = readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; - DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); dma_start_sync(dev, 0); @@ -2963,10 +2873,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, buffer_index = devpriv->ao_dma_index; prev_buffer_index = prev_ao_dma_index(dev); - DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, - (unsigned long long)devpriv->ao_buffer_bus_addr[ - buffer_index]); - num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); if (num_bytes > DMA_BUFFER_SIZE) num_bytes = DMA_BUFFER_SIZE; @@ -2977,8 +2883,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, if (num_bytes == 0) return 0; - DEBUG_PRINT("loading %i bytes\n", num_bytes); - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, devpriv-> ao_buffer[buffer_index], @@ -3052,14 +2956,12 @@ static void handle_ao_interrupt(struct comedi_device *dev, writeb(PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) { load_ao_dma(dev, cmd); /* try to recover from dma end-of-chain event */ if (ao_dma_needs_restart(dev, dma0_status)) restart_ao_dma(dev); } - DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } else { spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -3068,12 +2970,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, async->events |= COMEDI_CB_EOA; if (ao_stopped_by_error(dev, cmd)) async->events |= COMEDI_CB_ERROR; - DEBUG_PRINT("plx dma0 desc reg 0x%x\n", - readl(devpriv->plx9080_iobase + - PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT("plx dma0 address reg 0x%x\n", - readl(devpriv->plx9080_iobase + - PLX_DMA0_PCI_ADDRESS_REG)); } cfc_handle_events(dev, s); } @@ -3089,15 +2985,12 @@ static irqreturn_t handle_interrupt(int irq, void *d) plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); status = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status); - /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ - if (!dev->attached) { - DEBUG_PRINT("premature interrupt, ignoring\n"); + if (!dev->attached) return IRQ_HANDLED; - } + handle_ai_interrupt(dev, status, plx_status); handle_ao_interrupt(dev, status, plx_status); @@ -3105,11 +2998,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); - DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } - DEBUG_PRINT("exiting handler\n"); - return IRQ_HANDLED; } @@ -3130,7 +3020,6 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) abort_dma(dev, 1); - DEBUG_PRINT("ai canceled\n"); return 0; } @@ -3458,7 +3347,6 @@ static int dio_callback(int dir, int port, int data, unsigned long arg) void __iomem *iobase = (void __iomem *)arg; if (dir) { writeb(data, iobase + port); - DEBUG_PRINT("wrote 0x%x to port %i\n", data, port); return 0; } else { return readb(iobase + port); @@ -4046,11 +3934,6 @@ static int auto_attach(struct comedi_device *dev, return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); - DEBUG_PRINT(" diocounter remapped to 0x%p\n", - devpriv->dio_counter_iobase); - /* figure out what local addresses are */ local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; @@ -4065,9 +3948,6 @@ static int auto_attach(struct comedi_device *dev, devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & ~local_range) | local_decode; - DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); - retval = alloc_and_init_dma_members(dev); if (retval < 0) return retval; @@ -4161,7 +4041,7 @@ static int cb_pcidas64_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { +static const struct pci_device_id cb_pcidas64_pci_table[] = { { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 }, { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 }, { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 }, diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 94f115820279..8cca0518cfda 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -407,7 +407,7 @@ static int cb_pcidda_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { +static const struct pci_device_id cb_pcidda_pci_table[] = { { PCI_VDEVICE(CB, 0x0020), BOARD_DDA02_12 }, { PCI_VDEVICE(CB, 0x0021), BOARD_DDA04_12 }, { PCI_VDEVICE(CB, 0x0022), BOARD_DDA08_12 }, diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 30520d4c16a6..57295d189ff6 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -44,9 +44,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #include "plx9052.h" #include "8255.h" -/* #define CBPCIMDAS_DEBUG */ -#undef CBPCIMDAS_DEBUG - /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ @@ -145,10 +142,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, if (!busy) break; } - if (i == TIMEOUT) { - printk("timeout\n"); + if (i == TIMEOUT) return -ETIMEDOUT; - } + /* read data */ data[n] = inw(dev->iobase + 0); } @@ -222,15 +218,6 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, devpriv->BADR3 = pci_resource_start(pcidev, 3); iobase_8255 = pci_resource_start(pcidev, 4); -/* Dont support IRQ yet */ -/* get irq */ -/* if(request_irq(pcidev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev )) */ -/* { */ -/* printk(" unable to allocate irq %u\n", pcidev->irq); */ -/* return -EINVAL; */ -/* } */ -/* dev->irq = pcidev->irq; */ - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -288,7 +275,7 @@ static int cb_pcimdas_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { +static const struct pci_device_id cb_pcimdas_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index edf17b63096f..43a86630a66e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -206,7 +206,7 @@ static int cb_pcimdda_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { +static const struct pci_device_id cb_pcimdda_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 89836c0828d9..323a7f39cd97 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -111,7 +111,7 @@ static int contec_pci_dio_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { +static const struct pci_device_id contec_pci_dio_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index de920ccff400..ce153fcb8b2a 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -772,7 +772,7 @@ static int daqboard2000_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { +static const struct pci_device_id daqboard2000_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_IOTECH, 0x0409) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index 3a6d3725b25f..d94af09151b0 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -89,7 +89,7 @@ static int das08_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { +static const struct pci_device_id das08_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index fce9acfe8084..36c2ba5057fa 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -269,11 +269,6 @@ static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_cmd *cmd = &async->cmd; unsigned int byte, i; - if (dev->irq == 0) { - comedi_error(dev, "irq required to execute comedi_cmd"); - return -1; - } - /* disable interrupts and internal pacer */ devpriv->control_state &= ~INTE & ~PACER_MASK; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); @@ -508,38 +503,26 @@ static irqreturn_t das16m1_interrupt(int irq, void *d) static int das16m1_irq_bits(unsigned int irq) { - int ret; - switch (irq) { case 10: - ret = 0x0; - break; + return 0x0; case 11: - ret = 0x1; - break; + return 0x1; case 12: - ret = 0x2; - break; + return 0x2; case 15: - ret = 0x3; - break; + return 0x3; case 2: - ret = 0x4; - break; + return 0x4; case 3: - ret = 0x5; - break; + return 0x5; case 5: - ret = 0x6; - break; + return 0x6; case 7: - ret = 0x7; - break; + return 0x7; default: - return -1; - break; + return 0x0; } - return ret << 4; } /* @@ -553,7 +536,6 @@ static int das16m1_attach(struct comedi_device *dev, struct das16m1_private_struct *devpriv; struct comedi_subdevice *s; int ret; - unsigned int irq; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -569,24 +551,12 @@ static int das16m1_attach(struct comedi_device *dev, return ret; devpriv->extra_iobase = dev->iobase + DAS16M1_82C55; - /* now for the irq */ - irq = it->options[1]; - /* make sure it is valid */ - if (das16m1_irq_bits(irq) >= 0) { - ret = request_irq(irq, das16m1_interrupt, 0, - dev->driver->driver_name, dev); - if (ret < 0) - return ret; - dev->irq = irq; - printk - ("irq %u\n", irq); - } else if (irq == 0) { - printk - (", no irq\n"); - } else { - comedi_error(dev, "invalid irq\n" - " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n"); - return -EINVAL; + /* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */ + if ((1 << it->options[1]) & 0xdcfc) { + ret = request_irq(it->options[1], das16m1_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } ret = comedi_alloc_subdevices(dev, 4); @@ -594,20 +564,22 @@ static int das16m1_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF; s->n_chan = 8; - s->subdev_flags = SDF_DIFF; - s->len_chanlist = 256; s->maxdata = (1 << 12) - 1; s->range_table = &range_das16m1; s->insn_read = das16m1_ai_rinsn; - s->do_cmdtest = das16m1_cmd_test; - s->do_cmd = das16m1_cmd_exec; - s->cancel = das16m1_cancel; - s->poll = das16m1_poll; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 256; + s->do_cmdtest = das16m1_cmd_test; + s->do_cmd = das16m1_cmd_exec; + s->cancel = das16m1_cancel; + s->poll = das16m1_poll; + } s = &dev->subdevices[1]; /* di */ @@ -640,10 +612,7 @@ static int das16m1_attach(struct comedi_device *dev, outb(0, dev->iobase + DAS16M1_DIO); /* set the interrupt level */ - if (dev->irq) - devpriv->control_state = das16m1_irq_bits(dev->irq); - else - devpriv->control_state = 0; + devpriv->control_state = das16m1_irq_bits(dev->irq) << 4; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); return 0; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 1880038956d0..37e92a0373f1 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -644,7 +644,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void das1800_ai_handler(struct comedi_device *dev) { struct das1800_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int status = inb(dev->iobase + DAS1800_STATUS); @@ -1150,12 +1150,6 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_async *async = s->async; const struct comedi_cmd *cmd = &async->cmd; - if (!dev->irq) { - comedi_error(dev, - "no irq assigned for das-1800, cannot do hardware conversions"); - return -1; - } - /* disable dma on TRIG_WAKE_EOS, or TRIG_RT * (because dma in handler is unsafe at hard real-time priority) */ if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) @@ -1522,43 +1516,34 @@ static int das1800_attach(struct comedi_device *dev, devpriv->iobase2 = iobase2; } - /* grab our IRQ */ - if (irq) { - if (request_irq(irq, das1800_interrupt, 0, - dev->driver->driver_name, dev)) { - dev_dbg(dev->class_dev, "unable to allocate irq %u\n", - irq); - return -EINVAL; - } - } - dev->irq = irq; + if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 || + irq == 15) { + ret = request_irq(irq, das1800_interrupt, 0, + dev->board_name, dev); + if (ret == 0) { + dev->irq = irq; - /* set bits that tell card which irq to use */ - switch (irq) { - case 0: - break; - case 3: - devpriv->irq_dma_bits |= 0x8; - break; - case 5: - devpriv->irq_dma_bits |= 0x10; - break; - case 7: - devpriv->irq_dma_bits |= 0x18; - break; - case 10: - devpriv->irq_dma_bits |= 0x28; - break; - case 11: - devpriv->irq_dma_bits |= 0x30; - break; - case 15: - devpriv->irq_dma_bits |= 0x38; - break; - default: - dev_err(dev->class_dev, "irq out of range\n"); - return -EINVAL; - break; + switch (irq) { + case 3: + devpriv->irq_dma_bits |= 0x8; + break; + case 5: + devpriv->irq_dma_bits |= 0x10; + break; + case 7: + devpriv->irq_dma_bits |= 0x18; + break; + case 10: + devpriv->irq_dma_bits |= 0x28; + break; + case 11: + devpriv->irq_dma_bits |= 0x30; + break; + case 15: + devpriv->irq_dma_bits |= 0x38; + break; + } + } } ret = das1800_init_dma(dev, dma0, dma1); @@ -1578,20 +1563,23 @@ static int das1800_attach(struct comedi_device *dev, /* analog input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; if (thisboard->common) s->subdev_flags |= SDF_COMMON; s->n_chan = thisboard->qram_len; - s->len_chanlist = thisboard->qram_len; s->maxdata = (1 << thisboard->resolution) - 1; s->range_table = thisboard->range_ai; - s->do_cmd = das1800_ai_do_cmd; - s->do_cmdtest = das1800_ai_do_cmdtest; s->insn_read = das1800_ai_rinsn; - s->poll = das1800_ai_poll; - s->cancel = das1800_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmd = das1800_ai_do_cmd; + s->do_cmdtest = das1800_ai_do_cmdtest; + s->poll = das1800_ai_poll; + s->cancel = das1800_cancel; + } /* analog out */ s = &dev->subdevices[1]; diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index fb25cb847032..e80c19a892cd 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -152,21 +152,12 @@ static irqreturn_t intr_handler(int irq, void *d) dev_warn(dev->class_dev, "BUG: spurious interrupt\n"); return IRQ_HANDLED; } -#ifdef DEBUG - printk("das6402: interrupt! das6402_irqcount=%i\n", - devpriv->das6402_irqcount); - printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2)); -#endif das6402_ai_fifo_dregs(dev, s); if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) { outw_p(SCANL, dev->iobase + 2); /* clears the fifo */ outb(0x07, dev->iobase + 8); /* clears all flip-flops */ -#ifdef DEBUG - printk("das6402: Got %i samples\n\n", - devpriv->das6402_wordsread - diff); -#endif s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); } diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index b04a5633f754..174735d37b51 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -182,8 +182,6 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1); range = CR_RANGE(insn->chanspec); - /* printk("channel=0x%02x, range=%d\n",chan,range); */ - /* zero scan and fifo control and reset fifo */ outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); @@ -199,10 +197,8 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } /* convert n samples */ for (n = 0; n < insn->n; n++) { @@ -214,10 +210,8 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } /* read data */ lsb = inb(dev->iobase + DMM32AT_AILSB); @@ -453,10 +447,8 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } if (devpriv->ai_scans_left > 1) { /* start the clock and enable the interrupts */ @@ -467,8 +459,6 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(0xff, dev->iobase + DMM32AT_CONV); } -/* printk("dmmat32 in command\n"); */ - /* for(i=0;i<cmd->chanlist_len;i++) */ /* comedi_buf_put(s->async,i*100); */ @@ -556,7 +546,6 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, lo = data[i] & 0x00ff; /* high byte also contains channel number */ hi = (data[i] >> 8) + chan * (1 << 6); - /* printk("writing 0x%02x 0x%02x\n",hi,lo); */ /* write the low and high values to the board */ outb(lo, dev->iobase + DMM32AT_DACLSB); outb(hi, dev->iobase + DMM32AT_DACMSB); @@ -567,10 +556,9 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, if ((status & DMM32AT_DACBUSY) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } + /* dummy read to update trigger the output */ status = inb(dev->iobase + DMM32AT_DACMSB); @@ -682,9 +670,6 @@ static int dmm32at_attach(struct comedi_device *dev, int ret; struct comedi_subdevice *s; unsigned char aihi, ailo, fifostat, aistat, intstat, airback; - unsigned int irq; - - irq = it->options[1]; ret = comedi_request_region(dev, it->options[0], DMM32AT_MEMSIZE); if (ret) @@ -723,26 +708,17 @@ static int dmm32at_attach(struct comedi_device *dev, intstat = inb(dev->iobase + DMM32AT_INTCLOCK); airback = inb(dev->iobase + DMM32AT_AIRBACK); - printk(KERN_DEBUG "dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n", - ailo, aihi, fifostat); - printk(KERN_DEBUG - "dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n", - aistat, intstat, airback); - if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) || (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) { - printk(KERN_ERR "dmmat32: board detection failed\n"); + dev_err(dev->class_dev, "board detection failed\n"); return -EIO; } - /* board is there, register interrupt */ - if (irq) { - ret = request_irq(irq, dmm32at_isr, 0, dev->board_name, dev); - if (ret < 0) { - printk(KERN_ERR "dmm32at: irq conflict\n"); - return ret; - } - dev->irq = irq; + if (it->options[1]) { + ret = request_irq(it->options[1], dmm32at_isr, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); @@ -754,20 +730,22 @@ static int dmm32at_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; /* we support single-ended (ground) and differential */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 32; s->maxdata = 0xffff; s->range_table = &dmm32at_airanges; - s->len_chanlist = 32; /* This is the maximum chanlist length that - the board can handle */ s->insn_read = dmm32at_ai_rinsn; - s->do_cmd = dmm32at_ai_cmd; - s->do_cmdtest = dmm32at_ai_cmdtest; - s->cancel = dmm32at_ai_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 32; + s->do_cmd = dmm32at_ai_cmd; + s->do_cmdtest = dmm32at_ai_cmdtest; + s->cancel = dmm32at_ai_cancel; + } s = &dev->subdevices[1]; /* analog output subdevice */ @@ -799,11 +777,7 @@ static int dmm32at_attach(struct comedi_device *dev, s->insn_bits = dmm32at_dio_insn_bits; s->insn_config = dmm32at_dio_insn_config; - /* success */ - printk(KERN_INFO "comedi%d: dmm32at: attached\n", dev->minor); - - return 1; - + return 0; } static struct comedi_driver dmm32at_driver = { diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 811c8c59c017..4bf2c7f8f551 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -289,13 +289,6 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data) outb_p(data & 0xff, dev->iobase + DT2801_DATA); return 0; } -#if 0 - if (stat & DT_S_READY) { - printk - ("dt2801: ready flag set (bad!) in dt2801_writedata()\n"); - return -EIO; - } -#endif } while (--timeout > 0); return -ETIME; @@ -343,11 +336,11 @@ static int dt2801_writecmd(struct comedi_device *dev, int command) stat = inb_p(dev->iobase + DT2801_STATUS); if (stat & DT_S_COMPOSITE_ERROR) { - printk - ("dt2801: composite-error in dt2801_writecmd(), ignoring\n"); + dev_dbg(dev->class_dev, + "composite-error in %s, ignoring\n", __func__); } if (!(stat & DT_S_READY)) - printk("dt2801: !ready in dt2801_writecmd(), ignoring\n"); + dev_dbg(dev->class_dev, "!ready in %s, ignoring\n", __func__); outb_p(command, dev->iobase + DT2801_CMD); return 0; @@ -359,17 +352,12 @@ static int dt2801_reset(struct comedi_device *dev) unsigned int stat; int timeout; - DPRINTK("dt2801: resetting board...\n"); - DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase), - inb_p(dev->iobase + 1)); - /* pull random data from data port */ inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); - DPRINTK("dt2801: stop\n"); /* dt2801_writecmd(dev,DT_C_STOP); */ outb_p(DT_C_STOP, dev->iobase + DT2801_CMD); @@ -382,12 +370,10 @@ static int dt2801_reset(struct comedi_device *dev) break; } while (timeout--); if (!timeout) - printk("dt2801: timeout 1 status=0x%02x\n", stat); + dev_dbg(dev->class_dev, "timeout 1 status=0x%02x\n", stat); - /* printk("dt2801: reading dummy\n"); */ /* dt2801_readdata(dev,&board_code); */ - DPRINTK("dt2801: reset\n"); outb_p(DT_C_RESET, dev->iobase + DT2801_CMD); /* dt2801_writecmd(dev,DT_C_RESET); */ @@ -399,13 +385,10 @@ static int dt2801_reset(struct comedi_device *dev) break; } while (timeout--); if (!timeout) - printk("dt2801: timeout 2 status=0x%02x\n", stat); + dev_dbg(dev->class_dev, "timeout 2 status=0x%02x\n", stat); - DPRINTK("dt2801: reading code\n"); dt2801_readdata(dev, &board_code); - DPRINTK("dt2801: ok. code=0x%02x\n", board_code); - return board_code; } @@ -465,12 +448,12 @@ static int dt2801_error(struct comedi_device *dev, int stat) { if (stat < 0) { if (stat == -ETIME) - printk("dt2801: timeout\n"); + dev_dbg(dev->class_dev, "timeout\n"); else - printk("dt2801: error %d\n", stat); + dev_dbg(dev->class_dev, "error %d\n", stat); return stat; } - printk("dt2801: error status 0x%02x, resetting...\n", stat); + dev_dbg(dev->class_dev, "error status 0x%02x, resetting...\n", stat); dt2801_reset(dev); dt2801_reset(dev); @@ -601,8 +584,8 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (boardtypes[type].boardcode == board_code) goto havetype; } - printk("dt2801: unrecognized board code=0x%02x, contact author\n", - board_code); + dev_dbg(dev->class_dev, + "unrecognized board code=0x%02x, contact author\n", board_code); type = 0; havetype: diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 0ca02fa7ba1b..115eb0ad77ef 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -42,7 +42,6 @@ Configuration options: */ #include <linux/module.h> -#include <linux/interrupt.h> #include "../comedidev.h" static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { @@ -227,33 +226,6 @@ static const struct comedi_lrange *dac_range_types[] = { #define DT2811_TIMEOUT 5 -#if 0 -static irqreturn_t dt2811_interrupt(int irq, void *d) -{ - int lo, hi; - int data; - struct comedi_device *dev = d; - struct dt2811_private *devpriv = dev->private; - - if (!dev->attached) { - comedi_error(dev, "spurious interrupt"); - return IRQ_HANDLED; - } - - lo = inb(dev->iobase + DT2811_ADDATLO); - hi = inb(dev->iobase + DT2811_ADDATHI); - - data = lo + (hi << 8); - - if (!(--devpriv->ntrig)) { - /* how to turn off acquisition */ - s->async->events |= COMEDI_SB_EOA; - } - comedi_event(dev, s); - return IRQ_HANDLED; -} -#endif - static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -278,35 +250,6 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -#if 0 -/* Wow. This is code from the Comedi stone age. But it hasn't been - * replaced, so I'll let it stay. */ -int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) -{ - struct comedi_device *dev = comedi_devices + minor; - - if (adtrig->n < 1) - return 0; - dev->curadchan = adtrig->chan; - switch (dev->i_admode) { - case COMEDI_MDEMAND: - dev->ntrig = adtrig->n - 1; - /* not necessary */ - /*printk("dt2811: AD soft trigger\n"); */ - /*outb(DT2811_CLRERROR|DT2811_INTENB, - dev->iobase+DT2811_ADCSR); */ - outb(dev->curadchan, dev->iobase + DT2811_ADGCR); - do_gettimeofday(&trigtime); - break; - case COMEDI_MCONTS: - dev->ntrig = adtrig->n; - break; - } - - return 0; -} -#endif - static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -386,10 +329,7 @@ static int dt2811_do_insn_bits(struct comedi_device *dev, */ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - /* int i, irq; */ - /* unsigned long irqs; */ - /* long flags; */ - + /* int i; */ const struct dt2811_board *board = comedi_board(dev); struct dt2811_private *devpriv; int ret; @@ -406,45 +346,6 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) i = inb(dev->iobase + DT2811_ADDATHI); #endif -#if 0 - irq = it->options[1]; - if (irq < 0) { - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - outb(DT2811_CLRERROR | DT2811_INTENB, - dev->iobase + DT2811_ADCSR); - outb(0, dev->iobase + DT2811_ADGCR); - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - - /*outb(DT2811_CLRERROR|DT2811_INTENB, - dev->iobase+DT2811_ADCSR);*/ - - if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) - printk(KERN_ERR "error probing irq (bad)\n"); - dev->irq = 0; - if (irq > 0) { - i = inb(dev->iobase + DT2811_ADDATLO); - i = inb(dev->iobase + DT2811_ADDATHI); - printk(KERN_INFO "(irq = %d)\n", irq); - ret = request_irq(irq, dt2811_interrupt, 0, - dev->board_name, dev); - if (ret < 0) - return -EIO; - dev->irq = irq; - } else if (irq == 0) { - printk(KERN_INFO "(no irq)\n"); - } else { - printk(KERN_ERR "( multiple irq's -- this is bad! )\n"); - } - } -#endif - ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 6514b9e00552..abad6e49c1c1 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -80,15 +80,12 @@ static int dt2814_ai_insn_read(struct comedi_device *dev, outb(chan, dev->iobase + DT2814_CSR); for (i = 0; i < DT2814_TIMEOUT; i++) { status = inb(dev->iobase + DT2814_CSR); - printk(KERN_INFO "dt2814: status: %02x\n", status); udelay(10); if (status & DT2814_FINISH) break; } - if (i >= DT2814_TIMEOUT) { - printk(KERN_INFO "dt2814: status: %02x\n", status); + if (i >= DT2814_TIMEOUT) return -ETIMEDOUT; - } hi = inb(dev->iobase + DT2814_DATA); lo = inb(dev->iobase + DT2814_DATA); @@ -200,7 +197,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) int lo, hi; struct comedi_device *dev = d; struct dt2814_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s = dev->read_subdev; int data; if (!dev->attached) { @@ -208,8 +205,6 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = &dev->subdevices[0]; - hi = inb(dev->iobase + DT2814_DATA); lo = inb(dev->iobase + DT2814_DATA); @@ -238,9 +233,9 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct dt2814_private *devpriv; - int i, irq; - int ret; struct comedi_subdevice *s; + int ret; + int i; ret = comedi_request_region(dev, it->options[0], DT2814_SIZE); if (ret) @@ -249,49 +244,17 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, dev->iobase + DT2814_CSR); udelay(100); if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) { - printk(KERN_ERR "reset error (fatal)\n"); + dev_err(dev->class_dev, "reset error (fatal)\n"); return -EIO; } i = inb(dev->iobase + DT2814_DATA); i = inb(dev->iobase + DT2814_DATA); - irq = it->options[1]; -#if 0 - if (irq < 0) { - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - outb(0, dev->iobase + DT2814_CSR); - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) - printk(KERN_DEBUG "error probing irq (bad)\n"); - - - i = inb(dev->iobase + DT2814_DATA); - i = inb(dev->iobase + DT2814_DATA); - } -#endif - dev->irq = 0; - if (irq > 0) { - if (request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) { - printk(KERN_WARNING "(irq %d unavailable)\n", irq); - } else { - printk(KERN_INFO "( irq = %d )\n", irq); - dev->irq = irq; - } - } else if (irq == 0) { - printk(KERN_WARNING "(no irq)\n"); - } else { -#if 0 - printk(KERN_DEBUG "(probe returned multiple irqs--bad)\n"); -#else - printk(KERN_WARNING "(irq probe not implemented)\n"); -#endif + if (it->options[1]) { + ret = request_irq(it->options[1], dt2814_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } ret = comedi_alloc_subdevices(dev, 1); @@ -303,16 +266,19 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 16; /* XXX */ - s->len_chanlist = 1; s->insn_read = dt2814_ai_insn_read; - s->do_cmd = dt2814_ai_cmd; - s->do_cmdtest = dt2814_ai_cmdtest; s->maxdata = 0xfff; s->range_table = &range_unknown; /* XXX */ + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 1; + s->do_cmd = dt2814_ai_cmd; + s->do_cmdtest = dt2814_ai_cmdtest; + } return 0; } diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 34040f0175e8..ee24717821e1 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -107,8 +107,9 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x00); if (status != 0) { - printk(KERN_WARNING "dt2815: failed to write low byte " - "on %d reason %x\n", chan, status); + dev_dbg(dev->class_dev, + "failed to write low byte on %d reason %x\n", + chan, status); return -EBUSY; } @@ -116,8 +117,9 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x10); if (status != 0x10) { - printk(KERN_WARNING "dt2815: failed to write high byte " - "on %d reason %x\n", chan, status); + dev_dbg(dev->class_dev, + "failed to write high byte on %d reason %x\n", + chan, status); return -EBUSY; } devpriv->ao_readback[chan] = data[i]; @@ -200,12 +202,13 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int program; program = (it->options[4] & 0x3) << 3 | 0x7; outb(program, dev->iobase + DT2815_DATA); - printk(KERN_INFO ", program: 0x%x (@t=%d)\n", - program, i); + dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n", + program, i); break; } else if (status != 0x00) { - printk(KERN_WARNING "dt2815: unexpected status 0x%x " - "(@t=%d)\n", status, i); + dev_dbg(dev->class_dev, + "unexpected status 0x%x (@t=%d)\n", + status, i); if (status & 0x60) outb(0x00, dev->iobase + DT2815_STATUS); } diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index a01e6b553887..ae714a526c35 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -63,8 +63,6 @@ Notes: #include "comedi_fc.h" -#define DEBUG - #define DT2821_TIMEOUT 100 /* 500 us */ #define DT2821_SIZE 0x10 @@ -308,15 +306,15 @@ static void dt282x_munge(struct comedi_device *dev, unsigned short *buf, static void dt282x_ao_dma_interrupt(struct comedi_device *dev) { struct dt282x_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->write_subdev; void *ptr; int size; int i; - struct comedi_subdevice *s = &dev->subdevices[1]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); if (!s->async->prealloc_buf) { - printk(KERN_ERR "async->data disappeared. dang!\n"); + dev_err(dev->class_dev, "no buffer in %s\n", __func__); return; } @@ -329,7 +327,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); dt282x_ao_cancel(dev, s); s->async->events |= COMEDI_CB_OVERFLOW; return; @@ -341,16 +339,16 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) static void dt282x_ai_dma_interrupt(struct comedi_device *dev) { struct dt282x_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; void *ptr; int size; int i; int ret; - struct comedi_subdevice *s = &dev->subdevices[0]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); if (!s->async->prealloc_buf) { - printk(KERN_ERR "async->data disappeared. dang!\n"); + dev_err(dev->class_dev, "no buffer in %s\n", __func__); return; } @@ -371,7 +369,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) devpriv->nread -= size / 2; if (devpriv->nread < 0) { - printk(KERN_INFO "dt282x: off by one\n"); + dev_info(dev->class_dev, "nread off by one\n"); devpriv->nread = 0; } if (!devpriv->nread) { @@ -450,8 +448,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct dt282x_private *devpriv = dev->private; - struct comedi_subdevice *s; - struct comedi_subdevice *s_ao; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_subdevice *s_ao = dev->write_subdev; unsigned int supcsr, adcsr, dacsr; int handled = 0; @@ -460,8 +458,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = &dev->subdevices[0]; - s_ao = &dev->subdevices[1]; adcsr = inw(dev->iobase + DT2821_ADCSR); dacsr = inw(dev->iobase + DT2821_DACSR); supcsr = inw(dev->iobase + DT2821_SUPCSR); @@ -481,13 +477,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) handled = 1; } if (dacsr & DT2821_DAERR) { -#if 0 - static int warn = 5; - if (--warn <= 0) { - disable_irq(dev->irq); - printk(KERN_INFO "disabling irq\n"); - } -#endif comedi_error(dev, "D/A error"); dt282x_ao_cancel(dev, s_ao); s->async->events |= COMEDI_CB_ERROR; @@ -520,8 +509,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) } #endif comedi_event(dev, s); - /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", - adcsr, dacsr, supcsr); */ + return IRQ_RETVAL(handled); } @@ -894,7 +882,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 0, size); @@ -902,7 +890,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 1, size); @@ -1062,10 +1050,8 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->usedma = 0; - if (!dma1 && !dma2) { - printk(KERN_ERR " (no dma)"); + if (!dma1 && !dma2) return 0; - } if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) return -EINVAL; @@ -1090,12 +1076,8 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->dma_maxsize = PAGE_SIZE; devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { - printk(KERN_ERR " can't get DMA memory"); + if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) return -ENOMEM; - } - - printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); devpriv->usedma = 1; @@ -1120,9 +1102,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dt282x_board *board = comedi_board(dev); struct dt282x_private *devpriv; - int i, irq; - int ret; struct comedi_subdevice *s; + int ret; + int i; ret = comedi_request_region(dev, it->options[0], DT2821_SIZE); if (ret) @@ -1130,14 +1112,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR); i = inw(dev->iobase + DT2821_ADCSR); -#ifdef DEBUG - printk(KERN_DEBUG " fingerprint=%x,%x,%x,%x,%x", - inw(dev->iobase + DT2821_ADCSR), - inw(dev->iobase + DT2821_CHANCSR), - inw(dev->iobase + DT2821_DACSR), - inw(dev->iobase + DT2821_SUPCSR), - inw(dev->iobase + DT2821_TMRCTR)); -#endif if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK) != DT2821_ADCSR_VAL) || @@ -1149,58 +1123,28 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) != DT2821_SUPCSR_VAL) || ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK) != DT2821_TMRCTR_VAL)) { - printk(KERN_ERR " board not found"); + dev_err(dev->class_dev, "board not found\n"); return -EIO; } /* should do board test */ - irq = it->options[opt_irq]; -#if 0 - if (irq < 0) { - unsigned long flags; - int irqs; - - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - /* trigger interrupt */ - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - if (0 /* error */) - printk(KERN_ERR " error probing irq (bad)"); - } -#endif - if (irq > 0) { - printk(KERN_INFO " ( irq = %d )", irq); - ret = request_irq(irq, dt282x_interrupt, 0, + if (it->options[opt_irq] > 0) { + ret = request_irq(it->options[opt_irq], dt282x_interrupt, 0, dev->board_name, dev); - if (ret < 0) { - printk(KERN_ERR " failed to get irq\n"); - return -EIO; - } - dev->irq = irq; - } else if (irq == 0) { - printk(KERN_INFO " (no irq)"); - } else { -#if 0 - printk(KERN_INFO " (probe returned multiple irqs--bad)"); -#else - printk(KERN_INFO " (irq probe not implemented)"); -#endif + if (ret == 0) + dev->irq = it->options[opt_irq]; } devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; - ret = dt282x_grab_dma(dev, it->options[opt_dma1], - it->options[opt_dma2]); - if (ret < 0) - return ret; + if (dev->irq) { + ret = dt282x_grab_dma(dev, it->options[opt_dma1], + it->options[opt_dma2]); + if (ret < 0) + return ret; + } ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -1208,22 +1152,25 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ | + s->subdev_flags = SDF_READABLE | ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON); s->n_chan = (it->options[opt_diff]) ? board->adchan_di : board->adchan_se; s->insn_read = dt282x_ai_insn_read; - s->do_cmdtest = dt282x_ai_cmdtest; - s->do_cmd = dt282x_ai_cmd; - s->cancel = dt282x_ai_cancel; s->maxdata = (1 << board->adbits) - 1; - s->len_chanlist = 16; s->range_table = opt_ai_range_lkup(board->ispgl, it->options[opt_ai_range]); devpriv->ad_2scomp = it->options[opt_ai_twos]; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 16; + s->do_cmdtest = dt282x_ai_cmdtest; + s->do_cmd = dt282x_ai_cmd; + s->cancel = dt282x_ai_cancel; + } s = &dev->subdevices[1]; @@ -1231,15 +1178,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (s->n_chan) { /* ao subsystem */ s->type = COMEDI_SUBD_AO; - dev->write_subdev = s; - s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE; + s->subdev_flags = SDF_WRITABLE; s->insn_read = dt282x_ao_insn_read; s->insn_write = dt282x_ao_insn_write; - s->do_cmdtest = dt282x_ao_cmdtest; - s->do_cmd = dt282x_ao_cmd; - s->cancel = dt282x_ao_cancel; s->maxdata = (1 << board->dabits) - 1; - s->len_chanlist = 2; s->range_table_list = devpriv->darangelist; devpriv->darangelist[0] = opt_ao_range_lkup(it->options[opt_ao0_range]); @@ -1247,6 +1189,14 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) opt_ao_range_lkup(it->options[opt_ao1_range]); devpriv->da0_2scomp = it->options[opt_ao0_twos]; devpriv->da1_2scomp = it->options[opt_ao1_twos]; + if (dev->irq) { + dev->write_subdev = s; + s->subdev_flags |= SDF_CMD_WRITE; + s->len_chanlist = 2; + s->do_cmdtest = dt282x_ao_cmdtest; + s->do_cmd = dt282x_ao_cmd; + s->cancel = dt282x_ao_cancel; + } } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1261,8 +1211,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->range_table = &range_digital; - printk(KERN_INFO "\n"); - return 0; } diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 292226eeff92..f52a4476cb73 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -48,8 +48,6 @@ AO commands are not supported. you the docs without one, also. */ -#define DEBUG 1 - #include <linux/module.h> #include <linux/pci.h> #include <linux/delay.h> @@ -253,24 +251,6 @@ struct dt3k_private { unsigned int ai_rear; }; -#ifdef DEBUG -static char *intr_flags[] = { - "AdFull", "AdSwError", "AdHwError", "DaEmpty", - "DaSwError", "DaHwError", "CtDone", "CmDone", -}; - -static void debug_intr_flags(unsigned int flags) -{ - int i; - printk(KERN_DEBUG "dt3k: intr_flags:"); - for (i = 0; i < 8; i++) { - if (flags & (1 << i)) - printk(KERN_CONT " %s", intr_flags[i]); - } - printk(KERN_CONT "\n"); -} -#endif - #define TIMEOUT 100 static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) @@ -372,17 +352,13 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct dt3k_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s = dev->read_subdev; unsigned int status; if (!dev->attached) return IRQ_NONE; - s = &dev->subdevices[0]; status = readw(devpriv->io_addr + DPR_Intr_Flag); -#ifdef DEBUG - debug_intr_flags(status); -#endif if (status & DT3000_ADFULL) { dt3k_ai_empty_fifo(dev, s); @@ -725,29 +701,33 @@ static int dt3000_auto_attach(struct comedi_device *dev, if (!devpriv->io_addr) return -ENOMEM; - ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret) - return ret; - dev->irq = pcidev->irq; + if (pcidev->irq) { + ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = this_board->adchan; s->insn_read = dt3k_ai_insn; s->maxdata = (1 << this_board->adbits) - 1; - s->len_chanlist = 512; s->range_table = &range_dt3000_ai; /* XXX */ - s->do_cmd = dt3k_ai_cmd; - s->do_cmdtest = dt3k_ai_cmdtest; - s->cancel = dt3k_ai_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 512; + s->do_cmd = dt3k_ai_cmd; + s->do_cmdtest = dt3k_ai_cmdtest; + s->cancel = dt3k_ai_cancel; + } s = &dev->subdevices[1]; /* ao subsystem */ @@ -818,7 +798,7 @@ static int dt3000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &dt3000_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { +static const struct pci_device_id dt3000_pci_table[] = { { PCI_VDEVICE(DT, 0x0022), BOARD_DT3001 }, { PCI_VDEVICE(DT, 0x0023), BOARD_DT3002 }, { PCI_VDEVICE(DT, 0x0024), BOARD_DT3003 }, diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index f2a9f1c2f3b6..8fd705cb235b 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -90,8 +90,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, goto conv_finish; } data[n] = 0; - printk(KERN_DEBUG "comedi: dyna_pci10xx: " - "timeout reading analog input\n"); + dev_dbg(dev->class_dev, "timeout reading analog input\n"); continue; conv_finish: /* mask the first 4 bits - EOC bits */ @@ -260,7 +259,7 @@ static int dyna_pci10xx_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { +static const struct pci_device_id dyna_pci10xx_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index e3ff4c438979..aff1e7db138e 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -16,8 +16,6 @@ Configuration options: [0] - I/O port base address */ -#define DEBUG 0 - #include <linux/module.h> #include "../comedidev.h" diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 559bf5583530..de60a2871d70 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -60,15 +60,6 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static irqreturn_t handle_interrupt(int irq, void *d); static int dio_config_block_size(struct comedi_device *dev, unsigned int *data); -#undef HPDI_DEBUG /* disable debugging messages */ -/* #define HPDI_DEBUG enable debugging code */ - -#ifdef HPDI_DEBUG -#define DEBUG_PRINT(format, args...) pr_debug(format , ## args) -#else -#define DEBUG_PRINT(format, args...) no_printk(pr_fmt(format), ## args) -#endif - #define TIMER_BASE 50 /* 20MHz master clock */ #define DMA_BUFFER_SIZE 0x10000 #define NUM_DMA_BUFFERS 4 @@ -260,32 +251,6 @@ static void init_plx9080(struct comedi_device *dev) uint32_t bits; void __iomem *plx_iobase = devpriv->plx9080_iobase; - /* plx9080 dump */ - DEBUG_PRINT(" plx interrupt status 0x%x\n", - readl(plx_iobase + PLX_INTRCS_REG)); - DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", - readl(devpriv->plx9080_iobase + PLX_CONTROL_REG)); - - DEBUG_PRINT(" plx revision 0x%x\n", - readl(plx_iobase + PLX_REVISION_REG)); - DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n", - readl(plx_iobase + PLX_DMA0_MODE_REG)); - DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n", - readl(plx_iobase + PLX_DMA1_MODE_REG)); - DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n", - readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n", - readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n", - readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG)); - DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n", - readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n", - readb(plx_iobase + PLX_DMA0_CS_REG)); - DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n", - readl(plx_iobase + PLX_DMA0_THRESHOLD_REG)); - DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG)); #ifdef __BIG_ENDIAN bits = BIGEND_DMA0 | BIGEND_DMA1; #else @@ -395,10 +360,6 @@ static int setup_dma_descriptors(struct comedi_device *dev, if (transfer_size == 0) return -1; - DEBUG_PRINT(" transfer_size %i\n", transfer_size); - DEBUG_PRINT(" descriptors at 0x%lx\n", - (unsigned long)devpriv->dma_desc_phys_addr); - buffer_offset = 0; buffer_index = 0; for (i = 0; i < NUM_DMA_DESCRIPTORS && @@ -423,21 +384,11 @@ static int setup_dma_descriptors(struct comedi_device *dev, buffer_offset = 0; buffer_index++; } - - DEBUG_PRINT(" desc %i\n", i); - DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n", - devpriv->desc_dio_buffer[i], - (unsigned long)devpriv->dma_desc[i]. - pci_start_addr); - DEBUG_PRINT(" next 0x%lx\n", - (unsigned long)devpriv->dma_desc[i].next); } devpriv->num_dma_descriptors = i; /* fix last descriptor to point back to first */ devpriv->dma_desc[i - 1].next = cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits); - DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1, - (unsigned long)devpriv->dma_desc[i - 1].next); devpriv->block_size = transfer_size; @@ -489,9 +440,6 @@ static int hpdi_auto_attach(struct comedi_device *dev, return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase); - init_plx9080(dev); /* get irq */ @@ -510,9 +458,6 @@ static int hpdi_auto_attach(struct comedi_device *dev, devpriv->dio_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->dio_buffer_phys_addr[i]); - DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n", - devpriv->dio_buffer[i], - (unsigned long)devpriv->dio_buffer_phys_addr[i]); } /* allocate dma descriptors */ devpriv->dma_desc = pci_alloc_consistent(pcidev, @@ -687,8 +632,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG); - DEBUG_PRINT("hpdi: in di_cmd\n"); - abort_dma(dev, 0); devpriv->dma_desc_index = 0; @@ -725,7 +668,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(intr_bit(RX_FULL_INTR), devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); - DEBUG_PRINT("hpdi: starting rx\n"); hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG); return 0; @@ -778,11 +720,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) num_samples * sizeof(uint32_t)); devpriv->dma_desc_index++; devpriv->dma_desc_index %= devpriv->num_dma_descriptors; - - DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long) - devpriv->dma_desc[devpriv->dma_desc_index]. - next); - DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } /* XXX check for buffer overrun somehow */ } @@ -812,7 +749,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) async->events = 0; if (hpdi_intr_status) { - DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status); writel(hpdi_intr_status, devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); } @@ -823,10 +759,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); - DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 0); - DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -836,9 +770,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA1_CS_REG); - DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); - - DEBUG_PRINT(" cleared dma ch1 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -846,15 +777,11 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); - DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } if (hpdi_board_status & RX_OVERRUN_BIT) { comedi_error(dev, "rx fifo overrun"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - DEBUG_PRINT("dma0_status 0x%x\n", - (int)readb(devpriv->plx9080_iobase + - PLX_DMA0_CS_REG)); } if (hpdi_board_status & RX_UNDERRUN_BIT) { @@ -865,11 +792,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; - DEBUG_PRINT("board status 0x%x, ", hpdi_board_status); - DEBUG_PRINT("plx status 0x%x\n", plx_status); - if (async->events) - DEBUG_PRINT(" events 0x%x\n", async->events); - cfc_handle_events(dev, s); return IRQ_HANDLED; @@ -914,7 +836,7 @@ static int gsc_hpdi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(gsc_hpdi_pci_table) = { +static const struct pci_device_id gsc_hpdi_pci_table[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400, 0, 0, 0}, { 0 } diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 1e16641ec52d..e00aa9089e5f 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -597,7 +597,7 @@ static int icp_multi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &icp_multi_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(icp_multi_pci_table) = { +static const struct pci_device_id icp_multi_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ICP, PCI_DEVICE_ID_ICP_MULTI) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index b52d58e5de27..6100c12c164f 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -807,7 +807,7 @@ static int jr3_pci_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { +static const struct pci_device_id jr3_pci_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 15589f62a619..6b9846fd8c48 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -139,7 +139,7 @@ static int ke_counter_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ke_counter_pci_table) = { +static const struct pci_device_id ke_counter_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 3d12e9135926..7276002db38d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1105,7 +1105,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) { unsigned int tmp; struct comedi_device *dev = dev_id; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i; int c = 0; unsigned int lval; @@ -1116,12 +1116,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Reset all events */ s->async->events = 0; - /* Check if irq number is right */ - if (irq != dev->irq) { - dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq); - return IRQ_HANDLED; - } - if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & ME4000_IRQ_STATUS_BIT_AI_HF) { /* Read status register to find out what happened */ @@ -1505,6 +1499,13 @@ static int me4000_auto_attach(struct comedi_device *dev, me4000_reset(dev); + if (pcidev->irq > 0) { + result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED, + dev->board_name, dev); + if (result == 0) + dev->irq = pcidev->irq; + } + result = comedi_alloc_subdevices(dev, 4); if (result) return result; @@ -1525,22 +1526,12 @@ static int me4000_auto_attach(struct comedi_device *dev, s->range_table = &me4000_ai_range; s->insn_read = me4000_ai_insn_read; - if (pcidev->irq > 0) { - if (request_irq(pcidev->irq, me4000_ai_isr, - IRQF_SHARED, dev->board_name, dev)) { - dev_warn(dev->class_dev, - "request_irq failed\n"); - } else { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = me4000_ai_cancel; - s->do_cmdtest = me4000_ai_do_cmd_test; - s->do_cmd = me4000_ai_do_cmd; - - dev->irq = pcidev->irq; - } - } else { - dev_warn(dev->class_dev, "No interrupt available\n"); + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = me4000_ai_cancel; + s->do_cmdtest = me4000_ai_do_cmd_test; + s->do_cmd = me4000_ai_do_cmd; } } else { s->type = COMEDI_SUBD_UNUSED; @@ -1635,7 +1626,7 @@ static int me4000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { +static const struct pci_device_id me4000_pci_table[] = { { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 }, { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 }, { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I }, diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 24ec9ef9b1a0..7f6687896401 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -576,7 +576,7 @@ static int me_daq_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me_daq_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = { +static const struct pci_device_id me_daq_pci_table[] = { { PCI_VDEVICE(MEILHAUS, 0x2600), BOARD_ME2600 }, { PCI_VDEVICE(MEILHAUS, 0x2000), BOARD_ME2000 }, { 0 } diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 35cb4ace7970..9c9a0ee432cf 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -288,7 +288,6 @@ void mite_dma_arm(struct mite_channel *mite_chan) int chor; unsigned long flags; - MDPRINTK("mite_dma_arm ch%i\n", mite_chan->channel); /* * memory barrier is intended to insure any twiddling with the buffer * is done before writing to the mite to arm dma transfer @@ -329,8 +328,6 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, n_links = async->prealloc_bufsz >> PAGE_SHIFT; - MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links); - ring->descriptors = dma_alloc_coherent(ring->hw_dev, n_links * sizeof(struct mite_dma_descriptor), @@ -345,7 +342,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, for (i = 0; i < n_links; i++) { ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE); ring->descriptors[i].addr = - cpu_to_le32(async->buf_page_list[i].dma_addr); + cpu_to_le32(async->buf_map->page_list[i].dma_addr); ring->descriptors[i].next = cpu_to_le32(ring->descriptors_dma_addr + (i + 1) * @@ -368,8 +365,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, unsigned int chor, chcr, mcr, dcr, lkcr; struct mite_struct *mite = mite_chan->mite; - MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel); - /* reset DMA and FIFO */ chor = CHOR_DMARESET | CHOR_FRESET; writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); @@ -448,8 +443,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, /* starting address for link chaining */ writel(mite_chan->ring->descriptors_dma_addr, mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); - - MDPRINTK("exit mite_prep_dma\n"); } EXPORT_SYMBOL_GPL(mite_prep_dma); @@ -515,8 +508,6 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan) lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); - MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel, - lkar, tcr); return tcr; } @@ -642,140 +633,6 @@ int mite_done(struct mite_channel *mite_chan) } EXPORT_SYMBOL_GPL(mite_done); -#ifdef DEBUG_MITE - -/* names of bits in mite registers */ - -static const char *const mite_CHOR_strings[] = { - "start", "cont", "stop", "abort", - "freset", "clrlc", "clrrb", "clrdone", - "clr_lpause", "set_lpause", "clr_send_tc", - "set_send_tc", "12", "13", "14", - "15", "16", "17", "18", - "19", "20", "21", "22", - "23", "24", "25", "26", - "27", "28", "29", "30", - "dmareset", -}; - -static const char *const mite_CHCR_strings[] = { - "continue", "ringbuff", "2", "3", - "4", "5", "6", "7", - "8", "9", "10", "11", - "12", "13", "bursten", "fifodis", - "clr_cont_rb_ie", "set_cont_rb_ie", "clr_lc_ie", "set_lc_ie", - "clr_drdy_ie", "set_drdy_ie", "clr_mrdy_ie", "set_mrdy_ie", - "clr_done_ie", "set_done_ie", "clr_sar_ie", "set_sar_ie", - "clr_linkp_ie", "set_linkp_ie", "clr_dma_ie", "set_dma_ie", -}; - -static const char *const mite_MCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "11", - "12", "13", "blocken", "berhand", - "reqsintlim/reqs0", "reqs1", "reqs2", "rd32", - "rd512", "rl1", "rl2", "rl8", - "24", "25", "26", "27", - "28", "29", "30", "stopen", -}; - -static const char *const mite_DCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "aseqxp2", - "aseqxp8", "13", "blocken", "berhand", - "reqsintlim", "reqs1", "reqs2", "rd32", - "rd512", "rl1", "rl2", "rl8", - "23", "24", "25", "27", - "28", "wsdevc", "wsdevs", "rwdevpack", -}; - -static const char *const mite_LKCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "asequp", "aseqdown", - "12", "13", "14", "berhand", - "16", "17", "18", "rd32", - "rd512", "rl1", "rl2", "rl8", - "24", "25", "26", "27", - "28", "29", "30", "chngend", -}; - -static const char *const mite_CHSR_strings[] = { - "d.err0", "d.err1", "m.err0", "m.err1", - "l.err0", "l.err1", "drq0", "drq1", - "end", "xferr", "operr0", "operr1", - "stops", "habort", "sabort", "error", - "16", "conts_rb", "18", "linkc", - "20", "drdy", "22", "mrdy", - "24", "done", "26", "sars", - "28", "lpauses", "30", "int", -}; - -static void mite_decode(const char *const *bit_str, unsigned int bits) -{ - int i; - - for (i = 31; i >= 0; i--) { - if (bits & (1 << i)) - pr_debug(" %s\n", bit_str[i]); - } -} - -void mite_dump_regs(struct mite_channel *mite_chan) -{ - void __iomem *mite_io_addr = mite_chan->mite->mite_io_addr; - unsigned int offset; - unsigned int value; - int channel = mite_chan->channel; - - pr_debug("mite_dump_regs ch%i\n", channel); - pr_debug("mite address is =%p\n", mite_io_addr); - - offset = MITE_CHOR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHOR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHOR_strings, value); - offset = MITE_CHCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHCR_strings, value); - offset = MITE_TCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[TCR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_MCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[MCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_MCR_strings, value); - offset = MITE_MAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[MAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_DCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[DCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_DCR_strings, value); - offset = MITE_DAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[DAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_LKCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[LKCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_LKCR_strings, value); - offset = MITE_LKAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[LKAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_CHSR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHSR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHSR_strings, value); - offset = MITE_FCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value); -} -EXPORT_SYMBOL_GPL(mite_dump_regs); -#endif - static int __init mite_module_init(void) { return 0; diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 8423b8bf3384..bcf2f972376e 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -24,15 +24,8 @@ #include <linux/slab.h> #include "../comedidev.h" -/* #define DEBUG_MITE */ #define PCIMIO_COMPAT -#ifdef DEBUG_MITE -#define MDPRINTK(format, args...) pr_debug(format , ## args) -#else -#define MDPRINTK(format, args...) do { } while (0) -#endif - #define MAX_MITE_DMA_CHANNELS 8 struct mite_dma_descriptor { @@ -129,11 +122,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *async); -#ifdef DEBUG_MITE -void mite_print_chsr(unsigned int chsr); -void mite_dump_regs(struct mite_channel *mite_chan); -#endif - static inline int CHAN_OFFSET(int channel) { return 0x500 + 0x100 * channel; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index acbaeee6250c..fe4621ea65c3 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -159,11 +159,6 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, * We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc */ outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); -/* printk("Channel %d:\n", insn->chanspec); */ - if (!insn->n) { - printk(KERN_INFO "MPC624: Warning, no data to acquire\n"); - return 0; - } for (n = 0; n < insn->n; n++) { /* Trigger the conversion */ @@ -182,11 +177,9 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, else break; } - if (i == TIMEOUT) { - printk(KERN_ERR "MPC624: timeout (%dms)\n", TIMEOUT); - data[n] = 0; + if (i == TIMEOUT) return -ETIMEDOUT; - } + /* Start reading data */ data_in = 0; data_out = devpriv->ulConvertionRate; @@ -245,11 +238,11 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, */ if (data_in & MPC624_EOC_BIT) - printk(KERN_INFO "MPC624:EOC bit is set (data_in=%lu)!", - data_in); + dev_dbg(dev->class_dev, + "EOC bit is set (data_in=%lu)!", data_in); if (data_in & MPC624_DMY_BIT) - printk(KERN_INFO "MPC624:DMY bit is set (data_in=%lu)!", - data_in); + dev_dbg(dev->class_dev, + "DMY bit is set (data_in=%lu)!", data_in); if (data_in & MPC624_SGN_BIT) { /* Volatge is positive */ /* * comedi operates on unsigned numbers, so mask off EOC diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 85aa9609d6a2..860fc81fb11c 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -455,7 +455,7 @@ static int ni6527_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { +static const struct pci_device_id ni6527_pci_table[] = { { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 }, { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 }, { 0 } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 853f62b2b1a9..6e42001f686e 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -43,9 +43,6 @@ except maybe the 6514. */ -#define DEBUG 1 -#define DEBUG_FLAGS - #include <linux/module.h> #include <linux/pci.h> #include <linux/interrupt.h> @@ -430,7 +427,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct ni_65xx_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[2]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int status; status = readb(devpriv->mite->daq_io_addr + Change_Status); @@ -741,7 +738,7 @@ static int ni_65xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { +static const struct pci_device_id ni_65xx_pci_table[] = { { PCI_VDEVICE(NI, 0x1710), BOARD_PXI6509 }, { PCI_VDEVICE(NI, 0x7085), BOARD_PCI6509 }, { PCI_VDEVICE(NI, 0x7086), BOARD_PXI6528 }, diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 8a991dcab24a..61c64a9e3c30 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1320,7 +1320,7 @@ static int ni_660x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { +static const struct pci_device_id ni_660x_pci_table[] = { { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 }, { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index e4414cf110e7..8550fdc4ccd3 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -282,7 +282,7 @@ static int ni_670x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_670x_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { +static const struct pci_device_id ni_670x_pci_table[] = { { PCI_VDEVICE(NI, 0x1290), BOARD_PCI6704 }, { PCI_VDEVICE(NI, 0x1920), BOARD_PXI6704 }, { PCI_VDEVICE(NI, 0x2c90), BOARD_PCI6703 }, diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 63c847932eb8..0c71fdfecac2 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -74,9 +74,6 @@ TRIG_WAKE_EOS #define A2150_SIZE 28 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */ -/* #define A2150_DEBUG enable debugging code */ -#undef A2150_DEBUG /* disable debugging code */ - /* Registers and bits */ #define CONFIG_REG 0x0 #define CHANNEL_BITS(x) ((x) & 0x7) @@ -167,19 +164,6 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel, unsigned int num_channels); -#ifdef A2150_DEBUG - -static void ni_dump_regs(struct comedi_device *dev) -{ - struct a2150_private *devpriv = dev->private; - - printk("config bits 0x%x\n", devpriv->config_bits); - printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits); - printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG)); -} - -#endif - /* interrupt service routine */ static irqreturn_t a2150_interrupt(int irq, void *d) { @@ -411,11 +395,6 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int old_config_bits = devpriv->config_bits; unsigned int trigger_bits; - if (!dev->irq || !devpriv->dma) { - comedi_error(dev, - " irq and dma required, cannot do hardware conversions"); - return -1; - } if (cmd->flags & TRIG_RT) { comedi_error(dev, " dma incompatible with hard real-time interrupt (TRIG_RT), aborting"); @@ -506,9 +485,6 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* start acquisition for soft trigger */ if (cmd->start_src == TRIG_NOW) outw(0, dev->iobase + FIFO_START_REG); -#ifdef A2150_DEBUG - ni_dump_regs(dev); -#endif return 0; } @@ -573,13 +549,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, comedi_error(dev, "timeout"); return -ETIME; } -#ifdef A2150_DEBUG - ni_dump_regs(dev); -#endif data[n] = inw(dev->iobase + FIFO_DATA_REG); -#ifdef A2150_DEBUG - printk(" data is %i\n", data[n]); -#endif data[n] ^= 0x8000; } @@ -728,46 +698,35 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - /* grab our IRQ */ - if (irq) { - /* check that irq is supported */ - if (irq < 3 || irq == 8 || irq == 13 || irq > 15) { - printk(" invalid irq line %u\n", irq); - return -EINVAL; - } - if (request_irq(irq, a2150_interrupt, 0, - dev->driver->driver_name, dev)) { - printk("unable to allocate irq %u\n", irq); - return -EINVAL; + dev->board_ptr = a2150_boards + a2150_probe(dev); + thisboard = comedi_board(dev); + dev->board_name = thisboard->name; + + if ((irq >= 3 && irq <= 7) || (irq >= 9 && irq <= 12) || + irq == 14 || irq == 15) { + ret = request_irq(irq, a2150_interrupt, 0, + dev->board_name, dev); + if (ret == 0) { + devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); + dev->irq = irq; } - devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); - dev->irq = irq; } - /* initialize dma */ - if (dma) { - if (dma == 4 || dma > 7) { - printk(" invalid dma channel %u\n", dma); - return -EINVAL; - } - if (request_dma(dma, dev->driver->driver_name)) { - printk(" failed to allocate dma channel %u\n", dma); - return -EINVAL; - } - devpriv->dma = dma; - devpriv->dma_buffer = - kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->dma_buffer == NULL) - return -ENOMEM; - disable_dma(dma); - set_dma_mode(dma, DMA_MODE_READ); + if (dev->irq && dma <= 7 && dma != 4) { + ret = request_dma(dma, dev->board_name); + if (ret == 0) { + devpriv->dma = dma; + devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE, + GFP_KERNEL | GFP_DMA); + if (!devpriv->dma_buffer) + return -ENOMEM; - devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); - } + disable_dma(dma); + set_dma_mode(dma, DMA_MODE_READ); - dev->board_ptr = a2150_boards + a2150_probe(dev); - thisboard = comedi_board(dev); - dev->board_name = thisboard->name; + devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); + } + } ret = comedi_alloc_subdevices(dev, 1); if (ret) @@ -775,17 +734,20 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* analog input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER; s->n_chan = 4; - s->len_chanlist = 4; s->maxdata = 0xffff; s->range_table = &range_a2150; - s->do_cmd = a2150_ai_cmd; - s->do_cmdtest = a2150_ai_cmdtest; s->insn_read = a2150_ai_rinsn; - s->cancel = a2150_cancel; + if (dev->irq && devpriv->dma) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmd = a2150_ai_cmd; + s->do_cmdtest = a2150_ai_cmdtest; + s->cancel = a2150_cancel; + } /* need to do this for software counting of completed conversions, to * prevent hardware count from stopping acquisition */ diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 856c73d8b7cd..d03935257b97 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -98,8 +98,6 @@ are not supported. #include "ni_stc.h" #include "8255.h" -#undef DEBUG - #define ATMIO 1 #undef PCIMIO @@ -437,19 +435,6 @@ static int ni_atmio_attach(struct comedi_device *dev, if (ret) return ret; -#ifdef DEBUG - /* board existence sanity check */ - { - int i; - - printk(" board fingerprint:"); - for (i = 0; i < 16; i += 2) { - printk(" %04x %02x", inw(dev->iobase + i), - inb(dev->iobase + i + 1)); - } - } -#endif - /* get board type */ board = ni_getboardtype(dev); diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index a9f7d40d6db2..3a92fe52b9ac 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -229,7 +229,7 @@ static void reset_atmio16d(struct comedi_device *dev) static irqreturn_t atmio16d_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG)); @@ -495,18 +495,13 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, break; } if (status & STAT_AD_OVERFLOW) { - printk(KERN_INFO "atmio16d: a/d FIFO overflow\n"); outw(0, dev->iobase + AD_CLEAR_REG); - return -ETIME; } } /* end waiting, now check if it timed out */ - if (t == ATMIO16D_TIMEOUT) { - printk(KERN_INFO "atmio16d: timeout\n"); - + if (t == ATMIO16D_TIMEOUT) return -ETIME; - } } return i; @@ -636,7 +631,6 @@ static int atmio16d_attach(struct comedi_device *dev, const struct atmio16_board_t *board = comedi_board(dev); struct atmio16d_private *devpriv; struct comedi_subdevice *s; - unsigned int irq; int ret; ret = comedi_request_region(dev, it->options[0], ATMIO16D_SIZE); @@ -654,19 +648,11 @@ static int atmio16d_attach(struct comedi_device *dev, /* reset the atmio16d hardware */ reset_atmio16d(dev); - /* check if our interrupt is available and get it */ - irq = it->options[1]; - if (irq) { - - ret = request_irq(irq, atmio16d_interrupt, 0, "atmio16d", dev); - if (ret < 0) { - printk(KERN_INFO "failed to allocate irq %u\n", irq); - return ret; - } - dev->irq = irq; - printk(KERN_INFO "( irq = %u )\n", irq); - } else { - printk(KERN_INFO "( no irq )"); + if (it->options[1]) { + ret = request_irq(it->options[1], atmio16d_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } /* set device options */ @@ -682,16 +668,11 @@ static int atmio16d_attach(struct comedi_device *dev, /* setup sub-devices */ s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = (devpriv->adc_mux ? 16 : 8); - s->len_chanlist = 16; s->insn_read = atmio16d_ai_insn_read; - s->do_cmdtest = atmio16d_ai_cmdtest; - s->do_cmd = atmio16d_ai_cmd; - s->cancel = atmio16d_ai_cancel; s->maxdata = 0xfff; /* 4095 decimal */ switch (devpriv->adc_range) { case adc_bipolar10: @@ -704,6 +685,14 @@ static int atmio16d_attach(struct comedi_device *dev, s->range_table = &range_atmio16d_ai_unipolar; break; } + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 16; + s->do_cmdtest = atmio16d_ai_cmdtest; + s->do_cmd = atmio16d_ai_cmd; + s->cancel = atmio16d_ai_cancel; + } /* ao subdevice */ s = &dev->subdevices[1]; @@ -756,7 +745,6 @@ static int atmio16d_attach(struct comedi_device *dev, s->n_chan = 0; s->maxdata = 0 #endif - printk("\n"); return 0; } diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c index 8be681fca907..739597068297 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_pci.c +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -107,7 +107,7 @@ static struct comedi_driver labpc_pci_comedi_driver = { .detach = labpc_pci_detach, }; -static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { +static const struct pci_device_id labpc_pci_table[] = { { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 5113397bfecf..65db6add0a68 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -52,10 +52,6 @@ fully tested as yet. Terry Barnaby, BEAM Ltd. */ -/* #define DEBUG_INTERRUPT */ -/* #define DEBUG_STATUS_A */ -/* #define DEBUG_STATUS_B */ - #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/delay.h> @@ -63,10 +59,6 @@ #include "mite.h" #include "comedi_fc.h" -#ifndef MDPRINTK -#define MDPRINTK(format, args...) -#endif - /* A timeout count */ #define NI_TIMEOUT 1000 static const unsigned old_RTSI_clock_channel = 7; @@ -266,17 +258,6 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s); static int ni_read_eeprom(struct comedi_device *dev, int addr); -#ifdef DEBUG_STATUS_A -static void ni_mio_print_status_a(int status); -#else -#define ni_mio_print_status_a(a) -#endif -#ifdef DEBUG_STATUS_B -static void ni_mio_print_status_b(int status); -#else -#define ni_mio_print_status_b(a) -#endif - static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s); #ifndef PCIDMA static void ni_handle_fifo_half_full(struct comedi_device *dev); @@ -322,10 +303,6 @@ static int cs5529_do_conversion(struct comedi_device *dev, static int cs5529_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -#ifdef NI_CS5529_DEBUG -static unsigned int cs5529_config_read(struct comedi_device *dev, - unsigned int reg_select_bits); -#endif static void cs5529_config_write(struct comedi_device *dev, unsigned int value, unsigned int reg_select_bits); @@ -1050,12 +1027,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (s->type == COMEDI_SUBD_UNUSED) return; -#ifdef DEBUG_INTERRUPT - printk - ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n", - status, ai_mite_status); - ni_mio_print_status_a(status); -#endif #ifdef PCIDMA if (ai_mite_status & CHSR_LINKC) { ni_sync_ai_dma(dev); @@ -1067,7 +1038,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, printk ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n", ai_mite_status); - /* mite_print_chsr(ai_mite_status); */ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; /* disable_irq(dev->irq); */ } @@ -1092,7 +1062,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, AI_SC_TC_Error_St)) { printk("ni_mio_common: ai error a_status=%04x\n", status); - ni_mio_print_status_a(status); shutdown_ai_command(dev); @@ -1105,9 +1074,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, return; } if (status & AI_SC_TC_St) { -#ifdef DEBUG_INTERRUPT - printk("ni_mio_common: SC_TC interrupt\n"); -#endif if (!devpriv->ai_continuous) { shutdown_ai_command(dev); } @@ -1134,15 +1100,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, } ni_event(dev, s); - -#ifdef DEBUG_INTERRUPT - status = devpriv->stc_readw(dev, AI_Status_1_Register); - if (status & Interrupt_A_St) { - printk - ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n", - status); - } -#endif } static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) @@ -1182,12 +1139,6 @@ static void handle_b_interrupt(struct comedi_device *dev, struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; /* unsigned short ack=0; */ -#ifdef DEBUG_INTERRUPT - printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", - b_status, ao_mite_status); - ni_mio_print_status_b(b_status); -#endif - #ifdef PCIDMA /* Currently, mite.c requires us to handle LINKC */ if (ao_mite_status & CHSR_LINKC) { @@ -1200,7 +1151,6 @@ static void handle_b_interrupt(struct comedi_device *dev, printk ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n", ao_mite_status); - /* mite_print_chsr(ao_mite_status); */ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } #endif @@ -1214,12 +1164,9 @@ static void handle_b_interrupt(struct comedi_device *dev, s->async->events |= COMEDI_CB_OVERFLOW; } - if (b_status & AO_BC_TC_St) { - MDPRINTK - ("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n", - b_status, devpriv->stc_readw(dev, AO_Status_2_Register)); + if (b_status & AO_BC_TC_St) s->async->events |= COMEDI_CB_EOA; - } + #ifndef PCIDMA if (b_status & AO_FIFO_Request_St) { int ret; @@ -1238,50 +1185,6 @@ static void handle_b_interrupt(struct comedi_device *dev, ni_event(dev, s); } -#ifdef DEBUG_STATUS_A -static const char *const status_a_strings[] = { - "passthru0", "fifo", "G0_gate", "G0_TC", - "stop", "start", "sc_tc", "start1", - "start2", "sc_tc_error", "overflow", "overrun", - "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a" -}; - -static void ni_mio_print_status_a(int status) -{ - int i; - - printk("A status:"); - for (i = 15; i >= 0; i--) { - if (status & (1 << i)) { - printk(" %s", status_a_strings[i]); - } - } - printk("\n"); -} -#endif - -#ifdef DEBUG_STATUS_B -static const char *const status_b_strings[] = { - "passthru1", "fifo", "G1_gate", "G1_TC", - "UI2_TC", "UPDATE", "UC_TC", "BC_TC", - "start1", "overrun", "start", "bc_tc_error", - "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b" -}; - -static void ni_mio_print_status_b(int status) -{ - int i; - - printk("B status:"); - for (i = 15; i >= 0; i--) { - if (status & (1 << i)) { - printk(" %s", status_b_strings[i]); - } - } - printk("\n"); -} -#endif - #ifndef PCIDMA static void ni_ao_fifo_load(struct comedi_device *dev, @@ -2392,7 +2295,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int stop_count; int interrupt_a_enable = 0; - MDPRINTK("ni_ai_cmd\n"); if (dev->irq == 0) { comedi_error(dev, "cannot run command without an irq"); return -EIO; @@ -2630,15 +2532,11 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ni_set_bits(dev, Interrupt_A_Enable_Register, interrupt_a_enable, 1); - - MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n", - devpriv->int_a_enable_reg); } else { /* interrupt on nothing */ ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0); /* XXX start polling if necessary */ - MDPRINTK("interrupting on nothing\n"); } /* end configuration */ @@ -2664,7 +2562,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (retval) return retval; } - /* mite_dump_regs(devpriv->mite); */ #endif switch (cmd->start_src) { @@ -2682,8 +2579,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; } - MDPRINTK("exit ni_ai_cmd\n"); - return 0; } @@ -3819,10 +3714,6 @@ static int ni_serial_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_SERIAL_CLOCK: - -#ifdef DEBUG_DIO - printk("SPI serial clock Config cd\n", data[1]); -#endif devpriv->serial_hw_mode = 1; devpriv->dio_control |= DIO_HW_Serial_Enable; @@ -3911,10 +3802,6 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, unsigned int status1; int err = 0, count = 20; -#ifdef DEBUG_DIO - printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out); -#endif - devpriv->dio_output &= ~DIO_Serial_Data_Mask; devpriv->dio_output |= DIO_Serial_Data_Out(data_out); devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register); @@ -3948,12 +3835,8 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, DIO_Serial_IO_In_Progress_St goes high one bit too early. */ udelay((devpriv->serial_interval_ns + 999) / 1000); - if (data_in != NULL) { + if (data_in != NULL) *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register); -#ifdef DEBUG_DIO - printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in); -#endif - } Error: devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); @@ -3969,10 +3852,6 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, struct ni_private *devpriv = dev->private; unsigned char mask, input = 0; -#ifdef DEBUG_DIO - printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out); -#endif - /* Wait for one bit before transfer */ udelay((devpriv->serial_interval_ns + 999) / 1000); @@ -4009,9 +3888,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, input |= mask; } } -#ifdef DEBUG_DIO - printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input); -#endif + if (data_in) *data_in = input; @@ -5873,25 +5750,6 @@ static void cs5529_config_write(struct comedi_device *dev, unsigned int value, comedi_error(dev, "time or signal in cs5529_config_write()"); } -#ifdef NI_CS5529_DEBUG -/* read from cs5529 register */ -static unsigned int cs5529_config_read(struct comedi_device *dev, - unsigned int reg_select_bits) -{ - unsigned int value; - - reg_select_bits &= CSCMD_REGISTER_SELECT_MASK; - cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits); - if (cs5529_wait_for_idle(dev)) - comedi_error(dev, "timeout or signal in cs5529_config_read()"); - value = (ni_ao_win_inw(dev, - CAL_ADC_Config_Data_High_Word_67xx) << 16) & - 0xff0000; - value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff; - return value; -} -#endif - static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data) { int retval; @@ -5968,12 +5826,5 @@ static int init_cs5529(struct comedi_device *dev) if (cs5529_wait_for_idle(dev)) comedi_error(dev, "timeout or signal in init_cs5529()\n"); #endif -#ifdef NI_CS5529_DEBUG - printk("config: 0x%x\n", cs5529_config_read(dev, - CSCMD_CONFIG_REGISTER)); - printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER)); - printk("offset: 0x%x\n", cs5529_config_read(dev, - CSCMD_OFFSET_REGISTER)); -#endif return 0; } diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 229a273f2016..de421486b758 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -47,8 +47,6 @@ See the notes in the ni_atmio.o driver. #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> -#undef DEBUG - #define ATMIO 1 #undef PCIMIO diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index e3a8fa96d9b3..30c46a3c1767 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -47,8 +47,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org */ #define USE_DMA -/* #define DEBUG 1 */ -/* #define DEBUG_FLAGS */ #include <linux/module.h> #include <linux/delay.h> @@ -60,13 +58,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #include "comedi_fc.h" #include "mite.h" -#undef DPRINTK -#ifdef DEBUG -#define DPRINTK(format, args...) pr_debug(format, ## args) -#else -#define DPRINTK(format, args...) do { } while (0) -#endif - #define PCI_DIO_SIZE 4096 #define PCI_MITE_SIZE 4096 @@ -319,14 +310,6 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode); static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s); -#ifdef DEBUG_FLAGS -static void ni_pcidio_print_flags(unsigned int flags); -static void ni_pcidio_print_status(unsigned int status); -#else -#define ni_pcidio_print_flags(x) -#define ni_pcidio_print_status(x) -#endif - static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) { struct nidio96_private *devpriv = dev->private; @@ -401,7 +384,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct nidio96_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; @@ -427,19 +410,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d) Interrupt_And_Window_Status); flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n", - status, flags); - ni_pcidio_print_flags(flags); - ni_pcidio_print_status(status); - spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) m_status = mite_get_status(devpriv->di_mite_chan); -#ifdef MITE_DEBUG - mite_print_chsr(m_status); -#endif - /* mite_dump_regs(mite); */ if (m_status & CHSR_INT) { if (m_status & CHSR_LINKC) { writel(CHOR_CLRLC, @@ -450,7 +424,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY | CHSR_DRQ1 | CHSR_MRDY)) { - DPRINTK("unknown mite interrupt, disabling IRQ\n"); + dev_dbg(dev->class_dev, + "unknown mite interrupt, disabling IRQ\n"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; disable_irq(dev->irq); } @@ -460,7 +435,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) while (status & DataLeft) { work++; if (work > 20) { - DPRINTK("too much work in interrupt\n"); + dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); @@ -470,11 +445,11 @@ static irqreturn_t nidio_interrupt(int irq, void *d) flags &= IntEn; if (flags & TransferReady) { - /* DPRINTK("TransferReady\n"); */ while (flags & TransferReady) { work++; if (work > 100) { - DPRINTK("too much work in interrupt\n"); + dev_dbg(dev->class_dev, + "too much work in interrupt\n"); writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control @@ -488,21 +463,13 @@ static irqreturn_t nidio_interrupt(int irq, void *d) data2 = (auxdata & 0xffff0000) >> 16; comedi_buf_put(async, data1); comedi_buf_put(async, data2); - /* DPRINTK("read:%d, %d\n",data1,data2); */ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); } - /* DPRINTK("buf_int_count: %d\n", - async->buf_int_count); */ - /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n", - IntEn,flags,status); */ - /* ni_pcidio_print_flags(flags); */ - /* ni_pcidio_print_status(status); */ async->events |= COMEDI_CB_BLOCK; } if (flags & CountExpired) { - DPRINTK("CountExpired\n"); writeb(ClearExpired, devpriv->mite->daq_io_addr + Group_1_Second_Clear); @@ -511,41 +478,26 @@ static irqreturn_t nidio_interrupt(int irq, void *d) writeb(0x00, devpriv->mite->daq_io_addr + OpMode); break; } else if (flags & Waited) { - DPRINTK("Waited\n"); writeb(ClearWaited, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; break; } else if (flags & PrimaryTC) { - DPRINTK("PrimaryTC\n"); writeb(ClearPrimaryTC, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA; } else if (flags & SecondaryTC) { - DPRINTK("SecondaryTC\n"); writeb(ClearSecondaryTC, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA; } -#if 0 - else { - DPRINTK("ni_pcidio: unknown interrupt\n"); - async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - writeb(0x00, - devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); - } -#endif + flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); status = readb(devpriv->mite->daq_io_addr + Interrupt_And_Window_Status); - /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x," - "status=0x%02x\n", IntEn, flags, status); */ - /* ni_pcidio_print_flags(flags); */ - /* ni_pcidio_print_status(status); */ } out: @@ -562,82 +514,6 @@ out: return IRQ_HANDLED; } -#ifdef DEBUG_FLAGS -static const char *bit_set_string(unsigned int bits, unsigned int bit, - const char *const strings[]) -{ - return (bits & (1U << bit)) ? strings[bit] : ""; -} - -static const char *const flags_strings[] = { - " TransferReady", " CountExpired", " 2", " 3", - " 4", " Waited", " PrimaryTC", " SecondaryTC", -}; - - -static void ni_pcidio_print_flags(unsigned int flags) -{ - pr_debug("group_1_flags:%s%s%s%s%s%s%s%s\n", - bit_set_string(flags, 7, flags_strings), - bit_set_string(flags, 6, flags_strings), - bit_set_string(flags, 5, flags_strings), - bit_set_string(flags, 4, flags_strings), - bit_set_string(flags, 3, flags_strings), - bit_set_string(flags, 2, flags_strings), - bit_set_string(flags, 1, flags_strings), - bit_set_string(flags, 0, flags_strings)); -} - -static const char *const status_strings[] = { - " DataLeft1", " Reserved1", " Req1", " StopTrig1", - " DataLeft2", " Reserved2", " Req2", " StopTrig2", -}; - -static void ni_pcidio_print_status(unsigned int flags) -{ - pr_debug("group_status:%s%s%s%s%s%s%s%s\n", - bit_set_string(flags, 7, status_strings), - bit_set_string(flags, 6, status_strings), - bit_set_string(flags, 5, status_strings), - bit_set_string(flags, 4, status_strings), - bit_set_string(flags, 3, status_strings), - bit_set_string(flags, 2, status_strings), - bit_set_string(flags, 1, status_strings), - bit_set_string(flags, 0, status_strings)); -} -#endif - -#ifdef unused -static void debug_int(struct comedi_device *dev) -{ - struct nidio96_private *devpriv = dev->private; - int a, b; - static int n_int; - struct timeval tv; - - do_gettimeofday(&tv); - a = readb(devpriv->mite->daq_io_addr + Group_Status); - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - - if (n_int < 10) { - DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b, - (int)tv.tv_usec); - } - - while (b & 1) { - writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO); - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - } - - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - - if (n_int < 10) { - DPRINTK("new status 0x%02x\n", b); - n_int++; - } -} -#endif - static int ni_pcidio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -883,7 +759,6 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) s->async->inttrig = ni_pcidio_inttrig; } - DPRINTK("ni_pcidio: command started\n"); return 0; } @@ -1074,6 +949,19 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) return ret; } +static void nidio_reset_board(struct comedi_device *dev) +{ + struct nidio96_private *devpriv = dev->private; + void __iomem *daq_mmio = devpriv->mite->daq_io_addr; + + writel(0, daq_mmio + Port_IO(0)); + writel(0, daq_mmio + Port_Pin_Directions(0)); + writel(0, daq_mmio + Port_Pin_Mask(0)); + + /* disable interrupts on board */ + writeb(0, daq_mmio + Master_DMA_And_Interrupt_Control); +} + static int nidio_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -1115,13 +1003,14 @@ static int nidio_auto_attach(struct comedi_device *dev, if (devpriv->di_mite_ring == NULL) return -ENOMEM; - irq = mite_irq(devpriv->mite); if (board->uses_firmware) { ret = pci_6534_upload_firmware(dev); if (ret < 0) return ret; } + nidio_reset_board(dev); + ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; @@ -1149,21 +1038,13 @@ static int nidio_auto_attach(struct comedi_device *dev, s->async_dma_dir = DMA_BIDIRECTIONAL; s->poll = &ni_pcidio_poll; - writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0)); - - /* disable interrupts on board */ - writeb(0x00, - devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); - - ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, - "ni_pcidio", dev); - if (ret < 0) - dev_warn(dev->class_dev, "irq not available\n"); - - dev->irq = irq; + irq = mite_irq(devpriv->mite); + if (irq) { + ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = irq; + } return 0; } @@ -1200,7 +1081,7 @@ static int ni_pcidio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { +static const struct pci_device_id ni_pcidio_pci_table[] = { { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS }, { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 }, { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 }, diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 536be83af549..ec4fa3d839c4 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -116,8 +116,6 @@ Bugs: #include "ni_stc.h" #include "mite.h" -/* #define PCI_DEBUG */ - #define PCIDMA #define PCIMIO 1 @@ -1178,9 +1176,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, offset = M_Offset_AO_FIFO_Clear; break; case DIO_Control_Register: - printk - ("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n", - __func__, reg); + dev_dbg(dev->class_dev, + "%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n", + __func__, reg); return; break; case G_Autoincrement_Register(0): @@ -1471,6 +1469,7 @@ static int pcimio_auto_attach(struct comedi_device *dev, struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct ni_board_struct *board = NULL; struct ni_private *devpriv; + unsigned int irq; int ret; if (context < ARRAY_SIZE(ni_boards)) @@ -1532,18 +1531,12 @@ static int pcimio_auto_attach(struct comedi_device *dev, if (board->reg_type == ni_reg_6143) init_6143(dev); - dev->irq = mite_irq(devpriv->mite); - - if (dev->irq == 0) { - pr_warn("unknown irq (bad)\n"); - } else { - pr_debug("( irq = %u )\n", dev->irq); - ret = request_irq(dev->irq, ni_E_interrupt, NI_E_IRQ_FLAGS, - DRV_NAME, dev); - if (ret < 0) { - pr_warn("irq not available\n"); - dev->irq = 0; - } + irq = mite_irq(devpriv->mite); + if (irq) { + ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS, + dev->board_name, dev); + if (ret == 0) + dev->irq = irq; } ret = ni_E_init(dev); @@ -1639,7 +1632,7 @@ static int ni_pcimio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = { +static const struct pci_device_id ni_pcimio_pci_table[] = { { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */ { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 }, { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 }, diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 9b120c77d83a..cf8892bcf01e 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1319,7 +1319,6 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, counter_dev->regs[abz_reg] &= ~mask; counter_dev->regs[abz_reg] |= (source << shift) & mask; write_register(counter, counter_dev->regs[abz_reg], abz_reg); -/* printk("%s %x %d %d\n", __func__, counter_dev->regs[abz_reg], index, source); */ return 0; } return -EINVAL; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 03315abcca19..380c9c29645a 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -404,9 +404,7 @@ static int pcl812_ai_insn_read(struct comedi_device *dev, goto conv_finish; udelay(1); } - printk - ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D insn read timeout\n"); outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE); return -ETIME; @@ -441,9 +439,7 @@ static int acl8216_ai_insn_read(struct comedi_device *dev, goto conv_finish; udelay(1); } - printk - ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D insn read timeout\n"); outb(0, dev->iobase + PCL812_MODE); return -ETIME; @@ -759,7 +755,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) unsigned int mask, timeout; struct comedi_device *dev = d; struct pcl812_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int next_chan; s->async->events = 0; @@ -786,10 +782,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) } if (err) { - printk - ("comedi%d: pcl812: (%s at 0x%lx) " - "A/D cmd IRQ without DRDY!\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); pcl812_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -865,7 +858,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl812_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned long dma_flags; int len, bufptr; unsigned short *ptr; @@ -1095,7 +1088,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl812_board *board = comedi_board(dev); struct pcl812_private *devpriv; int ret, subdev; - unsigned int irq; unsigned int dma; unsigned long pages; struct comedi_subdevice *s; @@ -1109,31 +1101,13 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, " - "DISABLING IT", irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl812, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, " - "DISABLING IT", irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_INFO ", irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl812, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - dma = 0; devpriv->dma = dma; if (!dev->irq) @@ -1141,21 +1115,22 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (((1 << dma) & board->DMAbits) == 0) { - printk(", DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); if (ret) { - printk(KERN_ERR ", unable to allocate DMA %u, FAIL!\n", - dma); + dev_err(dev->class_dev, + "unable to allocate DMA %u, FAIL!\n", dma); return -EBUSY; /* DMA isn't free */ } devpriv->dma = dma; - printk(KERN_INFO ", dma=%u", dma); pages = 1; /* we want 8KB */ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[0]) { - printk(", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); /* * maybe experiment with try_to_free_pages() * will help .... @@ -1167,7 +1142,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages); devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { - printk(KERN_ERR ", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); return -EBUSY; } devpriv->dmapages[1] = pages; @@ -1225,7 +1201,6 @@ no_dma: break; } s->maxdata = board->ai_maxdata; - s->len_chanlist = MAX_CHANLIST_LEN; s->range_table = board->rangelist_ai; if (board->board_type == boardACL8216) s->insn_read = acl8216_ai_insn_read; @@ -1233,13 +1208,14 @@ no_dma: s->insn_read = pcl812_ai_insn_read; devpriv->use_MPC = board->haveMPC508; - s->cancel = pcl812_ai_cancel; if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = MAX_CHANLIST_LEN; s->do_cmdtest = pcl812_ai_cmdtest; s->do_cmd = pcl812_ai_cmd; s->poll = pcl812_ai_poll; + s->cancel = pcl812_ai_cancel; } switch (board->board_type) { case boardPCL812PG: @@ -1269,10 +1245,6 @@ no_dma: default: s->range_table = &range_bipolar10; break; - printk - (", incorrect range number %d, changing " - "to 0 (+/-10V)", it->options[4]); - break; } break; break; @@ -1299,10 +1271,6 @@ no_dma: default: s->range_table = &range_iso813_1_ai; break; - printk - (", incorrect range number %d, " - "changing to 0 ", it->options[1]); - break; } break; case boardACL8113: @@ -1324,10 +1292,6 @@ no_dma: default: s->range_table = &range_acl8113_1_ai; break; - printk - (", incorrect range number %d, " - "changing to 0 ", it->options[1]); - break; } break; } @@ -1341,7 +1305,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = board->n_aochan; s->maxdata = 0xfff; - s->len_chanlist = 1; s->range_table = board->rangelist_ao; s->insn_read = pcl812_ao_insn_read; s->insn_write = pcl812_ao_insn_write; @@ -1370,7 +1333,6 @@ no_dma: s->subdev_flags = SDF_READABLE; s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl812_di_insn_bits; subdev++; @@ -1383,7 +1345,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE; s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl812_do_insn_bits; subdev++; @@ -1402,7 +1363,7 @@ no_dma: break; case boardA821: devpriv->max_812_ai_mode0_rangewait = 1; - devpriv->mode_reg_int = (irq << 4) & 0xf0; + devpriv->mode_reg_int = (dev->irq << 4) & 0xf0; break; case boardPCL813B: case boardPCL813: @@ -1413,7 +1374,6 @@ no_dma: break; } - printk(KERN_INFO "\n"); devpriv->valid = 1; pcl812_reset(dev); diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index ab9d2bd26a20..a2e0b545401b 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -44,14 +44,10 @@ Configuration Options: #include "comedi_fc.h" #include "8253.h" -#define DEBUG(x) x - /* boards constants */ /* IO space len */ #define PCLx1x_RANGE 16 -/* #define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) */ - /* INTEL 8254 counters */ #define PCL816_CTR0 4 #define PCL816_CTR1 5 @@ -132,7 +128,6 @@ struct pcl816_private { unsigned int ai_scans; /* len of scanlist */ unsigned char ai_neverending; /* if=1, then we do neverending record (you must use cancel()) */ - int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ int irq_was_now_closed; /* when IRQ finish, there's stored int816_mode for last interrupt */ int int816_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ @@ -143,7 +138,6 @@ struct pcl816_private { unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ unsigned int ai_n_chan; /* how many channels per scan */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ - struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ }; /* @@ -176,7 +170,6 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, int n; int timeout; - DPRINTK("mode 0 analog input\n"); /* software trigger, DMA and INT off */ outb(0, dev->iobase + PCL816_CONTROL); /* clear INT (conversion end) flag */ @@ -228,7 +221,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned char low, hi; int timeout = 50; /* wait max 50us */ @@ -322,7 +315,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int len, bufptr, this_dma_buf; unsigned long dma_flags; unsigned short *ptr; @@ -372,8 +365,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - DPRINTK("<I>"); - if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; @@ -389,8 +380,7 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) } outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ - if (!dev->irq || !devpriv->irq_free || !devpriv->irq_blocked || - !devpriv->int816_mode) { + if (!dev->irq || !devpriv->irq_blocked || !devpriv->int816_mode) { if (devpriv->irq_was_now_closed) { devpriv->irq_was_now_closed = 0; /* comedi_error(dev,"last IRQ.."); */ @@ -405,22 +395,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) /* ============================================================================== - COMMAND MODE -*/ -static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd) -{ - printk(KERN_INFO "pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e, - cmd->start_src, cmd->scan_begin_src, cmd->convert_src); - printk(KERN_INFO "pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e, - cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg); - printk(KERN_INFO "pcl816 e=%d stopsrc=%x scanend=%x\n", e, - cmd->stop_src, cmd->scan_end_src); - printk(KERN_INFO "pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", - e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len); -} - -/* -============================================================================== */ static int pcl816_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -429,10 +403,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp, divisor1 = 0, divisor2 = 0; - DEBUG(printk(KERN_INFO "pcl816 pcl812_ai_cmdtest\n"); - pcl816_cmdtest_out(-1, cmd); - ); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); @@ -566,15 +536,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_neverending = 1; } - /* don't we want wake up every scan? */ - if ((cmd->flags & TRIG_WAKE_EOS)) { - printk(KERN_INFO - "pl816: You wankt WAKE_EOS but I dont want handle it"); - /* devpriv->ai_eos=1; */ - /* if (devpriv->ai_n_chan==1) */ - /* devpriv->dma=0; // DMA is useless for this situation */ - } - if (devpriv->dma) { bytes = devpriv->hwdmasize[0]; if (!devpriv->ai_neverending) { @@ -630,7 +591,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; } - DPRINTK("pcl816 END: pcl812_ai_cmd()\n"); return 0; } @@ -685,8 +645,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev, { struct pcl816_private *devpriv = dev->private; -/* DEBUG(printk("pcl816_ai_cancel()\n");) */ - if (devpriv->irq_blocked > 0) { switch (devpriv->int816_mode) { case INT_TYPE_AI1_DMA: @@ -719,9 +677,7 @@ static int pcl816_ai_cancel(struct comedi_device *dev, break; } } - - DEBUG(printk("comedi: pcl816_ai_cancel() successful\n");) - return 0; + return 0; } /* @@ -788,8 +744,8 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, udelay(1); if (mode == 1) { - DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1, - divisor2); + dev_dbg(dev->class_dev, "mode %d, divisor1 %d, divisor2 %d\n", + mode, divisor1, divisor2); outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2); outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2); outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1); @@ -823,11 +779,6 @@ check_channel_list(struct comedi_device *dev, /* first channel is every time ok */ chansegment[0] = chanlist[0]; for (i = 1, seglen = 1; i < chanlen; i++, seglen++) { - /* build part of chanlist */ - DEBUG(printk(KERN_INFO "%d. %d %d\n", i, - CR_CHAN(chanlist[i]), - CR_RANGE(chanlist[i]));) - /* we detect loop, this must by finish */ if (chanlist[0] == chanlist[i]) break; @@ -835,12 +786,10 @@ check_channel_list(struct comedi_device *dev, (CR_CHAN(chansegment[i - 1]) + 1) % chanlen; if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk(KERN_WARNING - "comedi%d: pcl816: channel list must " - "be continuous! chanlist[%i]=%d but " - "must be %d or %d!\n", dev->minor, - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); + dev_dbg(dev->class_dev, + "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); return 0; } /* well, this is next correct channel in list */ @@ -849,22 +798,15 @@ check_channel_list(struct comedi_device *dev, /* check whole chanlist */ for (i = 0, segpos = 0; i < chanlen; i++) { - DEBUG(printk("%d %d=%d %d\n", - CR_CHAN(chansegment[i % seglen]), - CR_RANGE(chansegment[i % seglen]), - CR_CHAN(chanlist[i]), - CR_RANGE(chanlist[i]));) if (chanlist[i] != chansegment[i % seglen]) { - printk(KERN_WARNING - "comedi%d: pcl816: bad channel or range" - " number! chanlist[%i]=%d,%d,%d and not" - " %d,%d,%d!\n", dev->minor, i, - CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); + dev_dbg(dev->class_dev, + "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); return 0; /* chan/gain list is strange */ } } @@ -909,7 +851,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl816_board *board = comedi_board(dev); struct pcl816_private *devpriv; int ret; - unsigned int irq, dma; + unsigned int dma; unsigned long pages; /* int i; */ struct comedi_subdevice *s; @@ -919,7 +861,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; if (pcl816_check(dev->iobase)) { - printk(KERN_ERR ", I cann't detect board. FAIL!\n"); + dev_err(dev->class_dev, "I can't detect board. FAIL!\n"); return -EIO; } @@ -927,43 +869,20 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - /* grab our IRQ */ - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, " - "DISABLING IT", irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl816, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, " - "DISABLING IT", irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_INFO ", irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl816, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - if (irq) /* 1=we have allocated irq */ - devpriv->irq_free = 1; - else - devpriv->irq_free = 0; - devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */ devpriv->int816_mode = 0; /* mode of irq */ /* grab our DMA */ dma = 0; devpriv->dma = dma; - if (!devpriv->irq_free) + if (!dev->irq) goto no_dma; /* if we haven't IRQ, we can't use DMA */ if (board->DMAbits != 0) { /* board support DMA */ @@ -972,23 +891,24 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) goto no_dma; /* DMA disabled */ if (((1 << dma) & board->DMAbits) == 0) { - printk(", DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); if (ret) { - printk(KERN_ERR - ", unable to allocate DMA %u, FAIL!\n", dma); + dev_err(dev->class_dev, + "unable to allocate DMA %u, FAIL!\n", dma); return -EBUSY; /* DMA isn't free */ } devpriv->dma = dma; - printk(KERN_INFO ", dma=%u", dma); pages = 2; /* we need 16KB */ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[0]) { - printk(", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); /* * maybe experiment with try_to_free_pages() * will help .... @@ -998,13 +918,11 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; - /* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { - printk(KERN_ERR - ", unable to allocate DMA buffer, " - "FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); return -EBUSY; } devpriv->dmapages[1] = pages; @@ -1029,20 +947,20 @@ no_dma: s = &dev->subdevices[0]; if (board->n_aichan > 0) { s->type = COMEDI_SUBD_AI; - devpriv->sub_ai = s; - dev->read_subdev = s; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_CMD_READ | SDF_DIFF; s->n_chan = board->n_aichan; - s->subdev_flags |= SDF_DIFF; - /* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */ s->maxdata = board->ai_maxdata; - s->len_chanlist = board->ai_chanlist; s->range_table = board->ai_range_type; - s->cancel = pcl816_ai_cancel; - s->do_cmdtest = pcl816_ai_cmdtest; - s->do_cmd = pcl816_ai_cmd; - s->poll = pcl816_ai_poll; s->insn_read = pcl816_ai_insn_read; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = board->ai_chanlist; + s->do_cmdtest = pcl816_ai_cmdtest; + s->do_cmd = pcl816_ai_cmd; + s->poll = pcl816_ai_poll; + s->cancel = pcl816_ai_cancel; + } } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1075,8 +993,6 @@ case COMEDI_SUBD_DO: pcl816_reset(dev); - printk("\n"); - return 0; } @@ -1085,7 +1001,7 @@ static void pcl816_detach(struct comedi_device *dev) struct pcl816_private *devpriv = dev->private; if (dev->private) { - pcl816_ai_cancel(dev, devpriv->sub_ai); + pcl816_ai_cancel(dev, dev->read_subdev); pcl816_reset(dev); if (devpriv->dma) free_dma(devpriv->dma); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 9e4d7e860509..695e84a94ced 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -274,7 +274,6 @@ struct pcl818_private { unsigned char neverending_ai; /* if=1, then we do neverending record (you must use cancel()) */ unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */ int i8253_osc_base; /* 1/frequency of on board oscilator in ns */ - int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ int irq_was_now_closed; /* when IRQ finish, there's stored int818_mode for last interrupt */ int ai_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ @@ -291,7 +290,6 @@ struct pcl818_private { unsigned int ai_data_len; /* len of data buffer */ unsigned int ai_timer1; /* timers */ unsigned int ai_timer2; - struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ unsigned char usefifo; /* 1=use fifo */ unsigned int ao_readback[2]; }; @@ -441,7 +439,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned char low; int timeout = 50; /* wait max 50us */ @@ -463,10 +461,10 @@ conv_finish: outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n", - (low & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos]); + dev_dbg(dev->class_dev, + "A/D mode1/3 IRQ - channel dropout %x!=%x !\n", + (low & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos]); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -478,7 +476,6 @@ conv_finish: s->async->cur_chan++; if (s->async->cur_chan >= devpriv->ai_n_chan) { - /* printk("E"); */ s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -501,7 +498,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i, len, bufptr; unsigned long flags; unsigned short *ptr; @@ -523,7 +520,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) release_dma_lock(flags); enable_dma(devpriv->dma); } - printk("comedi: A/D mode1/3 IRQ \n"); devpriv->dma_runs_to_end--; outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ @@ -534,11 +530,11 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) for (i = 0; i < len; i++) { if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n", - (ptr[bufptr] & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos], - devpriv->act_chanlist_pos); + dev_dbg(dev->class_dev, + "A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n", + (ptr[bufptr] & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos], + devpriv->act_chanlist_pos); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -562,7 +558,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); - /* printk("done int ai13 dma\n"); */ return IRQ_HANDLED; } } @@ -580,7 +575,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i, len; unsigned char lo; @@ -612,10 +607,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) for (i = 0; i < len; i++) { lo = inb(dev->iobase + PCL818_FI_DATALO); if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n", - (lo & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos]); + dev_dbg(dev->class_dev, + "A/D mode1/3 FIFO - channel dropout %d!=%d !\n", + (lo & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos]); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -661,7 +656,6 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } - /* printk("I\n"); */ if (devpriv->irq_blocked && devpriv->irq_was_now_closed) { if ((devpriv->neverending_ai || (!devpriv->neverending_ai && @@ -673,10 +667,9 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) being reprogrammed while a DMA transfer is in progress. */ - struct comedi_subdevice *s = &dev->subdevices[0]; devpriv->ai_act_scan = 0; devpriv->neverending_ai = 0; - pcl818_ai_cancel(dev, s); + pcl818_ai_cancel(dev, dev->read_subdev); } outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ @@ -705,8 +698,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ - if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked) - || (!devpriv->ai_mode)) { + if (!devpriv->irq_blocked || !devpriv->ai_mode) { comedi_error(dev, "bad IRQ!"); return IRQ_NONE; } @@ -726,7 +718,6 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, unsigned int flags; unsigned int bytes; - printk("mode13dma_int, mode: %d\n", mode); disable_dma(devpriv->dma); /* disable dma */ bytes = devpriv->hwdmasize[0]; if (!devpriv->neverending_ai) { @@ -753,7 +744,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, } else { devpriv->ai_mode = INT_TYPE_AI3_DMA; outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */ - }; + } } /* @@ -768,12 +759,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, int divisor1 = 0, divisor2 = 0; unsigned int seglen; - dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode()\n"); - if (!dev->irq) { - comedi_error(dev, "IRQ not defined!"); - return -EINVAL; - } - if (devpriv->irq_blocked) return -EBUSY; @@ -824,7 +809,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, case 0: if (!devpriv->usefifo) { /* IRQ */ - /* printk("IRQ\n"); */ if (mode == 1) { devpriv->ai_mode = INT_TYPE_AI1_INT; /* Pacer+IRQ */ @@ -853,7 +837,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, start_pacer(dev, mode, divisor1, divisor2); - dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode() end\n"); return 0; } @@ -899,10 +882,6 @@ static int check_channel_list(struct comedi_device *dev, chansegment[0] = chanlist[0]; /* build part of chanlist */ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { - - /* printk("%d. %d * %d\n",i, - * CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));*/ - /* we detect loop, this must by finish */ if (chanlist[0] == chanlist[i]) @@ -910,10 +889,10 @@ static int check_channel_list(struct comedi_device *dev, nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk - ("comedi%d: pcl818: channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - dev->minor, i, CR_CHAN(chanlist[i]), - nowmustbechan, CR_CHAN(chanlist[0])); + dev_dbg(dev->class_dev, + "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); return 0; } /* well, this is next correct channel in list */ @@ -922,23 +901,21 @@ static int check_channel_list(struct comedi_device *dev, /* check whole chanlist */ for (i = 0, segpos = 0; i < n_chan; i++) { - /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i])); */ if (chanlist[i] != chansegment[i % seglen]) { - printk - ("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - dev->minor, i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); + dev_dbg(dev->class_dev, + "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); return 0; /* chan/gain list is strange */ } } } else { seglen = 1; } - printk("check_channel_list: seglen %d\n", seglen); return seglen; } @@ -1067,7 +1044,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_cmd *cmd = &s->async->cmd; int retval; - dev_dbg(dev->class_dev, "pcl818_ai_cmd()\n"); devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_chanlist = cmd->chanlist; devpriv->ai_flags = cmd->flags; @@ -1084,7 +1060,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->convert_src == TRIG_TIMER) { /* mode 1 */ devpriv->ai_timer1 = cmd->convert_arg; retval = pcl818_ai_cmd_mode(1, dev, s); - dev_dbg(dev->class_dev, "pcl818_ai_cmd() end\n"); return retval; } if (cmd->convert_src == TRIG_EXT) { /* mode 3 */ @@ -1105,7 +1080,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev, struct pcl818_private *devpriv = dev->private; if (devpriv->irq_blocked > 0) { - dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n"); devpriv->irq_was_now_closed = 1; switch (devpriv->ai_mode) { @@ -1149,7 +1123,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev, } end: - dev_dbg(dev->class_dev, "pcl818_ai_cancel() end\n"); return 0; } @@ -1216,7 +1189,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl818_board *board = comedi_board(dev); struct pcl818_private *devpriv; int ret; - unsigned int irq; int dma; unsigned long pages; struct comedi_subdevice *s; @@ -1240,50 +1212,28 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - /* grab our IRQ */ - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, DISABLING IT", - irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl818, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_DEBUG "irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl818, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - if (irq) - devpriv->irq_free = 1; /* 1=we have allocated irq */ - else - devpriv->irq_free = 0; - devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */ devpriv->ai_mode = 0; /* mode of irq */ /* grab our DMA */ dma = 0; devpriv->dma = dma; - if (!devpriv->irq_free) + if (!dev->irq) goto no_dma; /* if we haven't IRQ, we can't use DMA */ if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (dma < 1) goto no_dma; /* DMA disabled */ if (((1 << dma) & board->DMAbits) == 0) { - printk(KERN_ERR "DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); @@ -1298,7 +1248,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; - /* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) return -EBUSY; @@ -1318,27 +1267,24 @@ no_dma: s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_AI; - devpriv->sub_ai = s; s->subdev_flags = SDF_READABLE; if (check_single_ended(dev->iobase)) { s->n_chan = board->n_aichan_se; s->subdev_flags |= SDF_COMMON | SDF_GROUND; - printk(", %dchans S.E. DAC", s->n_chan); } else { s->n_chan = board->n_aichan_diff; s->subdev_flags |= SDF_DIFF; - printk(", %dchans DIFF DAC", s->n_chan); } s->maxdata = board->ai_maxdata; - s->len_chanlist = s->n_chan; s->range_table = board->ai_range_type; - s->cancel = pcl818_ai_cancel; s->insn_read = pcl818_ai_insn_read; - if (irq) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; s->do_cmdtest = ai_cmdtest; s->do_cmd = ai_cmd; + s->cancel = pcl818_ai_cancel; } if (board->is_818) { if ((it->options[4] == 1) || (it->options[4] == 10)) @@ -1387,7 +1333,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = board->n_aochan; s->maxdata = board->ao_maxdata; - s->len_chanlist = board->n_aochan; s->range_table = board->ao_range_type; s->insn_read = pcl818_ao_insn_read; s->insn_write = pcl818_ao_insn_write; @@ -1412,7 +1357,6 @@ no_dma: s->subdev_flags = SDF_READABLE; s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl818_di_insn_bits; } @@ -1425,7 +1369,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE; s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl818_do_insn_bits; } @@ -1446,8 +1389,6 @@ no_dma: pcl818_reset(dev); - printk("\n"); - return 0; } @@ -1456,7 +1397,7 @@ static void pcl818_detach(struct comedi_device *dev) struct pcl818_private *devpriv = dev->private; if (devpriv) { - pcl818_ai_cancel(dev, devpriv->sub_ai); + pcl818_ai_cancel(dev, dev->read_subdev); pcl818_reset(dev); if (devpriv->dma) free_dma(devpriv->dma); diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index cc1dc7f66e5b..f4a49bd649f0 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -70,14 +70,11 @@ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; unsigned char inbres; - /* printk("8255cb %d %d %d %lx\n", dir,port,data,arg); */ if (dir) { - /* printk("8255 cb outb(%x, %lx)\n", data, iobase+port); */ outb(data, iobase + port); return 0; } else { inbres = inb(iobase + port); - /* printk("8255 cb inb(%lx) = %x\n", iobase+port, inbres); */ return inbres; } } @@ -137,8 +134,6 @@ static void do_3724_config(struct comedi_device *dev, port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; outb(buffer_config, dev->iobase + 8); /* update buffer register */ - /* printk("pcm3724 buffer_config (%lx) %d, %x\n", - dev->iobase + _8255_CR, chanspec, buffer_config); */ outb(config, port_8255_cfg); } @@ -177,7 +172,6 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, if (priv->dio_2 & 0xff) gatecfg |= GATE_A1; - /* printk("gate control %x\n", gatecfg); */ outb(gatecfg, dev->iobase + 9); } diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 14cee3ac92c5..ec098d883eb7 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -250,11 +250,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. */ -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "write mask: %08x data: %08x\n", data[0], data[1]); -#endif - s->state = 0; for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) { @@ -271,14 +266,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, byte = inb(ioaddr); /* read all 8-bits for this port */ -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk - (KERN_DEBUG "byte %d wmb %02x db %02x offset %02d io %04x," - " data_in %02x ", byte_no, (unsigned)write_mask_byte, - (unsigned)data_byte, offset, ioaddr, (unsigned)byte); -#endif - if (write_mask_byte) { /* * this byte has some write_bits @@ -291,10 +278,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, /* Write out the new digital output state */ outb(byte, ioaddr); } -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte); -#endif /* save the digital input lines for this byte.. */ s->state |= ((unsigned int)byte) << offset; } @@ -302,11 +285,6 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, /* now return the DIO lines to data[1] - note they came inverted! */ data[1] = ~s->state; -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "s->state %08x data_out %08x\n", s->state, data[1]); -#endif - return insn->n; } @@ -379,13 +357,6 @@ static void init_asics(struct comedi_device *dev) outb(0, baseaddr + reg); } - /* DEBUG set rising edge interrupts on port0 of both asics */ - /*switch_page(dev, asic, PAGE_POL); - outb(0xff, baseaddr + REG_POL0); - switch_page(dev, asic, PAGE_ENAB); - outb(0xff, baseaddr + REG_ENAB0); */ - /* END DEBUG */ - /* switch back to default page 0 */ switch_page(dev, asic, 0); } @@ -505,9 +476,9 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) * TODO here: dispatch io lines to subdevs * with commands.. */ - printk - (KERN_DEBUG "got edge detect interrupt %d asic %d which_chans: %06x\n", - irq, asic, triggered); + dev_dbg(dev->class_dev, + "got edge detect interrupt %d asic %d which_chans: %06x\n", + irq, asic, triggered); for (i = 2; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; /* @@ -1020,11 +991,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->sprivs = kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), GFP_KERNEL); - if (!devpriv->sprivs) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", - dev->minor); + if (!devpriv->sprivs) return -ENOMEM; - } ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 954fa96a50ac..a8f390f7a874 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -75,7 +75,6 @@ #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include "../comedidev.h" @@ -127,36 +126,53 @@ static const struct pcmuio_board pcmuio_boards[] = { }, }; -struct pcmuio_subdev_private { - /* The below is only used for intr subdevices */ - struct { - /* if non-negative, this subdev has an interrupt asic */ - int asic; - /* - * subdev-relative channel mask for channels - * we are interested in - */ - int enabled_mask; - int active; - int stop_count; - int continuous; - spinlock_t spinlock; - } intr; +struct pcmuio_asic { + spinlock_t pagelock; /* protects the page registers */ + spinlock_t spinlock; /* protects member variables */ + unsigned int enabled_mask; + unsigned int stop_count; + unsigned int active:1; + unsigned int continuous:1; }; struct pcmuio_private { - struct { - unsigned int irq; - spinlock_t spinlock; - } asics[PCMUIO_MAX_ASICS]; - struct pcmuio_subdev_private *sprivs; + struct pcmuio_asic asics[PCMUIO_MAX_ASICS]; + unsigned int irq2; }; +static inline unsigned long pcmuio_asic_iobase(struct comedi_device *dev, + int asic) +{ + return dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); +} + +static inline int pcmuio_subdevice_to_asic(struct comedi_subdevice *s) +{ + /* + * subdevice 0 and 1 are handled by the first asic + * subdevice 2 and 3 are handled by the second asic + */ + return s->index / 2; +} + +static inline int pcmuio_subdevice_to_port(struct comedi_subdevice *s) +{ + /* + * subdevice 0 and 2 use port registers 0-2 + * subdevice 1 and 3 use port registers 3-5 + */ + return (s->index % 2) ? 3 : 0; +} + static void pcmuio_write(struct comedi_device *dev, unsigned int val, int asic, int page, int port) { - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); + struct pcmuio_private *devpriv = dev->private; + struct pcmuio_asic *chip = &devpriv->asics[asic]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned long flags; + spin_lock_irqsave(&chip->pagelock, flags); if (page == 0) { /* Port registers are valid for any page */ outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0)); @@ -168,14 +184,19 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val, outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1)); outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2)); } + spin_unlock_irqrestore(&chip->pagelock, flags); } static unsigned int pcmuio_read(struct comedi_device *dev, int asic, int page, int port) { - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); + struct pcmuio_private *devpriv = dev->private; + struct pcmuio_asic *chip = &devpriv->asics[asic]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned long flags; unsigned int val; + spin_lock_irqsave(&chip->pagelock, flags); if (page == 0) { /* Port registers are valid for any page */ val = inb(iobase + PCMUIO_PORT_REG(port + 0)); @@ -187,6 +208,7 @@ static unsigned int pcmuio_read(struct comedi_device *dev, val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8); val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16); } + spin_unlock_irqrestore(&chip->pagelock, flags); return val; } @@ -203,30 +225,35 @@ static unsigned int pcmuio_read(struct comedi_device *dev, */ static int pcmuio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int mask = data[0] & s->io_bits; /* outputs only */ - unsigned int bits = data[1]; - int asic = s->index / 2; - int port = (s->index % 2) ? 3 : 0; + int asic = pcmuio_subdevice_to_asic(s); + int port = pcmuio_subdevice_to_port(s); + unsigned int chanmask = (1 << s->n_chan) - 1; + unsigned int mask; unsigned int val; - /* get inverted state of the channels from the port */ - val = pcmuio_read(dev, asic, 0, port); - - /* get the true state of the channels */ - s->state = val ^ ((0x1 << s->n_chan) - 1); - + mask = comedi_dio_update_state(s, data); if (mask) { - s->state &= ~mask; - s->state |= (mask & bits); - - /* invert the state and update the channels */ - val = s->state ^ ((0x1 << s->n_chan) - 1); + /* + * Outputs are inverted, invert the state and + * update the channels. + * + * The s->io_bits mask makes sure the input channels + * are '0' so that the outputs pins stay in a high + * z-state. + */ + val = ~s->state & chanmask; + val &= s->io_bits; pcmuio_write(dev, val, asic, 0, port); } - data[1] = s->state; + /* get inverted state of the channels from the port */ + val = pcmuio_read(dev, asic, 0, port); + + /* return the true state of the channels */ + data[1] = ~val & chanmask; return insn->n; } @@ -236,8 +263,8 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int asic = s->index / 2; - int port = (s->index % 2) ? 3 : 0; + int asic = pcmuio_subdevice_to_asic(s); + int port = pcmuio_subdevice_to_port(s); int ret; ret = comedi_dio_insn_config(dev, s, insn, data, 0); @@ -267,18 +294,16 @@ static void pcmuio_reset(struct comedi_device *dev) } } +/* chip->spinlock is already locked */ static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; - int asic; - - asic = subpriv->intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 0; + chip->enabled_mask = 0; + chip->active = 0; s->async->inttrig = NULL; /* disable all intrs for this subdev.. */ @@ -289,29 +314,27 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, struct comedi_subdevice *s, unsigned triggered) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned int len = s->async->cmd.chanlist_len; unsigned oldevents = s->async->events; unsigned int val = 0; unsigned long flags; - unsigned mytrig; unsigned int i; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); + spin_lock_irqsave(&chip->spinlock, flags); - if (!subpriv->intr.active) + if (!chip->active) goto done; - mytrig = triggered; - mytrig &= ((0x1 << s->n_chan) - 1); - - if (!(mytrig & subpriv->intr.enabled_mask)) + if (!(triggered & chip->enabled_mask)) goto done; for (i = 0; i < len; i++) { unsigned int chan = CR_CHAN(s->async->cmd.chanlist[i]); - if (mytrig & (1U << chan)) - val |= (1U << i); + if (triggered & (1 << chan)) + val |= (1 << i); } /* Write the scan to the buffer. */ @@ -325,11 +348,11 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, } /* Check for end of acquisition. */ - if (!subpriv->intr.continuous) { + if (!chip->continuous) { /* stop_src == TRIG_COUNT */ - if (subpriv->intr.stop_count > 0) { - subpriv->intr.stop_count--; - if (subpriv->intr.stop_count == 0) { + if (chip->stop_count > 0) { + chip->stop_count--; + if (chip->stop_count == 0) { s->async->events |= COMEDI_CB_EOA; /* TODO: STOP_ACQUISITION_CALL_HERE!! */ pcmuio_stop_intr(dev, s); @@ -338,7 +361,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, } done: - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (oldevents != s->async->events) comedi_event(dev, s); @@ -346,114 +369,93 @@ done: static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic) { - struct pcmuio_private *devpriv = dev->private; - struct pcmuio_subdev_private *subpriv; - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); - unsigned int triggered = 0; - int got1 = 0; - unsigned long flags; - unsigned char int_pend; - int i; + /* there are could be two asics so we can't use dev->read_subdev */ + struct comedi_subdevice *s = &dev->subdevices[asic * 2]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned int val; - spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags); + /* are there any interrupts pending */ + val = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07; + if (!val) + return 0; - int_pend = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07; - if (int_pend) { - triggered = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0); - pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0); + /* get, and clear, the pending interrupts */ + val = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0); + pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0); - ++got1; - } + /* handle the pending interrupts */ + pcmuio_handle_intr_subdev(dev, s, val); - spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags); - - if (triggered) { - struct comedi_subdevice *s; - /* TODO here: dispatch io lines to subdevs with commands.. */ - for (i = 0; i < dev->n_subdevices; i++) { - s = &dev->subdevices[i]; - subpriv = s->private; - if (subpriv->intr.asic == asic) { - /* - * This is an interrupt subdev, and it - * matches this asic! - */ - pcmuio_handle_intr_subdev(dev, s, - triggered); - } - } - } - return got1; + return 1; } static irqreturn_t pcmuio_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct pcmuio_private *devpriv = dev->private; - int got1 = 0; - int asic; + int handled = 0; - for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) { - if (irq == devpriv->asics[asic].irq) { - /* it is an interrupt for ASIC #asic */ - if (pcmuio_handle_asic_interrupt(dev, asic)) - got1++; - } - } - if (!got1) - return IRQ_NONE; /* interrupt from other source */ - return IRQ_HANDLED; + if (irq == dev->irq) + handled += pcmuio_handle_asic_interrupt(dev, 0); + if (irq == devpriv->irq2) + handled += pcmuio_handle_asic_interrupt(dev, 1); + + return handled ? IRQ_HANDLED : IRQ_NONE; } +/* chip->spinlock is already locked */ static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int bits = 0; + unsigned int pol_bits = 0; + int i; - if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) { + if (!chip->continuous && chip->stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; - subpriv->intr.active = 0; + chip->active = 0; return 1; - } else { - unsigned bits = 0, pol_bits = 0, n; - int asic; - struct comedi_cmd *cmd = &s->async->cmd; - - asic = subpriv->intr.asic; - if (asic < 0) - return 1; /* not an interrupt - subdev */ - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 1; - if (cmd->chanlist) { - for (n = 0; n < cmd->chanlist_len; n++) { - bits |= (1U << CR_CHAN(cmd->chanlist[n])); - pol_bits |= (CR_AREF(cmd->chanlist[n]) - || CR_RANGE(cmd-> - chanlist[n]) ? 1U : 0U) - << CR_CHAN(cmd->chanlist[n]); - } - } - bits &= ((0x1 << s->n_chan) - 1); - subpriv->intr.enabled_mask = bits; + } - /* set pol and enab intrs for this subdev.. */ - pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0); - pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0); + chip->enabled_mask = 0; + chip->active = 1; + if (cmd->chanlist) { + for (i = 0; i < cmd->chanlist_len; i++) { + unsigned int chanspec = cmd->chanlist[i]; + unsigned int chan = CR_CHAN(chanspec); + unsigned int range = CR_RANGE(chanspec); + unsigned int aref = CR_AREF(chanspec); + + bits |= (1 << chan); + pol_bits |= ((aref || range) ? 1 : 0) << chan; + } } + bits &= ((1 << s->n_chan) - 1); + chip->enabled_mask = bits; + + /* set pol and enab intrs for this subdev.. */ + pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0); + pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0); + return 0; } static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); - if (subpriv->intr.active) + spin_lock_irqsave(&chip->spinlock, flags); + if (chip->active) pcmuio_stop_intr(dev, s); - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); return 0; } @@ -465,19 +467,21 @@ static int pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; int event = 0; if (trignum != 0) return -EINVAL; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); + spin_lock_irqsave(&chip->spinlock, flags); s->async->inttrig = NULL; - if (subpriv->intr.active) + if (chip->active) event = pcmuio_start_intr(dev, s); - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (event) comedi_event(dev, s); @@ -490,24 +494,26 @@ pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, */ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; int event = 0; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); - subpriv->intr.active = 1; + spin_lock_irqsave(&chip->spinlock, flags); + chip->active = 1; /* Set up end of acquisition. */ switch (cmd->stop_src) { case TRIG_COUNT: - subpriv->intr.continuous = 0; - subpriv->intr.stop_count = cmd->stop_arg; + chip->continuous = 0; + chip->stop_count = cmd->stop_arg; break; default: /* TRIG_NONE */ - subpriv->intr.continuous = 1; - subpriv->intr.stop_count = 0; + chip->continuous = 1; + chip->stop_count = 0; break; } @@ -521,7 +527,7 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) event = pcmuio_start_intr(dev, s); break; } - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (event) comedi_event(dev, s); @@ -589,13 +595,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcmuio_board *board = comedi_board(dev); struct comedi_subdevice *s; struct pcmuio_private *devpriv; - struct pcmuio_subdev_private *subpriv; - int sdev_no, n_subdevs, asic; - unsigned int irq[PCMUIO_MAX_ASICS]; int ret; - - irq[0] = it->options[1]; - irq[1] = it->options[2]; + int i; ret = comedi_request_region(dev, it->options[0], board->num_asics * PCMUIO_ASIC_IOSIZE); @@ -606,62 +607,60 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) - spin_lock_init(&devpriv->asics[asic].spinlock); + for (i = 0; i < PCMUIO_MAX_ASICS; ++i) { + struct pcmuio_asic *chip = &devpriv->asics[i]; - n_subdevs = board->num_asics * 2; - devpriv->sprivs = kcalloc(n_subdevs, sizeof(*subpriv), GFP_KERNEL); - if (!devpriv->sprivs) - return -ENOMEM; + spin_lock_init(&chip->pagelock); + spin_lock_init(&chip->spinlock); + } - ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret) - return ret; + pcmuio_reset(dev); - for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - s = &dev->subdevices[sdev_no]; - subpriv = &devpriv->sprivs[sdev_no]; - s->private = subpriv; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmuio_dio_insn_bits; - s->insn_config = pcmuio_dio_insn_config; - s->n_chan = 24; - - /* subdevices 0 and 2 suppport interrupts */ - if ((sdev_no % 2) == 0) { - /* setup the interrupt subdevice */ - subpriv->intr.asic = sdev_no / 2; - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = pcmuio_cancel; - s->do_cmd = pcmuio_cmd; - s->do_cmdtest = pcmuio_cmdtest; - s->len_chanlist = s->n_chan; - } else { - subpriv->intr.asic = -1; - s->len_chanlist = 1; + if (it->options[1]) { + /* request the irq for the 1st asic */ + ret = request_irq(it->options[1], pcmuio_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; + } + + if (board->num_asics == 2) { + if (it->options[2] == dev->irq) { + /* the same irq (or none) is used by both asics */ + devpriv->irq2 = it->options[2]; + } else if (it->options[2]) { + /* request the irq for the 2nd asic */ + ret = request_irq(it->options[2], pcmuio_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + devpriv->irq2 = it->options[2]; } - spin_lock_init(&subpriv->intr.spinlock); } - pcmuio_reset(dev); + ret = comedi_alloc_subdevices(dev, board->num_asics * 2); + if (ret) + return ret; - for (asic = 0; irq[0] && asic < PCMUIO_MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], pcmuio_interrupt, - IRQF_SHARED, board->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; + for (i = 0; i < dev->n_subdevices; ++i) { + s = &dev->subdevices[i]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pcmuio_dio_insn_bits; + s->insn_config = pcmuio_dio_insn_config; + + /* subdevices 0 and 2 can suppport interrupts */ + if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) { + /* setup the interrupt subdevice */ + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->cancel = pcmuio_cancel; + s->do_cmd = pcmuio_cmd; + s->do_cmdtest = pcmuio_cmdtest; } - devpriv->asics[asic].irq = irq[asic]; } return 0; @@ -670,14 +669,13 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmuio_detach(struct comedi_device *dev) { struct pcmuio_private *devpriv = dev->private; - int i; if (devpriv) { - for (i = 0; i < PCMUIO_MAX_ASICS; ++i) { - if (devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - kfree(devpriv->sprivs); + pcmuio_reset(dev); + + /* free the 2nd irq if used, the core will free the 1st one */ + if (devpriv->irq2 && devpriv->irq2 != dev->irq) + free_irq(devpriv->irq2, dev); } comedi_legacy_detach(dev); } diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index 0d254a1b78a7..55e3c2e2bc52 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -402,12 +402,9 @@ static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) udelay(1); dma_status = readb(dma_cs_addr); } - if (i == timeout) { - printk - ("plx9080: cancel() timed out waiting for dma %i done clear\n", - channel); + if (i == timeout) return -ETIMEDOUT; - } + /* disable and abort channel */ writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); /* wait for dma done bit */ @@ -416,12 +413,8 @@ static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) udelay(1); dma_status = readb(dma_cs_addr); } - if (i == timeout) { - printk - ("plx9080: cancel() timed out waiting for dma %i done set\n", - channel); + if (i == timeout) return -ETIMEDOUT; - } return 0; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 44c8712ed9e0..0f026afde9be 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -495,8 +495,6 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, case AREF_OTHER: /* ??? */ break; } - /*printk ("chan=%d r=%d a=%d -> 0x%x\n", - chan, range, aref, r); */ return r; } @@ -606,7 +604,6 @@ static int rtd_ai_rinsn(struct comedi_device *dev, /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); - /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ d = d >> 3; /* low 3 bits are marker lines */ if (test_bit(0, devpriv->chan_is_bipolar)) /* convert to comedi unsigned data */ @@ -692,7 +689,7 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t rtd_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct rtd_private *devpriv = dev->private; u32 overrun; u16 status; @@ -1427,7 +1424,7 @@ static int rtd520_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { +static const struct pci_device_id rtd520_pci_table[] = { { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 }, { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 }, { 0 } diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index b486099b543d..ae13b0ee725b 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1614,12 +1614,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d) static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl) { struct s626_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; uint32_t *rps; uint32_t jmp_adrs; uint16_t i; uint16_t n; uint32_t local_ppl; - struct comedi_cmd *cmd = &dev->subdevices->async->cmd; /* Stop RPS program in case it is currently running */ s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1); @@ -2079,12 +2080,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd == NULL) return -EINVAL; - if (dev->irq == 0) { - comedi_error(dev, - "s626_ai_cmd: cannot run command without an irq"); - return -EIO; - } - s626_ai_load_polllist(ppl, cmd); devpriv->ai_cmd_running = 1; devpriv->ai_convert_count = 0; @@ -2645,6 +2640,7 @@ static void s626_initialize(struct comedi_device *dev) * a defined state after a PCI reset. */ { + struct comedi_subdevice *s = dev->read_subdev; uint8_t poll_list; uint16_t adc_data; uint16_t start_val; @@ -2656,7 +2652,7 @@ static void s626_initialize(struct comedi_device *dev) s626_reset_adc(dev, &poll_list); /* Get initial ADC value */ - s626_ai_rinsn(dev, dev->subdevices, NULL, data); + s626_ai_rinsn(dev, s, NULL, data); start_val = data[0]; /* @@ -2670,7 +2666,7 @@ static void s626_initialize(struct comedi_device *dev) * being unusually quiet or at the rail. */ for (index = 0; index < 500; index++) { - s626_ai_rinsn(dev, dev->subdevices, NULL, data); + s626_ai_rinsn(dev, s, NULL, data); adc_data = data[0]; if (adc_data != start_val) break; @@ -2833,7 +2829,7 @@ static int s626_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF; s->n_chan = S626_ADC_CHANNELS; s->maxdata = 0x3fff; s->range_table = &s626_range_table; @@ -2841,6 +2837,7 @@ static int s626_auto_attach(struct comedi_device *dev, s->insn_read = s626_ai_insn_read; if (dev->irq) { dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->do_cmd = s626_ai_cmd; s->do_cmdtest = s626_ai_cmdtest; s->cancel = s626_ai_cancel; @@ -2965,7 +2962,7 @@ static int s626_pci_probe(struct pci_dev *dev, * also subvendor:subdevice ids, because otherwise it will conflict with * Philips SAA7146 media/dvb based cards. */ -static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { +static const struct pci_device_id s626_pci_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x6000, 0x0272) }, { 0 } diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index daee2f42bde0..77e2059ff62e 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -698,7 +698,7 @@ static int skel_pci_probe(struct pci_dev *dev, * This is used by modprobe to translate PCI IDs to drivers. * Should only be used for PCI and ISA-PnP devices */ -static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { +static const struct pci_device_id skel_pci_table[] = { { PCI_VDEVICE(SKEL, 0x0100), BOARD_SKEL100 }, { PCI_VDEVICE(SKEL, 0x0200), BOARD_SKEL200 }, { 0 } diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 93eec2fc254c..adf7cb7086cc 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -38,7 +38,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/delay.h> @@ -91,12 +90,14 @@ static int __unioxx5_define_chan_offset(int chan_num) } #if 0 /* not used? */ -static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode) +static void __unioxx5_digital_config(struct comedi_subdevice *s, int mode) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int i, mask; mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00; - printk("COMEDI: mode = %d\n", mask); + dev_dbg(csdev, "mode = %d\n", mask); outb(1, usp->usp_iobase + 0); @@ -135,15 +136,18 @@ static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel) usp->usp_prev_cn_val[channel_offset - 1] = conf; } -static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, +static int __unioxx5_digital_read(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int channel_offset, mask = 1 << (channel & 0x07); channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); + dev_err(csdev, + "undefined channel %d. channel range is 0 .. 23\n", + channel); return 0; } @@ -157,9 +161,11 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, +static int __unioxx5_analog_read(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int module_no, read_ch; char control; @@ -168,8 +174,9 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* defining if given module can work on input */ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { - pr_err("comedi%d: module in position %d with id 0x%02x is for output only", - minor, module_no, usp->usp_module_type[module_no]); + dev_err(csdev, + "module in position %d with id 0x%02x is for output only", + module_no, usp->usp_module_type[module_no]); return 0; } @@ -185,7 +192,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* if four bytes readding error occurs - return 0(false) */ if ((control & Rx4CA_ERR_MASK)) { - printk("COMEDI: 4 bytes error\n"); + dev_err(csdev, "4 bytes error\n"); return 0; } @@ -197,16 +204,19 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, +static int __unioxx5_digital_write(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int channel_offset, val; int mask = 1 << (channel & 0x07); channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); + dev_err(csdev, + "undefined channel %d. channel range is 0 .. 23\n", + channel); return 0; } @@ -225,9 +235,11 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, +static int __unioxx5_analog_write(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int module, i; module = channel / 2; /* definig module number(0 .. 11) */ @@ -235,8 +247,9 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, /* defining if given module can work on output */ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { - pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n", - minor, module, usp->usp_module_type[module]); + dev_err(csdev, + "module in position %d with id 0x%0x is for input only!\n", + module, usp->usp_module_type[module]); return 0; } @@ -273,10 +286,10 @@ static int unioxx5_subdev_read(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { - if (!__unioxx5_digital_read(usp, data, channel, dev->minor)) + if (!__unioxx5_digital_read(subdev, data, channel, dev->minor)) return -1; } else { - if (!__unioxx5_analog_read(usp, data, channel, dev->minor)) + if (!__unioxx5_analog_read(subdev, data, channel, dev->minor)) return -1; } @@ -295,10 +308,10 @@ static int unioxx5_subdev_write(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { - if (!__unioxx5_digital_write(usp, data, channel, dev->minor)) + if (!__unioxx5_digital_write(subdev, data, channel, dev->minor)) return -1; } else { - if (!__unioxx5_analog_write(usp, data, channel, dev->minor)) + if (!__unioxx5_analog_write(subdev, data, channel, dev->minor)) return -1; } @@ -318,16 +331,15 @@ static int unioxx5_insn_config(struct comedi_device *dev, if (type != MODULE_DIGITAL) { dev_err(dev->class_dev, - "comedi%d: channel configuration accessible only for digital modules\n", - dev->minor); + "channel configuration accessible only for digital modules\n"); return -1; } channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { dev_err(dev->class_dev, - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - dev->minor, channel); + "undefined channel %d. channel range is 0 .. 23\n", + channel); return -1; } @@ -342,8 +354,7 @@ static int unioxx5_insn_config(struct comedi_device *dev, flags |= mask; break; default: - dev_err(dev->class_dev, - "comedi%d: unknown flag\n", dev->minor); + dev_err(dev->class_dev, "unknown flag\n"); return -1; } @@ -435,9 +446,10 @@ static int unioxx5_attach(struct comedi_device *dev, dev->iobase = iobase; iobase += UNIOXX5_SUBDEV_BASE; + n_subd = 0; - /* defining number of subdevices and getting they types (it must be 'g01') */ - for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { + /* getting number of subdevices with types 'g01' */ + for (i = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { id = inb(ba + 0xE); num = inb(ba + 0xF); diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index 18ee99bdde08..3aff8ed08e2d 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -1,3 +1,5 @@ +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG + obj-$(CONFIG_COMEDI_KCOMEDILIB) += kcomedilib.o kcomedilib-objs := kcomedilib_main.o diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index cd60677a3ed2..7dc5a18e69d4 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); struct comedi_device *comedi_open(const char *filename) { - struct comedi_device *dev; + struct comedi_device *dev, *retval = NULL; unsigned int minor; if (strncmp(filename, "/dev/comedi", 11) != 0) @@ -46,24 +46,27 @@ struct comedi_device *comedi_open(const char *filename) if (minor >= COMEDI_NUM_BOARD_MINORS) return NULL; - dev = comedi_dev_from_minor(minor); - - if (!dev || !dev->attached) + dev = comedi_dev_get_from_minor(minor); + if (!dev) return NULL; - if (!try_module_get(dev->driver->module)) - return NULL; + down_read(&dev->attach_lock); + if (dev->attached) + retval = dev; + else + retval = NULL; + up_read(&dev->attach_lock); + + if (retval == NULL) + comedi_dev_put(dev); - return dev; + return retval; } EXPORT_SYMBOL_GPL(comedi_open); -int comedi_close(struct comedi_device *d) +int comedi_close(struct comedi_device *dev) { - struct comedi_device *dev = (struct comedi_device *)d; - - module_put(dev->driver->module); - + comedi_dev_put(dev); return 0; } EXPORT_SYMBOL_GPL(comedi_close); @@ -73,7 +76,14 @@ static int comedi_do_insn(struct comedi_device *dev, unsigned int *data) { struct comedi_subdevice *s; - int ret = 0; + int ret; + + mutex_lock(&dev->mutex); + + if (!dev->attached) { + ret = -EINVAL; + goto error; + } /* a subdevice instruction */ if (insn->subdev >= dev->n_subdevices) { @@ -120,6 +130,7 @@ static int comedi_do_insn(struct comedi_device *dev, s->busy = NULL; error: + mutex_unlock(&dev->mutex); return ret; } @@ -169,9 +180,6 @@ int comedi_dio_bitfield2(struct comedi_device *dev, unsigned int subdev, unsigned int shift; int ret; - if (subdev >= dev->n_subdevices) - return -EINVAL; - base_channel = CR_CHAN(base_channel); n_chan = comedi_get_n_channels(dev, subdev); if (base_channel >= n_chan) @@ -211,23 +219,33 @@ int comedi_find_subdevice_by_type(struct comedi_device *dev, int type, unsigned int subd) { struct comedi_subdevice *s; - - if (subd > dev->n_subdevices) - return -ENODEV; - - for (; subd < dev->n_subdevices; subd++) { - s = &dev->subdevices[subd]; - if (s->type == type) - return subd; - } - return -1; + int ret = -ENODEV; + + down_read(&dev->attach_lock); + if (dev->attached) + for (; subd < dev->n_subdevices; subd++) { + s = &dev->subdevices[subd]; + if (s->type == type) { + ret = subd; + break; + } + } + up_read(&dev->attach_lock); + return ret; } EXPORT_SYMBOL_GPL(comedi_find_subdevice_by_type); int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice) { - struct comedi_subdevice *s = &dev->subdevices[subdevice]; + int n; + + down_read(&dev->attach_lock); + if (!dev->attached || subdevice >= dev->n_subdevices) + n = 0; + else + n = dev->subdevices[subdevice].n_chan; + up_read(&dev->attach_lock); - return s->n_chan; + return n; } EXPORT_SYMBOL_GPL(comedi_get_n_channels); diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index ade00035d3bb..da6bc5855ebc 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -41,16 +41,20 @@ static int comedi_read(struct seq_file *m, void *v) "driver_name, board_name, n_subdevices"); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { - struct comedi_device *dev = comedi_dev_from_minor(i); + struct comedi_device *dev = comedi_dev_get_from_minor(i); + if (!dev) continue; + down_read(&dev->attach_lock); if (dev->attached) { devices_q = 1; seq_printf(m, "%2d: %-20s %-20s %4d\n", i, dev->driver->driver_name, dev->board_name, dev->n_subdevices); } + up_read(&dev->attach_lock); + comedi_dev_put(dev); } if (!devices_q) seq_puts(m, "no devices\n"); diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 8fde55495d34..46b3da686384 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -83,8 +83,10 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, } if (RANGE_LENGTH(it.range_type) != lr->length) { - DPRINTK("wrong length %d should be %d (0x%08x)\n", - RANGE_LENGTH(it.range_type), lr->length, it.range_type); + dev_dbg(dev->class_dev, + "wrong length %d should be %d (0x%08x)\n", + RANGE_LENGTH(it.range_type), + lr->length, it.range_type); return -EINVAL; } @@ -123,7 +125,8 @@ static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) default: break; } - DPRINTK("subdevice does not support aref %i", aref); + dev_dbg(s->device->class_dev, "subdevice does not support aref %i", + aref); return 1; } diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h index 981708f3ee39..92b0cff248cb 100644 --- a/drivers/staging/crystalhd/bc_dts_glob_lnx.h +++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h @@ -229,7 +229,7 @@ enum BC_DRV_CMD { DRV_CMD_REG_RD, /* Read Device Register */ DRV_CMD_REG_WR, /* Write Device Register */ DRV_CMD_FPGA_RD, /* Read FPGA Register */ - DRV_CMD_FPGA_WR, /* Wrtie FPGA Reister */ + DRV_CMD_FPGA_WR, /* Write FPGA Register */ DRV_CMD_MEM_RD, /* Read Device Memory */ DRV_CMD_MEM_WR, /* Write Device Memory */ DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */ diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 07a2f24d0d47..642f438793c3 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -798,7 +798,7 @@ static const struct crystalhd_cmd_tbl g_crystalhd_cproc_tbl[] = { * * Current gstreamer frame work does not provide any power management * related notification to user mode decoder plug-in. As a work-around - * we pass on the power mangement notification to our plug-in by completing + * we pass on the power management notification to our plug-in by completing * all outstanding requests with BC_STS_IO_USER_ABORT return code. */ enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, @@ -1059,7 +1059,7 @@ bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx) { if (!ctx) { BCMLOG_ERR("Invalid arg..\n"); - return 0; + return false; } return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx); diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h index 377cd9d68b08..b5bf59dbcde9 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.h +++ b/drivers/staging/crystalhd/crystalhd_cmds.h @@ -29,7 +29,7 @@ /* * NOTE:: This is the main interface file between the Linux layer - * and the harware layer. This file will use the definitions + * and the hardware layer. This file will use the definitions * from _dts_glob and dts_defs etc.. which are defined for * windows. */ diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h index 4b363a5069d7..05615e2a231a 100644 --- a/drivers/staging/crystalhd/crystalhd_fw_if.h +++ b/drivers/staging/crystalhd/crystalhd_fw_if.h @@ -115,7 +115,7 @@ struct fgt_sei { unsigned char model_id; /* Model id. */ /* +unused SE based on Thomson spec */ - unsigned char color_desc_flag; /* Separate color descrition flag. */ + unsigned char color_desc_flag; /* Separate color description flag. */ unsigned char bit_depth_luma; /* Bit depth luma minus 8. */ unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */ unsigned char full_range_flag; /* Full range flag. */ diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 043bd49843ff..8d0680d93684 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -398,7 +398,7 @@ static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw, * Call back from TX - IOQ deletion. * * This routine will release the TX DMA rings allocated - * druing setup_dma rings interface. + * during setup_dma rings interface. * * Memory is allocated per DMA ring basis. This is just * a place holder to be able to create the dio queues. diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h index 37809442c553..d5cb68dfe695 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.h +++ b/drivers/staging/crystalhd/crystalhd_hw.h @@ -46,7 +46,7 @@ #define Cpu2HstMbx1 0x00100F04 #define MbxStat1 0x00100F08 #define Stream2Host_Intr_Sts 0x00100F24 -#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */ +#define C011_RET_SUCCESS 0x0 /* Return status of firmware command. */ /* TS input status register */ #define TS_StreamAFIFOStatus 0x0010044C @@ -141,7 +141,7 @@ union link_misc_perst_deco_ctrl { uint32_t reserved0:3; /* Reserved.No Effect*/ uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ - uint32_t reserved1:27; /* Reseved. No Effect*/ + uint32_t reserved1:27; /* Reserved. No Effect*/ }; uint32_t whole_reg; @@ -176,7 +176,7 @@ union link_misc_perst_decoder_ctrl { uint32_t res0:3; /* Reserved.No Effect*/ uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ - uint32_t res1:27; /* Reseved. No Effect */ + uint32_t res1:27; /* Reserved. No Effect */ }; uint32_t whole_reg; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 190b9b924368..99eefd0291c3 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -703,7 +703,7 @@ static int chd_dec_pci_resume(struct pci_dev *pdev) } #endif -static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { +static const struct pci_device_id chd_dec_pci_id_table[] = { { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, { 0, }, }; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h index bac572a8bc2e..33d7431de837 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.h +++ b/drivers/staging/crystalhd/crystalhd_lnx.h @@ -53,7 +53,7 @@ /* OS specific PCI information structure and adapter information. */ struct crystalhd_adp { - /* Hardware borad/PCI specifics */ + /* Hardware board/PCI specifics */ char name[32]; struct pci_dev *pdev; diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index 51f698052aff..c3d024406337 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -389,7 +389,7 @@ void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz, void *temp = NULL; if (!adp || !sz || !phy_addr) { - BCMLOG_ERR("Invalide Arg..\n"); + BCMLOG_ERR("Invalid Arg..\n"); return temp; } @@ -415,7 +415,7 @@ void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka, dma_addr_t phy_addr) { if (!adp || !ka || !sz || !phy_addr) { - BCMLOG_ERR("Invalide Arg..\n"); + BCMLOG_ERR("Invalid Arg..\n"); return; } diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h index aa736c8855de..77ab72a2a061 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.h +++ b/drivers/staging/crystalhd/crystalhd_misc.h @@ -206,7 +206,7 @@ extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, enum _chd_log_levels { BCMLOG_ERROR = 0x80000000, /* Don't disable this option */ BCMLOG_DATA = 0x40000000, /* Data, enable by default */ - BCMLOG_SPINLOCK = 0x20000000, /* Spcial case for Spin locks*/ + BCMLOG_SPINLOCK = 0x20000000, /* Special case for Spin locks*/ /* Following are allowed only in debug mode */ BCMLOG_INFO = 0x00000001, /* Generic informational */ diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c index 46a0d92173e0..c4c8c0f9c959 100644 --- a/drivers/staging/cxt1e1/comet.c +++ b/drivers/staging/cxt1e1/comet.c @@ -28,9 +28,9 @@ extern int cxt1e1_log_level; #define COMET_NUM_UNITS 5 /* Number of points per entry in table */ /* forward references */ -static void SetPwrLevel(comet_t *comet); -static void WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table); -static void WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); +static void SetPwrLevel(struct s_comet_reg *comet); +static void WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table); +static void WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); void *TWV_table[12] = { @@ -58,7 +58,7 @@ lbo_tbl_lkup(int t1, int lbo) { return lbo - 1; } -void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, +void init_comet(void *ci, struct s_comet_reg *comet, u_int32_t port_mode, int clockmaster, u_int8_t moreParams) { u_int8_t isT1mode; @@ -159,8 +159,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* 60: t1 ALMI cfg */ /* Configure Line Coding */ - switch (port_mode) - { + switch (port_mode) { /* 1 - T1 B8ZS */ case CFG_FRAME_SF: pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0); @@ -286,8 +285,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */ /* note "rate bits can only be set once after reset" */ - if (clockmaster) - { + if (clockmaster) { /* CMODE == clockMode, 0=clock master (so all 3 others should be slave) */ /* rate = 1.544 Mb/s */ if (isT1mode) @@ -302,16 +300,17 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* Master Mode i.e.FPMODE=0 (@0x20) */ pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x00); - if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) - { + if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) { if (cxt1e1_log_level >= LOG_SBEBUG12) - pr_info(">> %s: clockmaster internal clock\n", __func__); + pr_info(">> %s: clockmaster internal clock\n", + __func__); /* internal oscillator */ pci_write_32((u_int32_t *) &comet->tx_time, 0x0d); } else { /* external clock source */ if (cxt1e1_log_level >= LOG_SBEBUG12) - pr_info(">> %s: clockmaster external clock\n", __func__); + pr_info(">> %s: clockmaster external clock\n", + __func__); /* loop timing(external) */ pci_write_32((u_int32_t *) &comet->tx_time, 0x09); } @@ -399,7 +398,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, ** Returns: Nothing */ static void -WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int8_t data) +WrtXmtWaveform(ci_t *ci, struct s_comet_reg *comet, u_int32_t sample, u_int32_t unit, u_int8_t data) { u_int8_t WaveformAddr; @@ -417,19 +416,20 @@ WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int ** Returns: Nothing */ static void -WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, +WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]) { u_int32_t sample, unit; - for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) - { + for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) { for (unit = 0; unit < COMET_NUM_UNITS; unit++) - WrtXmtWaveform(ci, comet, sample, unit, table[sample][unit]); + WrtXmtWaveform(ci, comet, sample, unit, + table[sample][unit]); } /* Enable transmitter and set output amplitude */ - pci_write_32((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]); + pci_write_32((u_int32_t *) &comet->xlpg_cfg, + table[COMET_NUM_SAMPLES][0]); } @@ -444,7 +444,7 @@ WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, */ static void -WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) +WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table) { u_int32_t ramaddr; volatile u_int32_t value; @@ -457,7 +457,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) /* for write order preservation when Optimizing driver */ pci_flush_write(ci); /* write the addr, initiate a read */ - pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); + pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, + (u_int8_t) ramaddr); /* for write order preservation when Optimizing driver */ pci_flush_write(ci); /* @@ -470,9 +471,12 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) } value = *table++; - pci_write_32((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24)); - pci_write_32((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16)); - pci_write_32((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8)); + pci_write_32((u_int32_t *) &comet->rlps_idata3, + (u_int8_t) (value >> 24)); + pci_write_32((u_int32_t *) &comet->rlps_idata2, + (u_int8_t) (value >> 16)); + pci_write_32((u_int32_t *) &comet->rlps_idata1, + (u_int8_t) (value >> 8)); pci_write_32((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value); /* for write order preservation when Optimizing driver */ pci_flush_write(ci); @@ -484,7 +488,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) /* for write order preservation when optimizing driver */ pci_flush_write(ci); /* write the addr, initiate a read */ - pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); + pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, + (u_int8_t) ramaddr); /* for write order preservation when optimizing driver */ pci_flush_write(ci); @@ -508,7 +513,7 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) */ static void -SetPwrLevel(comet_t *comet) +SetPwrLevel(struct s_comet_reg *comet) { volatile u_int32_t temp; @@ -550,12 +555,11 @@ SetPwrLevel(comet_t *comet) */ #if 0 static void -SetCometOps(comet_t *comet) +SetCometOps(struct s_comet_reg *comet) { volatile u_int8_t rd_value; - if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) - { + if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) { /* read the BRIF Configuration */ rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg); rd_value &= ~0x20; diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h index 03b9bb77a809..d5d286e47a4b 100644 --- a/drivers/staging/cxt1e1/comet.h +++ b/drivers/staging/cxt1e1/comet.h @@ -25,304 +25,313 @@ #define VINT32 volatile u_int32_t -struct s_comet_reg -{ - VINT32 gbl_cfg; /* 00 Global Cfg */ - VINT32 clkmon; /* 01 Clk Monitor */ - VINT32 rx_opt; /* 02 RX Options */ - VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */ - VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */ - VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */ - VINT32 tx_time; /* 06 TX Timing Options */ - VINT32 intr_1; /* 07 Intr Source #1 */ - VINT32 intr_2; /* 08 Intr Source #2 */ - VINT32 intr_3; /* 09 Intr Source #3 */ - VINT32 mdiag; /* 0A Master Diagnostics */ - VINT32 mtest; /* 0B Master Test */ - VINT32 adiag; /* 0C Analog Diagnostics */ - VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */ +struct s_comet_reg { + VINT32 gbl_cfg; /* 00 Global Cfg */ + VINT32 clkmon; /* 01 Clk Monitor */ + VINT32 rx_opt; /* 02 RX Options */ + VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */ + VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */ + VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */ + VINT32 tx_time; /* 06 TX Timing Options */ + VINT32 intr_1; /* 07 Intr Source #1 */ + VINT32 intr_2; /* 08 Intr Source #2 */ + VINT32 intr_3; /* 09 Intr Source #3 */ + VINT32 mdiag; /* 0A Master Diagnostics */ + VINT32 mtest; /* 0B Master Test */ + VINT32 adiag; /* 0C Analog Diagnostics */ + VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */ #define pmon rev_id - VINT32 reset; /* 0E Reset */ - VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */ - VINT32 cdrc_cfg; /* 10 CDRC Cfg */ - VINT32 cdrc_ien; /* 11 CDRC Intr Enable */ - VINT32 cdrc_ists; /* 12 CDRC Intr Sts */ - VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */ - - VINT32 rjat_ists; /* 14 RJAT Intr Sts */ - VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */ - VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */ - VINT32 rjat_cfg; /* 17 RJAT Cfg */ - - VINT32 tjat_ists; /* 18 TJAT Intr Sts */ - VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */ - VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */ - VINT32 tjat_cfg; /* 1B TJAT Cfg */ - - VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */ - VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */ - VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */ - VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */ - - VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */ - VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */ - VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */ - VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */ - VINT32 __res24; /* 24 Reserved */ - VINT32 __res25; /* 25 Reserved */ - VINT32 __res26; /* 26 Reserved */ - VINT32 __res27; /* 27 Reserved */ - - VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */ - VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */ - VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */ - VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */ - VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */ - VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */ - VINT32 _rxce_res2E; /* 2E RXCE Reserved */ - VINT32 _rxce_res2F; /* 2F RXCE Reserved */ - - VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */ - VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */ - VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */ - VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */ - VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */ - VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */ - VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */ - VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */ - - VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */ - VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */ - VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */ - VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */ - VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */ - VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */ - VINT32 _txci_res3E; /* 3E TXCI Reserved */ - VINT32 _txci_res3F; /* 3F TXCI Reserved */ - - VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */ - VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */ - VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */ - VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */ - VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */ - VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */ - VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */ - VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */ - VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */ - VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */ - VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */ - VINT32 __res_4B; /* 4B Reserved */ - VINT32 ibcd_cfg; /* 4C IBCD Cfg */ - VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */ - VINT32 ibcd_act; /* 4E IBCD Activate Code */ - VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */ - - VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */ - VINT32 sigx_acc_cos; /* 51 SIGX uP Access Sts/Change of Signaling State */ - VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect - * Addr/Ctl/Change of Signaling State */ - VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data - * Buffer/Change of Signaling State */ - - VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */ - VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */ - VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */ - VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */ - - VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */ - VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */ - VINT32 pmon_feb_lsb; /* 5A PMON OFF/COFA/Far End Block Err Cnt (LSB) */ - VINT32 pmon_feb_msb; /* 5B PMON OFF/COFA/Far End Block Err Cnt (MSB) */ - VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */ - VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */ - VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */ - VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */ - - VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */ - VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */ - VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */ - VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */ - - VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */ - VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */ - VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */ - VINT32 t1_xboc_code; /* 67 T1 XBOC Code */ - VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */ - VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */ - - VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */ - VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */ - - VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */ - VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */ - VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect - * Addr/Ctl */ - VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data - * Buffer */ - VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */ - VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */ - VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect - * Addr/Ctl */ - VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data - * Buffer */ - VINT32 __res74; /* 74 Reserved */ - VINT32 __res75; /* 75 Reserved */ - VINT32 __res76; /* 76 Reserved */ - VINT32 __res77; /* 77 Reserved */ - - VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */ - VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */ - VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */ - VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */ - VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */ - VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */ - VINT32 t1_aprm_1sec_5; /* 7E T1 APRM One Second Content MSB (Octect 5) */ - VINT32 t1_aprm_1sec_6; /* 7F T1 APRM One Second Content MSB (Octect 6) */ - - VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */ - VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */ - VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */ - VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */ - VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */ - VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */ - VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword - * Select */ - VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */ - VINT32 __res88; /* 88 Reserved */ - VINT32 __res89; /* 89 Reserved */ - VINT32 __res8A; /* 8A Reserved */ - VINT32 __res8B; /* 8B Reserved */ - - VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */ - VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */ - VINT32 __res8E; /* 8E Reserved */ - VINT32 __res8F; /* 8F Reserved */ - - VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */ - VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */ - VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */ - VINT32 e1_frmr_mien; /* 93 E1 FRMR Maintenance/Alarm Sts Intr Enable */ - VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */ - VINT32 e1_frmr_mists; /* 95 E1 FRMR Maintenance/Alarm Sts Indication Enable */ - VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */ - VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */ - VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */ - VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */ - VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */ - VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR National Bit Codeword Intr Enables */ - VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR National Bit Codeword Intr/Sts */ - VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */ - VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR Frame Pulse/Alarm Intr Enables */ - VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */ - - VINT32 __resA0; /* A0 Reserved */ - VINT32 __resA1; /* A1 Reserved */ - VINT32 __resA2; /* A2 Reserved */ - VINT32 __resA3; /* A3 Reserved */ - VINT32 __resA4; /* A4 Reserved */ - VINT32 __resA5; /* A5 Reserved */ - VINT32 __resA6; /* A6 Reserved */ - VINT32 __resA7; /* A7 Reserved */ - - VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */ - VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */ - VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */ - VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */ - VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */ - VINT32 tdpr1_data; /* AD TDPR #1 TX Data */ - VINT32 __resAE; /* AE Reserved */ - VINT32 __resAF; /* AF Reserved */ - VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */ - VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */ - VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */ - VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */ - VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */ - VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */ - VINT32 __resB6; /* B6 Reserved */ - VINT32 __resB7; /* B7 Reserved1 */ - VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */ - VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */ - VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */ - VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */ - VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */ - VINT32 tdpr3_data; /* BD TDPR #3 TX Data */ - VINT32 __resBE; /* BE Reserved */ - VINT32 __resBF; /* BF Reserved */ - - VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */ - VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */ - VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */ - VINT32 rdlc1_data; /* C3 RDLC #1 Data */ - VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */ - VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */ - VINT32 __resC6; /* C6 Reserved */ - VINT32 __resC7; /* C7 Reserved */ - VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */ - VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */ - VINT32 rdlc2_sts; /* CA RDLC #2 Sts */ - VINT32 rdlc2_data; /* CB RDLC #2 Data */ - VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */ - VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */ - VINT32 __resCE; /* CE Reserved */ - VINT32 __resCF; /* CF Reserved */ - VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */ - VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */ - VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */ - VINT32 rdlc3_data; /* D3 RDLC #3 Data */ - VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */ - VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */ - - VINT32 csu_cfg; /* D6 CSU Cfg */ - VINT32 _csu_resD7; /* D7 CSU Reserved */ - - VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */ - VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */ - VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */ - VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */ - VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference - * (E1 missing) */ - VINT32 _rlps_resDD; /* DD RLPS Reserved */ - VINT32 _rlps_resDE; /* DE RLPS Reserved */ - VINT32 _rlps_resDF; /* DF RLPS Reserved */ - - VINT32 prgd_ctl; /* E0 PRGD Ctl */ - VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */ - VINT32 prgd_shift_len; /* E2 PRGD Shift Length */ - VINT32 prgd_tap; /* E3 PRGD Tap */ - VINT32 prgd_errin; /* E4 PRGD Err Insertion */ - VINT32 _prgd_resE5; /* E5 PRGD Reserved */ - VINT32 _prgd_resE6; /* E6 PRGD Reserved */ - VINT32 _prgd_resE7; /* E7 PRGD Reserved */ - VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */ - VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */ - VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */ - VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */ - VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */ - VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */ - VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */ - VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */ - - VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */ - VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */ - VINT32 xlpg_pwave_addr; /* F2 XLPG Pulse Waveform Storage Write Addr */ - VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */ - VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */ - VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */ - VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */ - VINT32 _xlpg_resF7; /* F7 XLPG Reserved */ - - VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */ - VINT32 rlps_alos_thresh; /* F9 RLPS ALOS Detection/Clearance Threshold */ - VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */ - VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */ - VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */ - VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */ - VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */ - VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */ + VINT32 reset; /* 0E Reset */ + VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */ + VINT32 cdrc_cfg; /* 10 CDRC Cfg */ + VINT32 cdrc_ien; /* 11 CDRC Intr Enable */ + VINT32 cdrc_ists; /* 12 CDRC Intr Sts */ + VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */ + + VINT32 rjat_ists; /* 14 RJAT Intr Sts */ + VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */ + VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */ + VINT32 rjat_cfg; /* 17 RJAT Cfg */ + + VINT32 tjat_ists; /* 18 TJAT Intr Sts */ + VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */ + VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */ + VINT32 tjat_cfg; /* 1B TJAT Cfg */ + + VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */ + VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */ + VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */ + VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */ + + VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */ + VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */ + VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */ + VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */ + VINT32 __res24; /* 24 Reserved */ + VINT32 __res25; /* 25 Reserved */ + VINT32 __res26; /* 26 Reserved */ + VINT32 __res27; /* 27 Reserved */ + + VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */ + VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */ + VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */ + VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */ + VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */ + VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */ + VINT32 _rxce_res2E; /* 2E RXCE Reserved */ + VINT32 _rxce_res2F; /* 2F RXCE Reserved */ + + VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */ + VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */ + VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */ + VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */ + VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */ + VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */ + VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */ + VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */ + + VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */ + VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */ + VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */ + VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */ + VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */ + VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */ + VINT32 _txci_res3E; /* 3E TXCI Reserved */ + VINT32 _txci_res3F; /* 3F TXCI Reserved */ + + VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */ + VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */ + VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */ + VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */ + VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */ + VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */ + VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */ + VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */ + VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */ + VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */ + VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */ + VINT32 __res_4B; /* 4B Reserved */ + VINT32 ibcd_cfg; /* 4C IBCD Cfg */ + VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */ + VINT32 ibcd_act; /* 4E IBCD Activate Code */ + VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */ + + VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */ + VINT32 sigx_acc_cos; /* 51 SIGX + * uP Access Sts/Change of Signaling State */ + VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect + * Addr/Ctl/Change of Signaling State */ + VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data + * Buffer/Change of Signaling State */ + + VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */ + VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */ + VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */ + VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */ + + VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */ + VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */ + VINT32 pmon_feb_lsb; /* 5A PMON + * OFF/COFA/Far End Block Err Cnt (LSB) */ + VINT32 pmon_feb_msb; /* 5B PMON + * OFF/COFA/Far End Block Err Cnt (MSB) */ + VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */ + VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */ + VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */ + VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */ + + VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */ + VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */ + VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */ + VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */ + + VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */ + VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */ + VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */ + VINT32 t1_xboc_code; /* 67 T1 XBOC Code */ + VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */ + VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */ + + VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */ + VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */ + + VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */ + VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */ + VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data + * Buffer */ + VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */ + VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */ + VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data + * Buffer */ + VINT32 __res74; /* 74 Reserved */ + VINT32 __res75; /* 75 Reserved */ + VINT32 __res76; /* 76 Reserved */ + VINT32 __res77; /* 77 Reserved */ + + VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */ + VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */ + VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */ + VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */ + VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */ + VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */ + VINT32 t1_aprm_1sec_5; /* 7E T1 APRM + * One Second Content MSB (Octect 5) */ + VINT32 t1_aprm_1sec_6; /* 7F T1 APRM + * One Second Content MSB (Octect 6) */ + + VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */ + VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */ + VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */ + VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */ + VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */ + VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */ + VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword + * Select */ + VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */ + VINT32 __res88; /* 88 Reserved */ + VINT32 __res89; /* 89 Reserved */ + VINT32 __res8A; /* 8A Reserved */ + VINT32 __res8B; /* 8B Reserved */ + + VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */ + VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */ + VINT32 __res8E; /* 8E Reserved */ + VINT32 __res8F; /* 8F Reserved */ + + VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */ + VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */ + VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */ + VINT32 e1_frmr_mien; /* 93 E1 FRMR + * Maintenance/Alarm Sts Intr Enable */ + VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */ + VINT32 e1_frmr_mists; /* 95 E1 FRMR + * Maintenance/Alarm Sts Indication Enable */ + VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */ + VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */ + VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */ + VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */ + VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */ + VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR + * National Bit Codeword Intr Enables */ + VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR + * National Bit Codeword Intr/Sts */ + VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */ + VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR + * Frame Pulse/Alarm Intr Enables */ + VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */ + + VINT32 __resA0; /* A0 Reserved */ + VINT32 __resA1; /* A1 Reserved */ + VINT32 __resA2; /* A2 Reserved */ + VINT32 __resA3; /* A3 Reserved */ + VINT32 __resA4; /* A4 Reserved */ + VINT32 __resA5; /* A5 Reserved */ + VINT32 __resA6; /* A6 Reserved */ + VINT32 __resA7; /* A7 Reserved */ + + VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */ + VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */ + VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */ + VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */ + VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */ + VINT32 tdpr1_data; /* AD TDPR #1 TX Data */ + VINT32 __resAE; /* AE Reserved */ + VINT32 __resAF; /* AF Reserved */ + VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */ + VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */ + VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */ + VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */ + VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */ + VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */ + VINT32 __resB6; /* B6 Reserved */ + VINT32 __resB7; /* B7 Reserved1 */ + VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */ + VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */ + VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */ + VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */ + VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */ + VINT32 tdpr3_data; /* BD TDPR #3 TX Data */ + VINT32 __resBE; /* BE Reserved */ + VINT32 __resBF; /* BF Reserved */ + + VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */ + VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */ + VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */ + VINT32 rdlc1_data; /* C3 RDLC #1 Data */ + VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */ + VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */ + VINT32 __resC6; /* C6 Reserved */ + VINT32 __resC7; /* C7 Reserved */ + VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */ + VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */ + VINT32 rdlc2_sts; /* CA RDLC #2 Sts */ + VINT32 rdlc2_data; /* CB RDLC #2 Data */ + VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */ + VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */ + VINT32 __resCE; /* CE Reserved */ + VINT32 __resCF; /* CF Reserved */ + VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */ + VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */ + VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */ + VINT32 rdlc3_data; /* D3 RDLC #3 Data */ + VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */ + VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */ + + VINT32 csu_cfg; /* D6 CSU Cfg */ + VINT32 _csu_resD7; /* D7 CSU Reserved */ + + VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */ + VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */ + VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */ + VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */ + VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference + * (E1 missing) */ + VINT32 _rlps_resDD; /* DD RLPS Reserved */ + VINT32 _rlps_resDE; /* DE RLPS Reserved */ + VINT32 _rlps_resDF; /* DF RLPS Reserved */ + + VINT32 prgd_ctl; /* E0 PRGD Ctl */ + VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */ + VINT32 prgd_shift_len; /* E2 PRGD Shift Length */ + VINT32 prgd_tap; /* E3 PRGD Tap */ + VINT32 prgd_errin; /* E4 PRGD Err Insertion */ + VINT32 _prgd_resE5; /* E5 PRGD Reserved */ + VINT32 _prgd_resE6; /* E6 PRGD Reserved */ + VINT32 _prgd_resE7; /* E7 PRGD Reserved */ + VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */ + VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */ + VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */ + VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */ + VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */ + VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */ + VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */ + VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */ + + VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */ + VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */ + VINT32 xlpg_pwave_addr; /* F2 XLPG + * Pulse Waveform Storage Write Addr */ + VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */ + VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */ + VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */ + VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */ + VINT32 _xlpg_resF7; /* F7 XLPG Reserved */ + + VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */ + VINT32 rlps_alos_thresh; /* F9 RLPS + * ALOS Detection/Clearance Threshold */ + VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */ + VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */ + VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */ + VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */ + VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */ + VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */ }; -typedef struct s_comet_reg comet_t; - /* 00AH: MDIAG Register bit definitions */ #define COMET_MDIAG_ID5 0x40 #define COMET_MDIAG_LBMASK 0x3F @@ -338,7 +347,7 @@ typedef struct s_comet_reg comet_t; #ifdef __KERNEL__ extern void -init_comet(void *, comet_t *, u_int32_t, int, u_int8_t); +init_comet(void *, struct s_comet_reg *, u_int32_t, int, u_int8_t); #endif #endif /* _INC_COMET_H_ */ diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c index d021b312ffa2..95218e283966 100644 --- a/drivers/staging/cxt1e1/functions.c +++ b/drivers/staging/cxt1e1/functions.c @@ -274,7 +274,7 @@ VMETRO_TRACE (void *x) void VMETRO_TRIGGER (ci_t *ci, int x) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t data; comet = ci->port[0].cometbase; /* default to COMET # 0 */ diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index 0ba8c3ae673b..7a3a30cd0f7f 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -1,5 +1,5 @@ -unsigned int max_intcnt = 0; -unsigned int max_bh = 0; +static unsigned int max_intcnt = 0; +static unsigned int max_bh = 0; /*----------------------------------------------------------------------------- * musycc.c - diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index 4028ea11c442..a9d95753be20 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -194,7 +194,7 @@ checkPorts (ci_t *ci) * alarms conflicts with NCOMM's interrupt servicing implementation. */ - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t value; u_int32_t copyVal, LEDval; @@ -507,7 +507,7 @@ c4_cleanup (void) int c4_get_portcfg (ci_t *ci) { - comet_t *comet; + struct s_comet_reg *comet; int portnum, mask; u_int32_t wdata, rdata; @@ -561,7 +561,7 @@ c4_init (ci_t *ci, u_char *func0, u_char *func1) for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++) { pi = &ci->port[portnum]; - pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum))); + pi->cometbase = (struct s_comet_reg *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum))); pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800)); pi->portnum = portnum; pi->p.portnum = portnum; @@ -693,7 +693,7 @@ c4_init2 (ci_t *ci) int c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t loopValue; comet = ci->port[portnum].cometbase; @@ -752,7 +752,7 @@ c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd) status_t c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t data; if (pp->portnum >= ci->max_port)/* sanity check */ diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h index b2b6e3702630..7edbd4e492e3 100644 --- a/drivers/staging/cxt1e1/pmcc4_private.h +++ b/drivers/staging/cxt1e1/pmcc4_private.h @@ -133,7 +133,7 @@ struct c4_port_info void *regram_saved; /* Original malloc value may have non-2KB * boundary. Need to save for use when * freeing. */ - comet_t *cometbase; + struct s_comet_reg *cometbase; struct sbe_card_info *up; /* diff --git a/drivers/staging/cxt1e1/sbeid.c b/drivers/staging/cxt1e1/sbeid.c index 6ec51bccceb1..97c5c6e7e299 100644 --- a/drivers/staging/cxt1e1/sbeid.c +++ b/drivers/staging/cxt1e1/sbeid.c @@ -20,190 +20,185 @@ #include "sbe_bid.h" char * -sbeid_get_bdname (ci_t *ci) +sbeid_get_bdname(ci_t *ci) { - char *np = NULL; + char *np = NULL; - switch (ci->brd_id) - { - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): - np = "wanPTMC-256T3 <E1>"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): - np = "wanPTMC-256T3 <T1>"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): - np = "wanPMC-C4T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): - np = "wanPMC-C2T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): - np = "wanPMC-C1T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): - np = "wanPCI-C4T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): - np = "wanPCI-C2T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): - np = "wanPCI-C1T1E1"; - break; - default: - /*** np = "<unknown>"; ***/ - np = "wanPCI-CxT1E1"; - break; - } + switch (ci->brd_id) { + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + np = "wanPTMC-256T3 <E1>"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + np = "wanPTMC-256T3 <T1>"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + np = "wanPMC-C4T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + np = "wanPMC-C2T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + np = "wanPMC-C1T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + np = "wanPCI-C4T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + np = "wanPCI-C2T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + np = "wanPCI-C1T1E1"; + break; + default: + /*** np = "<unknown>"; ***/ + np = "wanPCI-CxT1E1"; + break; + } - return np; + return np; } /* given the presetting of brd_id, set the corresponding hdw_id */ void -sbeid_set_hdwbid (ci_t *ci) +sbeid_set_hdwbid(ci_t *ci) { - /* - * set SBE's unique hardware identification (for legacy boards might not - * have this register implemented) - */ + /* + * set SBE's unique hardware identification (for legacy boards might not + * have this register implemented) + */ - switch (ci->brd_id) - { - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): - ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1 - * Version) */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): - ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1 - * Version) */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): - /* - * This Board ID is a generic identification. Use the found number - * of ports to further define this hardware. - */ - switch (ci->max_port) - { - default: /* shouldn't need a default, but have one - * anyway */ - case 4: - ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */ - break; - case 2: - ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); - break; - case 1: - ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); - break; - } - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): - ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): - ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ - break; + switch (ci->brd_id) { + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1 + * Version) */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1 + * Version) */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + /* + * This Board ID is a generic identification. Use the found number + * of ports to further define this hardware. + */ + switch (ci->max_port) { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + } + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + break; #ifdef SBE_PMCC4_ENABLE - /* - * This case is entered as a result of the inability to obtain the - * <bid> from the board's EEPROM. Assume a PCI board and set - * <hdsbid> according to the number ofr found ports. - */ - case 0: - /* start by assuming 4-port for ZERO casing */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */ + /* + * This case is entered as a result of the inability to obtain the + * <bid> from the board's EEPROM. Assume a PCI board and set + * <hdsbid> according to the number ofr found ports. + */ + case 0: + /* start by assuming 4-port for ZERO casing */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */ #endif - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): - /* - * This Board ID is a generic identification. Use the number of - * found ports to further define this hardware. - */ - switch (ci->max_port) - { - default: /* shouldn't need a default, but have one - * anyway */ - case 4: - ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */ - break; - case 2: - ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); - break; - case 1: - ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); - break; - } - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): - ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): - ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ - break; - default: - /*** bid = "<unknown>"; ***/ - ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */ - break; - } + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + /* + * This Board ID is a generic identification. Use the number of + * found ports to further define this hardware. + */ + switch (ci->max_port) { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; + } + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + break; + default: + /*** bid = "<unknown>"; ***/ + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */ + break; + } } /* given the presetting of hdw_bid, set the corresponding brd_id */ void -sbeid_set_bdtype (ci_t *ci) +sbeid_set_bdtype(ci_t *ci) { - /* set SBE's unique PCI VENDOR/DEVID */ - switch (ci->hdw_bid) - { - case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3); - break; - case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1); - break; - case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1); - break; - case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1); - break; - case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1); - break; - case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); - break; - case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); - break; - case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - break; - case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); - break; - case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); - break; + /* set SBE's unique PCI VENDOR/DEVID */ + switch (ci->hdw_bid) { + case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3); + break; + case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1); + break; + case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1); + break; + case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1); + break; + case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1); + break; + case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; - default: - /*** hdw_bid = "<unknown>"; ***/ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - break; - } + default: + /*** hdw_bid = "<unknown>"; ***/ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + } } diff --git a/drivers/staging/dgnc/dgnc_trace.c b/drivers/staging/dgnc/dgnc_trace.c index a98b7d4255c8..e59b7813c355 100644 --- a/drivers/staging/dgnc/dgnc_trace.c +++ b/drivers/staging/dgnc/dgnc_trace.c @@ -63,16 +63,16 @@ void dgnc_tracef(const char *fmt, ...) void dgnc_tracef(const char *fmt, ...) { - va_list ap; - char buf[TRC_MAXMSG+1]; - size_t lenbuf; - int i; - static int failed = FALSE; + va_list ap; + char buf[TRC_MAXMSG+1]; + size_t lenbuf; + int i; + static int failed = FALSE; # if defined(TRC_TO_KMEM) unsigned long flags; #endif - if(failed) + if (failed) return; # if defined(TRC_TO_KMEM) DGNC_LOCK(dgnc_tracef_lock, flags); @@ -86,7 +86,7 @@ void dgnc_tracef(const char *fmt, ...) # if defined(TRC_TO_KMEM) { - static int initd=0; + static int initd = 0; /* * Now, in addition to (or instead of) printing this stuff out @@ -95,7 +95,7 @@ void dgnc_tracef(const char *fmt, ...) */ if (!initd) { dgnc_trcbuf = (char *) vmalloc(dgnc_trcbuf_size); - if(!dgnc_trcbuf) { + if (!dgnc_trcbuf) { failed = TRUE; printk("dgnc: tracing init failed!\n"); return; @@ -179,6 +179,6 @@ void dgnc_tracef(const char *fmt, ...) */ void dgnc_tracer_free(void) { - if(dgnc_trcbuf) + if (dgnc_trcbuf) vfree(dgnc_trcbuf); } diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 33ac7fb88cbd..1f61b89eca44 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -2232,6 +2232,177 @@ done: return rtn; } +/* + * Common Packet Handling code + */ + +static void handle_data_in_packet(struct nd_struct *nd, struct ch_struct *ch, + long dlen, long plen, int n1, u8 *dbuf) +{ + char *error; + long n; + long remain; + u8 *buf; + u8 *b; + + remain = nd->nd_remain; + nd->nd_tx_work = 1; + + /* + * Otherwise data should appear only when we are + * in the CS_READY state. + */ + + if (ch->ch_state < CS_READY) { + error = "Data received before RWIN established"; + nd->nd_remain = 0; + nd->nd_state = NS_SEND_ERROR; + nd->nd_error = error; + } + + /* + * Assure that the data received is within the + * allowable window. + */ + + n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; + + if (dlen > n) { + error = "Receive data overrun"; + nd->nd_remain = 0; + nd->nd_state = NS_SEND_ERROR; + nd->nd_error = error; + } + + /* + * If we received 3 or less characters, + * assume it is a human typing, and set RTIME + * to 10 milliseconds. + * + * If we receive 10 or more characters, + * assume its not a human typing, and set RTIME + * to 100 milliseconds. + */ + + if (ch->ch_edelay != DGRP_RTIME) { + if (ch->ch_rtime != ch->ch_edelay) { + ch->ch_rtime = ch->ch_edelay; + ch->ch_flag |= CH_PARAM; + } + } else if (dlen <= 3) { + if (ch->ch_rtime != 10) { + ch->ch_rtime = 10; + ch->ch_flag |= CH_PARAM; + } + } else { + if (ch->ch_rtime != DGRP_RTIME) { + ch->ch_rtime = DGRP_RTIME; + ch->ch_flag |= CH_PARAM; + } + } + + /* + * If a portion of the packet is outside the + * buffer, shorten the effective length of the + * data packet to be the amount of data received. + */ + + if (remain < plen) + dlen -= plen - remain; + + /* + * Detect if receive flush is now complete. + */ + + if ((ch->ch_flag & CH_RX_FLUSH) != 0 && + ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= + ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { + ch->ch_flag &= ~CH_RX_FLUSH; + } + + /* + * If we are ready to receive, move the data into + * the receive buffer. + */ + + ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; + + if (ch->ch_state == CS_READY && + (ch->ch_tun.un_open_count != 0) && + (ch->ch_tun.un_flag & UN_CLOSING) == 0 && + (ch->ch_cflag & CF_CREAD) != 0 && + (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && + (ch->ch_send & RR_RX_FLUSH) == 0) { + + if (ch->ch_rin + dlen >= RBUF_MAX) { + n = RBUF_MAX - ch->ch_rin; + + memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); + + ch->ch_rin = 0; + dbuf += n; + dlen -= n; + } + + memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); + + ch->ch_rin += dlen; + + + /* + * If we are not in fastcook mode, or + * if there is a fastcook thread + * waiting for data, send the data to + * the line discipline. + */ + + if ((ch->ch_flag & CH_FAST_READ) == 0 || + ch->ch_inwait != 0) { + dgrp_input(ch); + } + + /* + * If there is a read thread waiting + * in select, and we are in fastcook + * mode, wake him up. + */ + + if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && + (ch->ch_flag & CH_FAST_READ) != 0) + wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); + + /* + * Wake any thread waiting in the + * fastcook loop. + */ + + if ((ch->ch_flag & CH_INPUT) != 0) { + ch->ch_flag &= ~CH_INPUT; + wake_up_interruptible(&ch->ch_flag_wait); + } + } + + /* + * Fabricate and insert a data packet header to + * preced the remaining data when it comes in. + */ + + if (remain < plen) { + dlen = plen - remain; + b = buf; + + b[0] = 0x90 + n1; + put_unaligned_be16(dlen, b + 1); + + remain = 3; + if (remain > 0 && b != buf) + memcpy(buf, b, remain); + + nd->nd_remain = remain; + return; + } +} + /** * dgrp_receive() -- decode data packets received from the remote PortServer. * @nd: pointer to a node structure @@ -2306,7 +2477,8 @@ static void dgrp_receive(struct nd_struct *nd) plen = dlen + 1; dbuf = b + 1; - goto data; + handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); + break; /* * Process 2-byte header data packet. @@ -2320,7 +2492,8 @@ static void dgrp_receive(struct nd_struct *nd) plen = dlen + 2; dbuf = b + 2; - goto data; + handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); + break; /* * Process 3-byte header data packet. @@ -2335,159 +2508,6 @@ static void dgrp_receive(struct nd_struct *nd) dbuf = b + 3; - /* - * Common packet handling code. - */ - -data: - nd->nd_tx_work = 1; - - /* - * Otherwise data should appear only when we are - * in the CS_READY state. - */ - - if (ch->ch_state < CS_READY) { - error = "Data received before RWIN established"; - goto prot_error; - } - - /* - * Assure that the data received is within the - * allowable window. - */ - - n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; - - if (dlen > n) { - error = "Receive data overrun"; - goto prot_error; - } - - /* - * If we received 3 or less characters, - * assume it is a human typing, and set RTIME - * to 10 milliseconds. - * - * If we receive 10 or more characters, - * assume its not a human typing, and set RTIME - * to 100 milliseconds. - */ - - if (ch->ch_edelay != DGRP_RTIME) { - if (ch->ch_rtime != ch->ch_edelay) { - ch->ch_rtime = ch->ch_edelay; - ch->ch_flag |= CH_PARAM; - } - } else if (dlen <= 3) { - if (ch->ch_rtime != 10) { - ch->ch_rtime = 10; - ch->ch_flag |= CH_PARAM; - } - } else { - if (ch->ch_rtime != DGRP_RTIME) { - ch->ch_rtime = DGRP_RTIME; - ch->ch_flag |= CH_PARAM; - } - } - - /* - * If a portion of the packet is outside the - * buffer, shorten the effective length of the - * data packet to be the amount of data received. - */ - - if (remain < plen) - dlen -= plen - remain; - - /* - * Detect if receive flush is now complete. - */ - - if ((ch->ch_flag & CH_RX_FLUSH) != 0 && - ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= - ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { - ch->ch_flag &= ~CH_RX_FLUSH; - } - - /* - * If we are ready to receive, move the data into - * the receive buffer. - */ - - ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; - - if (ch->ch_state == CS_READY && - (ch->ch_tun.un_open_count != 0) && - (ch->ch_tun.un_flag & UN_CLOSING) == 0 && - (ch->ch_cflag & CF_CREAD) != 0 && - (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && - (ch->ch_send & RR_RX_FLUSH) == 0) { - - if (ch->ch_rin + dlen >= RBUF_MAX) { - n = RBUF_MAX - ch->ch_rin; - - memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); - - ch->ch_rin = 0; - dbuf += n; - dlen -= n; - } - - memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); - - ch->ch_rin += dlen; - - - /* - * If we are not in fastcook mode, or - * if there is a fastcook thread - * waiting for data, send the data to - * the line discipline. - */ - - if ((ch->ch_flag & CH_FAST_READ) == 0 || - ch->ch_inwait != 0) { - dgrp_input(ch); - } - - /* - * If there is a read thread waiting - * in select, and we are in fastcook - * mode, wake him up. - */ - - if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && - (ch->ch_flag & CH_FAST_READ) != 0) - wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); - - /* - * Wake any thread waiting in the - * fastcook loop. - */ - - if ((ch->ch_flag & CH_INPUT) != 0) { - ch->ch_flag &= ~CH_INPUT; - - wake_up_interruptible(&ch->ch_flag_wait); - } - } - - /* - * Fabricate and insert a data packet header to - * preced the remaining data when it comes in. - */ - - if (remain < plen) { - dlen = plen - remain; - b = buf; - - b[0] = 0x90 + n1; - put_unaligned_be16(dlen, b + 1); - - remain = 3; - goto done; - } break; /* diff --git a/drivers/staging/dwc2/core.c b/drivers/staging/dwc2/core.c index 6d001b52f652..8565d87f94b4 100644 --- a/drivers/staging/dwc2/core.c +++ b/drivers/staging/dwc2/core.c @@ -114,7 +114,7 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ -static void dwc2_core_reset(struct dwc2_hsotg *hsotg) +static int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; @@ -129,7 +129,7 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg) dev_warn(hsotg->dev, "%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__, greset); - return; + return -EBUSY; } } while (!(greset & GRSTCTL_AHBIDLE)); @@ -144,7 +144,7 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg) dev_warn(hsotg->dev, "%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__, greset); - break; + return -EBUSY; } } while (greset & GRSTCTL_CSFTRST); @@ -153,11 +153,14 @@ static void dwc2_core_reset(struct dwc2_hsotg *hsotg) * not stay in host mode after a connector ID change! */ usleep_range(150000, 200000); + + return 0; } -static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) { u32 usbcfg, i2cctl; + int retval = 0; /* * core_init() is now called on every switch so only call the @@ -170,7 +173,12 @@ static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after a PHY select */ - dwc2_core_reset(hsotg); + retval = dwc2_core_reset(hsotg); + if (retval) { + dev_err(hsotg->dev, "%s() Reset failed, aborting", + __func__); + return retval; + } } /* @@ -198,14 +206,17 @@ static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) i2cctl |= GI2CCTL_I2CEN; writel(i2cctl, hsotg->regs + GI2CCTL); } + + return retval; } -static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) { u32 usbcfg; + int retval = 0; if (!select_phy) - return; + return -ENODEV; usbcfg = readl(hsotg->regs + GUSBCFG); @@ -238,20 +249,32 @@ static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after setting the PHY parameters */ - dwc2_core_reset(hsotg); + retval = dwc2_core_reset(hsotg); + if (retval) { + dev_err(hsotg->dev, "%s() Reset failed, aborting", + __func__); + return retval; + } + + return retval; } -static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) +static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) { u32 usbcfg; + int retval = 0; if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL && hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { /* If FS mode with FS PHY */ - dwc2_fs_phy_init(hsotg, select_phy); + retval = dwc2_fs_phy_init(hsotg, select_phy); + if (retval) + return retval; } else { /* High speed PHY */ - dwc2_hs_phy_init(hsotg, select_phy); + retval = dwc2_hs_phy_init(hsotg, select_phy); + if (retval) + return retval; } if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && @@ -268,6 +291,8 @@ static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M; writel(usbcfg, hsotg->regs + GUSBCFG); } + + return retval; } static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) @@ -382,12 +407,19 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset the Controller */ - dwc2_core_reset(hsotg); + retval = dwc2_core_reset(hsotg); + if (retval) { + dev_err(hsotg->dev, "%s(): Reset failed, aborting\n", + __func__); + return retval; + } /* * This needs to happen in FS mode before any other programming occurs */ - dwc2_phy_init(hsotg, select_phy); + retval = dwc2_phy_init(hsotg, select_phy); + if (retval) + return retval; /* Program the GAHBCFG Register */ retval = dwc2_gahbcfg_init(hsotg); @@ -451,9 +483,6 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) writel(0, hsotg->regs + GINTMSK); writel(0, hsotg->regs + HAINTMSK); - /* Clear any pending interrupts */ - writel(0xffffffff, hsotg->regs + GINTSTS); - /* Enable the common interrupts */ dwc2_enable_common_interrupts(hsotg); @@ -1912,13 +1941,12 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg) udelay(1); } -#define DWC2_PARAM_TEST(a, b, c) ((a) < (b) || (a) > (c)) +#define DWC2_OUT_OF_BOUNDS(a, b, c) ((a) < (b) || (a) > (c)) /* Parameter access functions */ -int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; switch (val) { case DWC2_CAP_PARAM_HNP_SRP_CAPABLE: @@ -1964,17 +1992,14 @@ int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val) break; } dev_dbg(hsotg->dev, "Setting otg_cap to %d\n", val); - retval = -EINVAL; } hsotg->core_params->otg_cap = val; - return retval; } -int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val > 0 && hsotg->hw_params.arch == GHWCFG2_SLAVE_ONLY_ARCH) valid = 0; @@ -1988,17 +2013,14 @@ int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.arch != GHWCFG2_SLAVE_ONLY_ARCH; dev_dbg(hsotg->dev, "Setting dma_enable to %d\n", val); - retval = -EINVAL; } hsotg->core_params->dma_enable = val; - return retval; } -int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val > 0 && (hsotg->core_params->dma_enable <= 0 || !hsotg->hw_params.dma_desc_enable)) @@ -2014,19 +2036,15 @@ int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val) val = (hsotg->core_params->dma_enable > 0 && hsotg->hw_params.dma_desc_enable); dev_dbg(hsotg->dev, "Setting dma_desc_enable to %d\n", val); - retval = -EINVAL; } hsotg->core_params->dma_desc_enable = val; - return retval; } -int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, - int val) +void dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, + int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for host_support_fs_low_power\n"); @@ -2036,17 +2054,14 @@ int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, val = 0; dev_dbg(hsotg->dev, "Setting host_support_fs_low_power to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_support_fs_ls_low_power = val; - return retval; } -int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val > 0 && !hsotg->hw_params.enable_dynamic_fifo) valid = 0; @@ -2060,17 +2075,14 @@ int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.enable_dynamic_fifo; dev_dbg(hsotg->dev, "Setting enable_dynamic_fifo to %d\n", val); - retval = -EINVAL; } hsotg->core_params->enable_dynamic_fifo = val; - return retval; } -int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 16 || val > hsotg->hw_params.host_rx_fifo_size) valid = 0; @@ -2082,17 +2094,14 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.host_rx_fifo_size; dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_rx_fifo_size = val; - return retval; } -int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 16 || val > hsotg->hw_params.host_nperio_tx_fifo_size) valid = 0; @@ -2105,17 +2114,14 @@ int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) val = hsotg->hw_params.host_nperio_tx_fifo_size; dev_dbg(hsotg->dev, "Setting host_nperio_tx_fifo_size to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_nperio_tx_fifo_size = val; - return retval; } -int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 16 || val > hsotg->hw_params.host_perio_tx_fifo_size) valid = 0; @@ -2128,17 +2134,14 @@ int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, int val) val = hsotg->hw_params.host_perio_tx_fifo_size; dev_dbg(hsotg->dev, "Setting host_perio_tx_fifo_size to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_perio_tx_fifo_size = val; - return retval; } -int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 2047 || val > hsotg->hw_params.max_transfer_size) valid = 0; @@ -2150,17 +2153,14 @@ int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.max_transfer_size; dev_dbg(hsotg->dev, "Setting max_transfer_size to %d\n", val); - retval = -EINVAL; } hsotg->core_params->max_transfer_size = val; - return retval; } -int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 15 || val > hsotg->hw_params.max_packet_count) valid = 0; @@ -2172,17 +2172,14 @@ int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.max_packet_count; dev_dbg(hsotg->dev, "Setting max_packet_count to %d\n", val); - retval = -EINVAL; } hsotg->core_params->max_packet_count = val; - return retval; } -int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; if (val < 1 || val > hsotg->hw_params.host_channels) valid = 0; @@ -2194,38 +2191,26 @@ int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.host_channels; dev_dbg(hsotg->dev, "Setting host_channels to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_channels = val; - return retval; } -int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) { -#ifndef NO_FS_PHY_HW_CHECKS int valid = 0; u32 hs_phy_type, fs_phy_type; -#endif - int retval = 0; - if (DWC2_PARAM_TEST(val, DWC2_PHY_TYPE_PARAM_FS, - DWC2_PHY_TYPE_PARAM_ULPI)) { + if (DWC2_OUT_OF_BOUNDS(val, DWC2_PHY_TYPE_PARAM_FS, + DWC2_PHY_TYPE_PARAM_ULPI)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for phy_type\n"); dev_err(hsotg->dev, "phy_type must be 0, 1 or 2\n"); } -#ifndef NO_FS_PHY_HW_CHECKS valid = 0; -#else - val = DWC2_PHY_TYPE_PARAM_FS; - dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val); - retval = -EINVAL; -#endif } -#ifndef NO_FS_PHY_HW_CHECKS hs_phy_type = hsotg->hw_params.hs_phy_type; fs_phy_type = hsotg->hw_params.fs_phy_type; if (val == DWC2_PHY_TYPE_PARAM_UTMI && @@ -2254,12 +2239,9 @@ int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val) val = DWC2_PHY_TYPE_PARAM_ULPI; } dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val); - retval = -EINVAL; } -#endif hsotg->core_params->phy_type = val; - return retval; } static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg) @@ -2267,12 +2249,11 @@ static int dwc2_get_param_phy_type(struct dwc2_hsotg *hsotg) return hsotg->core_params->phy_type; } -int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for speed parameter\n"); dev_err(hsotg->dev, "max_speed parameter must be 0 or 1\n"); @@ -2292,20 +2273,17 @@ int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val) val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ? DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH; dev_dbg(hsotg->dev, "Setting speed to %d\n", val); - retval = -EINVAL; } hsotg->core_params->speed = val; - return retval; } -int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; - if (DWC2_PARAM_TEST(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ, - DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) { + if (DWC2_OUT_OF_BOUNDS(val, DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ, + DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for host_ls_low_power_phy_clk parameter\n"); @@ -2329,36 +2307,28 @@ int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, int val) : DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ; dev_dbg(hsotg->dev, "Setting host_ls_low_power_phy_clk to %d\n", val); - retval = -EINVAL; } hsotg->core_params->host_ls_low_power_phy_clk = val; - return retval; } -int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for phy_ulpi_ddr\n"); dev_err(hsotg->dev, "phy_upli_ddr must be 0 or 1\n"); } val = 0; dev_dbg(hsotg->dev, "Setting phy_upli_ddr to %d\n", val); - retval = -EINVAL; } hsotg->core_params->phy_ulpi_ddr = val; - return retval; } -int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for phy_ulpi_ext_vbus\n"); @@ -2367,17 +2337,14 @@ int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val) } val = 0; dev_dbg(hsotg->dev, "Setting phy_ulpi_ext_vbus to %d\n", val); - retval = -EINVAL; } hsotg->core_params->phy_ulpi_ext_vbus = val; - return retval; } -int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val) { int valid = 0; - int retval = 0; switch (hsotg->hw_params.utmi_phy_data_width) { case GHWCFG4_UTMI_PHY_DATA_WIDTH_8: @@ -2400,72 +2367,52 @@ int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val) val = (hsotg->hw_params.utmi_phy_data_width == GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16; dev_dbg(hsotg->dev, "Setting phy_utmi_width to %d\n", val); - retval = -EINVAL; } hsotg->core_params->phy_utmi_width = val; - return retval; } -int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for ulpi_fs_ls\n"); dev_err(hsotg->dev, "ulpi_fs_ls must be 0 or 1\n"); } val = 0; dev_dbg(hsotg->dev, "Setting ulpi_fs_ls to %d\n", val); - retval = -EINVAL; } hsotg->core_params->ulpi_fs_ls = val; - return retval; } -int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for ts_dline\n"); dev_err(hsotg->dev, "ts_dline must be 0 or 1\n"); } val = 0; dev_dbg(hsotg->dev, "Setting ts_dline to %d\n", val); - retval = -EINVAL; } hsotg->core_params->ts_dline = val; - return retval; } -int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) { -#ifndef NO_FS_PHY_HW_CHECKS int valid = 1; -#endif - int retval = 0; - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for i2c_enable\n"); dev_err(hsotg->dev, "i2c_enable must be 0 or 1\n"); } -#ifndef NO_FS_PHY_HW_CHECKS valid = 0; -#else - val = 0; - dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val); - retval = -EINVAL; -#endif } -#ifndef NO_FS_PHY_HW_CHECKS if (val == 1 && !(hsotg->hw_params.i2c_enable)) valid = 0; @@ -2476,20 +2423,16 @@ int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.i2c_enable; dev_dbg(hsotg->dev, "Setting i2c_enable to %d\n", val); - retval = -EINVAL; } -#endif hsotg->core_params->i2c_enable = val; - return retval; } -int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "Wrong value for en_multiple_tx_fifo,\n"); @@ -2509,19 +2452,16 @@ int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.en_multiple_tx_fifo; dev_dbg(hsotg->dev, "Setting en_multiple_tx_fifo to %d\n", val); - retval = -EINVAL; } hsotg->core_params->en_multiple_tx_fifo = val; - return retval; } -int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) { int valid = 1; - int retval = 0; - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "'%d' invalid for parameter reload_ctl\n", val); @@ -2540,28 +2480,23 @@ int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) val); val = hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_92a; dev_dbg(hsotg->dev, "Setting reload_ctl to %d\n", val); - retval = -EINVAL; } hsotg->core_params->reload_ctl = val; - return retval; } -int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val) { if (val != -1) hsotg->core_params->ahbcfg = val; else hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT; - return 0; } -int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val) +void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val) { - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { if (val >= 0) { dev_err(hsotg->dev, "'%d' invalid for parameter otg_ver\n", val); @@ -2570,11 +2505,71 @@ int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val) } val = 0; dev_dbg(hsotg->dev, "Setting otg_ver to %d\n", val); - retval = -EINVAL; } hsotg->core_params->otg_ver = val; - return retval; +} + +static void dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val) +{ + if (DWC2_OUT_OF_BOUNDS(val, 0, 1)) { + if (val >= 0) { + dev_err(hsotg->dev, + "'%d' invalid for parameter uframe_sched\n", + val); + dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n"); + } + val = 1; + dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val); + } + + hsotg->core_params->uframe_sched = val; +} + +/* + * This function is called during module intialization to pass module parameters + * for the DWC_otg core. + */ +void dwc2_set_parameters(struct dwc2_hsotg *hsotg, + const struct dwc2_core_params *params) +{ + dev_dbg(hsotg->dev, "%s()\n", __func__); + + dwc2_set_param_otg_cap(hsotg, params->otg_cap); + dwc2_set_param_dma_enable(hsotg, params->dma_enable); + dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable); + dwc2_set_param_host_support_fs_ls_low_power(hsotg, + params->host_support_fs_ls_low_power); + dwc2_set_param_enable_dynamic_fifo(hsotg, + params->enable_dynamic_fifo); + dwc2_set_param_host_rx_fifo_size(hsotg, + params->host_rx_fifo_size); + dwc2_set_param_host_nperio_tx_fifo_size(hsotg, + params->host_nperio_tx_fifo_size); + dwc2_set_param_host_perio_tx_fifo_size(hsotg, + params->host_perio_tx_fifo_size); + dwc2_set_param_max_transfer_size(hsotg, + params->max_transfer_size); + dwc2_set_param_max_packet_count(hsotg, + params->max_packet_count); + dwc2_set_param_host_channels(hsotg, params->host_channels); + dwc2_set_param_phy_type(hsotg, params->phy_type); + dwc2_set_param_speed(hsotg, params->speed); + dwc2_set_param_host_ls_low_power_phy_clk(hsotg, + params->host_ls_low_power_phy_clk); + dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr); + dwc2_set_param_phy_ulpi_ext_vbus(hsotg, + params->phy_ulpi_ext_vbus); + dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width); + dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls); + dwc2_set_param_ts_dline(hsotg, params->ts_dline); + dwc2_set_param_i2c_enable(hsotg, params->i2c_enable); + dwc2_set_param_en_multiple_tx_fifo(hsotg, + params->en_multiple_tx_fifo); + dwc2_set_param_reload_ctl(hsotg, params->reload_ctl); + dwc2_set_param_ahbcfg(hsotg, params->ahbcfg); + dwc2_set_param_otg_ver(hsotg, params->otg_ver); + dwc2_set_param_uframe_sched(hsotg, params->uframe_sched); } /** @@ -2736,88 +2731,17 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) return 0; } -int dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val) -{ - int retval = 0; - - if (DWC2_PARAM_TEST(val, 0, 1)) { - if (val >= 0) { - dev_err(hsotg->dev, - "'%d' invalid for parameter uframe_sched\n", - val); - dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n"); - } - val = 1; - dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val); - retval = -EINVAL; - } - - hsotg->core_params->uframe_sched = val; - return retval; -} - -/* - * This function is called during module intialization to pass module parameters - * for the DWC_otg core. It returns non-0 if any parameters are invalid. - */ -int dwc2_set_parameters(struct dwc2_hsotg *hsotg, - const struct dwc2_core_params *params) -{ - int retval = 0; - - dev_dbg(hsotg->dev, "%s()\n", __func__); - - retval |= dwc2_set_param_otg_cap(hsotg, params->otg_cap); - retval |= dwc2_set_param_dma_enable(hsotg, params->dma_enable); - retval |= dwc2_set_param_dma_desc_enable(hsotg, - params->dma_desc_enable); - retval |= dwc2_set_param_host_support_fs_ls_low_power(hsotg, - params->host_support_fs_ls_low_power); - retval |= dwc2_set_param_enable_dynamic_fifo(hsotg, - params->enable_dynamic_fifo); - retval |= dwc2_set_param_host_rx_fifo_size(hsotg, - params->host_rx_fifo_size); - retval |= dwc2_set_param_host_nperio_tx_fifo_size(hsotg, - params->host_nperio_tx_fifo_size); - retval |= dwc2_set_param_host_perio_tx_fifo_size(hsotg, - params->host_perio_tx_fifo_size); - retval |= dwc2_set_param_max_transfer_size(hsotg, - params->max_transfer_size); - retval |= dwc2_set_param_max_packet_count(hsotg, - params->max_packet_count); - retval |= dwc2_set_param_host_channels(hsotg, params->host_channels); - retval |= dwc2_set_param_phy_type(hsotg, params->phy_type); - retval |= dwc2_set_param_speed(hsotg, params->speed); - retval |= dwc2_set_param_host_ls_low_power_phy_clk(hsotg, - params->host_ls_low_power_phy_clk); - retval |= dwc2_set_param_phy_ulpi_ddr(hsotg, params->phy_ulpi_ddr); - retval |= dwc2_set_param_phy_ulpi_ext_vbus(hsotg, - params->phy_ulpi_ext_vbus); - retval |= dwc2_set_param_phy_utmi_width(hsotg, params->phy_utmi_width); - retval |= dwc2_set_param_ulpi_fs_ls(hsotg, params->ulpi_fs_ls); - retval |= dwc2_set_param_ts_dline(hsotg, params->ts_dline); - retval |= dwc2_set_param_i2c_enable(hsotg, params->i2c_enable); - retval |= dwc2_set_param_en_multiple_tx_fifo(hsotg, - params->en_multiple_tx_fifo); - retval |= dwc2_set_param_reload_ctl(hsotg, params->reload_ctl); - retval |= dwc2_set_param_ahbcfg(hsotg, params->ahbcfg); - retval |= dwc2_set_param_otg_ver(hsotg, params->otg_ver); - retval |= dwc2_set_param_uframe_sched(hsotg, params->uframe_sched); - - return retval; -} - u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg) { - return (u16)(hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103); + return hsotg->core_params->otg_ver == 1 ? 0x0200 : 0x0103; } -int dwc2_check_core_status(struct dwc2_hsotg *hsotg) +bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg) { if (readl(hsotg->regs + GSNPSID) == 0xffffffff) - return -1; + return false; else - return 0; + return true; } /** diff --git a/drivers/staging/dwc2/core.h b/drivers/staging/dwc2/core.h index fab718d9b326..648519c024b5 100644 --- a/drivers/staging/dwc2/core.h +++ b/drivers/staging/dwc2/core.h @@ -544,7 +544,7 @@ extern void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg); extern void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg); extern u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg); -extern int dwc2_check_core_status(struct dwc2_hsotg *hsotg); +extern bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg); /* * Common core Functions. @@ -571,7 +571,7 @@ extern irqreturn_t dwc2_handle_common_intr(int irq, void *dev); * 1 - SRP Only capable * 2 - No HNP/SRP capable */ -extern int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val); #define DWC2_CAP_PARAM_HNP_SRP_CAPABLE 0 #define DWC2_CAP_PARAM_SRP_ONLY_CAPABLE 1 #define DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 @@ -583,7 +583,7 @@ extern int dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg, int val); * 0 - Slave * 1 - DMA (default, if available) */ -extern int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val); /* * When DMA mode is enabled specifies whether to use @@ -593,7 +593,7 @@ extern int dwc2_set_param_dma_enable(struct dwc2_hsotg *hsotg, int val); * 0 - address DMA * 1 - DMA Descriptor(default, if available) */ -extern int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val); /* * Specifies the maximum speed of operation in host and device mode. @@ -603,7 +603,7 @@ extern int dwc2_set_param_dma_desc_enable(struct dwc2_hsotg *hsotg, int val); * 0 - High Speed (default) * 1 - Full Speed */ -extern int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val); #define DWC2_SPEED_PARAM_HIGH 0 #define DWC2_SPEED_PARAM_FULL 1 @@ -614,8 +614,8 @@ extern int dwc2_set_param_speed(struct dwc2_hsotg *hsotg, int val); * 0 - Don't support low power mode (default) * 1 - Support low power mode */ -extern int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_host_support_fs_ls_low_power( + struct dwc2_hsotg *hsotg, int val); /* * Specifies the PHY clock rate in low power mode when connected to a @@ -626,8 +626,8 @@ extern int dwc2_set_param_host_support_fs_ls_low_power(struct dwc2_hsotg *hsotg, * 0 - 48 MHz * 1 - 6 MHz */ -extern int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, + int val); #define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0 #define DWC2_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1 @@ -635,50 +635,50 @@ extern int dwc2_set_param_host_ls_low_power_phy_clk(struct dwc2_hsotg *hsotg, * 0 - Use cC FIFO size parameters * 1 - Allow dynamic FIFO sizing (default) */ -extern int dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_enable_dynamic_fifo(struct dwc2_hsotg *hsotg, + int val); /* * Number of 4-byte words in the Rx FIFO in host mode when dynamic * FIFO sizing is enabled. * 16 to 32768 (default 1024) */ -extern int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val); /* * Number of 4-byte words in the non-periodic Tx FIFO in host mode * when Dynamic FIFO sizing is enabled in the core. * 16 to 32768 (default 256) */ -extern int dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_host_nperio_tx_fifo_size(struct dwc2_hsotg *hsotg, + int val); /* * Number of 4-byte words in the host periodic Tx FIFO when dynamic * FIFO sizing is enabled. * 16 to 32768 (default 256) */ -extern int dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_host_perio_tx_fifo_size(struct dwc2_hsotg *hsotg, + int val); /* * The maximum transfer size supported in bytes. * 2047 to 65,535 (default 65,535) */ -extern int dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_max_transfer_size(struct dwc2_hsotg *hsotg, int val); /* * The maximum number of packets in a transfer. * 15 to 511 (default 511) */ -extern int dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_max_packet_count(struct dwc2_hsotg *hsotg, int val); /* * The number of host channel registers to use. * 1 to 16 (default 11) * Note: The FPGA configuration supports a maximum of 11 host channels. */ -extern int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val); /* * Specifies the type of PHY interface to use. By default, the driver @@ -688,7 +688,7 @@ extern int dwc2_set_param_host_channels(struct dwc2_hsotg *hsotg, int val); * 1 - UTMI+ (default) * 2 - ULPI */ -extern int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val); #define DWC2_PHY_TYPE_PARAM_FS 0 #define DWC2_PHY_TYPE_PARAM_UTMI 1 #define DWC2_PHY_TYPE_PARAM_ULPI 2 @@ -704,7 +704,7 @@ extern int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val); * * 8 or 16 bits (default 16) */ -extern int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val); /* * Specifies whether the ULPI operates at double or single @@ -716,13 +716,13 @@ extern int dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg, int val); * 1 - double data rate ULPI interface with 4 bit wide data * bus */ -extern int dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_phy_ulpi_ddr(struct dwc2_hsotg *hsotg, int val); /* * Specifies whether to use the internal or external supply to * drive the vbus with a ULPI phy. */ -extern int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val); #define DWC2_PHY_ULPI_INTERNAL_VBUS 0 #define DWC2_PHY_ULPI_EXTERNAL_VBUS 1 @@ -732,11 +732,11 @@ extern int dwc2_set_param_phy_ulpi_ext_vbus(struct dwc2_hsotg *hsotg, int val); * 0 - No (default) * 1 - Yes */ -extern int dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_i2c_enable(struct dwc2_hsotg *hsotg, int val); -extern int dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_ulpi_fs_ls(struct dwc2_hsotg *hsotg, int val); -extern int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val); /* * Specifies whether dedicated transmit FIFOs are @@ -744,14 +744,14 @@ extern int dwc2_set_param_ts_dline(struct dwc2_hsotg *hsotg, int val); * 0 - No * 1 - Yes */ -extern int dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, - int val); +extern void dwc2_set_param_en_multiple_tx_fifo(struct dwc2_hsotg *hsotg, + int val); -extern int dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val); -extern int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val); -extern int dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val); +extern void dwc2_set_param_otg_ver(struct dwc2_hsotg *hsotg, int val); /* * Dump core registers and SPRAM diff --git a/drivers/staging/dwc2/core_intr.c b/drivers/staging/dwc2/core_intr.c index 07cfa2f6aa2b..8205799e6db3 100644 --- a/drivers/staging/dwc2/core_intr.c +++ b/drivers/staging/dwc2/core_intr.c @@ -55,7 +55,6 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) { -#ifdef DEBUG switch (hsotg->op_state) { case OTG_STATE_A_HOST: return "a_host"; @@ -70,9 +69,6 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) default: return "unknown"; } -#else - return ""; -#endif } /** @@ -419,12 +415,10 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) gintmsk = readl(hsotg->regs + GINTMSK); gahbcfg = readl(hsotg->regs + GAHBCFG); -#ifdef DEBUG /* If any common interrupts set */ if (gintsts & gintmsk_common) dev_dbg(hsotg->dev, "gintsts=%08x gintmsk=%08x\n", gintsts, gintmsk); -#endif if (gahbcfg & GAHBCFG_GLBL_INTR_EN) return gintsts & gintmsk & gintmsk_common; @@ -451,8 +445,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) u32 gintsts; irqreturn_t retval = IRQ_NONE; - if (dwc2_check_core_status(hsotg) < 0) { - dev_warn(hsotg->dev, "Controller is disconnected\n"); + if (!dwc2_is_controller_alive(hsotg)) { + dev_warn(hsotg->dev, "Controller is dead\n"); goto out; } diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index 3cfd2d5152c9..07dfe855dc20 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -355,6 +355,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, unsigned long flags; u32 intr_mask; int retval; + int dev_speed; if (!hsotg->flags.b.port_connect_status) { /* No longer connected */ @@ -362,6 +363,19 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, return -ENODEV; } + dev_speed = dwc2_host_get_speed(hsotg, urb->priv); + + /* Some configurations cannot support LS traffic on a FS root port */ + if ((dev_speed == USB_SPEED_LOW) && + (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) && + (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) { + u32 hprt0 = readl(hsotg->regs + HPRT0); + u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; + + if (prtspd == HPRT0_SPD_FULL_SPEED) + return -ENODEV; + } + qtd = kzalloc(sizeof(*qtd), mem_flags); if (!qtd) return -ENOMEM; @@ -369,7 +383,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, dwc2_hcd_qtd_init(qtd, urb); retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle, mem_flags); - if (retval < 0) { + if (retval) { dev_err(hsotg->dev, "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n", retval); @@ -378,7 +392,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, } intr_mask = readl(hsotg->regs + GINTMSK); - if (!(intr_mask & GINTSTS_SOF) && retval == 0) { + if (!(intr_mask & GINTSTS_SOF)) { enum dwc2_transaction_type tr_type; if (qtd->qh->ep_type == USB_ENDPOINT_XFER_BULK && @@ -396,7 +410,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, spin_unlock_irqrestore(&hsotg->lock, flags); } - return retval; + return 0; } /* Must be called with interrupt disabled and spinlock held */ @@ -1795,7 +1809,7 @@ int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg) { - return (hsotg->op_state == OTG_STATE_B_HOST); + return hsotg->op_state == OTG_STATE_B_HOST; } static struct dwc2_hcd_urb *dwc2_hcd_urb_alloc(struct dwc2_hsotg *hsotg, diff --git a/drivers/staging/dwc2/hcd.h b/drivers/staging/dwc2/hcd.h index 89a5484f5b74..fdc6d489084a 100644 --- a/drivers/staging/dwc2/hcd.h +++ b/drivers/staging/dwc2/hcd.h @@ -452,8 +452,8 @@ static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe) extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq, const struct dwc2_core_params *params); extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg); -extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg, - const struct dwc2_core_params *params); +extern void dwc2_set_parameters(struct dwc2_hsotg *hsotg, + const struct dwc2_core_params *params); extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); diff --git a/drivers/staging/dwc2/hcd_ddma.c b/drivers/staging/dwc2/hcd_ddma.c index c7d434519776..3376177e4d3c 100644 --- a/drivers/staging/dwc2/hcd_ddma.c +++ b/drivers/staging/dwc2/hcd_ddma.c @@ -621,8 +621,8 @@ static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg, struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[n_desc]; int len = chan->xfer_len; - if (len > MAX_DMA_DESC_SIZE) - len = MAX_DMA_DESC_SIZE - chan->max_packet + 1; + if (len > MAX_DMA_DESC_SIZE - (chan->max_packet - 1)) + len = MAX_DMA_DESC_SIZE - (chan->max_packet - 1); if (chan->ep_is_in) { int num_packets; @@ -1103,8 +1103,10 @@ static void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, for (i = 0; i < qtd->n_desc; i++) { if (dwc2_process_non_isoc_desc(hsotg, chan, chnum, qtd, desc_num, halt_status, - &xfer_done)) + &xfer_done)) { + qtd = NULL; break; + } desc_num++; } } diff --git a/drivers/staging/dwc2/hcd_intr.c b/drivers/staging/dwc2/hcd_intr.c index dda18540f5a7..012f17ec1a37 100644 --- a/drivers/staging/dwc2/hcd_intr.c +++ b/drivers/staging/dwc2/hcd_intr.c @@ -935,7 +935,7 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg, frame_desc->actual_length += len; - if (chan->align_buf && len) { + if (chan->align_buf) { dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); dma_sync_single_for_cpu(hsotg->dev, qtd->urb->dma, qtd->urb->length, DMA_FROM_DEVICE); @@ -2059,8 +2059,8 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg) u32 gintsts, dbg_gintsts; irqreturn_t retval = IRQ_NONE; - if (dwc2_check_core_status(hsotg) < 0) { - dev_warn(hsotg->dev, "Controller is disconnected\n"); + if (!dwc2_is_controller_alive(hsotg)) { + dev_warn(hsotg->dev, "Controller is dead\n"); return retval; } diff --git a/drivers/staging/dwc2/hcd_queue.c b/drivers/staging/dwc2/hcd_queue.c index f200f1f6e1c6..9540f7e1e20e 100644 --- a/drivers/staging/dwc2/hcd_queue.c +++ b/drivers/staging/dwc2/hcd_queue.c @@ -344,25 +344,17 @@ void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg) static int dwc2_find_single_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { unsigned short utime = qh->usecs; - int done = 0; - int i = 0; - int ret = -1; + int i; - while (!done) { + for (i = 0; i < 8; i++) { /* At the start hsotg->frame_usecs[i] = max_uframe_usecs[i] */ if (utime <= hsotg->frame_usecs[i]) { hsotg->frame_usecs[i] -= utime; qh->frame_usecs[i] += utime; - ret = i; - done = 1; - } else { - i++; - if (i == 8) - done = 1; + return i; } } - - return ret; + return -ENOSPC; } /* @@ -372,21 +364,14 @@ static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { unsigned short utime = qh->usecs; unsigned short xtime; - int t_left = utime; - int done = 0; - int i = 0; + int t_left; + int i; int j; - int ret = -1; - - while (!done) { - if (hsotg->frame_usecs[i] <= 0) { - i++; - if (i == 8) { - ret = -1; - done = 1; - } + int k; + + for (i = 0; i < 8; i++) { + if (hsotg->frame_usecs[i] <= 0) continue; - } /* * we need n consecutive slots so use j as a start slot @@ -400,50 +385,35 @@ static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) */ if (xtime + hsotg->frame_usecs[j] < utime) { if (hsotg->frame_usecs[j] < - max_uframe_usecs[j]) { - ret = -1; - break; - } + max_uframe_usecs[j]) + continue; } if (xtime >= utime) { - ret = i; - break; + t_left = utime; + for (k = i; k < 8; k++) { + t_left -= hsotg->frame_usecs[k]; + if (t_left <= 0) { + qh->frame_usecs[k] += + hsotg->frame_usecs[k] + + t_left; + hsotg->frame_usecs[k] = -t_left; + return i; + } else { + qh->frame_usecs[k] += + hsotg->frame_usecs[k]; + hsotg->frame_usecs[k] = 0; + } + } } /* add the frame time to x time */ xtime += hsotg->frame_usecs[j]; /* we must have a fully available next frame or break */ if (xtime < utime && - hsotg->frame_usecs[j] == max_uframe_usecs[j]) { - ret = -1; - break; - } - } - if (ret >= 0) { - t_left = utime; - for (j = i; t_left > 0 && j < 8; j++) { - t_left -= hsotg->frame_usecs[j]; - if (t_left <= 0) { - qh->frame_usecs[j] += - hsotg->frame_usecs[j] + t_left; - hsotg->frame_usecs[j] = -t_left; - ret = i; - done = 1; - } else { - qh->frame_usecs[j] += - hsotg->frame_usecs[j]; - hsotg->frame_usecs[j] = 0; - } - } - } else { - i++; - if (i == 8) { - ret = -1; - done = 1; - } + hsotg->frame_usecs[j] == max_uframe_usecs[j]) + continue; } } - - return ret; + return -ENOSPC; } static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) @@ -517,12 +487,12 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) frame = status - 1; /* Set the new frame up */ - if (frame > -1) { + if (frame >= 0) { qh->sched_frame &= ~0x7; qh->sched_frame |= (frame & 7); } - if (status != -1) + if (status > 0) status = 0; } else { status = dwc2_periodic_channel_available(hsotg); @@ -609,7 +579,7 @@ static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg, */ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) { - int status = 0; + int status; u32 intr_mask; if (dbg_qh(qh)) @@ -617,26 +587,27 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) if (!list_empty(&qh->qh_list_entry)) /* QH already in a schedule */ - return status; + return 0; /* Add the new QH to the appropriate schedule */ if (dwc2_qh_is_non_per(qh)) { /* Always start in inactive schedule */ list_add_tail(&qh->qh_list_entry, &hsotg->non_periodic_sched_inactive); - } else { - status = dwc2_schedule_periodic(hsotg, qh); - if (status == 0) { - if (!hsotg->periodic_qh_count) { - intr_mask = readl(hsotg->regs + GINTMSK); - intr_mask |= GINTSTS_SOF; - writel(intr_mask, hsotg->regs + GINTMSK); - } - hsotg->periodic_qh_count++; - } + return 0; } - return status; + status = dwc2_schedule_periodic(hsotg, qh); + if (status) + return status; + if (!hsotg->periodic_qh_count) { + intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask |= GINTSTS_SOF; + writel(intr_mask, hsotg->regs + GINTMSK); + } + hsotg->periodic_qh_count++; + + return 0; } /** @@ -661,14 +632,15 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) hsotg->non_periodic_qh_ptr = hsotg->non_periodic_qh_ptr->next; list_del_init(&qh->qh_list_entry); - } else { - dwc2_deschedule_periodic(hsotg, qh); - hsotg->periodic_qh_count--; - if (!hsotg->periodic_qh_count) { - intr_mask = readl(hsotg->regs + GINTMSK); - intr_mask &= ~GINTSTS_SOF; - writel(intr_mask, hsotg->regs + GINTMSK); - } + return; + } + + dwc2_deschedule_periodic(hsotg, qh); + hsotg->periodic_qh_count--; + if (!hsotg->periodic_qh_count) { + intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask &= ~GINTSTS_SOF; + writel(intr_mask, hsotg->regs + GINTMSK); } } @@ -723,6 +695,8 @@ static void dwc2_sched_periodic_split(struct dwc2_hsotg *hsotg, void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, int sched_next_periodic_split) { + u16 frame_number; + if (dbg_qh(qh)) dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -731,37 +705,36 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, if (!list_empty(&qh->qtd_list)) /* Add back to inactive non-periodic schedule */ dwc2_hcd_qh_add(hsotg, qh); + return; + } + + frame_number = dwc2_hcd_get_frame_number(hsotg); + + if (qh->do_split) { + dwc2_sched_periodic_split(hsotg, qh, frame_number, + sched_next_periodic_split); } else { - u16 frame_number = dwc2_hcd_get_frame_number(hsotg); - - if (qh->do_split) { - dwc2_sched_periodic_split(hsotg, qh, frame_number, - sched_next_periodic_split); - } else { - qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame, - qh->interval); - if (dwc2_frame_num_le(qh->sched_frame, frame_number)) - qh->sched_frame = frame_number; - } + qh->sched_frame = dwc2_frame_num_inc(qh->sched_frame, + qh->interval); + if (dwc2_frame_num_le(qh->sched_frame, frame_number)) + qh->sched_frame = frame_number; + } - if (list_empty(&qh->qtd_list)) { - dwc2_hcd_qh_unlink(hsotg, qh); - } else { - /* - * Remove from periodic_sched_queued and move to - * appropriate queue - */ - if ((hsotg->core_params->uframe_sched > 0 && - dwc2_frame_num_le(qh->sched_frame, frame_number)) - || (hsotg->core_params->uframe_sched <= 0 && - qh->sched_frame == frame_number)) - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_ready); - else - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_inactive); - } + if (list_empty(&qh->qtd_list)) { + dwc2_hcd_qh_unlink(hsotg, qh); + return; } + /* + * Remove from periodic_sched_queued and move to + * appropriate queue + */ + if ((hsotg->core_params->uframe_sched > 0 && + dwc2_frame_num_le(qh->sched_frame, frame_number)) || + (hsotg->core_params->uframe_sched <= 0 && + qh->sched_frame == frame_number)) + list_move(&qh->qh_list_entry, &hsotg->periodic_sched_ready); + else + list_move(&qh->qh_list_entry, &hsotg->periodic_sched_inactive); } /** diff --git a/drivers/staging/dwc2/pci.c b/drivers/staging/dwc2/pci.c index 3d14c8870fca..c291fca5d21f 100644 --- a/drivers/staging/dwc2/pci.c +++ b/drivers/staging/dwc2/pci.c @@ -152,7 +152,7 @@ static int dwc2_driver_probe(struct pci_dev *dev, return retval; } -static DEFINE_PCI_DEVICE_TABLE(dwc2_pci_ids) = { +static const struct pci_device_id dwc2_pci_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG), }, diff --git a/drivers/staging/dwc2/platform.c b/drivers/staging/dwc2/platform.c index 83ca1053bb1d..d01d0d3f2cf0 100644 --- a/drivers/staging/dwc2/platform.c +++ b/drivers/staging/dwc2/platform.c @@ -39,6 +39,7 @@ #include <linux/slab.h> #include <linux/device.h> #include <linux/dma-mapping.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include "core.h" @@ -46,6 +47,34 @@ static const char dwc2_driver_name[] = "dwc2"; +static const struct dwc2_core_params params_bcm2835 = { + .otg_cap = 0, /* HNP/SRP capable */ + .otg_ver = 0, /* 1.3 */ + .dma_enable = 1, + .dma_desc_enable = 0, + .speed = 0, /* High Speed */ + .enable_dynamic_fifo = 1, + .en_multiple_tx_fifo = 1, + .host_rx_fifo_size = 774, /* 774 DWORDs */ + .host_nperio_tx_fifo_size = 256, /* 256 DWORDs */ + .host_perio_tx_fifo_size = 512, /* 512 DWORDs */ + .max_transfer_size = 65535, + .max_packet_count = 511, + .host_channels = 8, + .phy_type = 1, /* UTMI */ + .phy_utmi_width = 8, /* 8 bits */ + .phy_ulpi_ddr = 0, /* Single */ + .phy_ulpi_ext_vbus = 0, + .i2c_enable = 0, + .ulpi_fs_ls = 0, + .host_support_fs_ls_low_power = 0, + .host_ls_low_power_phy_clk = 0, /* 48 MHz */ + .ts_dline = 0, + .reload_ctl = 0, + .ahbcfg = 0x10, + .uframe_sched = 0, +}; + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -66,6 +95,13 @@ static int dwc2_driver_remove(struct platform_device *dev) return 0; } +static const struct of_device_id dwc2_of_match_table[] = { + { .compatible = "brcm,bcm2835-usb", .data = ¶ms_bcm2835 }, + { .compatible = "snps,dwc2", .data = NULL }, + {}, +}; +MODULE_DEVICE_TABLE(of, dwc2_of_match_table); + /** * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg * driver @@ -80,14 +116,22 @@ static int dwc2_driver_remove(struct platform_device *dev) */ static int dwc2_driver_probe(struct platform_device *dev) { + const struct of_device_id *match; + const struct dwc2_core_params *params; + struct dwc2_core_params defparams; struct dwc2_hsotg *hsotg; struct resource *res; int retval; int irq; - struct dwc2_core_params params; - /* Default all params to autodetect */ - dwc2_set_all_params(¶ms, -1); + match = of_match_device(dwc2_of_match_table, &dev->dev); + if (match && match->data) { + params = match->data; + } else { + /* Default all params to autodetect */ + dwc2_set_all_params(&defparams, -1); + params = &defparams; + } hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL); if (!hsotg) @@ -118,7 +162,7 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); - retval = dwc2_hcd_init(hsotg, irq, ¶ms); + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; @@ -127,15 +171,9 @@ static int dwc2_driver_probe(struct platform_device *dev) return retval; } -static const struct of_device_id dwc2_of_match_table[] = { - { .compatible = "snps,dwc2" }, - {}, -}; -MODULE_DEVICE_TABLE(of, dwc2_of_match_table); - static struct platform_driver dwc2_platform_driver = { .driver = { - .name = (char *)dwc2_driver_name, + .name = dwc2_driver_name, .of_match_table = dwc2_of_match_table, }, .probe = dwc2_driver_probe, diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README index 8da96a6d2c92..3befc45fab8a 100644 --- a/drivers/staging/et131x/README +++ b/drivers/staging/et131x/README @@ -13,10 +13,6 @@ TODO: - Implement NAPI support - In et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with kfree_skb(). - Reduce the number of split lines by careful consideration of variable names etc. - - Do this in et131x.c: - struct fbr_lookup *fbr; - fbr = rx_local->fbr[id]; - Then replace all the instances of "rx_local->fbr[id]" with fbr. Please send patches to: Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index ab8b29d2cb26..fdb19df0268d 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -968,7 +968,7 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) /* Set up the if mode bits */ cfg2 &= ~ET_MAC_CFG2_IFMODE_MASK; - if (phydev && phydev->speed == SPEED_1000) { + if (phydev->speed == SPEED_1000) { cfg2 |= ET_MAC_CFG2_IFMODE_1000; /* Phy mode bit */ ifctrl &= ~ET_MAC_IFCTRL_PHYMODE; @@ -999,11 +999,11 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) cfg2 &= ~ET_MAC_CFG2_IFMODE_FULL_DPLX; /* Turn on duplex if needed */ - if (phydev && phydev->duplex == DUPLEX_FULL) + if (phydev->duplex == DUPLEX_FULL) cfg2 |= ET_MAC_CFG2_IFMODE_FULL_DPLX; ifctrl &= ~ET_MAC_IFCTRL_GHDMODE; - if (phydev && phydev->duplex == DUPLEX_HALF) + if (phydev->duplex == DUPLEX_HALF) ifctrl |= ET_MAC_IFCTRL_GHDMODE; writel(ifctrl, &mac->if_ctrl); @@ -1039,9 +1039,7 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) */ static int et1310_in_phy_coma(struct et131x_adapter *adapter) { - u32 pmcsr; - - pmcsr = readl(&adapter->regs->global.pm_csr); + u32 pmcsr = readl(&adapter->regs->global.pm_csr); return ET_PM_PHY_SW_COMA & pmcsr ? 1 : 0; } @@ -1351,8 +1349,6 @@ static void et1310_config_macstat_regs(struct et131x_adapter *adapter) * @addr: the address of the transceiver * @reg: the register to read * @value: pointer to a 16-bit value in which the value will be stored - * - * Returns 0 on success, errno on failure (as defined in errno.h) */ static int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 addr, u8 reg, u16 *value) @@ -1425,10 +1421,6 @@ static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value) * @adapter: pointer to our private adapter structure * @reg: the register to read * @value: 16-bit value to write - * - * FIXME: one caller in netdev still - * - * Return 0 on success, errno on failure (as defined in errno.h) */ static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) { @@ -1494,10 +1486,10 @@ static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) return status; } -/* Still used from _mac for BIT_READ */ -static void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, - u16 action, u16 regnum, u16 bitnum, - u8 *value) +static void et1310_phy_read_mii_bit(struct et131x_adapter *adapter, + u16 regnum, + u16 bitnum, + u8 *value) { u16 reg; u16 mask = 1 << bitnum; @@ -1505,22 +1497,7 @@ static void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, /* Read the requested register */ et131x_mii_read(adapter, regnum, ®); - switch (action) { - case TRUEPHY_BIT_READ: - *value = (reg & mask) >> bitnum; - break; - - case TRUEPHY_BIT_SET: - et131x_mii_write(adapter, regnum, reg | mask); - break; - - case TRUEPHY_BIT_CLEAR: - et131x_mii_write(adapter, regnum, reg & ~mask); - break; - - default: - break; - } + *value = (reg & mask) >> bitnum; } static void et1310_config_flow_control(struct et131x_adapter *adapter) @@ -1532,27 +1509,19 @@ static void et1310_config_flow_control(struct et131x_adapter *adapter) } else { char remote_pause, remote_async_pause; - et1310_phy_access_mii_bit(adapter, - TRUEPHY_BIT_READ, 5, 10, &remote_pause); - et1310_phy_access_mii_bit(adapter, - TRUEPHY_BIT_READ, 5, 11, - &remote_async_pause); + et1310_phy_read_mii_bit(adapter, 5, 10, &remote_pause); + et1310_phy_read_mii_bit(adapter, 5, 11, &remote_async_pause); - if ((remote_pause == TRUEPHY_BIT_SET) && - (remote_async_pause == TRUEPHY_BIT_SET)) { + if (remote_pause && remote_async_pause) { adapter->flowcontrol = adapter->wanted_flow; - } else if ((remote_pause == TRUEPHY_BIT_SET) && - (remote_async_pause == TRUEPHY_BIT_CLEAR)) { + } else if (remote_pause && !remote_async_pause) { if (adapter->wanted_flow == FLOW_BOTH) adapter->flowcontrol = FLOW_BOTH; else adapter->flowcontrol = FLOW_NONE; - } else if ((remote_pause == TRUEPHY_BIT_CLEAR) && - (remote_async_pause == TRUEPHY_BIT_CLEAR)) { + } else if (!remote_pause && !remote_async_pause) { adapter->flowcontrol = FLOW_NONE; - } else {/* if (remote_pause == TRUEPHY_CLEAR_BIT && - * remote_async_pause == TRUEPHY_SET_BIT) - */ + } else { if (adapter->wanted_flow == FLOW_BOTH) adapter->flowcontrol = FLOW_RXONLY; else @@ -1561,9 +1530,7 @@ static void et1310_config_flow_control(struct et131x_adapter *adapter) } } -/* et1310_update_macstat_host_counters - Update the local copy of the statistics - * @adapter: pointer to the adapter structure - */ +/* et1310_update_macstat_host_counters - Update local copy of the statistics */ static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) { struct ce_stats *stats = &adapter->stats; @@ -1589,7 +1556,6 @@ static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) } /* et1310_handle_macstat_interrupt - * @adapter: pointer to the adapter structure * * One of the MACSTAT counters has wrapped. Update the local copy of * the statistics held in the adapter structure, checking the "wrap" @@ -1679,7 +1645,7 @@ static int et131x_mdio_reset(struct mii_bus *bus) return 0; } -/* et1310_phy_power_down - PHY power control +/* et1310_phy_power_switch - PHY power control * @adapter: device to control * @down: true for off/false for back on * @@ -1688,7 +1654,7 @@ static int et131x_mdio_reset(struct mii_bus *bus) * Can't you see that this code processed * Phy power, phy power.. */ -static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) +static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) { u16 data; @@ -1699,10 +1665,7 @@ static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) et131x_mii_write(adapter, MII_BMCR, data); } -/* et131x_xcvr_init - Init the phy if we are setting it into force mode - * @adapter: pointer to our private adapter structure - * - */ +/* et131x_xcvr_init - Init the phy if we are setting it into force mode */ static void et131x_xcvr_init(struct et131x_adapter *adapter) { u16 lcr2; @@ -1731,7 +1694,6 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) } /* et131x_configure_global_regs - configure JAGCore global regs - * @adapter: pointer to our adapter structure * * Used to configure the global registers on the JAGCore */ @@ -1776,9 +1738,7 @@ static void et131x_configure_global_regs(struct et131x_adapter *adapter) writel(0, ®s->watchdog_timer); } -/* et131x_config_rx_dma_regs - Start of Rx_DMA init sequence - * @adapter: pointer to our adapter structure - */ +/* et131x_config_rx_dma_regs - Start of Rx_DMA init sequence */ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) { struct rxdma_regs __iomem *rx_dma = &adapter->regs->rxdma; @@ -1821,6 +1781,7 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) u32 __iomem *min_des; u32 __iomem *base_hi; u32 __iomem *base_lo; + struct fbr_lookup *fbr = rx_local->fbr[id]; if (id == 0) { num_des = &rx_dma->fbr0_num_des; @@ -1837,12 +1798,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) } /* Now's the best time to initialize FBR contents */ - fbr_entry = - (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr; - for (entry = 0; - entry < rx_local->fbr[id]->num_entries; entry++) { - fbr_entry->addr_hi = rx_local->fbr[id]->bus_high[entry]; - fbr_entry->addr_lo = rx_local->fbr[id]->bus_low[entry]; + fbr_entry = fbr->ring_virtaddr; + for (entry = 0; entry < fbr->num_entries; entry++) { + fbr_entry->addr_hi = fbr->bus_high[entry]; + fbr_entry->addr_lo = fbr->bus_low[entry]; fbr_entry->word2 = entry; fbr_entry++; } @@ -1850,19 +1809,16 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Set the address and parameters of Free buffer ring 1 and 0 * into the 1310's registers */ - writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr), - base_hi); - writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr), - base_lo); - writel(rx_local->fbr[id]->num_entries - 1, num_des); + writel(upper_32_bits(fbr->ring_physaddr), base_hi); + writel(lower_32_bits(fbr->ring_physaddr), base_lo); + writel(fbr->num_entries - 1, num_des); writel(ET_DMA10_WRAP, full_offset); /* This variable tracks the free buffer ring 1 full position, * so it has to match the above. */ - rx_local->fbr[id]->local_full = ET_DMA10_WRAP; - writel(((rx_local->fbr[id]->num_entries * - LO_MARK_PERCENT_FOR_RX) / 100) - 1, + fbr->local_full = ET_DMA10_WRAP; + writel(((fbr->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, min_des); } @@ -1884,7 +1840,6 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) } /* et131x_config_tx_dma_regs - Set up the tx dma section of the JAGCore. - * @adapter: pointer to our private adapter structure * * Configure the transmit engine with the ring buffers we have created * and prepare it for use. @@ -1914,11 +1869,7 @@ static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter) adapter->tx_ring.send_idx = 0; } -/* et131x_adapter_setup - Set the adapter up as per cassini+ documentation - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_adapter_setup - Set the adapter up as per cassini+ documentation */ static void et131x_adapter_setup(struct et131x_adapter *adapter) { /* Configure the JAGCore */ @@ -1938,13 +1889,11 @@ static void et131x_adapter_setup(struct et131x_adapter *adapter) et1310_config_macstat_regs(adapter); - et1310_phy_power_down(adapter, 0); + et1310_phy_power_switch(adapter, 0); et131x_xcvr_init(adapter); } -/* et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 - * @adapter: pointer to our private adapter structure - */ +/* et131x_soft_reset - Issue soft reset to the hardware, complete for ET1310 */ static void et131x_soft_reset(struct et131x_adapter *adapter) { u32 reg; @@ -1965,7 +1914,6 @@ static void et131x_soft_reset(struct et131x_adapter *adapter) } /* et131x_enable_interrupts - enable interrupt - * @adapter: et131x device * * Enable the appropriate interrupts on the ET131x according to our * configuration @@ -1976,7 +1924,7 @@ static void et131x_enable_interrupts(struct et131x_adapter *adapter) /* Enable all global interrupts */ if (adapter->flowcontrol == FLOW_TXONLY || - adapter->flowcontrol == FLOW_BOTH) + adapter->flowcontrol == FLOW_BOTH) mask = INT_MASK_ENABLE; else mask = INT_MASK_ENABLE_NO_FLOW; @@ -1985,7 +1933,6 @@ static void et131x_enable_interrupts(struct et131x_adapter *adapter) } /* et131x_disable_interrupts - interrupt disable - * @adapter: et131x device * * Block all interrupts from the et131x device at the device itself */ @@ -1995,9 +1942,7 @@ static void et131x_disable_interrupts(struct et131x_adapter *adapter) writel(INT_MASK_DISABLE, &adapter->regs->global.int_mask); } -/* et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 - * @adapter: pointer to our adapter structure - */ +/* et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 */ static void et131x_tx_dma_disable(struct et131x_adapter *adapter) { /* Setup the tramsmit dma configuration register */ @@ -2005,9 +1950,7 @@ static void et131x_tx_dma_disable(struct et131x_adapter *adapter) &adapter->regs->txdma.csr); } -/* et131x_enable_txrx - Enable tx/rx queues - * @netdev: device to be enabled - */ +/* et131x_enable_txrx - Enable tx/rx queues */ static void et131x_enable_txrx(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -2024,9 +1967,7 @@ static void et131x_enable_txrx(struct net_device *netdev) netif_start_queue(netdev); } -/* et131x_disable_txrx - Disable tx/rx queues - * @netdev: device to be disabled - */ +/* et131x_disable_txrx - Disable tx/rx queues */ static void et131x_disable_txrx(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -2042,9 +1983,7 @@ static void et131x_disable_txrx(struct net_device *netdev) et131x_disable_interrupts(adapter); } -/* et131x_init_send - Initialize send data structures - * @adapter: pointer to our private adapter structure - */ +/* et131x_init_send - Initialize send data structures */ static void et131x_init_send(struct et131x_adapter *adapter) { struct tcb *tcb; @@ -2076,7 +2015,6 @@ static void et131x_init_send(struct et131x_adapter *adapter) } /* et1310_enable_phy_coma - called when network cable is unplugged - * @adapter: pointer to our adapter structure * * driver receive an phy status change interrupt while in D0 and check that * phy_status is down. @@ -2104,11 +2042,6 @@ static void et1310_enable_phy_coma(struct et131x_adapter *adapter) /* Save the GbE PHY speed and duplex modes. Need to restore this * when cable is plugged back in */ - /* TODO - when PM is re-enabled, check if we need to - * perform a similar task as this - - * adapter->pdown_speed = adapter->ai_force_speed; - * adapter->pdown_duplex = adapter->ai_force_duplex; - */ /* Stop sending packets. */ spin_lock_irqsave(&adapter->send_hw_lock, flags); @@ -2128,9 +2061,7 @@ static void et1310_enable_phy_coma(struct et131x_adapter *adapter) writel(pmcsr, &adapter->regs->global.pm_csr); } -/* et1310_disable_phy_coma - Disable the Phy Coma Mode - * @adapter: pointer to our adapter structure - */ +/* et1310_disable_phy_coma - Disable the Phy Coma Mode */ static void et1310_disable_phy_coma(struct et131x_adapter *adapter) { u32 pmcsr; @@ -2145,11 +2076,6 @@ static void et1310_disable_phy_coma(struct et131x_adapter *adapter) /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY */ - /* TODO - when PM is re-enabled, check if we need to - * perform a similar task as this - - * adapter->ai_force_speed = adapter->pdown_speed; - * adapter->ai_force_duplex = adapter->pdown_duplex; - */ /* Re-initialize the send structures */ et131x_init_send(adapter); @@ -2183,15 +2109,12 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) tmp_free_buff_ring ^= ET_DMA10_WRAP; } /* For the 1023 case */ - tmp_free_buff_ring &= (ET_DMA10_MASK|ET_DMA10_WRAP); + tmp_free_buff_ring &= (ET_DMA10_MASK | ET_DMA10_WRAP); *free_buff_ring = tmp_free_buff_ring; return tmp_free_buff_ring; } /* et131x_rx_dma_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h) * * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required, * and the Packet Status Ring. @@ -2204,6 +2127,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) u32 pktstat_ringsize; u32 fbr_chunksize; struct rx_ring *rx_ring; + struct fbr_lookup *fbr; /* Setup some convenience pointers */ rx_ring = &adapter->rx_ring; @@ -2247,20 +2171,18 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->fbr[1]->num_entries = 128; } - adapter->rx_ring.psr_num_entries = - adapter->rx_ring.fbr[0]->num_entries + - adapter->rx_ring.fbr[1]->num_entries; + rx_ring->psr_num_entries = rx_ring->fbr[0]->num_entries + + rx_ring->fbr[1]->num_entries; for (id = 0; id < NUM_FBRS; id++) { + fbr = rx_ring->fbr[id]; /* Allocate an area of memory for Free Buffer Ring */ - bufsize = - (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries); - rx_ring->fbr[id]->ring_virtaddr = - dma_alloc_coherent(&adapter->pdev->dev, - bufsize, - &rx_ring->fbr[id]->ring_physaddr, - GFP_KERNEL); - if (!rx_ring->fbr[id]->ring_virtaddr) { + bufsize = sizeof(struct fbr_desc) * fbr->num_entries; + fbr->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, + bufsize, + &fbr->ring_physaddr, + GFP_KERNEL); + if (!fbr->ring_virtaddr) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Free Buffer Ring %d\n", id); return -ENOMEM; @@ -2268,25 +2190,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) } for (id = 0; id < NUM_FBRS; id++) { - fbr_chunksize = (FBR_CHUNKS * rx_ring->fbr[id]->buffsize); + fbr = rx_ring->fbr[id]; + fbr_chunksize = (FBR_CHUNKS * fbr->buffsize); - for (i = 0; - i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { + for (i = 0; i < fbr->num_entries / FBR_CHUNKS; i++) { dma_addr_t fbr_tmp_physaddr; - rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( + fbr->mem_virtaddrs[i] = dma_alloc_coherent( &adapter->pdev->dev, fbr_chunksize, - &rx_ring->fbr[id]->mem_physaddrs[i], + &fbr->mem_physaddrs[i], GFP_KERNEL); - if (!rx_ring->fbr[id]->mem_virtaddrs[i]) { + if (!fbr->mem_virtaddrs[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - fbr_tmp_physaddr = rx_ring->fbr[id]->mem_physaddrs[i]; + fbr_tmp_physaddr = fbr->mem_physaddrs[i]; for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; @@ -2294,26 +2216,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* Save the Virtual address of this index for * quick access later */ - rx_ring->fbr[id]->virt[index] = - (u8 *) rx_ring->fbr[id]->mem_virtaddrs[i] + - (j * rx_ring->fbr[id]->buffsize); + fbr->virt[index] = (u8 *)fbr->mem_virtaddrs[i] + + (j * fbr->buffsize); /* now store the physical address in the * descriptor so the device can access it */ - rx_ring->fbr[id]->bus_high[index] = + fbr->bus_high[index] = upper_32_bits(fbr_tmp_physaddr); - rx_ring->fbr[id]->bus_low[index] = + fbr->bus_low[index] = lower_32_bits(fbr_tmp_physaddr); - fbr_tmp_physaddr += rx_ring->fbr[id]->buffsize; + fbr_tmp_physaddr += fbr->buffsize; } } } /* Allocate an area of memory for FIFO of Packet Status ring entries */ pktstat_ringsize = - sizeof(struct pkt_stat_desc) * adapter->rx_ring.psr_num_entries; + sizeof(struct pkt_stat_desc) * rx_ring->psr_num_entries; rx_ring->ps_ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, pktstat_ringsize, @@ -2325,8 +2246,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Packet Status Ring\n"); return -ENOMEM; } - pr_info("Packet Status Ring %llx\n", - (unsigned long long) rx_ring->ps_ring_physaddr); /* NOTE : dma_alloc_coherent(), used above to alloc DMA regions, * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses @@ -2345,7 +2264,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } rx_ring->num_rfd = NIC_DEFAULT_NUM_RFD; - pr_info("PRS %llx\n", (unsigned long long)rx_ring->rx_status_bus); /* The RFDs are going to be put on lists later on, so initialize the * lists now. @@ -2354,9 +2272,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return 0; } -/* et131x_rx_dma_memory_free - Free all memory allocated within this module. - * @adapter: pointer to our private adapter structure - */ +/* et131x_rx_dma_memory_free - Free all memory allocated within this module */ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { u8 id; @@ -2365,6 +2281,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) u32 pktstat_ringsize; struct rfd *rfd; struct rx_ring *rx_ring; + struct fbr_lookup *fbr; /* Setup some convenience pointers */ rx_ring = &adapter->rx_ring; @@ -2373,8 +2290,8 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) WARN_ON(rx_ring->num_ready_recv != rx_ring->num_rfd); while (!list_empty(&rx_ring->recv_list)) { - rfd = (struct rfd *) list_entry(rx_ring->recv_list.next, - struct rfd, list_node); + rfd = list_entry(rx_ring->recv_list.next, + struct rfd, list_node); list_del(&rfd->list_node); rfd->skb = NULL; @@ -2383,34 +2300,35 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Free Buffer Rings */ for (id = 0; id < NUM_FBRS; id++) { - if (!rx_ring->fbr[id]->ring_virtaddr) + fbr = rx_ring->fbr[id]; + + if (!fbr->ring_virtaddr) continue; /* First the packet memory */ for (index = 0; - index < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); + index < fbr->num_entries / FBR_CHUNKS; index++) { - if (rx_ring->fbr[id]->mem_virtaddrs[index]) { - bufsize = - rx_ring->fbr[id]->buffsize * FBR_CHUNKS; + if (fbr->mem_virtaddrs[index]) { + bufsize = fbr->buffsize * FBR_CHUNKS; dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[id]->mem_virtaddrs[index], - rx_ring->fbr[id]->mem_physaddrs[index]); + bufsize, + fbr->mem_virtaddrs[index], + fbr->mem_physaddrs[index]); - rx_ring->fbr[id]->mem_virtaddrs[index] = NULL; + fbr->mem_virtaddrs[index] = NULL; } } - bufsize = - sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries; + bufsize = sizeof(struct fbr_desc) * fbr->num_entries; - dma_free_coherent(&adapter->pdev->dev, bufsize, - rx_ring->fbr[id]->ring_virtaddr, - rx_ring->fbr[id]->ring_physaddr); + dma_free_coherent(&adapter->pdev->dev, + bufsize, + fbr->ring_virtaddr, + fbr->ring_physaddr); - rx_ring->fbr[id]->ring_virtaddr = NULL; + fbr->ring_virtaddr = NULL; } /* Free Packet Status Ring */ @@ -2441,16 +2359,11 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->num_ready_recv = 0; } -/* et131x_init_recv - Initialize receive data structures. - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h) - */ +/* et131x_init_recv - Initialize receive data structures */ static int et131x_init_recv(struct et131x_adapter *adapter) { struct rfd *rfd; u32 rfdct; - u32 numrfd = 0; struct rx_ring *rx_ring; /* Setup some convenience pointers */ @@ -2467,24 +2380,18 @@ static int et131x_init_recv(struct et131x_adapter *adapter) /* Add this RFD to the recv_list */ list_add_tail(&rfd->list_node, &rx_ring->recv_list); - /* Increment both the available RFD's, and the total RFD's. */ + /* Increment the available RFD's */ rx_ring->num_ready_recv++; - numrfd++; } return 0; } -/* et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate. - * @adapter: pointer to our adapter structure - */ +/* et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate */ static void et131x_set_rx_dma_timer(struct et131x_adapter *adapter) { struct phy_device *phydev = adapter->phydev; - if (!phydev) - return; - /* For version B silicon, we do not use the RxDMA timer for 10 and 100 * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. */ @@ -2505,11 +2412,13 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) u16 buff_index = rfd->bufferindex; u8 ring_index = rfd->ringindex; unsigned long flags; + struct fbr_lookup *fbr = rx_local->fbr[ring_index]; /* We don't use any of the OOB data besides status. Otherwise, we * need to clean up OOB data */ - if (buff_index < rx_local->fbr[ring_index]->num_entries) { + if (buff_index < fbr->num_entries) { + u32 free_buff_ring; u32 __iomem *offset; struct fbr_desc *next; @@ -2520,22 +2429,20 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) else offset = &rx_dma->fbr1_full_offset; - next = (struct fbr_desc *) - (rx_local->fbr[ring_index]->ring_virtaddr) + - INDEX10(rx_local->fbr[ring_index]->local_full); + next = (struct fbr_desc *)(fbr->ring_virtaddr) + + INDEX10(fbr->local_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - next->addr_hi = rx_local->fbr[ring_index]->bus_high[buff_index]; - next->addr_lo = rx_local->fbr[ring_index]->bus_low[buff_index]; + next->addr_hi = fbr->bus_high[buff_index]; + next->addr_lo = fbr->bus_low[buff_index]; next->word2 = buff_index; - writel(bump_free_buff_ring( - &rx_local->fbr[ring_index]->local_full, - rx_local->fbr[ring_index]->num_entries - 1), - offset); + free_buff_ring = bump_free_buff_ring(&fbr->local_full, + fbr->num_entries - 1); + writel(free_buff_ring, offset); spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { @@ -2555,7 +2462,6 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) } /* nic_rx_pkts - Checks the hardware for available packets - * @adapter: pointer to our adapter * * Returns rfd, a pointer to our MPRFD. * @@ -2580,6 +2486,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) u32 word0; u32 word1; struct sk_buff *skb; + struct fbr_lookup *fbr; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet @@ -2601,6 +2508,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) */ len = psr->word1 & 0xFFFF; ring_index = (psr->word1 >> 26) & 0x03; + fbr = rx_local->fbr[ring_index]; buff_index = (psr->word1 >> 16) & 0x3FF; word0 = psr->word0; @@ -2616,8 +2524,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset); - if (ring_index > 1 || - buff_index > rx_local->fbr[ring_index]->num_entries - 1) { + if (ring_index > 1 || buff_index > fbr->num_entries - 1) { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates length of %d and/or bad bi(%d)\n", @@ -2629,7 +2536,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) spin_lock_irqsave(&adapter->rcv_lock, flags); element = rx_local->recv_list.next; - rfd = (struct rfd *) list_entry(element, struct rfd, list_node); + rfd = list_entry(element, struct rfd, list_node); if (!rfd) { spin_unlock_irqrestore(&adapter->rcv_lock, flags); @@ -2670,7 +2577,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) && !(adapter->packet_filter & ET131X_PACKET_TYPE_PROMISCUOUS) && !(adapter->packet_filter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - buf = rx_local->fbr[ring_index]->virt[buff_index]; + buf = fbr->virt[buff_index]; /* Loop through our list to see if the destination * address of this packet matches one in our list. @@ -2708,7 +2615,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) adapter->stats.unicast_pkts_rcvd++; } - if (len == 0) { + if (!len) { rfd->len = 0; goto out; } @@ -2723,9 +2630,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) adapter->net_stats.rx_bytes += rfd->len; - memcpy(skb_put(skb, rfd->len), - rx_local->fbr[ring_index]->virt[buff_index], - rfd->len); + memcpy(skb_put(skb, rfd->len), fbr->virt[buff_index], rfd->len); skb->protocol = eth_type_trans(skb, adapter->netdev); skb->ip_summed = CHECKSUM_NONE; @@ -2737,7 +2642,6 @@ out: } /* et131x_handle_recv_interrupt - Interrupt handler for receive processing - * @adapter: pointer to our adapter * * Assumption, Rcv spinlock has been acquired. */ @@ -2790,9 +2694,6 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter) } /* et131x_tx_dma_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h). * * Allocates memory that will be visible both to the device and to the CPU. * The OS will pass us packets, pointers to which we will insert in the Tx @@ -2812,11 +2713,10 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); - tx_ring->tx_desc_ring = - (struct tx_desc *) dma_alloc_coherent(&adapter->pdev->dev, - desc_size, - &tx_ring->tx_desc_ring_pa, - GFP_KERNEL); + tx_ring->tx_desc_ring = dma_alloc_coherent(&adapter->pdev->dev, + desc_size, + &tx_ring->tx_desc_ring_pa, + GFP_KERNEL); if (!adapter->tx_ring.tx_desc_ring) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx Ring\n"); @@ -2843,11 +2743,7 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) return 0; } -/* et131x_tx_dma_memory_free - Free all memory allocated within this module - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h). - */ +/* et131x_tx_dma_memory_free - Free all memory allocated within this module */ static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) { int desc_size = 0; @@ -2878,8 +2774,6 @@ static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) /* nic_send_packet - NIC specific send handler for version B silicon. * @adapter: pointer to our adapter * @tcb: pointer to struct tcb - * - * Returns 0 or errno. */ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { @@ -3056,10 +2950,6 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) } /* send_packet - Do the work to send a packet - * @skb: the packet(s) to send - * @adapter: a pointer to the device's private adapter structure - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only. * * Assumption: Send spinlock has been acquired */ @@ -3125,12 +3015,7 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) return 0; } -/* et131x_send_packets - This function is called by the OS to send packets - * @skb: the packet(s) to send - * @netdev:device on which to TX the above packet(s) - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only - */ +/* et131x_send_packets - This function is called by the OS to send packets */ static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) { int status = 0; @@ -3204,9 +3089,8 @@ static inline void free_send_packet(struct et131x_adapter *adapter, * they point to */ do { - desc = (struct tx_desc *) - (adapter->tx_ring.tx_desc_ring + - INDEX10(tcb->index_start)); + desc = adapter->tx_ring.tx_desc_ring + + INDEX10(tcb->index_start); dma_addr = desc->addr_lo; dma_addr |= (u64)desc->addr_hi << 32; @@ -3247,7 +3131,6 @@ static inline void free_send_packet(struct et131x_adapter *adapter, } /* et131x_free_busy_send_packets - Free and complete the stopped active sends - * @adapter: pointer to our adapter * * Assumption - Send spinlock has been acquired */ @@ -3290,7 +3173,6 @@ static void et131x_free_busy_send_packets(struct et131x_adapter *adapter) } /* et131x_handle_send_interrupt - Interrupt handler for sending processing - * @adapter: pointer to our adapter * * Re-claim the send resources, complete sends and get more to send from * the send wait queue. @@ -3548,9 +3430,7 @@ static struct ethtool_ops et131x_ethtool_ops = { .get_link = ethtool_op_get_link, }; -/* et131x_hwaddr_init - set up the MAC Address on the ET1310 - * @adapter: pointer to our private adapter structure - */ +/* et131x_hwaddr_init - set up the MAC Address on the ET1310 */ static void et131x_hwaddr_init(struct et131x_adapter *adapter) { /* If have our default mac from init and no mac address from @@ -3580,14 +3460,12 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter) } /* et131x_pci_init - initial PCI setup - * @adapter: pointer to our private adapter structure - * @pdev: our PCI device * * Perform the initial setup of PCI registers and if possible initialise * the MAC address. At this point the I/O registers have yet to be mapped */ static int et131x_pci_init(struct et131x_adapter *adapter, - struct pci_dev *pdev) + struct pci_dev *pdev) { u16 max_payload; int i, rc; @@ -3704,21 +3582,14 @@ static void et131x_error_timer_handler(unsigned long data) mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000); } -/* et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx - * @adapter: pointer to our private adapter structure - */ +/* et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx */ static void et131x_adapter_memory_free(struct et131x_adapter *adapter) { - /* Free DMA memory */ et131x_tx_dma_memory_free(adapter); et131x_rx_dma_memory_free(adapter); } /* et131x_adapter_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h). - * * Allocate all the memory blocks for send, receive and others. */ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) @@ -3727,14 +3598,14 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) /* Allocate memory for the Tx Ring */ status = et131x_tx_dma_memory_alloc(adapter); - if (status != 0) { + if (status) { dev_err(&adapter->pdev->dev, "et131x_tx_dma_memory_alloc FAILED\n"); return status; } /* Receive buffer memory allocation */ status = et131x_rx_dma_memory_alloc(adapter); - if (status != 0) { + if (status) { dev_err(&adapter->pdev->dev, "et131x_rx_dma_memory_alloc FAILED\n"); et131x_tx_dma_memory_free(adapter); @@ -3744,8 +3615,7 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) /* Init receive data structures */ status = et131x_init_recv(adapter); if (status) { - dev_err(&adapter->pdev->dev, - "et131x_init_recv FAILED\n"); + dev_err(&adapter->pdev->dev, "et131x_init_recv FAILED\n"); et131x_adapter_memory_free(adapter); } return status; @@ -3756,97 +3626,89 @@ static void et131x_adjust_link(struct net_device *netdev) struct et131x_adapter *adapter = netdev_priv(netdev); struct phy_device *phydev = adapter->phydev; - if (phydev && phydev->link != adapter->link) { - /* Check to see if we are in coma mode and if - * so, disable it because we will not be able - * to read PHY values until we are out. - */ - if (et1310_in_phy_coma(adapter)) - et1310_disable_phy_coma(adapter); - - adapter->link = phydev->link; - phy_print_status(phydev); - - if (phydev->link) { - adapter->boot_coma = 20; - if (phydev && phydev->speed == SPEED_10) { - /* NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(adapter->hTruePhy, 0)== - * EMI_TRUEPHY_A13O) { - */ - u16 register18; - - et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, - ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, - register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, - register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); - } + if (!phydev) + return; + if (phydev->link == adapter->link) + return; + + /* Check to see if we are in coma mode and if + * so, disable it because we will not be able + * to read PHY values until we are out. + */ + if (et1310_in_phy_coma(adapter)) + et1310_disable_phy_coma(adapter); - et1310_config_flow_control(adapter); + adapter->link = phydev->link; + phy_print_status(phydev); - if (phydev && phydev->speed == SPEED_1000 && - adapter->registry_jumbo_packet > 2048) { - u16 reg; + if (phydev->link) { + adapter->boot_coma = 20; + if (phydev->speed == SPEED_10) { + u16 register18; + + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, + ®ister18); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18 | 0x4); + et131x_mii_write(adapter, PHY_INDEX_REG, + register18 | 0x8402); + et131x_mii_write(adapter, PHY_DATA_REG, + register18 | 511); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18); + } - et131x_mii_read(adapter, PHY_CONFIG, ®); - reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; - reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; - et131x_mii_write(adapter, PHY_CONFIG, reg); - } + et1310_config_flow_control(adapter); - et131x_set_rx_dma_timer(adapter); - et1310_config_mac_regs2(adapter); - } else { - adapter->boot_coma = 0; + if (phydev->speed == SPEED_1000 && + adapter->registry_jumbo_packet > 2048) { + u16 reg; - if (phydev->speed == SPEED_10) { - /* NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(adapter->hTruePhy, 0) == - * EMI_TRUEPHY_A13O) - */ - u16 register18; - - et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, - ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, - register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, - register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); - } + et131x_mii_read(adapter, PHY_CONFIG, ®); + reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; + reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; + et131x_mii_write(adapter, PHY_CONFIG, reg); + } - /* Free the packets being actively sent & stopped */ - et131x_free_busy_send_packets(adapter); + et131x_set_rx_dma_timer(adapter); + et1310_config_mac_regs2(adapter); + } else { + adapter->boot_coma = 0; + + if (phydev->speed == SPEED_10) { + u16 register18; + + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, + ®ister18); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18 | 0x4); + et131x_mii_write(adapter, PHY_INDEX_REG, + register18 | 0x8402); + et131x_mii_write(adapter, PHY_DATA_REG, + register18 | 511); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18); + } - /* Re-initialize the send structures */ - et131x_init_send(adapter); + /* Free the packets being actively sent & stopped */ + et131x_free_busy_send_packets(adapter); - /* Bring the device back to the state it was during - * init prior to autonegotiation being complete. This - * way, when we get the auto-neg complete interrupt, - * we can complete init by calling config_mac_regs2. - */ - et131x_soft_reset(adapter); + /* Re-initialize the send structures */ + et131x_init_send(adapter); - /* Setup ET1310 as per the documentation */ - et131x_adapter_setup(adapter); + /* Bring the device back to the state it was during + * init prior to autonegotiation being complete. This + * way, when we get the auto-neg complete interrupt, + * we can complete init by calling config_mac_regs2. + */ + et131x_soft_reset(adapter); - /* perform reset of tx/rx */ - et131x_disable_txrx(netdev); - et131x_enable_txrx(netdev); - } + /* Setup ET1310 as per the documentation */ + et131x_adapter_setup(adapter); + /* perform reset of tx/rx */ + et131x_disable_txrx(netdev); + et131x_enable_txrx(netdev); } } @@ -3883,21 +3745,20 @@ static int et131x_mii_probe(struct net_device *netdev) phydev->advertising = phydev->supported; adapter->phydev = phydev; - dev_info(&adapter->pdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", + dev_info(&adapter->pdev->dev, + "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); return 0; } /* et131x_adapter_init - * @adapter: pointer to the private adapter struct - * @pdev: pointer to the PCI device * * Initialize the data structures for the et131x_adapter object and link * them together with the platform provided device structures. */ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, - struct pci_dev *pdev) + struct pci_dev *pdev) { static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }; @@ -3925,7 +3786,6 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, } /* et131x_pci_remove - * @pdev: a pointer to the device's pci_dev structure * * Registered in the pci_driver structure, this function is called when the * PCI subsystem detects that a PCI device which matches the information @@ -3952,9 +3812,7 @@ static void et131x_pci_remove(struct pci_dev *pdev) pci_disable_device(pdev); } -/* et131x_up - Bring up a device for use. - * @netdev: device to be opened - */ +/* et131x_up - Bring up a device for use. */ static void et131x_up(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -3963,9 +3821,7 @@ static void et131x_up(struct net_device *netdev) phy_start(adapter->phydev); } -/* et131x_down - Bring down the device - * @netdev: device to be brought down - */ +/* et131x_down - Bring down the device */ static void et131x_down(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4075,7 +3931,7 @@ static irqreturn_t et131x_isr(int irq, void *dev_id) status &= ~ET_INTR_WATCHDOG; } - if (status == 0) { + if (!status) { /* This interrupt has in some way been "handled" by * the ISR. Either it was a spurious Rx interrupt, or * it was a Tx interrupt that has been filtered by @@ -4101,7 +3957,6 @@ out: } /* et131x_isr_handler - The ISR handler - * @p_adapter, a pointer to the device's private adapter structure * * scheduled to run in a deferred context by the ISR. This is where the ISR's * work actually gets done. @@ -4125,17 +3980,15 @@ static void et131x_isr_handler(struct work_struct *work) if (status & ET_INTR_RXDMA_XFR_DONE) et131x_handle_recv_interrupt(adapter); - status &= 0xffffffd7; + status &= ~(ET_INTR_TXDMA_ERR | ET_INTR_RXDMA_XFR_DONE); if (!status) goto out; /* Handle the TXDMA Error interrupt */ if (status & ET_INTR_TXDMA_ERR) { - u32 txdma_err; - /* Following read also clears the register (COR) */ - txdma_err = readl(&iomem->txdma.tx_dma_error); + u32 txdma_err = readl(&iomem->txdma.tx_dma_error); dev_warn(&adapter->pdev->dev, "TXDMA_ERR interrupt, error = %d\n", @@ -4281,11 +4134,7 @@ out: et131x_enable_interrupts(adapter); } -/* et131x_stats - Return the current device statistics. - * @netdev: device whose stats are being queried - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_stats - Return the current device statistics */ static struct net_device_stats *et131x_stats(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4327,11 +4176,7 @@ static struct net_device_stats *et131x_stats(struct net_device *netdev) return stats; } -/* et131x_open - Open the device for use. - * @netdev: device to be opened - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_open - Open the device for use. */ static int et131x_open(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4360,11 +4205,7 @@ static int et131x_open(struct net_device *netdev) return result; } -/* et131x_close - Close the device - * @netdev: device to be closed - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_close - Close the device */ static int et131x_close(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4382,8 +4223,6 @@ static int et131x_close(struct net_device *netdev) * @netdev: device on which the control request is being made * @reqbuf: a pointer to the IOCTL request buffer * @cmd: the IOCTL command code - * - * Returns 0 on success, errno on failure (as defined in errno.h) */ static int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd) @@ -4400,8 +4239,6 @@ static int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, * @adapter: pointer to our private adapter structure * * FIXME: lot of dups with MAC code - * - * Returns 0 on success, errno on failure */ static int et131x_set_packet_filter(struct et131x_adapter *adapter) { @@ -4460,9 +4297,7 @@ static int et131x_set_packet_filter(struct et131x_adapter *adapter) return status; } -/* et131x_multicast - The handler to configure multicasting on the interface - * @netdev: a pointer to a net_device struct representing the device - */ +/* et131x_multicast - The handler to configure multicasting on the interface */ static void et131x_multicast(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4522,19 +4357,13 @@ static void et131x_multicast(struct net_device *netdev) * NOTE - This block will always update the multicast_list with the * hardware, even if the addresses aren't the same. */ - if (packet_filter != adapter->packet_filter) { - /* Call the device's filter function */ + if (packet_filter != adapter->packet_filter) et131x_set_packet_filter(adapter); - } + spin_unlock_irqrestore(&adapter->lock, flags); } -/* et131x_tx - The handler to tx a packet on the device - * @skb: data to be Tx'd - * @netdev: device on which data is to be Tx'd - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_tx - The handler to tx a packet on the device */ static int et131x_tx(struct sk_buff *skb, struct net_device *netdev) { int status = 0; @@ -4562,7 +4391,6 @@ static int et131x_tx(struct sk_buff *skb, struct net_device *netdev) } /* et131x_tx_timeout - Timeout handler - * @netdev: a pointer to a net_device struct representing the device * * The handler called when a Tx request times out. The timeout period is * specified by the 'tx_timeo" element in the net_device structure (see @@ -4619,12 +4447,7 @@ static void et131x_tx_timeout(struct net_device *netdev) spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); } -/* et131x_change_mtu - The handler called to change the MTU for the device - * @netdev: device whose MTU is to be changed - * @new_mtu: the desired MTU - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_change_mtu - The handler called to change the MTU for the device */ static int et131x_change_mtu(struct net_device *netdev, int new_mtu) { int result = 0; @@ -4669,22 +4492,13 @@ static int et131x_change_mtu(struct net_device *netdev, int new_mtu) return result; } -/* et131x_set_mac_addr - handler to change the MAC address for the device - * @netdev: device whose MAC is to be changed - * @new_mac: the desired MAC address - * - * Returns 0 on success, errno on failure (as defined in errno.h) - * - * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 - */ +/* et131x_set_mac_addr - handler to change the MAC address for the device */ static int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); struct sockaddr *address = new_mac; - /* begin blux */ - if (adapter == NULL) return -ENODEV; @@ -4746,15 +4560,13 @@ static const struct net_device_ops et131x_netdev_ops = { * @pdev: a pointer to the device's pci_dev structure * @ent: this device's entry in the pci_device_id table * - * Returns 0 on success, errno on failure (as defined in errno.h) - * * Registered in the pci_driver structure, this function is called when the * PCI subsystem finds a new PCI device which matches the information * contained in the pci_device_id table. This routine is the equivalent to * a device insertion routine. */ static int et131x_pci_setup(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct net_device *netdev; struct et131x_adapter *adapter; @@ -4930,7 +4742,7 @@ err_disable: goto out; } -static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = { +static const struct pci_device_id et131x_pci_table[] = { { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL}, { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, {0,} diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index bbe78a703a23..2ac6e9980117 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -1668,43 +1668,3 @@ struct address_map { #define LED_100TX_SHIFT 4 /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ - -/* Defines for PHY access routines */ - -/* Define bit operation flags */ -#define TRUEPHY_BIT_CLEAR 0 -#define TRUEPHY_BIT_SET 1 -#define TRUEPHY_BIT_READ 2 - -/* Define read/write operation flags */ -#ifndef TRUEPHY_READ -#define TRUEPHY_READ 0 -#define TRUEPHY_WRITE 1 -#define TRUEPHY_MASK 2 -#endif - -/* Define master/slave configuration values */ -#define TRUEPHY_CFG_SLAVE 0 -#define TRUEPHY_CFG_MASTER 1 - -/* Define MDI/MDI-X settings */ -#define TRUEPHY_MDI 0 -#define TRUEPHY_MDIX 1 -#define TRUEPHY_AUTO_MDI_MDIX 2 - -/* Define 10Base-T link polarities */ -#define TRUEPHY_POLARITY_NORMAL 0 -#define TRUEPHY_POLARITY_INVERTED 1 - -/* Define auto-negotiation results */ -#define TRUEPHY_ANEG_NOT_COMPLETE 0 -#define TRUEPHY_ANEG_COMPLETE 1 -#define TRUEPHY_ANEG_DISABLED 2 - -/* Define duplex advertisement flags */ -#define TRUEPHY_ADV_DUPLEX_NONE 0x00 -#define TRUEPHY_ADV_DUPLEX_FULL 0x01 -#define TRUEPHY_ADV_DUPLEX_HALF 0x02 -#define TRUEPHY_ADV_DUPLEX_BOTH \ - (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) - diff --git a/drivers/staging/ft1000/ft1000-pcmcia/boot.h b/drivers/staging/ft1000/ft1000-pcmcia/boot.h index 9dce54eae1cf..60c015c1c28a 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/boot.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/boot.h @@ -1,158 +1,158 @@ -//--------------------------------------------------------------------------- -// FT1000 driver for Flarion Flash OFDM NIC Device -// -// Copyright (C) 2002 Flarion Technologies, All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) any -// later version. This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. You should have received a copy of the GNU General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - -// Suite 330, Boston, MA 02111-1307, USA. -//--------------------------------------------------------------------------- -// -// File: boot.h -// -// Description: boatloader -// -// History: -// 1/11/05 Whc Ported to Linux. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + --------------------------------------------------------------------------- + + File: boot.h + + Description: boatloader + + History: + 1/11/05 Whc Ported to Linux. + +---------------------------------------------------------------------------*/ #ifndef _BOOTH_ #define _BOOTH_ -// Official bootloader -static unsigned char bootimage [] = { -0x00,0x00,0x01,0x5E,0x00,0x00 -,0x00,0x00,0x00,0x00,0x02,0xD7 -,0x00,0x00,0x01,0x5E,0x46,0xB3 -,0xE6,0x02,0x00,0x98,0xE6,0x8C -,0x00,0x98,0xFB,0x92,0xFF,0xFF -,0x98,0xFB,0x94,0xFF,0xFF,0x98 -,0xFB,0x06,0x08,0x00,0x98,0xFB -,0x96,0x84,0x00,0x98,0xFB,0x08 -,0x1C,0x00,0x98,0xFB,0x51,0x25 -,0x10,0x1C,0x00,0xE6,0x51,0x01 -,0x07,0xFD,0x4C,0xFF,0x20,0xF5 -,0x51,0x02,0x20,0x08,0x00,0x4C -,0xFF,0x20,0x3C,0x00,0xC0,0x64 -,0x98,0xC0,0x66,0x98,0xC0,0x68 -,0x98,0xC0,0x6A,0x98,0xC0,0x6C -,0x98,0x90,0x08,0x90,0x09,0x90 -,0x0A,0x90,0x0B,0x90,0x0C,0x90 -,0x0D,0x90,0x0E,0x90,0x0F,0x90 -,0x04,0x90,0x06,0xFB,0x51,0x22 -,0x16,0x08,0x03,0xFB,0x51,0x52 -,0x16,0x08,0x04,0xFB,0x51,0x24 -,0x2B,0x08,0x06,0xFB,0x51,0x54 -,0x2B,0x08,0x07,0xFB,0x51,0x24 -,0x2B,0x08,0x09,0xFB,0x51,0x54 -,0x2B,0x08,0x0A,0xFB,0x51,0x12 -,0x16,0x08,0x0C,0xFB,0x51,0x52 -,0x16,0x08,0x0D,0x78,0x00,0x00 -,0x00,0x16,0x00,0x00,0xEC,0x31 -,0xAE,0x00,0x00,0x81,0x4C,0x0F -,0xE6,0x43,0xFF,0xEC,0x31,0x4E -,0x00,0x00,0x91,0xEC,0x31,0xAE -,0x00,0x00,0x91,0x4C,0x0F,0xE6 -,0x43,0xFF,0xEC,0x31,0x5E,0x00 -,0x00,0xA1,0xEB,0x31,0x08,0x00 -,0x00,0xA6,0xEB,0x31,0x08,0x00 -,0x00,0xAC,0x3C,0x00,0xEB,0x31 -,0x08,0x00,0x00,0xA8,0x76,0xFE -,0xFE,0x08,0xEB,0x31,0x08,0x20 -,0x00,0x00,0x76,0xFF,0xFF,0x18 -,0xED,0x31,0x08,0x20,0x00,0x00 -,0x26,0x10,0x04,0x10,0xF5,0x3C -,0x01,0x3C,0x00,0x08,0x01,0x12 -,0x3C,0x11,0x3C,0x00,0x08,0x01 -,0x0B,0x08,0x00,0x6D,0xEC,0x31 -,0xAE,0x20,0x00,0x06,0xED,0x4D -,0x08,0x00,0x00,0x67,0x80,0x6F -,0x00,0x01,0x0B,0x6F,0x00,0x02 -,0x2E,0x76,0xEE,0x01,0x48,0x06 -,0x01,0x39,0xED,0x4D,0x18,0x00 -,0x02,0xED,0x4D,0x08,0x00,0x04 -,0x14,0x06,0xA4,0xED,0x31,0x22 -,0x00,0x00,0xAC,0x76,0xEE,0x07 -,0x48,0x6D,0x22,0x01,0x1E,0x08 -,0x01,0x58,0xEB,0x31,0x08,0x00 -,0x00,0xAC,0x06,0xFF,0xBA,0x3C -,0x00,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x30,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x00 -,0x00,0xA2,0x91,0x00,0x9C,0x3C -,0x80,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x20,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x20 -,0x00,0x04,0x42,0x10,0x90,0x08 -,0xEC,0x31,0xAE,0x20,0x00,0x06 -,0xA4,0x41,0x08,0x00,0xB6,0xED -,0x41,0x28,0x7D,0xFF,0xFF,0x22 -,0xB3,0x40,0x98,0x2A,0x32,0xEB -,0x41,0x28,0xB4,0x43,0xFC,0x05 -,0xFF,0xE6,0xA0,0x31,0x20,0x00 -,0x06,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x20,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x20 -,0x00,0x04,0x42,0x10,0x90,0x08 -,0xEC,0x31,0xAE,0x20,0x00,0x06 -,0xA4,0x41,0x08,0x00,0x68,0xED -,0x41,0x28,0x7D,0xFF,0xFF,0x22 -,0xB3,0x40,0x98,0x2A,0x32,0xEB -,0x41,0x28,0xB4,0x43,0xFC,0x05 -,0xFF,0xE6,0x48,0x04,0xEB,0x31 -,0x08,0x20,0x00,0x04,0xEB,0x31 -,0x18,0x20,0x00,0x02,0x3C,0x11 -,0xEB,0x31,0x18,0x20,0x00,0x00 -,0xED,0x31,0x08,0x20,0x00,0x00 -,0x04,0x10,0xF7,0xED,0x31,0x08 -,0x20,0x00,0x02,0x66,0x00,0x6F -,0x00,0x01,0x16,0x76,0xEE,0x06 -,0x48,0x4A,0x1E,0x48,0x04,0xED -,0x31,0x08,0x20,0x00,0x04,0xEB -,0x31,0x08,0x00,0x00,0xA4,0x48 -,0x04,0xED,0x31,0x08,0x20,0x00 -,0x04,0xEB,0x31,0x08,0x00,0x00 -,0xA2,0x48,0x04,0x20,0x20,0x4A -,0x7C,0x46,0x82,0x50,0x05,0x50 -,0x15,0xB5,0x1E,0x98,0xED,0x31 -,0x08,0x00,0x00,0xA8,0x10,0x47 -,0x3B,0x2C,0x01,0xDB,0x40,0x11 -,0x98,0xC1,0x1E,0x98,0x10,0x07 -,0x30,0xF9,0x40,0x07,0x18,0x98 -,0x2A,0x10,0xEB,0x31,0x08,0x00 -,0x00,0xA8,0xA4,0x1E,0x98,0xBB -,0x1E,0x98,0x50,0x14,0x50,0x04 -,0x46,0x83,0x48,0x04,0x02,0x01 -,0x00,0x50,0x05,0x50,0x15,0x10 -,0x87,0x3F,0x90,0x2B,0x18,0x01 -,0x00,0xC0,0x31,0x00,0x00,0xAE -,0xDF,0x41,0x00,0x08,0x00,0x1A -,0x42,0x11,0x67,0x01,0xDF,0x41 -,0x02,0x08,0x00,0x10,0x42,0x11 -,0x62,0x01,0xB4,0x43,0x4A,0x68 -,0x50,0x14,0x50,0x04,0x24,0x10 -,0x48,0x04,0xF2,0x31,0x00,0x01 -,0x00,0x00,0xAE,0xF6,0x31,0x00 -,0x01,0x00,0x00,0xAE,0x62,0xE4 -,0xE5,0x61,0x04,0x48,0x04,0xE5 -,0x63,0x05,0x48,0x04,0x20,0x20 -,0x00,0x00,0x00,0x00 +/* Official bootloader */ +static unsigned char bootimage[] = { + 0x00, 0x00, 0x01, 0x5E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0xD7, + 0x00, 0x00, 0x01, 0x5E, 0x46, 0xB3, + 0xE6, 0x02, 0x00, 0x98, 0xE6, 0x8C, + 0x00, 0x98, 0xFB, 0x92, 0xFF, 0xFF, + 0x98, 0xFB, 0x94, 0xFF, 0xFF, 0x98, + 0xFB, 0x06, 0x08, 0x00, 0x98, 0xFB, + 0x96, 0x84, 0x00, 0x98, 0xFB, 0x08, + 0x1C, 0x00, 0x98, 0xFB, 0x51, 0x25, + 0x10, 0x1C, 0x00, 0xE6, 0x51, 0x01, + 0x07, 0xFD, 0x4C, 0xFF, 0x20, 0xF5, + 0x51, 0x02, 0x20, 0x08, 0x00, 0x4C, + 0xFF, 0x20, 0x3C, 0x00, 0xC0, 0x64, + 0x98, 0xC0, 0x66, 0x98, 0xC0, 0x68, + 0x98, 0xC0, 0x6A, 0x98, 0xC0, 0x6C, + 0x98, 0x90, 0x08, 0x90, 0x09, 0x90, + 0x0A, 0x90, 0x0B, 0x90, 0x0C, 0x90, + 0x0D, 0x90, 0x0E, 0x90, 0x0F, 0x90, + 0x04, 0x90, 0x06, 0xFB, 0x51, 0x22, + 0x16, 0x08, 0x03, 0xFB, 0x51, 0x52, + 0x16, 0x08, 0x04, 0xFB, 0x51, 0x24, + 0x2B, 0x08, 0x06, 0xFB, 0x51, 0x54, + 0x2B, 0x08, 0x07, 0xFB, 0x51, 0x24, + 0x2B, 0x08, 0x09, 0xFB, 0x51, 0x54, + 0x2B, 0x08, 0x0A, 0xFB, 0x51, 0x12, + 0x16, 0x08, 0x0C, 0xFB, 0x51, 0x52, + 0x16, 0x08, 0x0D, 0x78, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0xEC, 0x31, + 0xAE, 0x00, 0x00, 0x81, 0x4C, 0x0F, + 0xE6, 0x43, 0xFF, 0xEC, 0x31, 0x4E, + 0x00, 0x00, 0x91, 0xEC, 0x31, 0xAE, + 0x00, 0x00, 0x91, 0x4C, 0x0F, 0xE6, + 0x43, 0xFF, 0xEC, 0x31, 0x5E, 0x00, + 0x00, 0xA1, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xA6, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xAC, 0x3C, 0x00, 0xEB, 0x31, + 0x08, 0x00, 0x00, 0xA8, 0x76, 0xFE, + 0xFE, 0x08, 0xEB, 0x31, 0x08, 0x20, + 0x00, 0x00, 0x76, 0xFF, 0xFF, 0x18, + 0xED, 0x31, 0x08, 0x20, 0x00, 0x00, + 0x26, 0x10, 0x04, 0x10, 0xF5, 0x3C, + 0x01, 0x3C, 0x00, 0x08, 0x01, 0x12, + 0x3C, 0x11, 0x3C, 0x00, 0x08, 0x01, + 0x0B, 0x08, 0x00, 0x6D, 0xEC, 0x31, + 0xAE, 0x20, 0x00, 0x06, 0xED, 0x4D, + 0x08, 0x00, 0x00, 0x67, 0x80, 0x6F, + 0x00, 0x01, 0x0B, 0x6F, 0x00, 0x02, + 0x2E, 0x76, 0xEE, 0x01, 0x48, 0x06, + 0x01, 0x39, 0xED, 0x4D, 0x18, 0x00, + 0x02, 0xED, 0x4D, 0x08, 0x00, 0x04, + 0x14, 0x06, 0xA4, 0xED, 0x31, 0x22, + 0x00, 0x00, 0xAC, 0x76, 0xEE, 0x07, + 0x48, 0x6D, 0x22, 0x01, 0x1E, 0x08, + 0x01, 0x58, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xAC, 0x06, 0xFF, 0xBA, 0x3C, + 0x00, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x30, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x00, + 0x00, 0xA2, 0x91, 0x00, 0x9C, 0x3C, + 0x80, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x20, + 0x00, 0x04, 0x42, 0x10, 0x90, 0x08, + 0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06, + 0xA4, 0x41, 0x08, 0x00, 0xB6, 0xED, + 0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22, + 0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB, + 0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05, + 0xFF, 0xE6, 0xA0, 0x31, 0x20, 0x00, + 0x06, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x20, + 0x00, 0x04, 0x42, 0x10, 0x90, 0x08, + 0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06, + 0xA4, 0x41, 0x08, 0x00, 0x68, 0xED, + 0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22, + 0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB, + 0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05, + 0xFF, 0xE6, 0x48, 0x04, 0xEB, 0x31, + 0x08, 0x20, 0x00, 0x04, 0xEB, 0x31, + 0x18, 0x20, 0x00, 0x02, 0x3C, 0x11, + 0xEB, 0x31, 0x18, 0x20, 0x00, 0x00, + 0xED, 0x31, 0x08, 0x20, 0x00, 0x00, + 0x04, 0x10, 0xF7, 0xED, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x66, 0x00, 0x6F, + 0x00, 0x01, 0x16, 0x76, 0xEE, 0x06, + 0x48, 0x4A, 0x1E, 0x48, 0x04, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x04, 0xEB, + 0x31, 0x08, 0x00, 0x00, 0xA4, 0x48, + 0x04, 0xED, 0x31, 0x08, 0x20, 0x00, + 0x04, 0xEB, 0x31, 0x08, 0x00, 0x00, + 0xA2, 0x48, 0x04, 0x20, 0x20, 0x4A, + 0x7C, 0x46, 0x82, 0x50, 0x05, 0x50, + 0x15, 0xB5, 0x1E, 0x98, 0xED, 0x31, + 0x08, 0x00, 0x00, 0xA8, 0x10, 0x47, + 0x3B, 0x2C, 0x01, 0xDB, 0x40, 0x11, + 0x98, 0xC1, 0x1E, 0x98, 0x10, 0x07, + 0x30, 0xF9, 0x40, 0x07, 0x18, 0x98, + 0x2A, 0x10, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xA8, 0xA4, 0x1E, 0x98, 0xBB, + 0x1E, 0x98, 0x50, 0x14, 0x50, 0x04, + 0x46, 0x83, 0x48, 0x04, 0x02, 0x01, + 0x00, 0x50, 0x05, 0x50, 0x15, 0x10, + 0x87, 0x3F, 0x90, 0x2B, 0x18, 0x01, + 0x00, 0xC0, 0x31, 0x00, 0x00, 0xAE, + 0xDF, 0x41, 0x00, 0x08, 0x00, 0x1A, + 0x42, 0x11, 0x67, 0x01, 0xDF, 0x41, + 0x02, 0x08, 0x00, 0x10, 0x42, 0x11, + 0x62, 0x01, 0xB4, 0x43, 0x4A, 0x68, + 0x50, 0x14, 0x50, 0x04, 0x24, 0x10, + 0x48, 0x04, 0xF2, 0x31, 0x00, 0x01, + 0x00, 0x00, 0xAE, 0xF6, 0x31, 0x00, + 0x01, 0x00, 0x00, 0xAE, 0x62, 0xE4, + 0xE5, 0x61, 0x04, 0x48, 0x04, 0xE5, + 0x63, 0x05, 0x48, 0x04, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00 }; #endif diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 29d0a72f0d65..d6421b9b5981 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -15,7 +15,7 @@ License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------*/ + -------------------------------------------------------------------------*/ #include <linux/kernel.h> #include <linux/module.h> @@ -80,19 +80,19 @@ MODULE_SUPPORTED_DEVICE("FT1000"); #define MAX_RCV_LOOP 100 -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_fifo_len -// Description: This function will read the ASIC Uplink FIFO status register -// which will return the number of bytes remaining in the Uplink FIFO. -// Sixteen bytes are subtracted to make sure that the ASIC does not -// reach its threshold. -// Input: -// dev - network device structure -// Output: -// value - number of bytes available in the ASIC Uplink FIFO. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_fifo_len + Description: This function will read the ASIC Uplink FIFO status register + which will return the number of bytes remaining in the Uplink FIFO. + Sixteen bytes are subtracted to make sure that the ASIC does not + reach its threshold. + Input: + dev - network device structure + Output: + value - number of bytes available in the ASIC Uplink FIFO. + + -------------------------------------------------------------------------*/ static inline u16 ft1000_read_fifo_len(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -103,25 +103,25 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram -// Description: This function will read the specific area of dpram -// (Electrabuzz ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram + Description: This function will read the specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u16 ft1000_read_dpram(struct net_device *dev, int offset) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA); @@ -130,54 +130,54 @@ u16 ft1000_read_dpram(struct net_device *dev, int offset) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram -// Description: This function will write to a specific area of dpram -// (Electrabuzz ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram + Description: This function will write to a specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram(struct net_device *dev, int offset, u16 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value); spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram_mag_16 -// Description: This function will read the specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram_mag_16 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); - // check if we want to read upper or lower 32-bit word + /* check if we want to read upper or lower 32-bit word */ if (Index) { data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL); } else { @@ -188,26 +188,26 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram_mag_16 -// Description: This function will write to a specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram_mag_16 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, int offset, u16 value, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); if (Index) { @@ -218,25 +218,25 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram_mag_32 -// Description: This function will read the specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram_mag_32 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u32 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL); @@ -245,41 +245,41 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram_mag_32 -// Description: This function will write to a specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram_mag_32 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL); spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_enable_interrupts -// Description: This function will enable interrupts base on the current interrupt mask. -// Input: -// dev - device structure -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_enable_interrupts + Description: This function will enable interrupts base on the current interrupt mask. + Input: + dev - device structure + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_enable_interrupts(struct net_device *dev) { u16 tempword; @@ -292,16 +292,16 @@ static void ft1000_enable_interrupts(struct net_device *dev) tempword); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_disable_interrupts -// Description: This function will disable all interrupts. -// Input: -// dev - device structure -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_disable_interrupts + Description: This function will disable all interrupts. + Input: + dev - device structure + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_disable_interrupts(struct net_device *dev) { u16 tempword; @@ -314,17 +314,17 @@ static void ft1000_disable_interrupts(struct net_device *dev) tempword); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_asic -// Description: This function will call the Card Service function to reset the -// ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_reset_asic + Description: This function will call the Card Service function to reset the + ASIC. + Input: + dev - device structure + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_reset_asic(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -335,21 +335,23 @@ static void ft1000_reset_asic(struct net_device *dev) (*info->ft1000_reset) (pcmcia->link); - // Let's use the register provided by the Magnemite ASIC to reset the - // ASIC and DSP. + /* + * Let's use the register provided by the Magnemite ASIC to reset the + * ASIC and DSP. + */ if (info->AsicID == MAGNEMITE_ID) { ft1000_write_reg(dev, FT1000_REG_RESET, (DSP_RESET_BIT | ASIC_RESET_BIT)); } mdelay(1); if (info->AsicID == ELECTRABUZZ_ID) { - // set watermark to -1 in order to not generate an interrupt + /* set watermark to -1 in order to not generate an interrupt */ ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff); } else { - // set watermark to -1 in order to not generate an interrupt + /* set watermark to -1 in order to not generate an interrupt */ ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff); } - // clear interrupts + /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); @@ -358,17 +360,17 @@ static void ft1000_reset_asic(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_card -// Description: This function will reset the card -// Input: -// dev - device structure -// Output: -// status - false (card reset fail) -// true (card reset successful) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_reset_card + Description: This function will reset the card + Input: + dev - device structure + Output: + status - false (card reset fail) + true (card reset successful) + + -------------------------------------------------------------------------*/ static int ft1000_reset_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -384,9 +386,9 @@ static int ft1000_reset_card(struct net_device *dev) info->squeseqnum = 0; ft1000_disable_interrupts(dev); -// del_timer(&poll_timer); + /* del_timer(&poll_timer); */ - // Make sure we free any memory reserve for provisioning + /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { DEBUG(0, "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); @@ -406,7 +408,7 @@ static int ft1000_reset_card(struct net_device *dev) (DSP_RESET_BIT | ASIC_RESET_BIT)); } - // Copy DSP session record into info block if this is not a coldstart + /* Copy DSP session record into info block if this is not a coldstart */ if (ft1000_card_present == 1) { spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { @@ -430,29 +432,29 @@ static int ft1000_reset_card(struct net_device *dev) DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n"); mdelay(10); - //reset ASIC + /* reset ASIC */ ft1000_reset_asic(dev); DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n"); if (info->AsicID == MAGNEMITE_ID) { - // Put dsp in reset and take ASIC out of reset + /* Put dsp in reset and take ASIC out of reset */ DEBUG(0, "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); - // Setting MAGNEMITE ASIC to big endian mode + /* Setting MAGNEMITE ASIC to big endian mode */ ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE); - // Download bootloader + /* Download bootloader */ card_bootload(dev); - // Take DSP out of reset + /* Take DSP out of reset */ ft1000_write_reg(dev, FT1000_REG_RESET, 0); - // FLARION_DSP_ACTIVE; + /* FLARION_DSP_ACTIVE; */ mdelay(10); DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n"); - // Wait for 0xfefe indicating dsp ready before starting download + /* Wait for 0xfefe indicating dsp ready before starting download */ for (i = 0; i < 50; i++) { tempword = ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE, @@ -470,7 +472,7 @@ static int ft1000_reset_card(struct net_device *dev) } } else { - // Take DSP out of reset + /* Take DSP out of reset */ ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT); mdelay(10); } @@ -485,17 +487,19 @@ static int ft1000_reset_card(struct net_device *dev) mdelay(10); if (info->AsicID == ELECTRABUZZ_ID) { - // Need to initialize the FIFO length counter to zero in order to sync up - // with the DSP + /* + * Need to initialize the FIFO length counter to zero in order to sync up + * with the DSP + */ info->fifo_cnt = 0; ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt); - // Initialize DSP heartbeat area to ho + /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram(dev, FT1000_HI_HO, ho); tempword = ft1000_read_dpram(dev, FT1000_HI_HO); DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n", tempword); } else { - // Initialize DSP heartbeat area to ho + /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); tempword = @@ -509,40 +513,44 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_enable_interrupts(dev); /* Schedule heartbeat process to run every 2 seconds */ -// poll_timer.expires = jiffies + (2*HZ); -// poll_timer.data = (u_long)dev; -// add_timer(&poll_timer); + /* poll_timer.expires = jiffies + (2*HZ); */ + /* poll_timer.data = (u_long)dev; */ + /* add_timer(&poll_timer); */ return true; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_chkcard -// Description: This function will check if the device is presently available on -// the system. -// Input: -// dev - device structure -// Output: -// status - false (device is not present) -// true (device is present) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_chkcard + Description: This function will check if the device is presently available on + the system. + Input: + dev - device structure + Output: + status - false (device is not present) + true (device is present) + + -------------------------------------------------------------------------*/ static int ft1000_chkcard(struct net_device *dev) { u16 tempword; - // Mask register is used to check for device presence since it is never - // set to zero. + /* + * Mask register is used to check for device presence since it is never + * set to zero. + */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); if (tempword == 0) { DEBUG(1, "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); return false; } - // The system will return the value of 0xffff for the version register - // if the device is not present. + /* + * The system will return the value of 0xffff for the version register + * if the device is not present. + */ tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (tempword == 0xffff) { DEBUG(1, @@ -553,17 +561,17 @@ static int ft1000_chkcard(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_hbchk -// Description: This function will perform the heart beat check of the DSP as -// well as the ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_hbchk + Description: This function will perform the heart beat check of the DSP as + well as the ASIC. + Input: + dev - device structure + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_hbchk(u_long data) { struct net_device *dev = (struct net_device *)data; @@ -574,7 +582,7 @@ static void ft1000_hbchk(u_long data) info = netdev_priv(dev); if (info->CardReady == 1) { - // Perform dsp heartbeat check + /* Perform dsp heartbeat check */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_dpram(dev, FT1000_HI_HO); } else { @@ -585,7 +593,7 @@ static void ft1000_hbchk(u_long data) } DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n", tempword); - // Let's perform another check if ho is not detected + /* Let's perform another check if ho is not detected */ if (tempword != ho) { if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_dpram(dev, FT1000_HI_HO); @@ -639,7 +647,7 @@ static void ft1000_hbchk(u_long data) } tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - // Let's check doorbell again if fail + /* Let's check doorbell again if fail */ if (tempword & FT1000_DB_HB) { tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); } @@ -686,8 +694,10 @@ static void ft1000_hbchk(u_long data) add_timer(&poll_timer); return; } - // Set dedicated area to hi and ring appropriate doorbell according - // to hi/ho heartbeat protocol + /* + * Set dedicated area to hi and ring appropriate doorbell according + * to hi/ho heartbeat protocol + */ if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_dpram(dev, FT1000_HI_HO, hi); } else { @@ -703,7 +713,7 @@ static void ft1000_hbchk(u_long data) (dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX)); } - // Let's write hi again if fail + /* Let's write hi again if fail */ if (tempword != hi) { if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_dpram(dev, FT1000_HI_HO, hi); @@ -774,14 +784,14 @@ static void ft1000_hbchk(u_long data) add_timer(&poll_timer); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_send_cmd -// Description: -// Input: -// Output: -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_send_cmd + Description: + Input: + Output: + + -------------------------------------------------------------------------*/ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { struct ft1000_info *info = netdev_priv(dev); @@ -790,17 +800,19 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, unsigned long flags; size += sizeof(struct pseudo_hdr); - // check for odd byte and increment to 16-bit word align value + /* check for odd byte and increment to 16-bit word align value */ if ((size & 0x0001)) { size++; } DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size); DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer)); - // put message into slow queue area - // All messages are in the form total_len + pseudo header + message body + /* + * put message into slow queue area + * All messages are in the form total_len + pseudo header + message body + */ spin_lock_irqsave(&info->dpram_lock, flags); - // Make sure SLOWQ doorbell is clear + /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); i=0; while (tempword & FT1000_DB_DPRAM_TX) { @@ -816,9 +828,9 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_TX_BASE); - // Write total length to dpram + /* Write total length to dpram */ ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size); - // Write pseudo header and messgae body + /* Write pseudo header and messgae body */ for (i = 0; i < (size >> 1); i++) { DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i, *ptempbuffer); @@ -828,9 +840,9 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, } else { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE); - // Write total length to dpram + /* Write total length to dpram */ ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size)); - // Write pseudo header and messgae body + /* Write pseudo header and messgae body */ ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE + 1); for (i = 0; i < (size >> 2); i++) { @@ -850,23 +862,23 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, } spin_unlock_irqrestore(&info->dpram_lock, flags); - // ring doorbell to notify DSP that we have a message ready + /* ring doorbell to notify DSP that we have a message ready */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_receive_cmd -// Description: This function will read a message from the dpram area. -// Input: -// dev - network device structure -// pbuffer - caller supply address to buffer -// pnxtph - pointer to next pseudo header -// Output: -// Status = 0 (unsuccessful) -// = 1 (successful) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_receive_cmd + Description: This function will read a message from the dpram area. + Input: + dev - network device structure + pbuffer - caller supply address to buffer + pnxtph - pointer to next pseudo header + Output: + Status = 0 (unsuccessful) + = 1 (successful) + + -------------------------------------------------------------------------*/ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) { @@ -919,7 +931,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; } - //copy odd aligned word + /* copy odd aligned word */ *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL); DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); pbuffer++; @@ -928,14 +940,16 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, pbuffer++; } if (size & 0x0001) { - //copy odd byte from fifo + /* copy odd byte from fifo */ tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA); *pbuffer = ntohs(tempword); } spin_unlock_irqrestore(&info->dpram_lock, flags); - // Check if pseudo header checksum is good - // Calculate pseudo header checksum + /* + * Check if pseudo header checksum is good + * Calculate pseudo header checksum + */ tempword = *ppseudohdr++; for (i = 1; i < 7; i++) { tempword ^= *ppseudohdr++; @@ -943,24 +957,24 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, if ((tempword != *ppseudohdr)) { DEBUG(1, "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); - // Drop this message + /* Drop this message */ return false; } return true; } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_proc_drvmsg -// Description: This function will process the various driver messages. -// Input: -// dev - device structure -// pnxtph - pointer to next pseudo header -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_proc_drvmsg + Description: This function will process the various driver messages. + Input: + dev - device structure + pnxtph - pointer to next pseudo header + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_proc_drvmsg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -988,7 +1002,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) { - // Get the message type which is total_len + PSEUDO header + msgtype + message body + /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); DEBUG(1, "Command message type = 0x%x\n", msgtype); @@ -999,7 +1013,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) mdelay(25); while (list_empty(&info->prov_list) == 0) { DEBUG(0, "Sending a provisioning message\n"); - // Make sure SLOWQ doorbell is clear + /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); i = 0; @@ -1018,10 +1032,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) pmsg = (u16 *) ptr->pprov_data; ppseudo_hdr = (struct pseudo_hdr *) pmsg; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; DEBUG(1, "checksum = 0x%x\n", ppseudo_hdr->checksum); @@ -1036,8 +1050,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) kfree(ptr->pprov_data); kfree(ptr); } - // Indicate adapter is ready to take application messages after all - // provisioning messages are sent + /* + * Indicate adapter is ready to take application messages after all + * provisioning messages are sent + */ info->CardReady = 1; break; case MEDIA_STATE: @@ -1118,8 +1134,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) break; case DSP_GET_INFO: DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n"); - // copy dsp info block to dsp - // allow any outstanding ioctl to finish + /* + * copy dsp info block to dsp + * allow any outstanding ioctl to finish + */ mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { @@ -1132,8 +1150,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - // Put message into Slow Queue - // Form Pseudo header + /* + * Put message into Slow Queue + * Form Pseudo header + */ pmsg = (u16 *) info->DSPInfoBlk; ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = @@ -1147,11 +1167,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ppseudo_hdr->rsvd1 = 0; ppseudo_hdr->rsvd2 = 0; ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id + /* Insert application id */ ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; @@ -1165,8 +1185,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) break; case GET_DRV_ERR_RPT_MSG: DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); - // copy driver error message to dsp - // allow any outstanding ioctl to finish + /* + * copy driver error message to dsp + * allow any outstanding ioctl to finish + */ mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { @@ -1179,8 +1201,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - // Put message into Slow Queue - // Form Pseudo header + /* + * Put message into Slow Queue + * Form Pseudo header + */ pmsg = (u16 *) & tempbuffer[0]; ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = htons(0x0012); @@ -1193,11 +1217,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ppseudo_hdr->rsvd1 = 0; ppseudo_hdr->rsvd2 = 0; ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id + /* Insert application id */ ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; for (i=1; i<7; i++) { ppseudo_hdr->checksum ^= *pmsg++; @@ -1228,18 +1252,18 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_parse_dpram_msg -// Description: This function will parse the message received from the DSP -// via the DPRAM interface. -// Input: -// dev - device structure -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_parse_dpram_msg + Description: This function will parse the message received from the DSP + via the DPRAM interface. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_parse_dpram_msg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -1255,7 +1279,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) DEBUG(1, "Doorbell = 0x%x\n", doorbell); if (doorbell & FT1000_ASIC_RESET_REQ) { - // Copy DSP session record from info block + /* Copy DSP session record from info block */ spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -1274,7 +1298,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } spin_unlock_irqrestore(&info->dpram_lock, flags); - // clear ASIC RESET request + /* clear ASIC RESET request */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_REQ); DEBUG(1, "Got an ASIC RESET Request\n"); @@ -1282,7 +1306,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_ASIC_RESET_DSP); if (info->AsicID == MAGNEMITE_ID) { - // Setting MAGNEMITE ASIC to big endian mode + /* Setting MAGNEMITE ASIC to big endian mode */ ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE); } @@ -1315,8 +1339,10 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { total_len += nxtph; cnt = 0; - // ft1000_read_reg will return a value that needs to be byteswap - // in order to get DSP_QID_OFFSET. + /* + * ft1000_read_reg will return a value that needs to be byteswap + * in order to get DSP_QID_OFFSET. + */ if (info->AsicID == ELECTRABUZZ_ID) { portid = (ft1000_read_dpram @@ -1332,7 +1358,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) DEBUG(1, "DSP_QID = 0x%x\n", portid); if (portid == DRIVERID) { - // We are assumming one driver message from the DSP at a time. + /* We are assumming one driver message from the DSP at a time. */ ft1000_proc_drvmsg(dev); } } @@ -1340,7 +1366,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DB_COND_RESET) { - // Reset ASIC and DSP + /* Reset ASIC and DSP */ if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -1370,7 +1396,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_COND_RESET); } - // let's clear any unexpected doorbells from DSP + /* let's clear any unexpected doorbells from DSP */ doorbell = doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ | FT1000_DB_COND_RESET | 0xff00); @@ -1383,18 +1409,18 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_flush_fifo -// Description: This function will flush one packet from the downlink -// FIFO. -// Input: -// dev - device structure -// drv_err - driver error causing the flush fifo -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_flush_fifo + Description: This function will flush one packet from the downlink + FIFO. + Input: + dev - device structure + drv_err - driver error causing the flush fifo + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) { struct ft1000_info *info = netdev_priv(dev); @@ -1432,7 +1458,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) ft1000_reset_card(dev); return; } else { - // Flush corrupted pkt from FIFO + /* Flush corrupted pkt from FIFO */ i = 0; do { if (info->AsicID == ELECTRABUZZ_ID) { @@ -1447,8 +1473,10 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) inw(dev->base_addr + FT1000_REG_MAG_DFSR); } i++; - // This should never happen unless the ASIC is broken. - // We must reset to recover. + /* + * This should never happen unless the ASIC is broken. + * We must reset to recover. + */ if ((i > 2048) || (tempword == 0)) { if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = @@ -1482,17 +1510,19 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) FT1000_MAG_DSP_TIMER3_INDX); } if (tempword == 0) { - // Let's check if ASIC reads are still ok by reading the Mask register - // which is never zero at this point of the code. + /* + * Let's check if ASIC reads are still ok by reading the Mask register + * which is never zero at this point of the code. + */ tempword = inw(dev->base_addr + FT1000_REG_SUP_IMASK); if (tempword == 0) { - // This indicates that we can not communicate with the ASIC + /* This indicates that we can not communicate with the ASIC */ info->DrvErrNum = FIFO_FLUSH_BADCNT; } else { - // Let's assume that we really flush the FIFO + /* Let's assume that we really flush the FIFO */ pcmcia->PktIntfErr++; return; } @@ -1506,9 +1536,9 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) if (info->AsicID == ELECTRABUZZ_ID) { i++; DEBUG(0, "Flushing FIFO complete = %x\n", tempword); - // Flush last word in FIFO. + /* Flush last word in FIFO. */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); - // Update FIFO counter for DSP + /* Update FIFO counter for DSP */ i = i * 2; DEBUG(0, "Flush Data byte count to dsp = %d\n", i); info->fifo_cnt += i; @@ -1516,7 +1546,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) info->fifo_cnt); } else { DEBUG(0, "Flushing FIFO complete = %x\n", tempword); - // Flush last word in FIFO + /* Flush last word in FIFO */ templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT); DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword); @@ -1529,19 +1559,19 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_up_pkt -// Description: This function will pull Flarion packets out of the Downlink -// FIFO and convert it to an ethernet packet. The ethernet packet will -// then be deliver to the TCP/IP stack. -// Input: -// dev - device structure -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_copy_up_pkt + Description: This function will pull Flarion packets out of the Downlink + FIFO and convert it to an ethernet packet. The ethernet packet will + then be deliver to the TCP/IP stack. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_copy_up_pkt(struct net_device *dev) { u16 tempword; @@ -1556,7 +1586,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) u32 templong; DEBUG(1, "ft1000_copy_up_pkt\n"); - // Read length + /* Read length */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); len = tempword; @@ -1570,7 +1600,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) if (len > ENET_MAX_SIZE) { DEBUG(0, "size of ethernet packet invalid\n"); if (info->AsicID == MAGNEMITE_ID) { - // Read High word to complete 32 bit access + /* Read High word to complete 32 bit access */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); } ft1000_flush_fifo(dev, DSP_PKTLEN_INFO); @@ -1582,7 +1612,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) if (skb == NULL) { DEBUG(0, "No Network buffers available\n"); - // Read High word to complete 32 bit access + /* Read High word to complete 32 bit access */ if (info->AsicID == MAGNEMITE_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); } @@ -1592,13 +1622,13 @@ static int ft1000_copy_up_pkt(struct net_device *dev) } pbuffer = (u8 *) skb_put(skb, len + 12); - // Pseudo header + /* Pseudo header */ if (info->AsicID == ELECTRABUZZ_ID) { for (i = 1; i < 7; i++) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); chksum ^= tempword; } - // read checksum value + /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); } else { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1625,7 +1655,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) DEBUG(1, "Pseudo = 0x%x\n", tempword); chksum ^= tempword; - // read checksum value + /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); DEBUG(1, "Pseudo = 0x%x\n", tempword); } @@ -1638,10 +1668,10 @@ static int ft1000_copy_up_pkt(struct net_device *dev) kfree_skb(skb); return FAILURE; } - //subtract the number of bytes read already + /* subtract the number of bytes read already */ ptemp = pbuffer; - // fake MAC address + /* fake MAC address */ *pbuffer++ = dev->dev_addr[0]; *pbuffer++ = dev->dev_addr[1]; *pbuffer++ = dev->dev_addr[2]; @@ -1666,7 +1696,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) } } - // Need to read one more word if odd byte + /* Need to read one more word if odd byte */ if (len & 0x0001) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); *pbuffer++ = (u8) (tempword >> 8); @@ -1679,7 +1709,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) *ptemplong++ = templong; } - // Need to read one more word if odd align. + /* Need to read one more word if odd align. */ if (len & 0x0003) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); DEBUG(1, "Data = 0x%8x\n", templong); @@ -1699,11 +1729,11 @@ static int ft1000_copy_up_pkt(struct net_device *dev) netif_rx(skb); info->stats.rx_packets++; - // Add on 12 bytes for MAC address which was removed + /* Add on 12 bytes for MAC address which was removed */ info->stats.rx_bytes += (len + 12); if (info->AsicID == ELECTRABUZZ_ID) { - // track how many bytes have been read from FIFO - round up to 16 bit word + /* track how many bytes have been read from FIFO - round up to 16 bit word */ tempword = len + 16; if (tempword & 0x01) tempword++; @@ -1715,21 +1745,21 @@ static int ft1000_copy_up_pkt(struct net_device *dev) return SUCCESS; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_down_pkt -// Description: This function will take an ethernet packet and convert it to -// a Flarion packet prior to sending it to the ASIC Downlink -// FIFO. -// Input: -// dev - device structure -// packet - address of ethernet packet -// len - length of IP packet -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_copy_down_pkt + Description: This function will take an ethernet packet and convert it to + a Flarion packet prior to sending it to the ASIC Downlink + FIFO. + Input: + dev - device structure + packet - address of ethernet packet + len - length of IP packet + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) { struct ft1000_info *info = netdev_priv(dev); @@ -1744,7 +1774,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) DEBUG(1, "ft1000_hw: copy_down_pkt()\n"); - // Check if there is room on the FIFO + /* Check if there is room on the FIFO */ if (len > ft1000_read_fifo_len(dev)) { udelay(10); if (len > ft1000_read_fifo_len(dev)) { @@ -1769,15 +1799,15 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) return SUCCESS; } } - // Create pseudo header and send pseudo/ip to hardware + /* Create pseudo header and send pseudo/ip to hardware */ if (info->AsicID == ELECTRABUZZ_ID) { pseudo.blk.length = len; } else { pseudo.blk.length = ntohs(len); } - pseudo.blk.source = DSPID; // Need to swap to get in correct order + pseudo.blk.source = DSPID; /* Need to swap to get in correct order */ pseudo.blk.destination = HOSTID; - pseudo.blk.portdest = NETWORKID; // Need to swap to get in correct order + pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */ pseudo.blk.portsrc = DSPAIRID; pseudo.blk.sh_str_id = 0; pseudo.blk.control = 0; @@ -1791,14 +1821,14 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) pseudo.blk.checksum ^= pseudo.buff[i]; } - // Production Mode + /* Production Mode */ if (info->AsicID == ELECTRABUZZ_ID) { - // copy first word to UFIFO_BEG reg + /* copy first word to UFIFO_BEG reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n", pseudo.buff[0]); - // copy subsequent words to UFIFO_MID reg + /* copy subsequent words to UFIFO_MID reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n", pseudo.buff[1]); @@ -1821,7 +1851,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n", pseudo.buff[7]); - // Write PPP type + IP Packet into Downlink FIFO + /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 1) - 1; i++) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); @@ -1831,7 +1861,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) packet++; } - // Check for odd byte + /* Check for odd byte */ if (len & 0x0001) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); @@ -1870,12 +1900,12 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) *(u32 *) & pseudo.buff[6]); plong = (u32 *) packet; - // Write PPP type + IP Packet into Downlink FIFO + /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 2); i++) { outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); } - // Check for odd alignment + /* Check for odd alignment */ if (len & 0x0003) { DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", @@ -1886,7 +1916,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) } info->stats.tx_packets++; - // Add 14 bytes for MAC address plus ethernet type + /* Add 14 bytes for MAC address plus ethernet type */ info->stats.tx_bytes += (len + 14); return SUCCESS; } @@ -1931,7 +1961,7 @@ static int ft1000_close(struct net_device *dev) ft1000_disable_interrupts(dev); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); - //reset ASIC + /* reset ASIC */ ft1000_reset_asic(dev); } return 0; @@ -1995,10 +2025,10 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) ft1000_disable_interrupts(dev); - // Read interrupt type + /* Read interrupt type */ inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - // Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type + /* Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type */ while (inttype) { if (inttype & ISR_DOORBELL_PEND) ft1000_parse_dpram_msg(dev); @@ -2008,7 +2038,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) cnt = 0; do { - // Check if we have packets in the Downlink FIFO + /* Check if we have packets in the Downlink FIFO */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, @@ -2027,12 +2057,12 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) } while (cnt < MAX_RCV_LOOP); } - // clear interrupts + /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); - // Read interrupt type + /* Read interrupt type */ inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR); DEBUG(1,"ft1000_hw: interrupt status register after clear = 0x%x\n",inttype); } @@ -2044,7 +2074,7 @@ void stop_ft1000_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); struct prov_record *ptr; -// int cnt; + /* int cnt; */ DEBUG(0, "ft1000_hw: stop_ft1000_card()\n"); @@ -2053,7 +2083,7 @@ void stop_ft1000_card(struct net_device *dev) netif_stop_queue(dev); ft1000_disable_interrupts(dev); - // Make sure we free any memory reserve for provisioning + /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); @@ -2109,7 +2139,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, struct ft1000_pcmcia *pcmcia; struct net_device *dev; - static const struct net_device_ops ft1000ops = // Slavius 21.10.2009 due to kernel changes + static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */ { .ndo_open = &ft1000_open, .ndo_stop = &ft1000_close, @@ -2169,12 +2199,12 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, info->squeseqnum = 0; -// dev->hard_start_xmit = &ft1000_start_xmit; -// dev->get_stats = &ft1000_stats; -// dev->open = &ft1000_open; -// dev->stop = &ft1000_close; + /* dev->hard_start_xmit = &ft1000_start_xmit; */ + /* dev->get_stats = &ft1000_stats; */ + /* dev->open = &ft1000_open; */ + /* dev->stop = &ft1000_close; */ - dev->netdev_ops = &ft1000ops; // Slavius 21.10.2009 due to kernel changes + dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */ DEBUG(0, "device name = %s\n", dev->name); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 68a55ce69200..ffdc7f597a96 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -560,6 +560,8 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* Get the length field to see how many bytes to copy */ result = get_user(msgsz, (__u16 __user *)argp); + if (result) + break; msgsz = ntohs(msgsz); /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 12f333fa59b5..782aa9ed4718 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -55,7 +55,7 @@ #define MAX_LENGTH 0x7f0 -// Temporary download mechanism for Magnemite +/* Temporary download mechanism for Magnemite */ #define DWNLD_MAG_TYPE_LOC 0x00 #define DWNLD_MAG_LEN_LOC 0x01 #define DWNLD_MAG_ADDR_LOC 0x02 @@ -74,36 +74,36 @@ #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1 -// New Magnemite downloader +/* New Magnemite downloader */ #define DWNLD_MAG1_HANDSHAKE_LOC 0x00 #define DWNLD_MAG1_TYPE_LOC 0x01 #define DWNLD_MAG1_SIZE_LOC 0x02 #define DWNLD_MAG1_PS_HDR_LOC 0x03 struct dsp_file_hdr { - long version_id; // Version ID of this image format. - long package_id; // Package ID of code release. - long build_date; // Date/time stamp when file was built. - long commands_offset; // Offset to attached commands in Pseudo Hdr format. - long loader_offset; // Offset to bootloader code. - long loader_code_address; // Start address of bootloader. - long loader_code_end; // Where bootloader code ends. - long loader_code_size; - long version_data_offset; // Offset were scrambled version data begins. - long version_data_size; // Size, in words, of scrambled version data. - long nDspImages; // Number of DSP images in file. + long version_id; /* Version ID of this image format. */ + long package_id; /* Package ID of code release. */ + long build_date; /* Date/time stamp when file was built. */ + long commands_offset; /* Offset to attached commands in Pseudo Hdr format. */ + long loader_offset; /* Offset to bootloader code. */ + long loader_code_address; /* Start address of bootloader. */ + long loader_code_end; /* Where bootloader code ends. */ + long loader_code_size; + long version_data_offset; /* Offset were scrambled version data begins. */ + long version_data_size; /* Size, in words, of scrambled version data. */ + long nDspImages; /* Number of DSP images in file. */ }; #pragma pack(1) struct dsp_image_info { - long coff_date; // Date/time when DSP Coff image was built. - long begin_offset; // Offset in file where image begins. - long end_offset; // Offset in file where image begins. - long run_address; // On chip Start address of DSP code. - long image_size; // Size of image. - long version; // Embedded version # of DSP code. - unsigned short checksum; // DSP File checksum - unsigned short pad1; + long coff_date; /* Date/time when DSP Coff image was built. */ + long begin_offset; /* Offset in file where image begins. */ + long end_offset; /* Offset in file where image begins. */ + long run_address; /* On chip Start address of DSP code. */ + long image_size; /* Size of image. */ + long version; /* Embedded version # of DSP code. */ + unsigned short checksum; /* DSP File checksum */ + unsigned short pad1; }; @@ -151,7 +151,7 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) } } - return HANDSHAKE_MAG_TIMEOUT_VALUE; + return -1; } /* gets the handshake and compares it with the expected value */ @@ -172,9 +172,8 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) ft1000dev->fcodeldr); ft1000dev->fcodeldr = 0; status = check_usb_db(ft1000dev); - if (status != STATUS_SUCCESS) { + if (status != 0) { DEBUG("get_handshake: check_usb_db failed\n"); - status = STATUS_FAILURE; break; } status = ft1000_write_register(ft1000dev, @@ -202,7 +201,7 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) } /* write the handshake value to the handshake location */ -static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value) +static void put_handshake(struct ft1000_usb *ft1000dev, u16 handshake_value) { u32 tempx; u16 tempword; @@ -268,11 +267,12 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) return HANDSHAKE_TIMEOUT_VALUE; } -static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value) +static void put_handshake_usb(struct ft1000_usb *ft1000dev, u16 handshake_value) { int i; - for (i=0; i<1000; i++); + for (i = 0; i < 1000; i++) + ; } static u16 get_request_type(struct ft1000_usb *ft1000dev) @@ -450,7 +450,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - int status = STATUS_SUCCESS; + int status = 0; u16 dpram; int loopcnt, i; u16 tempword; @@ -499,7 +499,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, } else { status = write_dpram32_and_check(ft1000dev, tempbuffer, dpram); - if (status != STATUS_SUCCESS) { + if (status != 0) { DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]); break; } @@ -509,9 +509,9 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, return status; } -static void usb_dnld_complete (struct urb *urb) +static void usb_dnld_complete(struct urb *urb) { - //DEBUG("****** usb_dnld_complete\n"); + /* DEBUG("****** usb_dnld_complete\n"); */ } /* writes a block of DSP image to DPRAM @@ -523,7 +523,7 @@ static void usb_dnld_complete (struct urb *urb) static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - int Status = STATUS_SUCCESS; + int Status = 0; int byte_length; byte_length = word_length * 4; @@ -586,12 +586,12 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, /*NdisMSleep (100); */ if (word_length > MAX_LENGTH) { DEBUG("FT1000:download:Download error: Max length exceeded\n"); - return STATUS_FAILURE; + return -1; } if ((word_length * 2 + (long)c_file) > (long)endpoint) { /* Error, beyond boot code range.*/ DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length); - return STATUS_FAILURE; + return -1; } if (word_length & 0x1) word_length++; @@ -601,11 +601,11 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, status = write_blk(ft1000dev, s_file, c_file, word_length); /*DEBUG("write_blk returned %d\n", status); */ } else { - write_blk_fifo(ft1000dev, s_file, c_file, word_length); + status = write_blk_fifo(ft1000dev, s_file, c_file, word_length); if (ft1000dev->usbboot == 0) ft1000dev->usbboot++; if (ft1000dev->usbboot == 1) - ft1000_write_dpram16(ft1000dev, + status |= ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_PS_HDR_LOC, 0, 0); } return status; @@ -615,7 +615,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, u32 FileLength) { - int status = STATUS_SUCCESS; + int status = 0; u32 state; u16 handshake; struct pseudo_hdr *pseudo_header; @@ -651,9 +651,9 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, ft1000dev->usbboot = 0; ft1000dev->dspalive = 0xffff; - // - // Get version id of file, at first 4 bytes of file, for newer files. - // + /* + * Get version id of file, at first 4 bytes of file, for newer files. + */ state = STATE_START_DWNLD; @@ -670,7 +670,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, loader_code_size = file_hdr->loader_code_size; correct_version = false; - while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) { + while ((status == 0) && (state != STATE_DONE_FILE)) { switch (state) { case STATE_START_DWNLD: status = scram_start_dwnld(ft1000dev, &handshake, @@ -702,8 +702,8 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Reposition ptrs to beginning of code section */ s_file = (u16 *) (boot_end); c_file = (u8 *) (boot_end); - //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); - //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); + /* DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); */ + /* DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ state = STATE_CODE_DWNLD; ft1000dev->fcodeldr = 1; break; @@ -717,7 +717,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", request); - status = STATUS_FAILURE; + status = -1; break; } if (ft1000dev->usbboot) @@ -729,13 +729,13 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; + status = -1; } break; case STATE_CODE_DWNLD: - //DEBUG("FT1000:STATE_CODE_DWNLD\n"); + /* DEBUG("FT1000:STATE_CODE_DWNLD\n"); */ ft1000dev->bootmode = 0; if (ft1000dev->usbboot) handshake = @@ -773,7 +773,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Got Run address request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -789,7 +789,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Got Size request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -805,11 +805,11 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: - //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); + /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */ if (!correct_version) { DEBUG ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } @@ -823,7 +823,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, case REQUEST_MAILBOX_DATA: DEBUG ("FT1000:download: REQUEST_MAILBOX_DATA\n"); - // Convert length from byte count to word count. Make sure we round up. + /* Convert length from byte count to word count. Make sure we round up. */ word_length = (long)(pft1000info->DSPInfoBlklen + 1) / 2; @@ -836,7 +836,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ - data = (u16 *) & mailbox_data->data[0]; + data = (u16 *) &mailbox_data->data[0]; dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -850,7 +850,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, - (u8 *) & templong); + (u8 *) &templong); } break; @@ -939,7 +939,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } dsp_img_info++; - } //end of for + } /* end of for */ if (!correct_version) { /* @@ -948,7 +948,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", (int)requested_version); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -957,7 +957,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", request); - status = STATUS_FAILURE; + status = -1; break; } if (ft1000dev->usbboot) @@ -969,7 +969,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; + status = -1; } break; @@ -1002,7 +1002,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, (u32) (pseudo_header_len + sizeof(struct pseudo_hdr))); - // link provisioning data + /* link provisioning data */ pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC); @@ -1013,7 +1013,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, list, &pft1000info-> prov_list); - // Move to next entry if available + /* Move to next entry if available */ c_file = (u8 *) ((unsigned long) c_file + @@ -1026,14 +1026,14 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } } else { kfree(pbuffer); - status = STATUS_FAILURE; + status = -1; } } else { - status = STATUS_FAILURE; + status = -1; } } else { /* Checksum did not compute */ - status = STATUS_FAILURE; + status = -1; } DEBUG ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", @@ -1046,23 +1046,23 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; default: - status = STATUS_FAILURE; + status = -1; break; } /* End Switch */ - if (status != STATUS_SUCCESS) + if (status != 0) break; /**** // Check if Card is present status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { - break; + break; } status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { - break; + break; } ****/ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 0d4931b2c2e2..0d6c1d12170d 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1,11 +1,9 @@ -//===================================================== -// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -// -// -// This file is part of Express Card USB Driver -// -// $Id: -//==================================================== +/* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. +* +* +* This file is part of Express Card USB Driver +*/ + #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> @@ -27,7 +25,9 @@ #define HARLEY_READ_OPERATION 0xc1 #define HARLEY_WRITE_OPERATION 0x41 -//#define JDEBUG +#if 0 +#define JDEBUG +#endif static int ft1000_submit_rx_urb(struct ft1000_info *info); @@ -35,32 +35,22 @@ static u8 tempbuffer[1600]; #define MAX_RCV_LOOP 100 -//--------------------------------------------------------------------------- -// Function: ft1000_control -// -// Parameters: ft1000_usb - device structure -// pipe - usb control message pipe -// request - control request -// requesttype - control message request type -// value - value to be written or 0 -// index - register index -// data - data buffer to hold the read/write values -// size - data size -// timeout - control message time out value -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function sends a control message via USB interface synchronously -// -// Notes: -// -//--------------------------------------------------------------------------- +/* send a control message via USB interface synchronously +* Parameters: ft1000_usb - device structure +* pipe - usb control message pipe +* request - control request +* requesttype - control message request type +* value - value to be written or 0 +* index - register index +* data - data buffer to hold the read/write values +* size - data size +* timeout - control message time out value +*/ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout) { - u16 ret; + int ret; if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) { DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n"); @@ -76,26 +66,11 @@ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_register -// -// Parameters: ft1000_usb - device structure -// Data - data buffer to hold the value read -// nRegIndex - register index -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function returns the value in a register -// -// Notes: -// -//--------------------------------------------------------------------------- - -int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data, +/* returns the value in a register */ +int ft1000_read_register(struct ft1000_usb *ft1000dev, u16 *Data, u16 nRegIndx) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_rcvctrlpipe(ft1000dev->dev, 0), @@ -110,25 +85,11 @@ int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_register -// -// Parameters: ft1000_usb - device structure -// value - value to write into a register -// nRegIndex - register index -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes the value in a register -// -// Notes: -// -//--------------------------------------------------------------------------- +/* writes the value in a register */ int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value, u16 nRegIndx) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_sndctrlpipe(ft1000dev->dev, 0), @@ -143,27 +104,11 @@ int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// cnt - number of byte read from DPRAM -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read a number of bytes from DPRAM -// -// Notes: -// -//--------------------------------------------------------------------------- - +/* read a number of bytes from DPRAM */ int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_rcvctrlpipe(ft1000dev->dev, 0), @@ -178,26 +123,11 @@ int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write the data -// buffer - data buffer to write into DPRAM -// cnt - number of bytes to write -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes into DPRAM a number of bytes -// -// Notes: -// -//--------------------------------------------------------------------------- +/* writes into DPRAM a number of bytes */ int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - int ret = STATUS_SUCCESS; + int ret = 0; if (cnt % 4) cnt += cnt - (cnt % 4); @@ -215,26 +145,11 @@ int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_dpram16 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// hightlow - high or low 16 bit word -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read 16 bits from DPRAM -// -// Notes: -// -//--------------------------------------------------------------------------- +/* read 16 bits from DPRAM */ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u8 highlow) { - int ret = STATUS_SUCCESS; + int ret = 0; u8 request; if (highlow == 0) @@ -255,25 +170,11 @@ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_dpram16 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write the data -// value - 16bits value to write -// hightlow - high or low 16 bit word -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes into DPRAM a number of bytes -// -// Notes: -// -//--------------------------------------------------------------------------- -int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 highlow) +/* write into DPRAM a number of bytes */ +int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, + u8 highlow) { - int ret = STATUS_SUCCESS; + int ret = 0; u8 request; if (highlow == 0) @@ -294,33 +195,18 @@ int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 h return ret; } -//--------------------------------------------------------------------------- -// Function: fix_ft1000_read_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read DPRAM 4 words at a time -// -// Notes: -// -//--------------------------------------------------------------------------- +/* read DPRAM 4 words at a time */ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) { u8 buf[16]; u16 pos; - int ret = STATUS_SUCCESS; + int ret = 0; pos = (indx / 4) * 4; ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { pos = (indx % 4) * 4; *buffer++ = buf[pos++]; *buffer++ = buf[pos++]; @@ -338,22 +224,7 @@ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, } -//--------------------------------------------------------------------------- -// Function: fix_ft1000_write_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write -// buffer - data buffer to write -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function write to DPRAM 4 words at a time -// -// Notes: -// -//--------------------------------------------------------------------------- +/* Description: This function write to DPRAM 4 words at a time */ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) { u16 pos1; @@ -362,13 +233,13 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) u8 buf[32]; u8 resultbuffer[32]; u8 *pdata; - int ret = STATUS_SUCCESS; + int ret = 0; pos1 = (indx / 4) * 4; pdata = buffer; ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { pos2 = (indx % 4)*4; buf[pos2++] = *buffer++; buf[pos2++] = *buffer++; @@ -382,24 +253,24 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { buffer = pdata; for (i = 0; i < 16; i++) { if (buf[i] != resultbuffer[i]) - ret = STATUS_FAILURE; + ret = -1; } } - if (ret == STATUS_FAILURE) { + if (ret == -1) { ret = ft1000_write_dpram32(ft1000dev, pos1, (u8 *)&tempbuffer[0], 16); ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { buffer = pdata; for (i = 0; i < 16; i++) { if (tempbuffer[i] != resultbuffer[i]) { - ret = STATUS_FAILURE; + ret = -1; DEBUG("%s Failed to write\n", __func__); } @@ -410,20 +281,10 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) return ret; } - -//------------------------------------------------------------------------ -// -// Function: card_reset_dsp -// -// Synopsis: This function is called to reset or activate the DSP -// -// Arguments: value - reset or activate -// -// Returns: None -//----------------------------------------------------------------------- +/* reset or activate the DSP */ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) { - u16 status = STATUS_SUCCESS; + int status = 0; u16 tempword; status = ft1000_write_register(ft1000dev, HOST_INTF_BE, @@ -457,21 +318,11 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) } } -//--------------------------------------------------------------------------- -// Function: card_send_command -// -// Parameters: ft1000_usb - device structure -// ptempbuffer - command buffer -// size - command buffer size -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function sends a command to ASIC -// -// Notes: -// -//--------------------------------------------------------------------------- +/* send a command to ASIC +* Parameters: ft1000_usb - device structure +* ptempbuffer - command buffer +* size - command buffer size +*/ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, int size) { @@ -486,7 +337,7 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); if (temp & 0x0100) - msleep(10); + usleep_range(900, 1100); /* check for odd word */ size = size + 2; @@ -496,29 +347,21 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, size += 4 - (size % 4); ft1000_write_dpram32(ft1000dev, 0, commandbuf, size); - msleep(1); + usleep_range(900, 1100); ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); - msleep(1); + usleep_range(900, 1100); ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - if ((temp & 0x0100) == 0) { - //DEBUG("card_send_command: Message sent\n"); - } +#if 0 + if ((temp & 0x0100) == 0) + DEBUG("card_send_command: Message sent\n"); +#endif } -//-------------------------------------------------------------------------- -// -// Function: dsp_reload -// -// Synopsis: This function is called to load or reload the DSP -// -// Arguments: ft1000dev - device structure -// -// Returns: None -//----------------------------------------------------------------------- +/* load or reload the DSP */ int dsp_reload(struct ft1000_usb *ft1000dev) { int status; @@ -559,7 +402,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) /* call codeloader */ status = scram_dnldr(ft1000dev, pFileStart, FileLength); - if (status != STATUS_SUCCESS) + if (status != 0) return -EIO; msleep(1000); @@ -569,17 +412,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_asic -// Description: This function will call the Card Service function to reset the -// ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/* call the Card Service function to reset the ASIC. */ static void ft1000_reset_asic(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -607,18 +440,6 @@ static void ft1000_reset_asic(struct net_device *dev) DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); } - -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_card -// Description: This function will reset the card -// Input: -// dev - device structure -// Output: -// status - FALSE (card reset fail) -// TRUE (card reset successful) -// -//--------------------------------------------------------------------------- static int ft1000_reset_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -666,19 +487,7 @@ static int ft1000_reset_card(struct net_device *dev) return TRUE; } -//--------------------------------------------------------------------------- -// Function: ft1000_usb_transmit_complete -// -// Parameters: urb - transmitted usb urb -// -// -// Returns: none -// -// Description: This is the callback function when a urb is transmitted -// -// Notes: -// -//--------------------------------------------------------------------------- +/* callback function when a urb is transmitted */ static void ft1000_usb_transmit_complete(struct urb *urb) { @@ -690,22 +499,10 @@ static void ft1000_usb_transmit_complete(struct urb *urb) netif_wake_queue(ft1000dev->net); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_down_pkt -// Description: This function will take an ethernet packet and convert it to -// a Flarion packet prior to sending it to the ASIC Downlink -// FIFO. -// Input: -// dev - device structure -// packet - address of ethernet packet -// len - length of IP packet -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- -static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) +/* take an ethernet packet and convert it to a Flarion +* packet prior to sending it to the ASIC Downlink FIFO. +*/ +static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) { struct ft1000_info *pInfo = netdev_priv(netdev); struct ft1000_usb *pFt1000Dev = pInfo->priv; @@ -769,20 +566,10 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) return 0; } -//--------------------------------------------------------------------------- -// Function: ft1000_start_xmit -// -// Parameters: skb - socket buffer to be sent -// dev - network device -// -// -// Returns: none -// -// Description: transmit a ethernet packet -// -// Notes: -// -//--------------------------------------------------------------------------- +/* transmit an ethernet packet +* Parameters: skb - socket buffer to be sent +* dev - network device +*/ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -827,20 +614,7 @@ err: return NETDEV_TX_OK; } -//--------------------------------------------------------------------------- -// Function: ft1000_open -// -// Parameters: -// dev - network device -// -// -// Returns: none -// -// Description: open the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* open the network driver */ static int ft1000_open(struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -871,29 +645,14 @@ static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev) return &(info->stats); } -static const struct net_device_ops ftnet_ops = -{ +static const struct net_device_ops ftnet_ops = { .ndo_open = &ft1000_open, .ndo_stop = &ft1000_close, .ndo_start_xmit = &ft1000_start_xmit, .ndo_get_stats = &ft1000_netdev_stats, }; -//--------------------------------------------------------------------------- -// Function: init_ft1000_netdev -// -// Parameters: ft1000dev - device structure -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function initialize the network device -// -// Notes: -// -//--------------------------------------------------------------------------- - +/* initialize the network device */ static int ft1000_reset(void *dev) { ft1000_reset_card(dev); @@ -931,14 +690,14 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) card_nr[1] = '\0'; ret_val = kstrtou8(card_nr, 10, &gCardIndex); if (ret_val) { - printk(KERN_ERR "Can't parse netdev\n"); + netdev_err(ft1000dev->net, "Can't parse netdev\n"); goto err_net; } ft1000dev->CardNumber = gCardIndex; DEBUG("card number = %d\n", ft1000dev->CardNumber); } else { - printk(KERN_ERR "ft1000: Invalid device name\n"); + netdev_err(ft1000dev->net, "ft1000: Invalid device name\n"); ret_val = -ENXIO; goto err_net; } @@ -1014,20 +773,7 @@ err_net: return ret_val; } -//--------------------------------------------------------------------------- -// Function: reg_ft1000_netdev -// -// Parameters: ft1000dev - device structure -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function register the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* register the network driver */ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, struct usb_interface *intf) { @@ -1060,19 +806,9 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_up_pkt -// Description: This function will take a packet from the FIFO up link and -// convert it into an ethernet packet and deliver it to the IP stack -// Input: -// urb - the receiving usb urb -// -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/* take a packet from the FIFO up link and +* convert it into an ethernet packet and deliver it to the IP stack +*/ static int ft1000_copy_up_pkt(struct urb *urb) { struct ft1000_info *info = urb->context; @@ -1090,9 +826,9 @@ static int ft1000_copy_up_pkt(struct urb *urb) if (ft1000dev->status & FT1000_STATUS_CLOSING) { DEBUG("network driver is closed, return\n"); - return STATUS_SUCCESS; + return 0; } - // Read length + /* Read length */ len = urb->transfer_buffer_length; lena = urb->actual_length; @@ -1105,7 +841,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) if (tempword != *chksum) { info->stats.rx_errors++; ft1000_submit_rx_urb(info); - return STATUS_FAILURE; + return -1; } skb = dev_alloc_skb(len + 12 + 2); @@ -1114,7 +850,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); info->stats.rx_errors++; ft1000_submit_rx_urb(info); - return STATUS_FAILURE; + return -1; } pbuffer = (u8 *) skb_put(skb, len + 12); @@ -1151,23 +887,11 @@ static int ft1000_copy_up_pkt(struct urb *urb) ft1000_submit_rx_urb(info); - return SUCCESS; + return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_submit_rx_urb -// Description: the receiving function of the network driver -// -// Input: -// info - a private structure contains the device information -// -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/* the receiving function of the network driver */ static int ft1000_submit_rx_urb(struct ft1000_info *info) { int result; @@ -1196,20 +920,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) return 0; } -//--------------------------------------------------------------------------- -// Function: ft1000_close -// -// Parameters: -// net - network device -// -// -// Returns: none -// -// Description: close the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* close the network driver */ int ft1000_close(struct net_device *net) { struct ft1000_info *pInfo = netdev_priv(net); @@ -1227,26 +938,14 @@ int ft1000_close(struct net_device *net) return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_chkcard -// Description: This function will check if the device is presently available on -// the system. -// Input: -// dev - device structure -// Output: -// status - FALSE (device is not present) -// TRUE (device is present) -// -//--------------------------------------------------------------------------- +/* check if the device is presently available on the system. */ static int ft1000_chkcard(struct ft1000_usb *dev) { u16 tempword; - u16 status; + int status; if (dev->fCondResetPend) { - DEBUG - ("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); + DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); return TRUE; } /* Mask register is used to check for device presence since it is never @@ -1254,8 +953,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) */ status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG - ("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); return FALSE; } /* The system will return the value of 0xffff for the version register @@ -1264,30 +962,22 @@ static int ft1000_chkcard(struct ft1000_usb *dev) status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); if (tempword != 0x1b01) { dev->status |= FT1000_STATUS_CLOSING; - DEBUG - ("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); return FALSE; } return TRUE; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_receive_cmd -// Description: This function will read a message from the dpram area. -// Input: -// dev - network device structure -// pbuffer - caller supply address to buffer -// pnxtph - pointer to next pseudo header -// Output: -// Status = 0 (unsuccessful) -// = 1 (successful) -// -//--------------------------------------------------------------------------- +/* read a message from the dpram area. +* Input: +* dev - network device structure +* pbuffer - caller supply address to buffer +*/ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, - int maxsz, u16 *pnxtph) + int maxsz) { - u16 size, ret; + u16 size; + int ret; u16 *ppseudohdr; int i; u16 tempword; @@ -1359,7 +1049,7 @@ static int ft1000_dsp_prov(void *arg) struct prov_record *ptr; struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; - u16 status; + int status; u16 TempShortBuf[256]; DEBUG("*** DspProv Entered\n"); @@ -1381,7 +1071,7 @@ static int ft1000_dsp_prov(void *arg) i++; if (i == 10) { DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); - return STATUS_FAILURE; + return -1; } ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); @@ -1405,9 +1095,8 @@ static int ft1000_dsp_prov(void *arg) ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; - for (i = 1; i < 7; i++) { + for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - } TempShortBuf[0] = 0; TempShortBuf[1] = htons(len); @@ -1425,7 +1114,7 @@ static int ft1000_dsp_prov(void *arg) kfree(ptr->pprov_data); kfree(ptr); } - msleep(10); + usleep_range(9000, 11000); } DEBUG("DSP Provisioning List Entry finished\n"); @@ -1435,7 +1124,7 @@ static int ft1000_dsp_prov(void *arg) dev->fProvComplete = true; info->CardReady = 1; - return STATUS_SUCCESS; + return 0; } static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) @@ -1449,7 +1138,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) u16 i; struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; - u16 status; + int status; union { u8 byte[2]; u16 wrd; @@ -1457,7 +1146,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) char *cmdbuffer = kmalloc(1600, GFP_KERNEL); if (!cmdbuffer) - return STATUS_FAILURE; + return -1; status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); @@ -1481,154 +1170,179 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); switch (msgtype) { case MEDIA_STATE:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); - - pmediamsg = (struct media_msg *)&cmdbuffer[0]; - if (info->ProgConStat != 0xFF) { - if (pmediamsg->state) { - DEBUG("Media is up\n"); - if (info->mediastate == 0) { - if (dev->NetDevRegDone) { - netif_wake_queue(dev-> - net); - } - info->mediastate = 1; - } - } else { - DEBUG("Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - if (dev->NetDevRegDone) { - } - info->ConTm = 0; - } + DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); + pmediamsg = (struct media_msg *)&cmdbuffer[0]; + if (info->ProgConStat != 0xFF) { + if (pmediamsg->state) { + DEBUG("Media is up\n"); + if (info->mediastate == 0) { + if (dev->NetDevRegDone) + netif_wake_queue(dev->net); + info->mediastate = 1; } } else { DEBUG("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; - info->ConTm = 0; + if (dev->NetDevRegDone) + info->ConTm = 0; } } - break; + } else { + DEBUG("Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + info->ConTm = 0; + } } + break; + } case DSP_INIT_MSG:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); - - pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; - memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); - memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, - HWSERNUMSZ); - memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); - memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); - DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", - info->eui64[0], info->eui64[1], info->eui64[2], - info->eui64[3], info->eui64[4], info->eui64[5], - info->eui64[6], info->eui64[7]); - dev->net->dev_addr[0] = info->eui64[0]; - dev->net->dev_addr[1] = info->eui64[1]; - dev->net->dev_addr[2] = info->eui64[2]; - dev->net->dev_addr[3] = info->eui64[5]; - dev->net->dev_addr[4] = info->eui64[6]; - dev->net->dev_addr[5] = info->eui64[7]; - - if (ntohs(pdspinitmsg->length) == - (sizeof(struct dsp_init_msg) - 20)) { - memcpy(info->ProductMode, - pdspinitmsg->ProductMode, MODESZ); - memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, - CALVERSZ); - memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, - CALDATESZ); - DEBUG("RFCalVer = 0x%2x 0x%2x\n", - info->RfCalVer[0], info->RfCalVer[1]); - } - break; + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; + memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); + DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); + memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, + HWSERNUMSZ); + memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); + memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); + DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", + info->eui64[0], info->eui64[1], info->eui64[2], + info->eui64[3], info->eui64[4], info->eui64[5], + info->eui64[6], info->eui64[7]); + dev->net->dev_addr[0] = info->eui64[0]; + dev->net->dev_addr[1] = info->eui64[1]; + dev->net->dev_addr[2] = info->eui64[2]; + dev->net->dev_addr[3] = info->eui64[5]; + dev->net->dev_addr[4] = info->eui64[6]; + dev->net->dev_addr[5] = info->eui64[7]; + + if (ntohs(pdspinitmsg->length) == + (sizeof(struct dsp_init_msg) - 20)) { + memcpy(info->ProductMode, pdspinitmsg->ProductMode, + MODESZ); + memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); + memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, + CALDATESZ); + DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], + info->RfCalVer[1]); } + break; + } case DSP_PROVISION:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); - /* kick off dspprov routine to start provisioning - * Send provisioning data to DSP - */ - if (list_empty(&info->prov_list) == 0) { - dev->fProvComplete = false; - status = ft1000_dsp_prov(dev); - if (status != STATUS_SUCCESS) - goto out; - } else { - dev->fProvComplete = true; - status = - ft1000_write_register(dev, FT1000_DB_HB, - FT1000_REG_DOORBELL); - DEBUG - ("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); - } - DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); - break; + /* kick off dspprov routine to start provisioning + * Send provisioning data to DSP + */ + if (list_empty(&info->prov_list) == 0) { + dev->fProvComplete = false; + status = ft1000_dsp_prov(dev); + if (status != 0) + goto out; + } else { + dev->fProvComplete = true; + status = ft1000_write_register(dev, FT1000_DB_HB, + FT1000_REG_DOORBELL); + DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); } + DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); + break; + } case DSP_STORE_INFO:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); - - DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); - tempword = ntohs(pdrvmsg->length); - info->DSPInfoBlklen = tempword; - if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) &pdrvmsg->data[0]; - for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG - ("FT1000:drivermsg:dsp info data = 0x%x\n", - *pmsg); - info->DSPInfoBlk[i + 10] = *pmsg++; - } - } else { - info->DSPInfoBlklen = 0; + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); + DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); + tempword = ntohs(pdrvmsg->length); + info->DSPInfoBlklen = tempword; + if (tempword < (MAX_DSP_SESS_REC - 4)) { + pmsg = (u16 *) &pdrvmsg->data[0]; + for (i = 0; i < ((tempword + 1) / 2); i++) { + DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); + info->DSPInfoBlk[i + 10] = *pmsg++; } - break; + } else { + info->DSPInfoBlklen = 0; } + break; + } case DSP_GET_INFO:{ - DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); - /* copy dsp info block to dsp */ - dev->DrvMsgPend = 1; - /* allow any outstanding ioctl to finish */ + DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); + /* copy dsp info block to dsp */ + dev->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) - break; - } + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + break; } - /* Put message into Slow Queue - * Form Pseudo header - */ - pmsg = (u16 *) info->DSPInfoBlk; - *pmsg++ = 0; - *pmsg++ = - htons(info->DSPInfoBlklen + 20 + - info->DSPInfoBlklen); - ppseudo_hdr = - (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; - ppseudo_hdr->length = - htons(info->DSPInfoBlklen + 4 + - info->DSPInfoBlklen); + } + /* Put message into Slow Queue Form Pseudo header */ + pmsg = (u16 *) info->DSPInfoBlk; + *pmsg++ = 0; + *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen); + ppseudo_hdr = + (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; + ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4 + + info->DSPInfoBlklen); + ppseudo_hdr->source = 0x10; + ppseudo_hdr->destination = 0x20; + ppseudo_hdr->portdest = 0; + ppseudo_hdr->portsrc = 0; + ppseudo_hdr->sh_str_id = 0; + ppseudo_hdr->control = 0; + ppseudo_hdr->rsvd1 = 0; + ppseudo_hdr->rsvd2 = 0; + ppseudo_hdr->qos_class = 0; + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + /* Insert application id */ + ppseudo_hdr->portsrc = 0; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) + ppseudo_hdr->checksum ^= *pmsg++; + + info->DSPInfoBlk[10] = 0x7200; + info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); + status = ft1000_write_dpram32(dev, 0, + (u8 *)&info->DSPInfoBlk[0], + (unsigned short)(info->DSPInfoBlklen + 22)); + status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); + dev->DrvMsgPend = 0; + break; + } + case GET_DRV_ERR_RPT_MSG:{ + DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + /* copy driver error message to dsp */ + dev->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + mdelay(10); + } + if ((tempword & FT1000_DB_DPRAM_TX) == 0) { + /* Put message into Slow Queue Form Pseudo header */ + pmsg = (u16 *) &tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; ppseudo_hdr->portdest = 0; @@ -1647,293 +1361,245 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - info->DSPInfoBlk[10] = 0x7200; - info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); - status = - ft1000_write_dpram32(dev, 0, - (u8 *) &info->DSPInfoBlk[0], - (unsigned short)(info-> - DSPInfoBlklen - + 22)); - status = - ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); - dev->DrvMsgPend = 0; - - break; + pmsg = (u16 *) &tempbuffer[16]; + *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); + *pmsg++ = htons(0x000e); + *pmsg++ = htons(info->DSP_TIME[0]); + *pmsg++ = htons(info->DSP_TIME[1]); + *pmsg++ = htons(info->DSP_TIME[2]); + *pmsg++ = htons(info->DSP_TIME[3]); + convert.byte[0] = info->DspVer[0]; + convert.byte[1] = info->DspVer[1]; + *pmsg++ = convert.wrd; + convert.byte[0] = info->DspVer[2]; + convert.byte[1] = info->DspVer[3]; + *pmsg++ = convert.wrd; + *pmsg++ = htons(info->DrvErrNum); + + card_send_command(dev, (unsigned char *)&tempbuffer[0], + (u16)(0x0012 + PSEUDOSZ)); + info->DrvErrNum = 0; } - - case GET_DRV_ERR_RPT_MSG:{ - DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); - /* copy driver error message to dsp */ - dev->DrvMsgPend = 1; - /* allow any outstanding ioctl to finish */ - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) - mdelay(10); - } - - if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - /* Put message into Slow Queue - * Form Pseudo header - */ - pmsg = (u16 *) &tempbuffer[0]; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - ppseudo_hdr->length = htons(0x0012); - ppseudo_hdr->source = 0x10; - ppseudo_hdr->destination = 0x20; - ppseudo_hdr->portdest = 0; - ppseudo_hdr->portsrc = 0; - ppseudo_hdr->sh_str_id = 0; - ppseudo_hdr->control = 0; - ppseudo_hdr->rsvd1 = 0; - ppseudo_hdr->rsvd2 = 0; - ppseudo_hdr->qos_class = 0; - /* Insert slow queue sequence number */ - ppseudo_hdr->seq_num = info->squeseqnum++; - /* Insert application id */ - ppseudo_hdr->portsrc = 0; - /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - for (i = 1; i < 7; i++) - ppseudo_hdr->checksum ^= *pmsg++; - - pmsg = (u16 *) &tempbuffer[16]; - *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); - *pmsg++ = htons(0x000e); - *pmsg++ = htons(info->DSP_TIME[0]); - *pmsg++ = htons(info->DSP_TIME[1]); - *pmsg++ = htons(info->DSP_TIME[2]); - *pmsg++ = htons(info->DSP_TIME[3]); - convert.byte[0] = info->DspVer[0]; - convert.byte[1] = info->DspVer[1]; - *pmsg++ = convert.wrd; - convert.byte[0] = info->DspVer[2]; - convert.byte[1] = info->DspVer[3]; - *pmsg++ = convert.wrd; - *pmsg++ = htons(info->DrvErrNum); - - card_send_command(dev, - (unsigned char *)&tempbuffer[0], - (u16) (0x0012 + PSEUDOSZ)); - info->DrvErrNum = 0; - } - dev->DrvMsgPend = 0; - - break; - } - + dev->DrvMsgPend = 0; + break; + } default: break; } - status = STATUS_SUCCESS; + status = 0; out: kfree(cmdbuffer); DEBUG("return from ft1000_proc_drvmsg\n"); return status; } -int ft1000_poll(void* dev_id) +/* Check which application has registered for dsp broadcast messages */ +static int dsp_broadcast_msg_id(struct ft1000_usb *dev) { - struct ft1000_usb *dev = (struct ft1000_usb *)dev_id; - struct ft1000_info *info = netdev_priv(dev->net); + struct dpram_blk *pdpram_blk; + unsigned long flags; + int i; - u16 tempword; - u16 status; - u16 size; - int i; - u16 data; - u16 modulo; - u16 portid; - u16 nxtph; + for (i = 0; i < MAX_NUM_APP; i++) { + if ((dev->app_info[i].DspBCMsgFlag) + && (dev->app_info[i].fileobject) + && (dev->app_info[i].NumOfMsg + < MAX_MSG_LIMIT)) { + pdpram_blk = ft1000_get_buffer(&freercvpool); + if (pdpram_blk == NULL) { + DEBUG("Out of memory in free receive command pool\n"); + dev->app_info[i].nRxMsgMiss++; + return -1; + } + if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer, + MAX_CMD_SQSIZE)) { + /* Put message into the + * appropriate application block + */ + dev->app_info[i].nRxMsg++; + spin_lock_irqsave(&free_buff_lock, flags); + list_add_tail(&pdpram_blk->list, + &dev->app_info[i] .app_sqlist); + dev->app_info[i].NumOfMsg++; + spin_unlock_irqrestore(&free_buff_lock, flags); + wake_up_interruptible(&dev->app_info[i] + .wait_dpram_msg); + } else { + dev->app_info[i].nRxMsgMiss++; + ft1000_free_buffer(pdpram_blk, &freercvpool); + DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); + return -1; + } + } + } + return 0; +} + +static int handle_misc_portid(struct ft1000_usb *dev) +{ struct dpram_blk *pdpram_blk; - struct pseudo_hdr *ppseudo_hdr; - unsigned long flags; - - if (ft1000_chkcard(dev) == FALSE) { - DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); - return STATUS_FAILURE; - } - - status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL); - - if ( !status ) - { - - if (tempword & FT1000_DB_DPRAM_RX) { - - status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0); - size = ntohs(data) + 16 + 2; - if (size % 4) { - modulo = 4 - (size % 4); - size = size + modulo; - } - status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1); - portid &= 0xff; - - if (size < MAX_CMD_SQSIZE) { - switch (portid) - { - case DRIVERID: - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); - - status = ft1000_proc_drvmsg (dev, size); - if (status != STATUS_SUCCESS ) - return status; - break; - case DSPBCMSGID: - // This is a dsp broadcast message - // Check which application has registered for dsp broadcast messages - - for (i=0; i<MAX_NUM_APP; i++) { - if ( (dev->app_info[i].DspBCMsgFlag) && (dev->app_info[i].fileobject) && - (dev->app_info[i].NumOfMsg < MAX_MSG_LIMIT) ) - { - nxtph = FT1000_DPRAM_RX_BASE + 2; - pdpram_blk = ft1000_get_buffer (&freercvpool); - if (pdpram_blk != NULL) { - if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) { - ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer; - // Put message into the appropriate application block - dev->app_info[i].nRxMsg++; - spin_lock_irqsave(&free_buff_lock, flags); - list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); - dev->app_info[i].NumOfMsg++; - spin_unlock_irqrestore(&free_buff_lock, flags); - wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); - } - else { - dev->app_info[i].nRxMsgMiss++; - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); - } - } - else { - DEBUG("Out of memory in free receive command pool\n"); - dev->app_info[i].nRxMsgMiss++; - } - } - } - break; - default: - pdpram_blk = ft1000_get_buffer (&freercvpool); - - if (pdpram_blk != NULL) { - if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) { - ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer; - // Search for correct application block - for (i=0; i<MAX_NUM_APP; i++) { - if (dev->app_info[i].app_id == ppseudo_hdr->portdest) { - break; - } - } - - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ppseudo_hdr->portdest); - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - else { - if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - else { - dev->app_info[i].nRxMsg++; - // Put message into the appropriate application block - list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); - dev->app_info[i].NumOfMsg++; - } - } - } - else { - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - } - else { - DEBUG("Out of memory in free receive command pool\n"); - } - break; - } - } - else { - DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); - } - status = ft1000_write_register (dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL); - } - else if (tempword & FT1000_DSP_ASIC_RESET) { - - // Let's reset the ASIC from the Host side as well - status = ft1000_write_register (dev, ASIC_RESET_BIT, FT1000_REG_RESET); - status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET); - i = 0; - while (tempword & ASIC_RESET_BIT) { - status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET); - msleep(10); - i++; - if (i==100) - break; - } - if (i==100) { - DEBUG("Unable to reset ASIC\n"); - return STATUS_SUCCESS; - } - msleep(10); - // Program WMARK register - status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK); - // clear ASIC reset doorbell - status = ft1000_write_register (dev, FT1000_DSP_ASIC_RESET, FT1000_REG_DOORBELL); - msleep(10); - } - else if (tempword & FT1000_ASIC_RESET_REQ) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); - - // clear ASIC reset request from DSP - status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL); - status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); - // copy dsp session record from Adapter block - status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024); - // Program WMARK register - status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK); - // ring doorbell to tell DSP that ASIC is out of reset - status = ft1000_write_register (dev, FT1000_ASIC_RESET_DSP, FT1000_REG_DOORBELL); - } - else if (tempword & FT1000_DB_COND_RESET) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); - - if (!dev->fAppMsgPend) { - // Reset ASIC and DSP - - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX); - info->CardReady = 0; - info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG("ft1000_hw:DSP conditional reset requested\n"); - info->ft1000_reset(dev->net); - } - else { - dev->fProvComplete = false; - dev->fCondResetPend = true; - } - - ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL); - } - - } - - return STATUS_SUCCESS; + int i; + + pdpram_blk = ft1000_get_buffer(&freercvpool); + if (pdpram_blk == NULL) { + DEBUG("Out of memory in free receive command pool\n"); + return -1; + } + if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE)) + goto exit_failure; + /* Search for correct application block */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (dev->app_info[i].app_id == ((struct pseudo_hdr *) + pdpram_blk->pbuffer)->portdest) + break; + } + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); + goto exit_failure; + } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { + goto exit_failure; + } else { + dev->app_info[i].nRxMsg++; + /* Put message into the appropriate application block */ + list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); + dev->app_info[i].NumOfMsg++; + } + return 0; + +exit_failure: + ft1000_free_buffer(pdpram_blk, &freercvpool); + return -1; +} + +int ft1000_poll(void *dev_id) +{ + struct ft1000_usb *dev = (struct ft1000_usb *)dev_id; + struct ft1000_info *info = netdev_priv(dev->net); + u16 tempword; + int status; + u16 size; + int i; + u16 data; + u16 modulo; + u16 portid; + + if (ft1000_chkcard(dev) == FALSE) { + DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); + return -1; + } + status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); + if (!status) { + if (tempword & FT1000_DB_DPRAM_RX) { + status = ft1000_read_dpram16(dev, + 0x200, (u8 *)&data, 0); + size = ntohs(data) + 16 + 2; + if (size % 4) { + modulo = 4 - (size % 4); + size = size + modulo; + } + status = ft1000_read_dpram16(dev, 0x201, + (u8 *)&portid, 1); + portid &= 0xff; + if (size < MAX_CMD_SQSIZE) { + switch (portid) { + case DRIVERID: + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); + status = ft1000_proc_drvmsg(dev, size); + if (status != 0) + return status; + break; + case DSPBCMSGID: + status = dsp_broadcast_msg_id(dev); + break; + default: + status = handle_misc_portid(dev); + break; + } + } else + DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); + status = ft1000_write_register(dev, + FT1000_DB_DPRAM_RX, + FT1000_REG_DOORBELL); + } else if (tempword & FT1000_DSP_ASIC_RESET) { + /* Let's reset the ASIC from the Host side as well */ + status = ft1000_write_register(dev, ASIC_RESET_BIT, + FT1000_REG_RESET); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_RESET); + i = 0; + while (tempword & ASIC_RESET_BIT) { + status = ft1000_read_register(dev, &tempword, + FT1000_REG_RESET); + usleep_range(9000, 11000); + i++; + if (i == 100) + break; + } + if (i == 100) { + DEBUG("Unable to reset ASIC\n"); + return 0; + } + usleep_range(9000, 11000); + /* Program WMARK register */ + status = ft1000_write_register(dev, 0x600, + FT1000_REG_MAG_WATERMARK); + /* clear ASIC reset doorbell */ + status = ft1000_write_register(dev, + FT1000_DSP_ASIC_RESET, + FT1000_REG_DOORBELL); + usleep_range(9000, 11000); + } else if (tempword & FT1000_ASIC_RESET_REQ) { + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); + /* clear ASIC reset request from DSP */ + status = ft1000_write_register(dev, + FT1000_ASIC_RESET_REQ, + FT1000_REG_DOORBELL); + status = ft1000_write_register(dev, HOST_INTF_BE, + FT1000_REG_SUP_CTRL); + /* copy dsp session record from Adapter block */ + status = ft1000_write_dpram32(dev, 0, + (u8 *)&info->DSPSess.Rec[0], 1024); + status = ft1000_write_register(dev, 0x600, + FT1000_REG_MAG_WATERMARK); + /* ring doorbell to tell DSP that + * ASIC is out of reset + * */ + status = ft1000_write_register(dev, + FT1000_ASIC_RESET_DSP, + FT1000_REG_DOORBELL); + } else if (tempword & FT1000_DB_COND_RESET) { + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); + if (!dev->fAppMsgPend) { + /* Reset ASIC and DSP */ + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER0, + (u8 *)&(info->DSP_TIME[0]), + FT1000_MAG_DSP_TIMER0_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER1, + (u8 *)&(info->DSP_TIME[1]), + FT1000_MAG_DSP_TIMER1_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER2, + (u8 *)&(info->DSP_TIME[2]), + FT1000_MAG_DSP_TIMER2_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER3, + (u8 *)&(info->DSP_TIME[3]), + FT1000_MAG_DSP_TIMER3_INDX); + info->CardReady = 0; + info->DrvErrNum = DSP_CONDRESET_INFO; + DEBUG("ft1000_hw:DSP conditional reset requested\n"); + info->ft1000_reset(dev->net); + } else { + dev->fProvComplete = false; + dev->fCondResetPend = true; + } + ft1000_write_register(dev, FT1000_DB_COND_RESET, + FT1000_REG_DOORBELL); + } + } + return 0; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 5ead942be680..2575d0d6bff3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -33,13 +33,13 @@ #define seq_putx(m, message, size, var) \ seq_printf(m, message); \ - for(i = 0; i < (size - 1); i++) \ + for (i = 0; i < (size - 1); i++) \ seq_printf(m, "%02x:", var[i]); \ seq_printf(m, "%02x\n", var[i]) #define seq_putd(m, message, size, var) \ seq_printf(m, message); \ - for(i = 0; i < (size - 1); i++) \ + for (i = 0; i < (size - 1); i++) \ seq_printf(m, "%d.", var[i]); \ seq_printf(m, "%d\n", var[i]) @@ -47,14 +47,14 @@ #define FTNET_PROC init_net.proc_net -int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx, +int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u8 highlow); static int ft1000ReadProc(struct seq_file *m, void *v) { - static const char *status[] = { - "Idle (Disconnect)", + static const char *status[] = { + "Idle (Disconnect)", "Searching", "Active (Connected)", "Waiting for L2", @@ -127,10 +127,10 @@ static int ft1000ReadProc(struct seq_file *m, void *v) } seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n", - ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); + ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); seq_printf(m, "Connection Time[s]: %ld\n", delta); seq_printf(m, "Asic ID: %s\n", - (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); + (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); seq_putx(m, "SKU: ", SKUSZ, info->Sku); seq_putx(m, "EUI64: ", EUISZ, info->eui64); seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index a8dd1e54878c..da6cc370c535 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -45,13 +45,13 @@ static int ft1000_poll_thread(void *arg) msleep(10); if (!gPollingfailed) { ret = ft1000_poll(arg); - if (ret != STATUS_SUCCESS) { + if (ret != 0) { DEBUG("ft1000_poll_thread: polling failed\n"); gPollingfailed = true; } } } - return STATUS_SUCCESS; + return 0; } static int ft1000_probe(struct usb_interface *interface, diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index e8d00a930dc6..a6fdd524ee6f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -11,8 +11,6 @@ #define PSEUDOSZ 16 -#define SUCCESS 0x00 - struct app_info_block { u32 nTxMsg; /* DPRAM msg sent to DSP with app_id */ u32 nRxMsg; /* DPRAM msg rcv from dsp with app_id */ @@ -31,9 +29,6 @@ struct app_info_block { #define FALSE 0 #define TRUE 1 -#define STATUS_SUCCESS 0 -#define STATUS_FAILURE 0x1001 - #define FT1000_STATUS_CLOSING 0x01 #define DSPBCMSGID 0x10 diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index c57a6ba5d010..74a03608b2dd 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -44,18 +44,6 @@ */ #define DEFAULT_MTU_SIZE 1500 -#define gdm_dev_endian(n) (\ - n->phy_dev->get_endian(n->phy_dev->priv_dev)) - -#define gdm_lte_hci_send(n, d, l) (\ - n->phy_dev->send_hci_func(n->phy_dev->priv_dev, d, l, NULL, NULL)) - -#define gdm_lte_sdu_send(n, d, l, c, b, i, t) (\ - n->phy_dev->send_sdu_func(n->phy_dev->priv_dev, d, l, n->pdn_table.dft_eps_id, 0, c, b, i, t)) - -#define gdm_lte_rcv_with_cb(n, c, b, e) (\ - n->rcv_func(n->priv_dev, c, b, e)) - #define IP_VERSION_4 4 #define IP_VERSION_6 6 @@ -458,13 +446,11 @@ static int gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) sscanf(dev->name, "lte%d", &idx); - ret = gdm_lte_sdu_send(nic, - data_buf, - data_len, - tx_complete, - nic, - idx, - nic_type); + ret = nic->phy_dev->send_sdu_func(nic->phy_dev->priv_dev, + data_buf, data_len, + nic->pdn_table.dft_eps_id, 0, + tx_complete, nic, idx, + nic_type); if (ret == TX_NO_BUFFER || ret == TX_NO_SPC) { netif_stop_queue(dev); @@ -503,14 +489,18 @@ static int gdm_lte_event_send(struct net_device *dev, char *buf, int len) sscanf(dev->name, "lte%d", &idx); return netlink_send(lte_event.sock, idx, 0, buf, - gdm_dev16_to_cpu(gdm_dev_endian(nic), hci->len) + HCI_HEADER_SIZE); + gdm_dev16_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), hci->len) + + HCI_HEADER_SIZE); } static void gdm_lte_event_rcv(struct net_device *dev, u16 type, void *msg, int len) { struct nic *nic = netdev_priv(dev); - gdm_lte_hci_send(nic, msg, len); + nic->phy_dev->send_hci_func(nic->phy_dev->priv_dev, msg, len, NULL, + NULL); } int gdm_lte_event_init(void) @@ -688,8 +678,14 @@ static void gdm_lte_pdn_table(struct net_device *dev, char *buf, int len) if (pdn_table->activate) { nic->pdn_table.activate = pdn_table->activate; - nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->dft_eps_id); - nic->pdn_table.nic_type = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->nic_type); + nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), + pdn_table->dft_eps_id); + nic->pdn_table.nic_type = gdm_dev32_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), + pdn_table->nic_type); netdev_info(dev, "pdn activated, nic_type=0x%x\n", nic->pdn_table.nic_type); @@ -762,7 +758,7 @@ void start_rx_proc(struct phy_dev *phy_dev) int i; for (i = 0; i < MAX_RX_SUBMIT_COUNT; i++) - gdm_lte_rcv_with_cb(phy_dev, rx_complete, phy_dev, USB_COMPLETE); + phy_dev->rcv_func(phy_dev->priv_dev, rx_complete, phy_dev, USB_COMPLETE); } static struct net_device_ops gdm_netdev_ops = { diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 62163673976c..2fa3a5a6580f 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c @@ -158,7 +158,6 @@ static int up_to_host(struct mux_rx *r) unsigned int start_flag; unsigned int payload_size; unsigned short packet_type; - int remain; int dummy_cnt; u32 packet_size_sum = r->offset; int index; @@ -176,8 +175,7 @@ static int up_to_host(struct mux_rx *r) break; } - remain = (MUX_HEADER_SIZE + payload_size) % 4; - dummy_cnt = remain ? (4-remain) : 0; + dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4); if (len - packet_size_sum < MUX_HEADER_SIZE + payload_size + dummy_cnt) { @@ -361,7 +359,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, struct mux_pkt_header *mux_header; struct mux_tx *t = NULL; static u32 seq_num = 1; - int remain; int dummy_cnt; int total_len; int ret; @@ -375,8 +372,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, spin_lock_irqsave(&mux_dev->write_lock, flags); - remain = (MUX_HEADER_SIZE + len) % 4; - dummy_cnt = remain ? (4 - remain) : 0; + dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4); total_len = len + MUX_HEADER_SIZE + dummy_cnt; diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c index 781134af69d1..33458a583142 100644 --- a/drivers/staging/gdm724x/gdm_usb.c +++ b/drivers/staging/gdm724x/gdm_usb.c @@ -830,24 +830,19 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id if (bInterfaceNumber > NETWORK_INTERFACE) { pr_info("not a network device\n"); - return -1; + return -ENODEV; } - phy_dev = kmalloc(sizeof(struct phy_dev), GFP_ATOMIC); - if (!phy_dev) { - ret = -ENOMEM; - goto out; - } + phy_dev = kzalloc(sizeof(struct phy_dev), GFP_KERNEL); + if (!phy_dev) + return -ENOMEM; - udev = kmalloc(sizeof(struct lte_udev), GFP_ATOMIC); + udev = kzalloc(sizeof(struct lte_udev), GFP_KERNEL); if (!udev) { ret = -ENOMEM; - goto out; + goto err_udev; } - memset(phy_dev, 0, sizeof(struct phy_dev)); - memset(udev, 0, sizeof(struct lte_udev)); - phy_dev->priv_dev = (void *)udev; phy_dev->send_hci_func = gdm_usb_hci_send; phy_dev->send_sdu_func = gdm_usb_sdu_send; @@ -858,7 +853,7 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = init_usb(udev); if (ret < 0) { pr_err("init_usb func failed\n"); - goto out; + goto err_init_usb; } udev->intf = intf; @@ -875,23 +870,22 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = request_mac_address(udev); if (ret < 0) { pr_err("request Mac address failed\n"); - goto out; + goto err_mac_address; } start_rx_proc(phy_dev); -out: - - if (ret < 0) { - kfree(phy_dev); - if (udev) { - release_usb(udev); - kfree(udev); - } - } - usb_get_dev(usbdev); usb_set_intfdata(intf, phy_dev); + return 0; + +err_mac_address: + release_usb(udev); +err_init_usb: + kfree(udev); +err_udev: + kfree(phy_dev); + return ret; } diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 4c9364b63c77..6f38ca95f9bb 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -439,13 +439,13 @@ static int adis16220_probe(struct spi_device *spi) indio_dev->channels = adis16220_channels; indio_dev->num_channels = ARRAY_SIZE(adis16220_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin); if (ret) - goto error_unregister_dev; + return ret; ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin); if (ret) @@ -470,8 +470,6 @@ error_rm_adc1_bin: sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); error_rm_accel_bin: sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); -error_unregister_dev: - iio_device_unregister(indio_dev); return ret; } @@ -482,7 +480,6 @@ static int adis16220_remove(struct spi_device *spi) sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); - iio_device_unregister(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 9f48e5c74eed..2369cf28412e 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -412,7 +412,7 @@ static int ad7816_probe(struct spi_device *spi_dev) return ret; } - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi_dev->dev, indio_dev); if (ret) return ret; @@ -422,15 +422,6 @@ static int ad7816_probe(struct spi_device *spi_dev) return 0; } -static int ad7816_remove(struct spi_device *spi_dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); - - iio_device_unregister(indio_dev); - - return 0; -} - static const struct spi_device_id ad7816_id[] = { { "ad7816", 0 }, { "ad7817", 0 }, @@ -446,7 +437,6 @@ static struct spi_driver ad7816_driver = { .owner = THIS_MODULE, }, .probe = ad7816_probe, - .remove = ad7816_remove, .id_table = ad7816_id, }; module_spi_driver(ad7816_driver); diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index ef0a21d8ce15..a876ce755351 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -183,7 +183,7 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) iodev->channels = lpc32xx_adc_iio_channels; iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels); - retval = iio_device_register(iodev); + retval = devm_iio_device_register(&pdev->dev, iodev); if (retval) return retval; @@ -192,15 +192,6 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) return 0; } -static int lpc32xx_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *iodev = platform_get_drvdata(pdev); - - iio_device_unregister(iodev); - - return 0; -} - #ifdef CONFIG_OF static const struct of_device_id lpc32xx_adc_match[] = { { .compatible = "nxp,lpc3220-adc" }, @@ -211,7 +202,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match); static struct platform_driver lpc32xx_adc_driver = { .probe = lpc32xx_adc_probe, - .remove = lpc32xx_adc_remove, .driver = { .name = MOD_NAME, .owner = THIS_MODULE, diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 0feea5541d02..75ddd4f801a3 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -108,11 +108,6 @@ static int adt7316_i2c_probe(struct i2c_client *client, return adt7316_probe(&client->dev, &bus, id->name); } -static int adt7316_i2c_remove(struct i2c_client *client) -{ - return adt7316_remove(&client->dev); -} - static const struct i2c_device_id adt7316_i2c_id[] = { { "adt7316", 0 }, { "adt7317", 0 }, @@ -132,7 +127,6 @@ static struct i2c_driver adt7316_driver = { .owner = THIS_MODULE, }, .probe = adt7316_i2c_probe, - .remove = adt7316_i2c_remove, .id_table = adt7316_i2c_id, }; module_i2c_driver(adt7316_driver); diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index 7f4f0a8245b4..e480abb72e4a 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -116,11 +116,6 @@ static int adt7316_spi_probe(struct spi_device *spi_dev) return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias); } -static int adt7316_spi_remove(struct spi_device *spi_dev) -{ - return adt7316_remove(&spi_dev->dev); -} - static const struct spi_device_id adt7316_spi_id[] = { { "adt7316", 0 }, { "adt7317", 0 }, @@ -140,7 +135,6 @@ static struct spi_driver adt7316_driver = { .owner = THIS_MODULE, }, .probe = adt7316_spi_probe, - .remove = adt7316_spi_remove, .id_table = adt7316_spi_id, }; module_spi_driver(adt7316_driver); diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 80266e801d56..16a8201228ff 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -2166,7 +2166,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, if (ret) return -EIO; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret) return ret; @@ -2177,16 +2177,6 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, } EXPORT_SYMBOL(adt7316_probe); -int adt7316_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - iio_device_unregister(indio_dev); - - return 0; -} -EXPORT_SYMBOL(adt7316_remove); - MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital" " temperature sensor, ADC and DAC driver"); diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index 4d3efff46ae7..2dbfb499528d 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h @@ -31,6 +31,5 @@ extern const struct dev_pm_ops adt7316_pm_ops; #define ADT7316_PM_OPS NULL #endif int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); -int adt7316_remove(struct device *dev); #endif diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 6d3d771154f3..d5d395c2e3e4 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -167,7 +167,7 @@ static int adis16060_r_probe(struct spi_device *spi) indio_dev->channels = adis16060_channels; indio_dev->num_channels = ARRAY_SIZE(adis16060_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; @@ -175,13 +175,6 @@ static int adis16060_r_probe(struct spi_device *spi) return 0; } -/* fixme, confirm ordering in this function */ -static int adis16060_r_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - return 0; -} - static int adis16060_w_probe(struct spi_device *spi) { int ret; @@ -211,7 +204,6 @@ static struct spi_driver adis16060_r_driver = { .owner = THIS_MODULE, }, .probe = adis16060_r_probe, - .remove = adis16060_r_remove, }; static struct spi_driver adis16060_w_driver = { diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 488e690388c9..3660a43b5f08 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -585,7 +585,7 @@ static int isl29018_probe(struct i2c_client *client, indio_dev->name = id->name; indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; - err = iio_device_register(indio_dev); + err = devm_iio_device_register(&client->dev, indio_dev); if (err) { dev_err(&client->dev, "iio registration fails\n"); return err; @@ -594,16 +594,6 @@ static int isl29018_probe(struct i2c_client *client, return 0; } -static int isl29018_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - - dev_dbg(&client->dev, "%s()\n", __func__); - iio_device_unregister(indio_dev); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int isl29018_suspend(struct device *dev) { @@ -664,7 +654,6 @@ static struct i2c_driver isl29018_driver = { .of_match_table = isl29018_of_match, }, .probe = isl29018_probe, - .remove = isl29018_remove, .id_table = isl29018_id, }; module_i2c_driver(isl29018_driver); diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 99421f90d189..bdb018878296 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -624,10 +624,17 @@ static const struct i2c_device_id hmc5843_id[] = { }; MODULE_DEVICE_TABLE(i2c, hmc5843_id); +static const struct of_device_id hmc5843_of_match[] = { + { .compatible = "honeywell,hmc5843" }, + {} +}; +MODULE_DEVICE_TABLE(of, hmc5843_of_match); + static struct i2c_driver hmc5843_driver = { .driver = { .name = "hmc5843", .pm = HMC5843_PM_OPS, + .of_match_table = of_match_ptr(hmc5843_of_match), }, .id_table = hmc5843_id, .probe = hmc5843_probe, diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 62d30179301f..36eedd8a0ea9 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -131,7 +131,7 @@ static int ad2s1200_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels); indio_dev->name = spi_get_device_id(spi)->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; @@ -142,13 +142,6 @@ static int ad2s1200_probe(struct spi_device *spi) return 0; } -static int ad2s1200_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - static const struct spi_device_id ad2s1200_id[] = { { "ad2s1200" }, { "ad2s1205" }, @@ -162,7 +155,6 @@ static struct spi_driver ad2s1200_driver = { .owner = THIS_MODULE, }, .probe = ad2s1200_probe, - .remove = ad2s1200_remove, .id_table = ad2s1200_id, }; module_spi_driver(ad2s1200_driver); diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 5032ff7c2259..78319ad176cd 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -53,3 +53,9 @@ config DRM_IMX_IPUV3 depends on DRM_IMX_IPUV3_CORE help Choose this if you have a i.MX5 or i.MX6 processor. + +config DRM_IMX_HDMI + tristate "Freescale i.MX DRM HDMI" + depends on DRM_IMX + help + Choose this if you want to use HDMI on i.MX6. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 8742432d7b01..4677585b5ad5 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o +obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 6bd015ac9d68..0507b662ae40 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -444,6 +444,8 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) if (!imx_drm_device_get()) ret = -EINVAL; + platform_set_drvdata(drm->platformdev, drm); + ret = 0; err_init: @@ -829,7 +831,7 @@ static int imx_drm_platform_probe(struct platform_device *pdev) static int imx_drm_platform_remove(struct platform_device *pdev) { - drm_platform_exit(&imx_drm_driver, pdev); + drm_put_dev(platform_get_drvdata(pdev)); return 0; } diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c new file mode 100644 index 000000000000..f3a1f5e2e492 --- /dev/null +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -0,0 +1,1916 @@ +/* + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * SH-Mobile High-Definition Multimedia Interface (HDMI) driver + * for SLISHDMI13T and SLIPHDMIT IP cores + * + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + */ + +#include <linux/irq.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> +#include <linux/of_device.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc_helper.h> +#include <drm/drm_edid.h> +#include <drm/drm_encoder_slave.h> + +#include "ipu-v3/imx-ipu-v3.h" +#include "imx-hdmi.h" +#include "imx-drm.h" + +#define HDMI_EDID_LEN 512 + +#define RGB 0 +#define YCBCR444 1 +#define YCBCR422_16BITS 2 +#define YCBCR422_8BITS 3 +#define XVYCC444 4 + +enum hdmi_datamap { + RGB444_8B = 0x01, + RGB444_10B = 0x03, + RGB444_12B = 0x05, + RGB444_16B = 0x07, + YCbCr444_8B = 0x09, + YCbCr444_10B = 0x0B, + YCbCr444_12B = 0x0D, + YCbCr444_16B = 0x0F, + YCbCr422_8B = 0x16, + YCbCr422_10B = 0x14, + YCbCr422_12B = 0x12, +}; + +enum hdmi_colorimetry { + ITU601, + ITU709, +}; + +enum imx_hdmi_devtype { + IMX6Q_HDMI, + IMX6DL_HDMI, +}; + +static const u16 csc_coeff_default[3][4] = { + { 0x2000, 0x0000, 0x0000, 0x0000 }, + { 0x0000, 0x2000, 0x0000, 0x0000 }, + { 0x0000, 0x0000, 0x2000, 0x0000 } +}; + +static const u16 csc_coeff_rgb_out_eitu601[3][4] = { + { 0x2000, 0x6926, 0x74fd, 0x010e }, + { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, + { 0x2000, 0x0000, 0x38b4, 0x7e3b } +}; + +static const u16 csc_coeff_rgb_out_eitu709[3][4] = { + { 0x2000, 0x7106, 0x7a02, 0x00a7 }, + { 0x2000, 0x3264, 0x0000, 0x7e6d }, + { 0x2000, 0x0000, 0x3b61, 0x7e25 } +}; + +static const u16 csc_coeff_rgb_in_eitu601[3][4] = { + { 0x2591, 0x1322, 0x074b, 0x0000 }, + { 0x6535, 0x2000, 0x7acc, 0x0200 }, + { 0x6acd, 0x7534, 0x2000, 0x0200 } +}; + +static const u16 csc_coeff_rgb_in_eitu709[3][4] = { + { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, + { 0x62f0, 0x2000, 0x7d11, 0x0200 }, + { 0x6756, 0x78ab, 0x2000, 0x0200 } +}; + +struct hdmi_vmode { + bool mdvi; + bool mhsyncpolarity; + bool mvsyncpolarity; + bool minterlaced; + bool mdataenablepolarity; + + unsigned int mpixelclock; + unsigned int mpixelrepetitioninput; + unsigned int mpixelrepetitionoutput; +}; + +struct hdmi_data_info { + unsigned int enc_in_format; + unsigned int enc_out_format; + unsigned int enc_color_depth; + unsigned int colorimetry; + unsigned int pix_repet_factor; + unsigned int hdcp_enable; + struct hdmi_vmode video_mode; +}; + +struct imx_hdmi { + struct drm_connector connector; + struct imx_drm_connector *imx_drm_connector; + struct drm_encoder encoder; + struct imx_drm_encoder *imx_drm_encoder; + + enum imx_hdmi_devtype dev_type; + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; + + struct hdmi_data_info hdmi_data; + int vic; + + u8 edid[HDMI_EDID_LEN]; + bool cable_plugin; + + bool phy_enabled; + struct drm_display_mode previous_mode; + + struct regmap *regmap; + struct i2c_adapter *ddc; + void __iomem *regs; + + unsigned long pixel_clk_rate; + unsigned int sample_rate; + int ratio; +}; + +static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di) +{ + regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, + IMX6Q_GPR3_HDMI_MUX_CTL_MASK, + ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); +} + +static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) +{ + writeb(val, hdmi->regs + offset); +} + +static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) +{ + return readb(hdmi->regs + offset); +} + +static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, + u8 shift, u8 mask) +{ + u8 value = hdmi_readb(hdmi, reg) & ~mask; + value |= (data << shift) & mask; + hdmi_writeb(hdmi, value, reg); +} + +static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, + unsigned int value) +{ + u8 val; + + hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); + hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2); + hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3); + + /* nshift factor = 0 */ + val = hdmi_readb(hdmi, HDMI_AUD_CTS3); + val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK; + hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); +} + +static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) +{ + u8 val; + + /* Must be set/cleared first */ + val = hdmi_readb(hdmi, HDMI_AUD_CTS3); + val &= ~HDMI_AUD_CTS3_CTS_MANUAL; + hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); + + hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); + hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); + hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); +} + +static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, + unsigned int ratio) +{ + unsigned int n = (128 * freq) / 1000; + + switch (freq) { + case 32000: + if (pixel_clk == 25170000) + n = (ratio == 150) ? 9152 : 4576; + else if (pixel_clk == 27020000) + n = (ratio == 150) ? 8192 : 4096; + else if (pixel_clk == 74170000 || pixel_clk == 148350000) + n = 11648; + else + n = 4096; + break; + + case 44100: + if (pixel_clk == 25170000) + n = 7007; + else if (pixel_clk == 74170000) + n = 17836; + else if (pixel_clk == 148350000) + n = (ratio == 150) ? 17836 : 8918; + else + n = 6272; + break; + + case 48000: + if (pixel_clk == 25170000) + n = (ratio == 150) ? 9152 : 6864; + else if (pixel_clk == 27020000) + n = (ratio == 150) ? 8192 : 6144; + else if (pixel_clk == 74170000) + n = 11648; + else if (pixel_clk == 148350000) + n = (ratio == 150) ? 11648 : 5824; + else + n = 6144; + break; + + case 88200: + n = hdmi_compute_n(44100, pixel_clk, ratio) * 2; + break; + + case 96000: + n = hdmi_compute_n(48000, pixel_clk, ratio) * 2; + break; + + case 176400: + n = hdmi_compute_n(44100, pixel_clk, ratio) * 4; + break; + + case 192000: + n = hdmi_compute_n(48000, pixel_clk, ratio) * 4; + break; + + default: + break; + } + + return n; +} + +static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, + unsigned int ratio) +{ + unsigned int cts = 0; + + pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq, + pixel_clk, ratio); + + switch (freq) { + case 32000: + if (pixel_clk == 297000000) { + cts = 222750; + break; + } + case 48000: + case 96000: + case 192000: + switch (pixel_clk) { + case 25200000: + case 27000000: + case 54000000: + case 74250000: + case 148500000: + cts = pixel_clk / 1000; + break; + case 297000000: + cts = 247500; + break; + /* + * All other TMDS clocks are not supported by + * DWC_hdmi_tx. The TMDS clocks divided or + * multiplied by 1,001 coefficients are not + * supported. + */ + default: + break; + } + break; + case 44100: + case 88200: + case 176400: + switch (pixel_clk) { + case 25200000: + cts = 28000; + break; + case 27000000: + cts = 30000; + break; + case 54000000: + cts = 60000; + break; + case 74250000: + cts = 82500; + break; + case 148500000: + cts = 165000; + break; + case 297000000: + cts = 247500; + break; + default: + break; + } + break; + default: + break; + } + if (ratio == 100) + return cts; + else + return (cts * ratio) / 100; +} + +static void hdmi_get_pixel_clk(struct imx_hdmi *hdmi) +{ + unsigned long rate; + + rate = 65000000; /* FIXME */ + + if (rate) + hdmi->pixel_clk_rate = rate; +} + +static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi) +{ + unsigned int clk_n, clk_cts; + + clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + + if (!clk_cts) { + dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", + __func__, hdmi->pixel_clk_rate); + return; + } + + dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", + __func__, hdmi->sample_rate, hdmi->ratio, + hdmi->pixel_clk_rate, clk_n, clk_cts); + + hdmi_set_clock_regenerator_n(hdmi, clk_n); + hdmi_regenerate_cts(hdmi, clk_cts); +} + +static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi) +{ + unsigned int clk_n, clk_cts; + + clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + + if (!clk_cts) { + dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", + __func__, hdmi->pixel_clk_rate); + return; + } + + dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", + __func__, hdmi->sample_rate, hdmi->ratio, + hdmi->pixel_clk_rate, clk_n, clk_cts); + + hdmi_set_clock_regenerator_n(hdmi, clk_n); + hdmi_regenerate_cts(hdmi, clk_cts); +} + +static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi) +{ + /* Get pixel clock from ipu */ + hdmi_get_pixel_clk(hdmi); + hdmi_set_clk_regenerator(hdmi); +} + +/* + * this submodule is responsible for the video data synchronization. + * for example, for RGB 4:4:4 input, the data map is defined as + * pin{47~40} <==> R[7:0] + * pin{31~24} <==> G[7:0] + * pin{15~8} <==> B[7:0] + */ +static void hdmi_video_sample(struct imx_hdmi *hdmi) +{ + int color_format = 0; + u8 val; + + if (hdmi->hdmi_data.enc_in_format == RGB) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x01; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x03; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x05; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_format = 0x07; + else + return; + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x09; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x0B; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x0D; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_format = 0x0F; + else + return; + } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x16; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x14; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x12; + else + return; + } + + val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | + ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & + HDMI_TX_INVID0_VIDEO_MAPPING_MASK); + hdmi_writeb(hdmi, val, HDMI_TX_INVID0); + + /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ + val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; + hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); + hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); + hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); + hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); +} + +static int is_color_space_conversion(struct imx_hdmi *hdmi) +{ + return (hdmi->hdmi_data.enc_in_format != + hdmi->hdmi_data.enc_out_format); +} + +static int is_color_space_decimation(struct imx_hdmi *hdmi) +{ + return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) && + (hdmi->hdmi_data.enc_in_format == RGB || + hdmi->hdmi_data.enc_in_format == YCBCR444)); +} + +static int is_color_space_interpolation(struct imx_hdmi *hdmi) +{ + return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) && + (hdmi->hdmi_data.enc_out_format == RGB || + hdmi->hdmi_data.enc_out_format == YCBCR444)); +} + +static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) +{ + const u16 (*csc_coeff)[3][4] = &csc_coeff_default; + u32 csc_scale = 1; + u8 val; + + if (is_color_space_conversion(hdmi)) { + if (hdmi->hdmi_data.enc_out_format == RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + csc_coeff = &csc_coeff_rgb_out_eitu601; + else + csc_coeff = &csc_coeff_rgb_out_eitu709; + } else if (hdmi->hdmi_data.enc_in_format == RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + csc_coeff = &csc_coeff_rgb_in_eitu601; + else + csc_coeff = &csc_coeff_rgb_in_eitu709; + csc_scale = 0; + } + } + + hdmi_writeb(hdmi, ((*csc_coeff)[0][0] & 0xff), HDMI_CSC_COEF_A1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][0] >> 8), HDMI_CSC_COEF_A1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][1] & 0xff), HDMI_CSC_COEF_A2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][1] >> 8), HDMI_CSC_COEF_A2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][2] & 0xff), HDMI_CSC_COEF_A3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][2] >> 8), HDMI_CSC_COEF_A3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][3] & 0xff), HDMI_CSC_COEF_A4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][3] >> 8), HDMI_CSC_COEF_A4_MSB); + + hdmi_writeb(hdmi, ((*csc_coeff)[1][0] & 0xff), HDMI_CSC_COEF_B1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][0] >> 8), HDMI_CSC_COEF_B1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][1] & 0xff), HDMI_CSC_COEF_B2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][1] >> 8), HDMI_CSC_COEF_B2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][2] & 0xff), HDMI_CSC_COEF_B3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][2] >> 8), HDMI_CSC_COEF_B3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][3] & 0xff), HDMI_CSC_COEF_B4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][3] >> 8), HDMI_CSC_COEF_B4_MSB); + + hdmi_writeb(hdmi, ((*csc_coeff)[2][0] & 0xff), HDMI_CSC_COEF_C1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][0] >> 8), HDMI_CSC_COEF_C1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][1] & 0xff), HDMI_CSC_COEF_C2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][1] >> 8), HDMI_CSC_COEF_C2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][2] & 0xff), HDMI_CSC_COEF_C3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][2] >> 8), HDMI_CSC_COEF_C3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][3] & 0xff), HDMI_CSC_COEF_C4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][3] >> 8), HDMI_CSC_COEF_C4_MSB); + + val = hdmi_readb(hdmi, HDMI_CSC_SCALE); + val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK; + val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK; + hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); +} + +static void hdmi_video_csc(struct imx_hdmi *hdmi) +{ + int color_depth = 0; + int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; + int decimation = 0; + u8 val; + + /* YCC422 interpolation to 444 mode */ + if (is_color_space_interpolation(hdmi)) + interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; + else if (is_color_space_decimation(hdmi)) + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; + + if (hdmi->hdmi_data.enc_color_depth == 8) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; + else + return; + + /* Configure the CSC registers */ + hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); + val = hdmi_readb(hdmi, HDMI_CSC_SCALE); + val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK; + val |= color_depth; + hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); + + imx_hdmi_update_csc_coeffs(hdmi); +} + +/* + * HDMI video packetizer is used to packetize the data. + * for example, if input is YCC422 mode or repeater is used, + * data should be repacked this module can be bypassed. + */ +static void hdmi_video_packetize(struct imx_hdmi *hdmi) +{ + unsigned int color_depth = 0; + unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; + unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; + struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; + u8 val; + + if (hdmi_data->enc_out_format == RGB + || hdmi_data->enc_out_format == YCBCR444) { + if (!hdmi_data->enc_color_depth) + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; + else if (hdmi_data->enc_color_depth == 8) { + color_depth = 4; + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; + } else if (hdmi_data->enc_color_depth == 10) + color_depth = 5; + else if (hdmi_data->enc_color_depth == 12) + color_depth = 6; + else if (hdmi_data->enc_color_depth == 16) + color_depth = 7; + else + return; + } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { + if (!hdmi_data->enc_color_depth || + hdmi_data->enc_color_depth == 8) + remap_size = HDMI_VP_REMAP_YCC422_16bit; + else if (hdmi_data->enc_color_depth == 10) + remap_size = HDMI_VP_REMAP_YCC422_20bit; + else if (hdmi_data->enc_color_depth == 12) + remap_size = HDMI_VP_REMAP_YCC422_24bit; + else + return; + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; + } else + return; + + /* set the packetizer registers */ + val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & + HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | + ((hdmi_data->pix_repet_factor << + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); + hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK; + val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + /* Data from pixel repeater block */ + if (hdmi_data->pix_repet_factor > 1) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_PR_EN_MASK | + HDMI_VP_CONF_BYPASS_SELECT_MASK); + val |= HDMI_VP_CONF_PR_EN_ENABLE | + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else { /* data from packetizer block */ + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_PR_EN_MASK | + HDMI_VP_CONF_BYPASS_SELECT_MASK); + val |= HDMI_VP_CONF_PR_EN_DISABLE | + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK; + val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); + + if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_ENABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_ENABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_ENABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else { + return; + } + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK | + HDMI_VP_STUFF_YCC422_STUFFING_MASK); + val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK; + val |= output_select; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); +} + +static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTCLR_MASK; + val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) & + HDMI_PHY_TST0_TSTCLR_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTEN_MASK; + val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) & + HDMI_PHY_TST0_TSTEN_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTCLK_MASK; + val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) & + HDMI_PHY_TST0_TSTCLK_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi, + unsigned char bit) +{ + hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); +} + +static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi, + unsigned char bit) +{ + hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); +} + +static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec) +{ + unsigned char val = 0; + val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3; + while (!val) { + udelay(1000); + if (msec-- == 0) + return false; + val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3; + } + return true; +} + +static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, + unsigned char addr) +{ + hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); + hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); + hdmi_writeb(hdmi, (unsigned char)(data >> 8), + HDMI_PHY_I2CM_DATAO_1_ADDR); + hdmi_writeb(hdmi, (unsigned char)(data >> 0), + HDMI_PHY_I2CM_DATAO_0_ADDR); + hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, + HDMI_PHY_I2CM_OPERATION_ADDR); + hdmi_phy_wait_i2c_done(hdmi, 1000); +} + +static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, + unsigned char addr) +{ + __hdmi_phy_i2c_write(hdmi, data, addr); + return 0; +} + +static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_PDZ_OFFSET, + HDMI_PHY_CONF0_PDZ_MASK); +} + +static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_ENTMDS_OFFSET, + HDMI_PHY_CONF0_ENTMDS_MASK); +} + +static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, + HDMI_PHY_CONF0_GEN2_PDDQ_MASK); +} + +static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); +} + +static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, + HDMI_PHY_CONF0_SELDATAENPOL_MASK); +} + +static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_SELDIPIF_OFFSET, + HDMI_PHY_CONF0_SELDIPIF_MASK); +} + +static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, + unsigned char res, int cscon) +{ + u8 val, msec; + + /* color resolution 0 is 8 bit colour depth */ + if (!res) + res = 8; + + if (prep) + return -EINVAL; + else if (res != 8 && res != 12) + return -EINVAL; + + /* Enable csc path */ + if (cscon) + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH; + else + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS; + + hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL); + + /* gen2 tx power off */ + imx_hdmi_phy_gen2_txpwron(hdmi, 0); + + /* gen2 pddq */ + imx_hdmi_phy_gen2_pddq(hdmi, 1); + + /* PHY reset */ + hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); + hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); + + hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); + + hdmi_phy_test_clear(hdmi, 1); + hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, + HDMI_PHY_I2CM_SLAVE_ADDR); + hdmi_phy_test_clear(hdmi, 0); + + if (hdmi->hdmi_data.video_mode.mpixelclock <= 45250000) { + switch (res) { + case 8: + /* PLL/MPLL Cfg */ + hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */ + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 92500000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x0140, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x2141, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x4142, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 148500000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + default: + return -EINVAL; + } + } else { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x2001, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x4002, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); + default: + return -EINVAL; + } + } + + if (hdmi->hdmi_data.video_mode.mpixelclock <= 54000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */ + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 58400000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 72000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 74250000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 118800000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 216000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else { + dev_err(hdmi->dev, + "Pixel clock %d - unsupported by HDMI\n", + hdmi->hdmi_data.video_mode.mpixelclock); + return -EINVAL; + } + + hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ + hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); + /* RESISTANCE TERM 133Ohm Cfg */ + hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ + /* PREEMP Cgf 0.00 */ + hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ + /* TX/CK LVL 10 */ + hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ + /* REMOVE CLK TERM */ + hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ + + imx_hdmi_phy_enable_power(hdmi, 1); + + /* toggle TMDS enable */ + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_tmds(hdmi, 1); + + /* gen2 tx power on */ + imx_hdmi_phy_gen2_txpwron(hdmi, 1); + imx_hdmi_phy_gen2_pddq(hdmi, 0); + + /*Wait for PHY PLL lock */ + msec = 5; + do { + val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; + if (!val) + break; + + if (msec == 0) { + dev_err(hdmi->dev, "PHY PLL not locked\n"); + return -ETIMEDOUT; + } + + udelay(1000); + msec--; + } while (1); + + return 0; +} + +static int imx_hdmi_phy_init(struct imx_hdmi *hdmi) +{ + int i, ret; + bool cscon = false; + + /*check csc whether needed activated in HDMI mode */ + cscon = (is_color_space_conversion(hdmi) && + !hdmi->hdmi_data.video_mode.mdvi); + + /* HDMI Phy spec says to do the phy initialization sequence twice */ + for (i = 0; i < 2; i++) { + imx_hdmi_phy_sel_data_en_pol(hdmi, 1); + imx_hdmi_phy_sel_interface_control(hdmi, 0); + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_power(hdmi, 0); + + /* Enable CSC */ + ret = hdmi_phy_configure(hdmi, 0, 8, cscon); + if (ret) + return ret; + } + + hdmi->phy_enabled = true; + return 0; +} + +static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi) +{ + u8 de, val; + + if (hdmi->hdmi_data.video_mode.mdataenablepolarity) + de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH; + else + de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW; + + /* disable rx detect */ + val = hdmi_readb(hdmi, HDMI_A_HDCPCFG0); + val &= HDMI_A_HDCPCFG0_RXDETECT_MASK; + val |= HDMI_A_HDCPCFG0_RXDETECT_DISABLE; + hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG0); + + val = hdmi_readb(hdmi, HDMI_A_VIDPOLCFG); + val &= HDMI_A_VIDPOLCFG_DATAENPOL_MASK; + val |= de; + hdmi_writeb(hdmi, val, HDMI_A_VIDPOLCFG); + + val = hdmi_readb(hdmi, HDMI_A_HDCPCFG1); + val &= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK; + val |= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE; + hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG1); +} + +static void hdmi_config_AVI(struct imx_hdmi *hdmi) +{ + u8 val, pix_fmt, under_scan; + u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry; + bool aspect_16_9; + + aspect_16_9 = false; /* FIXME */ + + /* AVI Data Byte 1 */ + if (hdmi->hdmi_data.enc_out_format == YCBCR444) + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444; + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422; + else + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB; + + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA; + + /* + * Active format identification data is present in the AVI InfoFrame. + * Under scan info, no bar data + */ + val = pix_fmt | under_scan | + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT | + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA; + + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); + + /* AVI Data Byte 2 -Set the Aspect Ratio */ + if (aspect_16_9) { + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9; + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9; + } else { + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3; + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3; + } + + /* Set up colorimetry */ + if (hdmi->hdmi_data.enc_out_format == XVYCC444) { + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; + if (hdmi->hdmi_data.colorimetry == ITU601) + ext_colorimetry = + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + else /* hdmi->hdmi_data.colorimetry == ITU709 */ + ext_colorimetry = + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; + } else if (hdmi->hdmi_data.enc_out_format != RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; + else /* hdmi->hdmi_data.colorimetry == ITU709 */ + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + } else { /* Carries no data */ + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA; + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + } + + val = colorimetry | coded_ratio | act_ratio; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); + + /* AVI Data Byte 3 */ + val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry | + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT | + HDMI_FC_AVICONF2_SCALING_NONE; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); + + /* AVI Data Byte 4 */ + hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID); + + /* AVI Data Byte 5- set up input and output pixel repetition */ + val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | + ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); + hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); + + /* IT Content and quantization range = don't care */ + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS | + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); + + /* AVI Data Bytes 6-13 */ + hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1); +} + +static void hdmi_av_composer(struct imx_hdmi *hdmi, + const struct drm_display_mode *mode) +{ + u8 inv_val; + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; + int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; + + vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC); + vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC); + vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); + vmode->mpixelclock = mode->clock * 1000; + + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); + + /* Set up HDMI_FC_INVIDCONF */ + inv_val = (hdmi->hdmi_data.hdcp_enable ? + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); + + inv_val |= (vmode->mvsyncpolarity ? + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW); + + inv_val |= (vmode->mhsyncpolarity ? + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW); + + inv_val |= (vmode->mdataenablepolarity ? + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); + + if (hdmi->vic == 39) + inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; + else + inv_val |= (vmode->minterlaced ? + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW); + + inv_val |= (vmode->minterlaced ? + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE); + + inv_val |= (vmode->mdvi ? + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE : + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE); + + hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); + + /* Set up horizontal active pixel width */ + hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); + hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); + + /* Set up vertical active lines */ + hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1); + hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0); + + /* Set up horizontal blanking pixel region width */ + hblank = mode->htotal - mode->hdisplay; + hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); + hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); + + /* Set up vertical blanking pixel region width */ + vblank = mode->vtotal - mode->vdisplay; + hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); + + /* Set up HSYNC active edge delay width (in pixel clks) */ + h_de_hs = mode->hsync_start - mode->hdisplay; + hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); + hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); + + /* Set up VSYNC active edge delay (in lines) */ + v_de_vs = mode->vsync_start - mode->vdisplay; + hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); + + /* Set up HSYNC active pulse width (in pixel clks) */ + hsync_len = mode->hsync_end - mode->hsync_start; + hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); + hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); + + /* Set up VSYNC active edge delay (in lines) */ + vsync_len = mode->vsync_end - mode->vsync_start; + hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); +} + +static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi) +{ + if (!hdmi->phy_enabled) + return; + + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_power(hdmi, 0); + + hdmi->phy_enabled = false; +} + +/* HDMI Initialization Step B.4 */ +static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi) +{ + u8 clkdis; + + /* control period minimum duration */ + hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); + hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); + hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); + + /* Set to fill TMDS data channels */ + hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); + hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); + hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); + + /* Enable pixel clock and tmds data path */ + clkdis = 0x7F; + clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + + clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + + /* Enable csc path */ + if (is_color_space_conversion(hdmi)) { + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + } +} + +static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi) +{ + u8 clkdis; + + clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS); + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); +} + +/* Workaround to clear the overflow condition */ +static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi) +{ + int count; + u8 val; + + /* TMDS software reset */ + hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); + + val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); + if (hdmi->dev_type == IMX6DL_HDMI) { + hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); + return; + } + + for (count = 0; count < 4; count++) + hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); +} + +static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); + hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); +} + +static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, + HDMI_IH_MUTE_FC_STAT2); +} + +static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) +{ + int ret; + + hdmi_disable_overflow_interrupts(hdmi); + + hdmi->vic = drm_match_cea_mode(mode); + + if (!hdmi->vic) { + dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); + hdmi->hdmi_data.video_mode.mdvi = true; + } else { + dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); + hdmi->hdmi_data.video_mode.mdvi = false; + } + + if ((hdmi->vic == 6) || (hdmi->vic == 7) || + (hdmi->vic == 21) || (hdmi->vic == 22) || + (hdmi->vic == 2) || (hdmi->vic == 3) || + (hdmi->vic == 17) || (hdmi->vic == 18)) + hdmi->hdmi_data.colorimetry = ITU601; + else + hdmi->hdmi_data.colorimetry = ITU709; + + if ((hdmi->vic == 10) || (hdmi->vic == 11) || + (hdmi->vic == 12) || (hdmi->vic == 13) || + (hdmi->vic == 14) || (hdmi->vic == 15) || + (hdmi->vic == 25) || (hdmi->vic == 26) || + (hdmi->vic == 27) || (hdmi->vic == 28) || + (hdmi->vic == 29) || (hdmi->vic == 30) || + (hdmi->vic == 35) || (hdmi->vic == 36) || + (hdmi->vic == 37) || (hdmi->vic == 38)) + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1; + else + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; + + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; + + /* TODO: Get input format from IPU (via FB driver interface) */ + hdmi->hdmi_data.enc_in_format = RGB; + + hdmi->hdmi_data.enc_out_format = RGB; + + hdmi->hdmi_data.enc_color_depth = 8; + hdmi->hdmi_data.pix_repet_factor = 0; + hdmi->hdmi_data.hdcp_enable = 0; + hdmi->hdmi_data.video_mode.mdataenablepolarity = true; + + /* HDMI Initialization Step B.1 */ + hdmi_av_composer(hdmi, mode); + + /* HDMI Initializateion Step B.2 */ + ret = imx_hdmi_phy_init(hdmi); + if (ret) + return ret; + + /* HDMI Initialization Step B.3 */ + imx_hdmi_enable_video_path(hdmi); + + /* not for DVI mode */ + if (hdmi->hdmi_data.video_mode.mdvi) + dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); + else { + dev_dbg(hdmi->dev, "%s CEA mode\n", __func__); + + /* HDMI Initialization Step E - Configure audio */ + hdmi_clk_regenerator_update_pixel_clock(hdmi); + hdmi_enable_audio_clk(hdmi); + + /* HDMI Initialization Step F - Configure AVI InfoFrame */ + hdmi_config_AVI(hdmi); + } + + hdmi_video_packetize(hdmi); + hdmi_video_csc(hdmi); + hdmi_video_sample(hdmi); + hdmi_tx_hdcp_config(hdmi); + + imx_hdmi_clear_overflow(hdmi); + if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi) + hdmi_enable_overflow_interrupts(hdmi); + + return 0; +} + +/* Wait until we are registered to enable interrupts */ +static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, + HDMI_PHY_I2CM_INT_ADDR); + + hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, + HDMI_PHY_I2CM_CTLINT_ADDR); + + /* enable cable hot plug irq */ + hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0); + + /* Clear Hotplug interrupts */ + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); + + /* Unmute interrupts */ + hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); + + return 0; +} + +static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi) +{ + u8 ih_mute; + + /* + * Boot up defaults are: + * HDMI_IH_MUTE = 0x03 (disabled) + * HDMI_IH_MUTE_* = 0x00 (enabled) + * + * Disable top level interrupt bits in HDMI block + */ + ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; + + hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); + + /* by default mask all interrupts */ + hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); + hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); + + /* Disable interrupts in the IH_MUTE_* registers */ + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); + + /* Enable top level interrupt bits in HDMI block */ + ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); + hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); +} + +static void imx_hdmi_poweron(struct imx_hdmi *hdmi) +{ + imx_hdmi_setup(hdmi, &hdmi->previous_mode); +} + +static void imx_hdmi_poweroff(struct imx_hdmi *hdmi) +{ + imx_hdmi_phy_disable(hdmi); +} + +static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector + *connector, bool force) +{ + /* FIXME */ + return connector_status_connected; +} + +static void imx_hdmi_connector_destroy(struct drm_connector *connector) +{ +} + +static int imx_hdmi_connector_get_modes(struct drm_connector *connector) +{ + struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, + connector); + struct edid *edid; + int ret; + + if (!hdmi->ddc) + return 0; + + edid = drm_get_edid(connector, hdmi->ddc); + if (edid) { + dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", + edid->width_cm, edid->height_cm); + + drm_mode_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + } else { + dev_dbg(hdmi->dev, "failed to get edid\n"); + } + + return 0; +} + +static int imx_hdmi_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + + return MODE_OK; +} + +static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector + *connector) +{ + struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, + connector); + + return &hdmi->encoder; +} + +static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + imx_hdmi_setup(hdmi, mode); + + /* Store the display mode for plugin/DKMS poweron events */ + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); +} + +static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void imx_hdmi_encoder_disable(struct drm_encoder *encoder) +{ +} + +static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + if (mode) + imx_hdmi_poweroff(hdmi); + else + imx_hdmi_poweron(hdmi); +} + +static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + imx_hdmi_poweroff(hdmi); + imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE, + V4L2_PIX_FMT_RGB24); +} + +static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + int mux = imx_drm_encoder_get_mux_id(hdmi->imx_drm_encoder, + encoder->crtc); + + imx_hdmi_set_ipu_di_mux(hdmi, mux); + + imx_hdmi_poweron(hdmi); +} + +static void imx_hdmi_encoder_destroy(struct drm_encoder *encoder) +{ + return; +} + +static struct drm_encoder_funcs imx_hdmi_encoder_funcs = { + .destroy = imx_hdmi_encoder_destroy, +}; + +static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = { + .dpms = imx_hdmi_encoder_dpms, + .prepare = imx_hdmi_encoder_prepare, + .commit = imx_hdmi_encoder_commit, + .mode_set = imx_hdmi_encoder_mode_set, + .mode_fixup = imx_hdmi_encoder_mode_fixup, + .disable = imx_hdmi_encoder_disable, +}; + +static struct drm_connector_funcs imx_hdmi_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = imx_hdmi_connector_detect, + .destroy = imx_hdmi_connector_destroy, +}; + +static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { + .get_modes = imx_hdmi_connector_get_modes, + .mode_valid = imx_hdmi_connector_mode_valid, + .best_encoder = imx_hdmi_connector_best_encoder, +}; + +static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) +{ + struct imx_hdmi *hdmi = dev_id; + u8 intr_stat; + u8 phy_int_pol; + u8 val; + + intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); + + phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); + + if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { + if (phy_int_pol & HDMI_PHY_HPD) { + dev_dbg(hdmi->dev, "EVENT=plugin\n"); + + val = hdmi_readb(hdmi, HDMI_PHY_POL0); + val &= ~HDMI_PHY_HPD; + hdmi_writeb(hdmi, val, HDMI_PHY_POL0); + + imx_hdmi_poweron(hdmi); + } else { + dev_dbg(hdmi->dev, "EVENT=plugout\n"); + + val = hdmi_readb(hdmi, HDMI_PHY_POL0); + val |= HDMI_PHY_HPD; + hdmi_writeb(hdmi, val, HDMI_PHY_POL0); + + imx_hdmi_poweroff(hdmi); + } + } + + hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); + + return IRQ_HANDLED; +} + +static int imx_hdmi_register(struct imx_hdmi *hdmi) +{ + int ret; + + hdmi->connector.funcs = &imx_hdmi_connector_funcs; + hdmi->encoder.funcs = &imx_hdmi_encoder_funcs; + + hdmi->encoder.encoder_type = DRM_MODE_ENCODER_TMDS; + hdmi->connector.connector_type = DRM_MODE_CONNECTOR_HDMIA; + + drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs); + ret = imx_drm_add_encoder(&hdmi->encoder, &hdmi->imx_drm_encoder, + THIS_MODULE); + if (ret) { + dev_err(hdmi->dev, "adding encoder failed: %d\n", ret); + return ret; + } + + drm_connector_helper_add(&hdmi->connector, + &imx_hdmi_connector_helper_funcs); + + ret = imx_drm_add_connector(&hdmi->connector, + &hdmi->imx_drm_connector, THIS_MODULE); + if (ret) { + imx_drm_remove_encoder(hdmi->imx_drm_encoder); + dev_err(hdmi->dev, "adding connector failed: %d\n", ret); + return ret; + } + + hdmi->connector.encoder = &hdmi->encoder; + + drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder); + + return 0; +} + +static struct platform_device_id imx_hdmi_devtype[] = { + { + .name = "imx6q-hdmi", + .driver_data = IMX6Q_HDMI, + }, { + .name = "imx6dl-hdmi", + .driver_data = IMX6DL_HDMI, + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype); + +static const struct of_device_id imx_hdmi_dt_ids[] = { +{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], }, +{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], }, +{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); + +static int imx_hdmi_platform_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(imx_hdmi_dt_ids, &pdev->dev); + struct device_node *np = pdev->dev.of_node; + struct device_node *ddc_node; + struct imx_hdmi *hdmi; + struct resource *iores; + int ret, irq; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + hdmi->dev = &pdev->dev; + + if (of_id) { + const struct platform_device_id *device_id = of_id->data; + hdmi->dev_type = device_id->driver_data; + } + + ddc_node = of_parse_phandle(np, "ddc", 0); + if (ddc_node) { + hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); + if (!hdmi->ddc) + dev_dbg(hdmi->dev, "failed to read ddc node\n"); + + of_node_put(ddc_node); + } else { + dev_dbg(hdmi->dev, "no ddc property found\n"); + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -EINVAL; + + ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0, + dev_name(&pdev->dev), hdmi); + if (ret) + return ret; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hdmi->regs = devm_ioremap_resource(&pdev->dev, iores); + if (IS_ERR(hdmi->regs)) + return PTR_ERR(hdmi->regs); + + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); + if (IS_ERR(hdmi->regmap)) + return PTR_ERR(hdmi->regmap); + + hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); + if (IS_ERR(hdmi->isfr_clk)) { + ret = PTR_ERR(hdmi->isfr_clk); + dev_err(hdmi->dev, + "Unable to get HDMI isfr clk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->isfr_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI isfr clock: %d\n", ret); + return ret; + } + + hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); + if (IS_ERR(hdmi->iahb_clk)) { + ret = PTR_ERR(hdmi->iahb_clk); + dev_err(hdmi->dev, + "Unable to get HDMI iahb clk: %d\n", ret); + goto err_isfr; + } + + ret = clk_prepare_enable(hdmi->iahb_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI iahb clock: %d\n", ret); + goto err_isfr; + } + + /* Product and revision IDs */ + dev_info(&pdev->dev, + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", + hdmi_readb(hdmi, HDMI_DESIGN_ID), + hdmi_readb(hdmi, HDMI_REVISION_ID), + hdmi_readb(hdmi, HDMI_PRODUCT_ID0), + hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); + + initialize_hdmi_ih_mutes(hdmi); + + /* + * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator + * N and cts values before enabling phy + */ + hdmi_init_clk_regenerator(hdmi); + + /* + * Configure registers related to HDMI interrupt + * generation before registering IRQ. + */ + hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0); + + /* Clear Hotplug interrupts */ + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); + + ret = imx_hdmi_fb_registered(hdmi); + if (ret) + goto err_iahb; + + ret = imx_hdmi_register(hdmi); + if (ret) + goto err_iahb; + + imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); + + platform_set_drvdata(pdev, hdmi); + + return 0; + +err_iahb: + clk_disable_unprepare(hdmi->iahb_clk); +err_isfr: + clk_disable_unprepare(hdmi->isfr_clk); + + return ret; +} + +static int imx_hdmi_platform_remove(struct platform_device *pdev) +{ + struct imx_hdmi *hdmi = platform_get_drvdata(pdev); + struct drm_connector *connector = &hdmi->connector; + struct drm_encoder *encoder = &hdmi->encoder; + + drm_mode_connector_detach_encoder(connector, encoder); + imx_drm_remove_connector(hdmi->imx_drm_connector); + imx_drm_remove_encoder(hdmi->imx_drm_encoder); + + clk_disable_unprepare(hdmi->iahb_clk); + clk_disable_unprepare(hdmi->isfr_clk); + i2c_put_adapter(hdmi->ddc); + + return 0; +} + +static struct platform_driver imx_hdmi_driver = { + .probe = imx_hdmi_platform_probe, + .remove = imx_hdmi_platform_remove, + .driver = { + .name = "imx-hdmi", + .owner = THIS_MODULE, + .of_match_table = imx_hdmi_dt_ids, + }, +}; + +module_platform_driver(imx_hdmi_driver); + +MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); +MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imx-hdmi"); diff --git a/drivers/staging/imx-drm/imx-hdmi.h b/drivers/staging/imx-drm/imx-hdmi.h new file mode 100644 index 000000000000..39b677689db6 --- /dev/null +++ b/drivers/staging/imx-drm/imx-hdmi.h @@ -0,0 +1,1032 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __IMX_HDMI_H__ +#define __IMX_HDMI_H__ + +/* Identification Registers */ +#define HDMI_DESIGN_ID 0x0000 +#define HDMI_REVISION_ID 0x0001 +#define HDMI_PRODUCT_ID0 0x0002 +#define HDMI_PRODUCT_ID1 0x0003 +#define HDMI_CONFIG0_ID 0x0004 +#define HDMI_CONFIG1_ID 0x0005 +#define HDMI_CONFIG2_ID 0x0006 +#define HDMI_CONFIG3_ID 0x0007 + +/* Interrupt Registers */ +#define HDMI_IH_FC_STAT0 0x0100 +#define HDMI_IH_FC_STAT1 0x0101 +#define HDMI_IH_FC_STAT2 0x0102 +#define HDMI_IH_AS_STAT0 0x0103 +#define HDMI_IH_PHY_STAT0 0x0104 +#define HDMI_IH_I2CM_STAT0 0x0105 +#define HDMI_IH_CEC_STAT0 0x0106 +#define HDMI_IH_VP_STAT0 0x0107 +#define HDMI_IH_I2CMPHY_STAT0 0x0108 +#define HDMI_IH_AHBDMAAUD_STAT0 0x0109 + +#define HDMI_IH_MUTE_FC_STAT0 0x0180 +#define HDMI_IH_MUTE_FC_STAT1 0x0181 +#define HDMI_IH_MUTE_FC_STAT2 0x0182 +#define HDMI_IH_MUTE_AS_STAT0 0x0183 +#define HDMI_IH_MUTE_PHY_STAT0 0x0184 +#define HDMI_IH_MUTE_I2CM_STAT0 0x0185 +#define HDMI_IH_MUTE_CEC_STAT0 0x0186 +#define HDMI_IH_MUTE_VP_STAT0 0x0187 +#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188 +#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189 +#define HDMI_IH_MUTE 0x01FF + +/* Video Sample Registers */ +#define HDMI_TX_INVID0 0x0200 +#define HDMI_TX_INSTUFFING 0x0201 +#define HDMI_TX_GYDATA0 0x0202 +#define HDMI_TX_GYDATA1 0x0203 +#define HDMI_TX_RCRDATA0 0x0204 +#define HDMI_TX_RCRDATA1 0x0205 +#define HDMI_TX_BCBDATA0 0x0206 +#define HDMI_TX_BCBDATA1 0x0207 + +/* Video Packetizer Registers */ +#define HDMI_VP_STATUS 0x0800 +#define HDMI_VP_PR_CD 0x0801 +#define HDMI_VP_STUFF 0x0802 +#define HDMI_VP_REMAP 0x0803 +#define HDMI_VP_CONF 0x0804 +#define HDMI_VP_STAT 0x0805 +#define HDMI_VP_INT 0x0806 +#define HDMI_VP_MASK 0x0807 +#define HDMI_VP_POL 0x0808 + +/* Frame Composer Registers */ +#define HDMI_FC_INVIDCONF 0x1000 +#define HDMI_FC_INHACTV0 0x1001 +#define HDMI_FC_INHACTV1 0x1002 +#define HDMI_FC_INHBLANK0 0x1003 +#define HDMI_FC_INHBLANK1 0x1004 +#define HDMI_FC_INVACTV0 0x1005 +#define HDMI_FC_INVACTV1 0x1006 +#define HDMI_FC_INVBLANK 0x1007 +#define HDMI_FC_HSYNCINDELAY0 0x1008 +#define HDMI_FC_HSYNCINDELAY1 0x1009 +#define HDMI_FC_HSYNCINWIDTH0 0x100A +#define HDMI_FC_HSYNCINWIDTH1 0x100B +#define HDMI_FC_VSYNCINDELAY 0x100C +#define HDMI_FC_VSYNCINWIDTH 0x100D +#define HDMI_FC_INFREQ0 0x100E +#define HDMI_FC_INFREQ1 0x100F +#define HDMI_FC_INFREQ2 0x1010 +#define HDMI_FC_CTRLDUR 0x1011 +#define HDMI_FC_EXCTRLDUR 0x1012 +#define HDMI_FC_EXCTRLSPAC 0x1013 +#define HDMI_FC_CH0PREAM 0x1014 +#define HDMI_FC_CH1PREAM 0x1015 +#define HDMI_FC_CH2PREAM 0x1016 +#define HDMI_FC_AVICONF3 0x1017 +#define HDMI_FC_GCP 0x1018 +#define HDMI_FC_AVICONF0 0x1019 +#define HDMI_FC_AVICONF1 0x101A +#define HDMI_FC_AVICONF2 0x101B +#define HDMI_FC_AVIVID 0x101C +#define HDMI_FC_AVIETB0 0x101D +#define HDMI_FC_AVIETB1 0x101E +#define HDMI_FC_AVISBB0 0x101F +#define HDMI_FC_AVISBB1 0x1020 +#define HDMI_FC_AVIELB0 0x1021 +#define HDMI_FC_AVIELB1 0x1022 +#define HDMI_FC_AVISRB0 0x1023 +#define HDMI_FC_AVISRB1 0x1024 +#define HDMI_FC_AUDICONF0 0x1025 +#define HDMI_FC_AUDICONF1 0x1026 +#define HDMI_FC_AUDICONF2 0x1027 +#define HDMI_FC_AUDICONF3 0x1028 +#define HDMI_FC_VSDIEEEID0 0x1029 +#define HDMI_FC_VSDSIZE 0x102A +#define HDMI_FC_VSDIEEEID1 0x1030 +#define HDMI_FC_VSDIEEEID2 0x1031 +#define HDMI_FC_VSDPAYLOAD0 0x1032 +#define HDMI_FC_VSDPAYLOAD1 0x1033 +#define HDMI_FC_VSDPAYLOAD2 0x1034 +#define HDMI_FC_VSDPAYLOAD3 0x1035 +#define HDMI_FC_VSDPAYLOAD4 0x1036 +#define HDMI_FC_VSDPAYLOAD5 0x1037 +#define HDMI_FC_VSDPAYLOAD6 0x1038 +#define HDMI_FC_VSDPAYLOAD7 0x1039 +#define HDMI_FC_VSDPAYLOAD8 0x103A +#define HDMI_FC_VSDPAYLOAD9 0x103B +#define HDMI_FC_VSDPAYLOAD10 0x103C +#define HDMI_FC_VSDPAYLOAD11 0x103D +#define HDMI_FC_VSDPAYLOAD12 0x103E +#define HDMI_FC_VSDPAYLOAD13 0x103F +#define HDMI_FC_VSDPAYLOAD14 0x1040 +#define HDMI_FC_VSDPAYLOAD15 0x1041 +#define HDMI_FC_VSDPAYLOAD16 0x1042 +#define HDMI_FC_VSDPAYLOAD17 0x1043 +#define HDMI_FC_VSDPAYLOAD18 0x1044 +#define HDMI_FC_VSDPAYLOAD19 0x1045 +#define HDMI_FC_VSDPAYLOAD20 0x1046 +#define HDMI_FC_VSDPAYLOAD21 0x1047 +#define HDMI_FC_VSDPAYLOAD22 0x1048 +#define HDMI_FC_VSDPAYLOAD23 0x1049 +#define HDMI_FC_SPDVENDORNAME0 0x104A +#define HDMI_FC_SPDVENDORNAME1 0x104B +#define HDMI_FC_SPDVENDORNAME2 0x104C +#define HDMI_FC_SPDVENDORNAME3 0x104D +#define HDMI_FC_SPDVENDORNAME4 0x104E +#define HDMI_FC_SPDVENDORNAME5 0x104F +#define HDMI_FC_SPDVENDORNAME6 0x1050 +#define HDMI_FC_SPDVENDORNAME7 0x1051 +#define HDMI_FC_SDPPRODUCTNAME0 0x1052 +#define HDMI_FC_SDPPRODUCTNAME1 0x1053 +#define HDMI_FC_SDPPRODUCTNAME2 0x1054 +#define HDMI_FC_SDPPRODUCTNAME3 0x1055 +#define HDMI_FC_SDPPRODUCTNAME4 0x1056 +#define HDMI_FC_SDPPRODUCTNAME5 0x1057 +#define HDMI_FC_SDPPRODUCTNAME6 0x1058 +#define HDMI_FC_SDPPRODUCTNAME7 0x1059 +#define HDMI_FC_SDPPRODUCTNAME8 0x105A +#define HDMI_FC_SDPPRODUCTNAME9 0x105B +#define HDMI_FC_SDPPRODUCTNAME10 0x105C +#define HDMI_FC_SDPPRODUCTNAME11 0x105D +#define HDMI_FC_SDPPRODUCTNAME12 0x105E +#define HDMI_FC_SDPPRODUCTNAME13 0x105F +#define HDMI_FC_SDPPRODUCTNAME14 0x1060 +#define HDMI_FC_SPDPRODUCTNAME15 0x1061 +#define HDMI_FC_SPDDEVICEINF 0x1062 +#define HDMI_FC_AUDSCONF 0x1063 +#define HDMI_FC_AUDSSTAT 0x1064 +#define HDMI_FC_DATACH0FILL 0x1070 +#define HDMI_FC_DATACH1FILL 0x1071 +#define HDMI_FC_DATACH2FILL 0x1072 +#define HDMI_FC_CTRLQHIGH 0x1073 +#define HDMI_FC_CTRLQLOW 0x1074 +#define HDMI_FC_ACP0 0x1075 +#define HDMI_FC_ACP28 0x1076 +#define HDMI_FC_ACP27 0x1077 +#define HDMI_FC_ACP26 0x1078 +#define HDMI_FC_ACP25 0x1079 +#define HDMI_FC_ACP24 0x107A +#define HDMI_FC_ACP23 0x107B +#define HDMI_FC_ACP22 0x107C +#define HDMI_FC_ACP21 0x107D +#define HDMI_FC_ACP20 0x107E +#define HDMI_FC_ACP19 0x107F +#define HDMI_FC_ACP18 0x1080 +#define HDMI_FC_ACP17 0x1081 +#define HDMI_FC_ACP16 0x1082 +#define HDMI_FC_ACP15 0x1083 +#define HDMI_FC_ACP14 0x1084 +#define HDMI_FC_ACP13 0x1085 +#define HDMI_FC_ACP12 0x1086 +#define HDMI_FC_ACP11 0x1087 +#define HDMI_FC_ACP10 0x1088 +#define HDMI_FC_ACP9 0x1089 +#define HDMI_FC_ACP8 0x108A +#define HDMI_FC_ACP7 0x108B +#define HDMI_FC_ACP6 0x108C +#define HDMI_FC_ACP5 0x108D +#define HDMI_FC_ACP4 0x108E +#define HDMI_FC_ACP3 0x108F +#define HDMI_FC_ACP2 0x1090 +#define HDMI_FC_ACP1 0x1091 +#define HDMI_FC_ISCR1_0 0x1092 +#define HDMI_FC_ISCR1_16 0x1093 +#define HDMI_FC_ISCR1_15 0x1094 +#define HDMI_FC_ISCR1_14 0x1095 +#define HDMI_FC_ISCR1_13 0x1096 +#define HDMI_FC_ISCR1_12 0x1097 +#define HDMI_FC_ISCR1_11 0x1098 +#define HDMI_FC_ISCR1_10 0x1099 +#define HDMI_FC_ISCR1_9 0x109A +#define HDMI_FC_ISCR1_8 0x109B +#define HDMI_FC_ISCR1_7 0x109C +#define HDMI_FC_ISCR1_6 0x109D +#define HDMI_FC_ISCR1_5 0x109E +#define HDMI_FC_ISCR1_4 0x109F +#define HDMI_FC_ISCR1_3 0x10A0 +#define HDMI_FC_ISCR1_2 0x10A1 +#define HDMI_FC_ISCR1_1 0x10A2 +#define HDMI_FC_ISCR2_15 0x10A3 +#define HDMI_FC_ISCR2_14 0x10A4 +#define HDMI_FC_ISCR2_13 0x10A5 +#define HDMI_FC_ISCR2_12 0x10A6 +#define HDMI_FC_ISCR2_11 0x10A7 +#define HDMI_FC_ISCR2_10 0x10A8 +#define HDMI_FC_ISCR2_9 0x10A9 +#define HDMI_FC_ISCR2_8 0x10AA +#define HDMI_FC_ISCR2_7 0x10AB +#define HDMI_FC_ISCR2_6 0x10AC +#define HDMI_FC_ISCR2_5 0x10AD +#define HDMI_FC_ISCR2_4 0x10AE +#define HDMI_FC_ISCR2_3 0x10AF +#define HDMI_FC_ISCR2_2 0x10B0 +#define HDMI_FC_ISCR2_1 0x10B1 +#define HDMI_FC_ISCR2_0 0x10B2 +#define HDMI_FC_DATAUTO0 0x10B3 +#define HDMI_FC_DATAUTO1 0x10B4 +#define HDMI_FC_DATAUTO2 0x10B5 +#define HDMI_FC_DATMAN 0x10B6 +#define HDMI_FC_DATAUTO3 0x10B7 +#define HDMI_FC_RDRB0 0x10B8 +#define HDMI_FC_RDRB1 0x10B9 +#define HDMI_FC_RDRB2 0x10BA +#define HDMI_FC_RDRB3 0x10BB +#define HDMI_FC_RDRB4 0x10BC +#define HDMI_FC_RDRB5 0x10BD +#define HDMI_FC_RDRB6 0x10BE +#define HDMI_FC_RDRB7 0x10BF +#define HDMI_FC_STAT0 0x10D0 +#define HDMI_FC_INT0 0x10D1 +#define HDMI_FC_MASK0 0x10D2 +#define HDMI_FC_POL0 0x10D3 +#define HDMI_FC_STAT1 0x10D4 +#define HDMI_FC_INT1 0x10D5 +#define HDMI_FC_MASK1 0x10D6 +#define HDMI_FC_POL1 0x10D7 +#define HDMI_FC_STAT2 0x10D8 +#define HDMI_FC_INT2 0x10D9 +#define HDMI_FC_MASK2 0x10DA +#define HDMI_FC_POL2 0x10DB +#define HDMI_FC_PRCONF 0x10E0 + +#define HDMI_FC_GMD_STAT 0x1100 +#define HDMI_FC_GMD_EN 0x1101 +#define HDMI_FC_GMD_UP 0x1102 +#define HDMI_FC_GMD_CONF 0x1103 +#define HDMI_FC_GMD_HB 0x1104 +#define HDMI_FC_GMD_PB0 0x1105 +#define HDMI_FC_GMD_PB1 0x1106 +#define HDMI_FC_GMD_PB2 0x1107 +#define HDMI_FC_GMD_PB3 0x1108 +#define HDMI_FC_GMD_PB4 0x1109 +#define HDMI_FC_GMD_PB5 0x110A +#define HDMI_FC_GMD_PB6 0x110B +#define HDMI_FC_GMD_PB7 0x110C +#define HDMI_FC_GMD_PB8 0x110D +#define HDMI_FC_GMD_PB9 0x110E +#define HDMI_FC_GMD_PB10 0x110F +#define HDMI_FC_GMD_PB11 0x1110 +#define HDMI_FC_GMD_PB12 0x1111 +#define HDMI_FC_GMD_PB13 0x1112 +#define HDMI_FC_GMD_PB14 0x1113 +#define HDMI_FC_GMD_PB15 0x1114 +#define HDMI_FC_GMD_PB16 0x1115 +#define HDMI_FC_GMD_PB17 0x1116 +#define HDMI_FC_GMD_PB18 0x1117 +#define HDMI_FC_GMD_PB19 0x1118 +#define HDMI_FC_GMD_PB20 0x1119 +#define HDMI_FC_GMD_PB21 0x111A +#define HDMI_FC_GMD_PB22 0x111B +#define HDMI_FC_GMD_PB23 0x111C +#define HDMI_FC_GMD_PB24 0x111D +#define HDMI_FC_GMD_PB25 0x111E +#define HDMI_FC_GMD_PB26 0x111F +#define HDMI_FC_GMD_PB27 0x1120 + +#define HDMI_FC_DBGFORCE 0x1200 +#define HDMI_FC_DBGAUD0CH0 0x1201 +#define HDMI_FC_DBGAUD1CH0 0x1202 +#define HDMI_FC_DBGAUD2CH0 0x1203 +#define HDMI_FC_DBGAUD0CH1 0x1204 +#define HDMI_FC_DBGAUD1CH1 0x1205 +#define HDMI_FC_DBGAUD2CH1 0x1206 +#define HDMI_FC_DBGAUD0CH2 0x1207 +#define HDMI_FC_DBGAUD1CH2 0x1208 +#define HDMI_FC_DBGAUD2CH2 0x1209 +#define HDMI_FC_DBGAUD0CH3 0x120A +#define HDMI_FC_DBGAUD1CH3 0x120B +#define HDMI_FC_DBGAUD2CH3 0x120C +#define HDMI_FC_DBGAUD0CH4 0x120D +#define HDMI_FC_DBGAUD1CH4 0x120E +#define HDMI_FC_DBGAUD2CH4 0x120F +#define HDMI_FC_DBGAUD0CH5 0x1210 +#define HDMI_FC_DBGAUD1CH5 0x1211 +#define HDMI_FC_DBGAUD2CH5 0x1212 +#define HDMI_FC_DBGAUD0CH6 0x1213 +#define HDMI_FC_DBGAUD1CH6 0x1214 +#define HDMI_FC_DBGAUD2CH6 0x1215 +#define HDMI_FC_DBGAUD0CH7 0x1216 +#define HDMI_FC_DBGAUD1CH7 0x1217 +#define HDMI_FC_DBGAUD2CH7 0x1218 +#define HDMI_FC_DBGTMDS0 0x1219 +#define HDMI_FC_DBGTMDS1 0x121A +#define HDMI_FC_DBGTMDS2 0x121B + +/* HDMI Source PHY Registers */ +#define HDMI_PHY_CONF0 0x3000 +#define HDMI_PHY_TST0 0x3001 +#define HDMI_PHY_TST1 0x3002 +#define HDMI_PHY_TST2 0x3003 +#define HDMI_PHY_STAT0 0x3004 +#define HDMI_PHY_INT0 0x3005 +#define HDMI_PHY_MASK0 0x3006 +#define HDMI_PHY_POL0 0x3007 + +/* HDMI Master PHY Registers */ +#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020 +#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021 +#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022 +#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023 +#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024 +#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025 +#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026 +#define HDMI_PHY_I2CM_INT_ADDR 0x3027 +#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028 +#define HDMI_PHY_I2CM_DIV_ADDR 0x3029 +#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a +#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b +#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c +#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d +#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e +#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f +#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 +#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 +#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 + +/* Audio Sampler Registers */ +#define HDMI_AUD_CONF0 0x3100 +#define HDMI_AUD_CONF1 0x3101 +#define HDMI_AUD_INT 0x3102 +#define HDMI_AUD_CONF2 0x3103 +#define HDMI_AUD_N1 0x3200 +#define HDMI_AUD_N2 0x3201 +#define HDMI_AUD_N3 0x3202 +#define HDMI_AUD_CTS1 0x3203 +#define HDMI_AUD_CTS2 0x3204 +#define HDMI_AUD_CTS3 0x3205 +#define HDMI_AUD_INPUTCLKFS 0x3206 +#define HDMI_AUD_SPDIFINT 0x3302 +#define HDMI_AUD_CONF0_HBR 0x3400 +#define HDMI_AUD_HBR_STATUS 0x3401 +#define HDMI_AUD_HBR_INT 0x3402 +#define HDMI_AUD_HBR_POL 0x3403 +#define HDMI_AUD_HBR_MASK 0x3404 + +/* + * Generic Parallel Audio Interface Registers + * Not used as GPAUD interface is not enabled in hw + */ +#define HDMI_GP_CONF0 0x3500 +#define HDMI_GP_CONF1 0x3501 +#define HDMI_GP_CONF2 0x3502 +#define HDMI_GP_STAT 0x3503 +#define HDMI_GP_INT 0x3504 +#define HDMI_GP_MASK 0x3505 +#define HDMI_GP_POL 0x3506 + +/* Audio DMA Registers */ +#define HDMI_AHB_DMA_CONF0 0x3600 +#define HDMI_AHB_DMA_START 0x3601 +#define HDMI_AHB_DMA_STOP 0x3602 +#define HDMI_AHB_DMA_THRSLD 0x3603 +#define HDMI_AHB_DMA_STRADDR0 0x3604 +#define HDMI_AHB_DMA_STRADDR1 0x3605 +#define HDMI_AHB_DMA_STRADDR2 0x3606 +#define HDMI_AHB_DMA_STRADDR3 0x3607 +#define HDMI_AHB_DMA_STPADDR0 0x3608 +#define HDMI_AHB_DMA_STPADDR1 0x3609 +#define HDMI_AHB_DMA_STPADDR2 0x360a +#define HDMI_AHB_DMA_STPADDR3 0x360b +#define HDMI_AHB_DMA_BSTADDR0 0x360c +#define HDMI_AHB_DMA_BSTADDR1 0x360d +#define HDMI_AHB_DMA_BSTADDR2 0x360e +#define HDMI_AHB_DMA_BSTADDR3 0x360f +#define HDMI_AHB_DMA_MBLENGTH0 0x3610 +#define HDMI_AHB_DMA_MBLENGTH1 0x3611 +#define HDMI_AHB_DMA_STAT 0x3612 +#define HDMI_AHB_DMA_INT 0x3613 +#define HDMI_AHB_DMA_MASK 0x3614 +#define HDMI_AHB_DMA_POL 0x3615 +#define HDMI_AHB_DMA_CONF1 0x3616 +#define HDMI_AHB_DMA_BUFFSTAT 0x3617 +#define HDMI_AHB_DMA_BUFFINT 0x3618 +#define HDMI_AHB_DMA_BUFFMASK 0x3619 +#define HDMI_AHB_DMA_BUFFPOL 0x361a + +/* Main Controller Registers */ +#define HDMI_MC_SFRDIV 0x4000 +#define HDMI_MC_CLKDIS 0x4001 +#define HDMI_MC_SWRSTZ 0x4002 +#define HDMI_MC_OPCTRL 0x4003 +#define HDMI_MC_FLOWCTRL 0x4004 +#define HDMI_MC_PHYRSTZ 0x4005 +#define HDMI_MC_LOCKONCLOCK 0x4006 +#define HDMI_MC_HEACPHY_RST 0x4007 + +/* Color Space Converter Registers */ +#define HDMI_CSC_CFG 0x4100 +#define HDMI_CSC_SCALE 0x4101 +#define HDMI_CSC_COEF_A1_MSB 0x4102 +#define HDMI_CSC_COEF_A1_LSB 0x4103 +#define HDMI_CSC_COEF_A2_MSB 0x4104 +#define HDMI_CSC_COEF_A2_LSB 0x4105 +#define HDMI_CSC_COEF_A3_MSB 0x4106 +#define HDMI_CSC_COEF_A3_LSB 0x4107 +#define HDMI_CSC_COEF_A4_MSB 0x4108 +#define HDMI_CSC_COEF_A4_LSB 0x4109 +#define HDMI_CSC_COEF_B1_MSB 0x410A +#define HDMI_CSC_COEF_B1_LSB 0x410B +#define HDMI_CSC_COEF_B2_MSB 0x410C +#define HDMI_CSC_COEF_B2_LSB 0x410D +#define HDMI_CSC_COEF_B3_MSB 0x410E +#define HDMI_CSC_COEF_B3_LSB 0x410F +#define HDMI_CSC_COEF_B4_MSB 0x4110 +#define HDMI_CSC_COEF_B4_LSB 0x4111 +#define HDMI_CSC_COEF_C1_MSB 0x4112 +#define HDMI_CSC_COEF_C1_LSB 0x4113 +#define HDMI_CSC_COEF_C2_MSB 0x4114 +#define HDMI_CSC_COEF_C2_LSB 0x4115 +#define HDMI_CSC_COEF_C3_MSB 0x4116 +#define HDMI_CSC_COEF_C3_LSB 0x4117 +#define HDMI_CSC_COEF_C4_MSB 0x4118 +#define HDMI_CSC_COEF_C4_LSB 0x4119 + +/* HDCP Encryption Engine Registers */ +#define HDMI_A_HDCPCFG0 0x5000 +#define HDMI_A_HDCPCFG1 0x5001 +#define HDMI_A_HDCPOBS0 0x5002 +#define HDMI_A_HDCPOBS1 0x5003 +#define HDMI_A_HDCPOBS2 0x5004 +#define HDMI_A_HDCPOBS3 0x5005 +#define HDMI_A_APIINTCLR 0x5006 +#define HDMI_A_APIINTSTAT 0x5007 +#define HDMI_A_APIINTMSK 0x5008 +#define HDMI_A_VIDPOLCFG 0x5009 +#define HDMI_A_OESSWCFG 0x500A +#define HDMI_A_TIMER1SETUP0 0x500B +#define HDMI_A_TIMER1SETUP1 0x500C +#define HDMI_A_TIMER2SETUP0 0x500D +#define HDMI_A_TIMER2SETUP1 0x500E +#define HDMI_A_100MSCFG 0x500F +#define HDMI_A_2SCFG0 0x5010 +#define HDMI_A_2SCFG1 0x5011 +#define HDMI_A_5SCFG0 0x5012 +#define HDMI_A_5SCFG1 0x5013 +#define HDMI_A_SRMVERLSB 0x5014 +#define HDMI_A_SRMVERMSB 0x5015 +#define HDMI_A_SRMCTRL 0x5016 +#define HDMI_A_SFRSETUP 0x5017 +#define HDMI_A_I2CHSETUP 0x5018 +#define HDMI_A_INTSETUP 0x5019 +#define HDMI_A_PRESETUP 0x501A +#define HDMI_A_SRM_BASE 0x5020 + +/* CEC Engine Registers */ +#define HDMI_CEC_CTRL 0x7D00 +#define HDMI_CEC_STAT 0x7D01 +#define HDMI_CEC_MASK 0x7D02 +#define HDMI_CEC_POLARITY 0x7D03 +#define HDMI_CEC_INT 0x7D04 +#define HDMI_CEC_ADDR_L 0x7D05 +#define HDMI_CEC_ADDR_H 0x7D06 +#define HDMI_CEC_TX_CNT 0x7D07 +#define HDMI_CEC_RX_CNT 0x7D08 +#define HDMI_CEC_TX_DATA0 0x7D10 +#define HDMI_CEC_TX_DATA1 0x7D11 +#define HDMI_CEC_TX_DATA2 0x7D12 +#define HDMI_CEC_TX_DATA3 0x7D13 +#define HDMI_CEC_TX_DATA4 0x7D14 +#define HDMI_CEC_TX_DATA5 0x7D15 +#define HDMI_CEC_TX_DATA6 0x7D16 +#define HDMI_CEC_TX_DATA7 0x7D17 +#define HDMI_CEC_TX_DATA8 0x7D18 +#define HDMI_CEC_TX_DATA9 0x7D19 +#define HDMI_CEC_TX_DATA10 0x7D1a +#define HDMI_CEC_TX_DATA11 0x7D1b +#define HDMI_CEC_TX_DATA12 0x7D1c +#define HDMI_CEC_TX_DATA13 0x7D1d +#define HDMI_CEC_TX_DATA14 0x7D1e +#define HDMI_CEC_TX_DATA15 0x7D1f +#define HDMI_CEC_RX_DATA0 0x7D20 +#define HDMI_CEC_RX_DATA1 0x7D21 +#define HDMI_CEC_RX_DATA2 0x7D22 +#define HDMI_CEC_RX_DATA3 0x7D23 +#define HDMI_CEC_RX_DATA4 0x7D24 +#define HDMI_CEC_RX_DATA5 0x7D25 +#define HDMI_CEC_RX_DATA6 0x7D26 +#define HDMI_CEC_RX_DATA7 0x7D27 +#define HDMI_CEC_RX_DATA8 0x7D28 +#define HDMI_CEC_RX_DATA9 0x7D29 +#define HDMI_CEC_RX_DATA10 0x7D2a +#define HDMI_CEC_RX_DATA11 0x7D2b +#define HDMI_CEC_RX_DATA12 0x7D2c +#define HDMI_CEC_RX_DATA13 0x7D2d +#define HDMI_CEC_RX_DATA14 0x7D2e +#define HDMI_CEC_RX_DATA15 0x7D2f +#define HDMI_CEC_LOCK 0x7D30 +#define HDMI_CEC_WKUPCTRL 0x7D31 + +/* I2C Master Registers (E-DDC) */ +#define HDMI_I2CM_SLAVE 0x7E00 +#define HDMI_I2CMESS 0x7E01 +#define HDMI_I2CM_DATAO 0x7E02 +#define HDMI_I2CM_DATAI 0x7E03 +#define HDMI_I2CM_OPERATION 0x7E04 +#define HDMI_I2CM_INT 0x7E05 +#define HDMI_I2CM_CTLINT 0x7E06 +#define HDMI_I2CM_DIV 0x7E07 +#define HDMI_I2CM_SEGADDR 0x7E08 +#define HDMI_I2CM_SOFTRSTZ 0x7E09 +#define HDMI_I2CM_SEGPTR 0x7E0A +#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C +#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E +#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F +#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10 +#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11 +#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 + +enum { +/* IH_FC_INT2 field values */ + HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, + HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_FC_STAT2 field values */ + HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_PHY_STAT0 field values */ + HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, + HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, + HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, + HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, + HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, + HDMI_IH_PHY_STAT0_HPD = 0x1, + +/* IH_MUTE_I2CMPHY_STAT0 field values */ + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, + +/* IH_AHBDMAAUD_STAT0 field values */ + HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, + HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, + HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, + HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, + +/* IH_MUTE_FC_STAT2 field values */ + HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_MUTE_AHBDMAAUD_STAT0 field values */ + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, + +/* IH_MUTE field values */ + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, + +/* TX_INVID0 field values */ + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, + HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, + HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, + +/* TX_INSTUFFING field values */ + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, + +/* VP_PR_CD field values */ + HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, + HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, + +/* VP_STUFF field values */ + HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, + HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, + HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, + HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, + HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, + HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, + HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, + HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, + HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, + HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, + HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, + HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, + HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, + HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, + +/* VP_CONF field values */ + HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, + HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, + HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, + HDMI_VP_CONF_PP_EN_ENMASK = 0x20, + HDMI_VP_CONF_PP_EN_ENABLE = 0x20, + HDMI_VP_CONF_PP_EN_DISABLE = 0x00, + HDMI_VP_CONF_PR_EN_MASK = 0x10, + HDMI_VP_CONF_PR_EN_ENABLE = 0x10, + HDMI_VP_CONF_PR_EN_DISABLE = 0x00, + HDMI_VP_CONF_YCC422_EN_MASK = 0x8, + HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, + HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, + HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, + HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, + HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, + HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, + HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, + +/* VP_REMAP field values */ + HDMI_VP_REMAP_MASK = 0x3, + HDMI_VP_REMAP_YCC422_24bit = 0x2, + HDMI_VP_REMAP_YCC422_20bit = 0x1, + HDMI_VP_REMAP_YCC422_16bit = 0x0, + +/* FC_INVIDCONF field values */ + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, + HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, + +/* FC_AUDICONF0 field values */ + HDMI_FC_AUDICONF0_CC_OFFSET = 4, + HDMI_FC_AUDICONF0_CC_MASK = 0x70, + HDMI_FC_AUDICONF0_CT_OFFSET = 0, + HDMI_FC_AUDICONF0_CT_MASK = 0xF, + +/* FC_AUDICONF1 field values */ + HDMI_FC_AUDICONF1_SS_OFFSET = 3, + HDMI_FC_AUDICONF1_SS_MASK = 0x18, + HDMI_FC_AUDICONF1_SF_OFFSET = 0, + HDMI_FC_AUDICONF1_SF_MASK = 0x7, + +/* FC_AUDICONF3 field values */ + HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, + HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, + HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, + HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, + HDMI_FC_AUDICONF3_LSV_OFFSET = 0, + HDMI_FC_AUDICONF3_LSV_MASK = 0xF, + +/* FC_AUDSCHNLS0 field values */ + HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, + HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, + HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, + HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, + +/* FC_AUDSCHNLS3-6 field values */ + HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, + HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, + HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, + HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, + HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, + HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, + HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, + HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, + + HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, + HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, + HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, + HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, + HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, + HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, + HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, + HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, + +/* HDMI_FC_AUDSCHNLS7 field values */ + HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, + HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, + +/* HDMI_FC_AUDSCHNLS8 field values */ + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, + +/* FC_AUDSCONF field values */ + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, + +/* FC_STAT2 field values */ + HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_INT2 field values */ + HDMI_FC_INT2_OVERFLOW_MASK = 0x03, + HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_MASK2 field values */ + HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, + HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_PRCONF field values */ + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, + +/* FC_AVICONF0-FC_AVICONF3 field values */ + HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, + HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, + HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, + HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, + HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, + HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, + HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, + HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, + HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, + HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, + HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, + HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, + HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, + HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, + + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, + HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, + HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, + HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, + HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, + HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, + + HDMI_FC_AVICONF2_SCALING_MASK = 0x03, + HDMI_FC_AVICONF2_SCALING_NONE = 0x00, + HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, + HDMI_FC_AVICONF2_SCALING_VERT = 0x02, + HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, + HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, + HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, + HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, + HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, + HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, + HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, + + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, + HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, + +/* FC_DBGFORCE field values */ + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, + +/* PHY_CONF0 field values */ + HDMI_PHY_CONF0_PDZ_MASK = 0x80, + HDMI_PHY_CONF0_PDZ_OFFSET = 7, + HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, + HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, + HDMI_PHY_CONF0_SPARECTRL = 0x20, + HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, + HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, + HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, + HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, + +/* PHY_TST0 field values */ + HDMI_PHY_TST0_TSTCLR_MASK = 0x20, + HDMI_PHY_TST0_TSTCLR_OFFSET = 5, + HDMI_PHY_TST0_TSTEN_MASK = 0x10, + HDMI_PHY_TST0_TSTEN_OFFSET = 4, + HDMI_PHY_TST0_TSTCLK_MASK = 0x1, + HDMI_PHY_TST0_TSTCLK_OFFSET = 0, + +/* PHY_STAT0 field values */ + HDMI_PHY_RX_SENSE3 = 0x80, + HDMI_PHY_RX_SENSE2 = 0x40, + HDMI_PHY_RX_SENSE1 = 0x20, + HDMI_PHY_RX_SENSE0 = 0x10, + HDMI_PHY_HPD = 0x02, + HDMI_PHY_TX_PHY_LOCK = 0x01, + +/* PHY_I2CM_SLAVE_ADDR field values */ + HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, + HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, + +/* PHY_I2CM_OPERATION_ADDR field values */ + HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, + HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, + +/* HDMI_PHY_I2CM_INT_ADDR */ + HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, + HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, + +/* HDMI_PHY_I2CM_CTLINT_ADDR */ + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, + +/* AUD_CTS3 field values */ + HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, + HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, + HDMI_AUD_CTS3_N_SHIFT_1 = 0, + HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, + HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, + HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, + HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, + HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, + /* note that the CTS3 MANUAL bit has been removed + from our part. Can't set it, will read as 0. */ + HDMI_AUD_CTS3_CTS_MANUAL = 0x10, + HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, + +/* AHB_DMA_CONF0 field values */ + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, + HDMI_AHB_DMA_CONF0_HBR = 0x10, + HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, + HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, + HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, + HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, + HDMI_AHB_DMA_CONF0_INCR4 = 0x0, + HDMI_AHB_DMA_CONF0_INCR8 = 0x2, + HDMI_AHB_DMA_CONF0_INCR16 = 0x4, + HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, + +/* HDMI_AHB_DMA_START field values */ + HDMI_AHB_DMA_START_START_OFFSET = 0, + HDMI_AHB_DMA_START_START_MASK = 0x01, + +/* HDMI_AHB_DMA_STOP field values */ + HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, + HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, + +/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ + HDMI_AHB_DMA_DONE = 0x80, + HDMI_AHB_DMA_RETRY_SPLIT = 0x40, + HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, + HDMI_AHB_DMA_ERROR = 0x10, + HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, + HDMI_AHB_DMA_FIFO_FULL = 0x02, + HDMI_AHB_DMA_FIFO_EMPTY = 0x01, + +/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */ + HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, + HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, + +/* MC_CLKDIS field values */ + HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, + HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, + HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, + HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, + HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, + HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, + HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, + +/* MC_SWRSTZ field values */ + HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, + +/* MC_FLOWCTRL field values */ + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, + +/* MC_PHYRSTZ field values */ + HDMI_MC_PHYRSTZ_ASSERT = 0x0, + HDMI_MC_PHYRSTZ_DEASSERT = 0x1, + +/* MC_HEACPHY_RST field values */ + HDMI_MC_HEACPHY_RST_ASSERT = 0x1, + HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, + +/* CSC_CFG field values */ + HDMI_CSC_CFG_INTMODE_MASK = 0x30, + HDMI_CSC_CFG_INTMODE_OFFSET = 4, + HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, + HDMI_CSC_CFG_DECMODE_MASK = 0x3, + HDMI_CSC_CFG_DECMODE_OFFSET = 0, + HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, + +/* CSC_SCALE field values */ + HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, + HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, + +/* A_HDCPCFG0 field values */ + HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, + HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, + HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, + HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, + HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, + HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, + HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, + HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, + HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, + HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, + HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, + HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, + HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, + HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, + HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, + HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, + HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, + HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, + HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, + HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, + HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, + HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, + HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, + HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, + +/* A_HDCPCFG1 field values */ + HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, + HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, + HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, + HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, + HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, + +/* A_VIDPOLCFG field values */ + HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, + HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, + HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, + HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, + HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, + HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, + HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, + HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, + HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, + HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, + HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, +}; +#endif /* __IMX_HDMI_H__ */ diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 654bf03e05ff..7e593296ac47 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -167,9 +167,8 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, /* set display clock mux to LDB input clock */ ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]); - if (ret) { + if (ret) dev_err(ldb->dev, "unable to set di%d parent clock to ldb_di%d\n", mux, chno); - } } static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) @@ -414,7 +413,7 @@ enum { LVDS_BIT_MAP_JEIDA }; -static const char *imx_ldb_bit_mappings[] = { +static const char * const imx_ldb_bit_mappings[] = { [LVDS_BIT_MAP_SPWG] = "spwg", [LVDS_BIT_MAP_JEIDA] = "jeida", }; diff --git a/drivers/staging/keucr/smil.h b/drivers/staging/keucr/smil.h index 1538d7bd600f..fff6c9e6164a 100644 --- a/drivers/staging/keucr/smil.h +++ b/drivers/staging/keucr/smil.h @@ -189,12 +189,6 @@ struct keucr_media_area { WORD PhyBlock; /* Physical Block Number on Zone 0 */ }; - -extern BYTE IsSSFDCCompliance; -extern BYTE IsXDCompliance; - -extern DWORD ErrXDCode; -extern DWORD ErrCode; extern WORD ReadBlock; extern WORD WriteBlock; extern DWORD MediaChange; diff --git a/drivers/staging/keucr/smilmain.c b/drivers/staging/keucr/smilmain.c index 2786808fde9f..9434cda885ca 100644 --- a/drivers/staging/keucr/smilmain.c +++ b/drivers/staging/keucr/smilmain.c @@ -4,49 +4,28 @@ #include "smcommon.h" #include "smil.h" -int Check_D_LogCHS(WORD *, BYTE *, BYTE *); -void Initialize_D_Media(void); -void PowerOff_D_Media(void); -int Check_D_MediaPower(void); -int Check_D_MediaExist(void); -int Check_D_MediaWP(void); -int Check_D_MediaFmt(struct us_data *); -int Check_D_MediaFmtForEraseAll(struct us_data *); -int Conv_D_MediaAddr(struct us_data *, DWORD); -int Inc_D_MediaAddr(struct us_data *); -int Check_D_FirstSect(void); -int Check_D_LastSect(void); -int Media_D_ReadOneSect(struct us_data *, WORD, BYTE *); -int Media_D_WriteOneSect(struct us_data *, WORD, BYTE *); -int Media_D_CopyBlockHead(struct us_data *); -int Media_D_CopyBlockTail(struct us_data *); -int Media_D_EraseOneBlock(void); -int Media_D_EraseAllBlock(void); - -int Copy_D_BlockAll(struct us_data *, DWORD); -int Copy_D_BlockHead(struct us_data *); -int Copy_D_BlockTail(struct us_data *); -int Reassign_D_BlockHead(struct us_data *); - -int Assign_D_WriteBlock(void); -int Release_D_ReadBlock(struct us_data *); -int Release_D_WriteBlock(struct us_data *); -int Release_D_CopySector(struct us_data *); - -int Copy_D_PhyOneSect(struct us_data *); -int Read_D_PhyOneSect(struct us_data *, WORD, BYTE *); -int Write_D_PhyOneSect(struct us_data *, WORD, BYTE *); -int Erase_D_PhyOneBlock(struct us_data *); - -int Set_D_PhyFmtValue(struct us_data *); -int Search_D_CIS(struct us_data *); -int Make_D_LogTable(struct us_data *); -void Check_D_BlockIsFull(void); - -int MarkFail_D_PhyOneBlock(struct us_data *); - -DWORD ErrXDCode; -DWORD ErrCode; +static int Conv_D_MediaAddr(struct us_data *, DWORD); +static int Inc_D_MediaAddr(struct us_data *); +static int Media_D_ReadOneSect(struct us_data *, WORD, BYTE *); + +static int Copy_D_BlockAll(struct us_data *, DWORD); + +static int Assign_D_WriteBlock(void); +static int Release_D_ReadBlock(struct us_data *); +static int Release_D_WriteBlock(struct us_data *); +static int Release_D_CopySector(struct us_data *); + +static int Copy_D_PhyOneSect(struct us_data *); +static int Read_D_PhyOneSect(struct us_data *, WORD, BYTE *); +static int Erase_D_PhyOneBlock(struct us_data *); + +static int Set_D_PhyFmtValue(struct us_data *); +static int Search_D_CIS(struct us_data *); +static int Make_D_LogTable(struct us_data *); + +static int MarkFail_D_PhyOneBlock(struct us_data *); + +static DWORD ErrCode; static BYTE WorkBuf[SECTSIZE]; static BYTE Redundant[REDTSIZE]; static BYTE WorkRedund[REDTSIZE]; @@ -65,10 +44,6 @@ static BYTE BitData[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; #define Clr_D_Bit(a, b) (a[(BYTE)((b) / 8)] &= ~BitData[(b) % 8]) #define Chk_D_Bit(a, b) (a[(BYTE)((b) / 8)] & BitData[(b) % 8]) -BYTE IsSSFDCCompliance; -BYTE IsXDCompliance; - - /* ----- SM_FreeMem() ------------------------------------------------- */ int SM_FreeMem(void) { @@ -167,7 +142,7 @@ int Media_D_CopySector(struct us_data *us, DWORD start, WORD count, BYTE *buf) } /* ----- Release_D_CopySector() ------------------------------------------ */ -int Release_D_CopySector(struct us_data *us) +static int Release_D_CopySector(struct us_data *us) { Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock; Media.PhyBlock = ReadBlock; @@ -211,7 +186,7 @@ int Check_D_MediaFmt(struct us_data *us) /* SmartMedia Physical Address Control Subroutine */ /* ----- Conv_D_MediaAddr() --------------------------------------------- */ -int Conv_D_MediaAddr(struct us_data *us, DWORD addr) +static int Conv_D_MediaAddr(struct us_data *us, DWORD addr) { DWORD temp; @@ -240,7 +215,7 @@ int Conv_D_MediaAddr(struct us_data *us, DWORD addr) } /* ----- Inc_D_MediaAddr() ---------------------------------------------- */ -int Inc_D_MediaAddr(struct us_data *us) +static int Inc_D_MediaAddr(struct us_data *us) { WORD LogBlock = Media.LogBlock; @@ -290,7 +265,7 @@ int Inc_D_MediaAddr(struct us_data *us) /* SmartMedia Read/Write Subroutine with Retry */ /* ----- Media_D_ReadOneSect() ------------------------------------------ */ -int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf) +static int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf) { DWORD err, retry; @@ -334,7 +309,7 @@ int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf) /* SmartMedia Physical Sector Data Copy Subroutine */ /* ----- Copy_D_BlockAll() ---------------------------------------------- */ -int Copy_D_BlockAll(struct us_data *us, DWORD mode) +static int Copy_D_BlockAll(struct us_data *us, DWORD mode) { BYTE sect; @@ -371,7 +346,7 @@ int Copy_D_BlockAll(struct us_data *us, DWORD mode) /* SmartMedia Physical Block Assign/Release Subroutine */ /* ----- Assign_D_WriteBlock() ------------------------------------------ */ -int Assign_D_WriteBlock(void) +static int Assign_D_WriteBlock(void) { ReadBlock = Media.PhyBlock; @@ -404,7 +379,7 @@ int Assign_D_WriteBlock(void) } /* ----- Release_D_ReadBlock() ------------------------------------------ */ -int Release_D_ReadBlock(struct us_data *us) +static int Release_D_ReadBlock(struct us_data *us) { DWORD mode; @@ -438,7 +413,7 @@ int Release_D_ReadBlock(struct us_data *us) } /* ----- Release_D_WriteBlock() ----------------------------------------- */ -int Release_D_WriteBlock(struct us_data *us) +static int Release_D_WriteBlock(struct us_data *us) { SectCopyMode = COMPLETED; Media.PhyBlock = WriteBlock; @@ -452,7 +427,7 @@ int Release_D_WriteBlock(struct us_data *us) /* SmartMedia Physical Sector Data Copy Subroutine */ /* ----- Copy_D_PhyOneSect() -------------------------------------------- */ -int Copy_D_PhyOneSect(struct us_data *us) +static int Copy_D_PhyOneSect(struct us_data *us) { int i; DWORD err, retry; @@ -529,7 +504,7 @@ int Copy_D_PhyOneSect(struct us_data *us) /* SmartMedia Physical Sector Read/Write/Erase Subroutine */ /* ----- Read_D_PhyOneSect() -------------------------------------------- */ -int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf) +static int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf) { int i; DWORD retry; @@ -580,7 +555,7 @@ int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf) } /* ----- Erase_D_PhyOneBlock() ------------------------------------------ */ -int Erase_D_PhyOneBlock(struct us_data *us) +static int Erase_D_PhyOneBlock(struct us_data *us) { if (Ssfdc_D_EraseBlock(us)) { ErrCode = ERR_HwError; @@ -597,7 +572,7 @@ int Erase_D_PhyOneBlock(struct us_data *us) /* SmartMedia Physical Format Check Local Subroutine */ /* ----- Set_D_PhyFmtValue() -------------------------------------------- */ -int Set_D_PhyFmtValue(struct us_data *us) +static int Set_D_PhyFmtValue(struct us_data *us) { if (Set_D_SsfdcModel(us->SM_DeviceID)) return ERROR; @@ -606,7 +581,7 @@ int Set_D_PhyFmtValue(struct us_data *us) } /* ----- Search_D_CIS() ------------------------------------------------- */ -int Search_D_CIS(struct us_data *us) +static int Search_D_CIS(struct us_data *us) { Media.Zone = 0; Media.Sector = 0; @@ -660,7 +635,7 @@ int Search_D_CIS(struct us_data *us) } /* ----- Make_D_LogTable() ---------------------------------------------- */ -int Make_D_LogTable(struct us_data *us) +static int Make_D_LogTable(struct us_data *us) { WORD phyblock, logblock; @@ -761,7 +736,7 @@ int Make_D_LogTable(struct us_data *us) } /* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */ -int MarkFail_D_PhyOneBlock(struct us_data *us) +static int MarkFail_D_PhyOneBlock(struct us_data *us) { BYTE sect; diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 346c5702f411..16da9a9b4033 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -6,45 +6,16 @@ #include "smcommon.h" #include "smil.h" -void _Set_D_SsfdcRdCmd(BYTE); -void _Set_D_SsfdcRdAddr(BYTE); -void _Set_D_SsfdcRdChip(void); -void _Set_D_SsfdcRdStandby(void); -void _Start_D_SsfdcRdHwECC(void); -void _Stop_D_SsfdcRdHwECC(void); -void _Load_D_SsfdcRdHwECC(BYTE); -void _Set_D_SsfdcWrCmd(BYTE); -void _Set_D_SsfdcWrAddr(BYTE); -void _Set_D_SsfdcWrBlock(void); -void _Set_D_SsfdcWrStandby(void); -void _Start_D_SsfdcWrHwECC(void); -void _Load_D_SsfdcWrHwECC(BYTE); -int _Check_D_SsfdcBusy(WORD); -int _Check_D_SsfdcStatus(void); -void _Reset_D_SsfdcErr(void); -void _Read_D_SsfdcBuf(BYTE *); -void _Write_D_SsfdcBuf(BYTE *); -void _Read_D_SsfdcByte(BYTE *); -void _ReadRedt_D_SsfdcBuf(BYTE *); -void _WriteRedt_D_SsfdcBuf(BYTE *); -BYTE _Check_D_DevCode(BYTE); - -void _Set_D_ECCdata(BYTE, BYTE *); -void _Calc_D_ECCdata(BYTE *); - +static BYTE _Check_D_DevCode(BYTE); +static DWORD ErrXDCode; +static BYTE IsSSFDCCompliance; +static BYTE IsXDCompliance; struct keucr_media_info Ssfdc; struct keucr_media_address Media; struct keucr_media_area CisArea; static BYTE EccBuf[6]; -extern PBYTE SMHostAddr; -extern DWORD ErrXDCode; - -extern WORD ReadBlock; -extern WORD WriteBlock; - - #define EVEN 0 /* Even Page for 256byte/page */ #define ODD 1 /* Odd Page for 256byte/page */ diff --git a/drivers/staging/keucr/smscsi.c b/drivers/staging/keucr/smscsi.c index 572d6489b66b..5c03eca4dba8 100644 --- a/drivers/staging/keucr/smscsi.c +++ b/drivers/staging/keucr/smscsi.c @@ -11,16 +11,12 @@ #include "transport.h" #include "smil.h" -int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Start_Stop(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb); - -extern PBYTE SMHostAddr; -extern DWORD ErrXDCode; +static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb); +static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb); +static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb); +static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb); +static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb); +static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb); /* ----- SM_SCSIIrp() -------------------------------------------------- */ int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) @@ -57,7 +53,7 @@ int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) } /* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */ -int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) { if (us->SM_Status.Insert && us->SM_Status.Ready) return USB_STOR_TRANSPORT_GOOD; @@ -70,7 +66,7 @@ int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) } /* ----- SM_SCSI_Inquiry() --------------------------------------------- */ -int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) { BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, @@ -84,7 +80,7 @@ int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) /* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */ -int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) { BYTE mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; @@ -101,7 +97,7 @@ int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) } /* ----- SM_SCSI_Read_Capacity() --------------------------------------- */ -int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) { unsigned int offset = 0; struct scatterlist *sg = NULL; @@ -133,7 +129,7 @@ int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) } /* ----- SM_SCSI_Read() -------------------------------------------------- */ -int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) { int result = 0; PBYTE Cdb = srb->cmnd; @@ -165,7 +161,7 @@ int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) } /* ----- SM_SCSI_Write() -------------------------------------------------- */ -int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) +static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) { int result = 0; PBYTE Cdb = srb->cmnd; diff --git a/drivers/staging/lustre/include/linux/libcfs/curproc.h b/drivers/staging/lustre/include/linux/libcfs/curproc.h index de8e35b796ab..507d16b9213c 100644 --- a/drivers/staging/lustre/include/linux/libcfs/curproc.h +++ b/drivers/staging/lustre/include/linux/libcfs/curproc.h @@ -61,7 +61,6 @@ int cfs_curproc_groups_nr(void); */ /* check if task is running in compat mode.*/ -int current_is_32bit(void); #define current_pid() (current->pid) #define current_comm() (current->comm) int cfs_get_environ(const char *key, char *value, int *val_len); diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 687dbab2c4ec..4a6c7da72174 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -181,8 +181,6 @@ static inline void *__container_of(void *ptr, unsigned long shift) #define container_of0(ptr, type, member) \ ((type *)__container_of((void *)(ptr), offsetof(type, member))) -#define SET_BUT_UNUSED(a) do { } while(sizeof(a) - sizeof(a)) - #define _LIBCFS_H #endif /* _LIBCFS_H */ diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h index 5be367973508..74dda57b98a8 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h @@ -69,6 +69,7 @@ struct libcfs_ioctl_data { char ioc_bulk[0]; }; +#define ioc_priority ioc_u32[0] struct libcfs_ioctl_hdr { __u32 ioc_len; @@ -110,41 +111,38 @@ struct libcfs_ioctl_handler { #define IOC_LIBCFS_TYPE 'e' #define IOC_LIBCFS_MIN_NR 30 /* libcfs ioctls */ -#define IOC_LIBCFS_PANIC _IOWR('e', 30, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_CONTROL _IOWR('e', 33, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_SNAPSHOT _IOWR('e', 34, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LWT_LOOKUP_STRING _IOWR('e', 35, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_PANIC _IOWR('e', 30, long) +#define IOC_LIBCFS_CLEAR_DEBUG _IOWR('e', 31, long) +#define IOC_LIBCFS_MARK_DEBUG _IOWR('e', 32, long) +#define IOC_LIBCFS_MEMHOG _IOWR('e', 36, long) +#define IOC_LIBCFS_PING_TEST _IOWR('e', 37, long) /* lnet ioctls */ -#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PING _IOWR('e', 61, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_LNETST _IOWR('e', 63, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_GET_NI _IOWR('e', 50, long) +#define IOC_LIBCFS_FAIL_NID _IOWR('e', 51, long) +#define IOC_LIBCFS_ADD_ROUTE _IOWR('e', 52, long) +#define IOC_LIBCFS_DEL_ROUTE _IOWR('e', 53, long) +#define IOC_LIBCFS_GET_ROUTE _IOWR('e', 54, long) +#define IOC_LIBCFS_NOTIFY_ROUTER _IOWR('e', 55, long) +#define IOC_LIBCFS_UNCONFIGURE _IOWR('e', 56, long) +#define IOC_LIBCFS_PORTALS_COMPATIBILITY _IOWR('e', 57, long) +#define IOC_LIBCFS_LNET_DIST _IOWR('e', 58, long) +#define IOC_LIBCFS_CONFIGURE _IOWR('e', 59, long) +#define IOC_LIBCFS_TESTPROTOCOMPAT _IOWR('e', 60, long) +#define IOC_LIBCFS_PING _IOWR('e', 61, long) +#define IOC_LIBCFS_DEBUG_PEER _IOWR('e', 62, long) +#define IOC_LIBCFS_LNETST _IOWR('e', 63, long) /* lnd ioctls */ -#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_TXDESC _IOWR('e', 77, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, IOCTL_LIBCFS_TYPE) -#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, IOCTL_LIBCFS_TYPE) +#define IOC_LIBCFS_REGISTER_MYNID _IOWR('e', 70, long) +#define IOC_LIBCFS_CLOSE_CONNECTION _IOWR('e', 71, long) +#define IOC_LIBCFS_PUSH_CONNECTION _IOWR('e', 72, long) +#define IOC_LIBCFS_GET_CONN _IOWR('e', 73, long) +#define IOC_LIBCFS_DEL_PEER _IOWR('e', 74, long) +#define IOC_LIBCFS_ADD_PEER _IOWR('e', 75, long) +#define IOC_LIBCFS_GET_PEER _IOWR('e', 76, long) +#define IOC_LIBCFS_GET_TXDESC _IOWR('e', 77, long) +#define IOC_LIBCFS_ADD_INTERFACE _IOWR('e', 78, long) +#define IOC_LIBCFS_DEL_INTERFACE _IOWR('e', 79, long) +#define IOC_LIBCFS_GET_INTERFACE _IOWR('e', 80, long) #define IOC_LIBCFS_MAX_NR 80 diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h b/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h index c204b677796f..5cc7ba000485 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h @@ -63,142 +63,15 @@ #include <linux/smp.h> #include <linux/ctype.h> #include <linux/compiler.h> -#ifdef HAVE_MM_INLINE -# include <linux/mm_inline.h> -#endif +#include <linux/mm_inline.h> #include <linux/kallsyms.h> #include <linux/moduleparam.h> #include <linux/scatterlist.h> #include <linux/libcfs/linux/portals_compat25.h> - -/******************************************************************************/ -/* Module parameter support */ -#define CFS_MODULE_PARM(name, t, type, perm, desc) \ - module_param(name, type, perm);\ - MODULE_PARM_DESC(name, desc) - -#define CFS_SYSFS_MODULE_PARM 1 /* module parameters accessible via sysfs */ - -/******************************************************************************/ -/* Light-weight trace - * Support for temporary event tracing with minimal Heisenberg effect. */ -#define LWT_SUPPORT 0 - -#define LWT_MEMORY (16<<20) - -#ifndef KLWT_SUPPORT -# if !defined(BITS_PER_LONG) -# error "BITS_PER_LONG not defined" -# endif - -/* kernel hasn't defined this? */ -typedef struct { - long long lwte_when; - char *lwte_where; - void *lwte_task; - long lwte_p1; - long lwte_p2; - long lwte_p3; - long lwte_p4; -# if BITS_PER_LONG > 32 - long lwte_pad; -# endif -} lwt_event_t; -#endif /* !KLWT_SUPPORT */ - -#if LWT_SUPPORT -# if !KLWT_SUPPORT - -typedef struct _lwt_page { - struct list_head lwtp_list; - struct page *lwtp_page; - lwt_event_t *lwtp_events; -} lwt_page_t; - -typedef struct { - int lwtc_current_index; - lwt_page_t *lwtc_current_page; -} lwt_cpu_t; - -extern int lwt_enabled; -extern lwt_cpu_t lwt_cpus[]; - -/* Note that we _don't_ define LWT_EVENT at all if LWT_SUPPORT isn't set. - * This stuff is meant for finding specific problems; it never stays in - * production code... */ - -#define LWTSTR(n) #n -#define LWTWHERE(f,l) f ":" LWTSTR(l) -#define LWT_EVENTS_PER_PAGE (PAGE_CACHE_SIZE / sizeof (lwt_event_t)) - -#define LWT_EVENT(p1, p2, p3, p4) \ -do { \ - unsigned long flags; \ - lwt_cpu_t *cpu; \ - lwt_page_t *p; \ - lwt_event_t *e; \ - \ - if (lwt_enabled) { \ - local_irq_save (flags); \ - \ - cpu = &lwt_cpus[smp_processor_id()]; \ - p = cpu->lwtc_current_page; \ - e = &p->lwtp_events[cpu->lwtc_current_index++]; \ - \ - if (cpu->lwtc_current_index >= LWT_EVENTS_PER_PAGE) { \ - cpu->lwtc_current_page = \ - list_entry (p->lwtp_list.next, \ - lwt_page_t, lwtp_list); \ - cpu->lwtc_current_index = 0; \ - } \ - \ - e->lwte_when = get_cycles(); \ - e->lwte_where = LWTWHERE(__FILE__,__LINE__); \ - e->lwte_task = current; \ - e->lwte_p1 = (long)(p1); \ - e->lwte_p2 = (long)(p2); \ - e->lwte_p3 = (long)(p3); \ - e->lwte_p4 = (long)(p4); \ - \ - local_irq_restore (flags); \ - } \ -} while (0) - -#endif /* !KLWT_SUPPORT */ - -extern int lwt_init (void); -extern void lwt_fini (void); -extern int lwt_lookup_string (int *size, char *knlptr, - char *usrptr, int usrsize); -extern int lwt_control (int enable, int clear); -extern int lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size, - void *user_ptr, int user_size); -#endif /* LWT_SUPPORT */ - -/* ------------------------------------------------------------------ */ - -#define IOCTL_LIBCFS_TYPE long - -#ifdef __CYGWIN__ -# ifndef BITS_PER_LONG -# define BITS_PER_LONG 64 -# endif -#endif - -# define LI_POISON 0x5a5a5a5a -#if BITS_PER_LONG > 32 -# define LL_POISON 0x5a5a5a5a5a5a5a5aL -#else -# define LL_POISON 0x5a5a5a5aL -#endif -# define LP_POISON ((void *)LL_POISON) - /* this is a bit chunky */ -#define _LWORDSIZE BITS_PER_LONG - # define LPU64 "%llu" # define LPD64 "%lld" # define LPX64 "%#llx" @@ -218,24 +91,4 @@ extern int lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size, */ # define LPPID "%d" - -#undef _LWORDSIZE - -/* compat macroses */ - - -#ifndef get_cpu -# ifdef CONFIG_PREEMPT -# define get_cpu() ({ preempt_disable(); smp_processor_id(); }) -# define put_cpu() preempt_enable() -# else -# define get_cpu() smp_processor_id() -# define put_cpu() -# endif -#else -#endif /* get_cpu & put_cpu */ - -#define INIT_CTL_NAME(a) -#define INIT_STRATEGY(a) - #endif diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h index 60ecaf63f9fb..a7bca40e9fb7 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h @@ -49,7 +49,6 @@ #include <linux/libcfs/linux/linux-mem.h> #include <linux/libcfs/linux/linux-prim.h> #include <linux/libcfs/linux/linux-lock.h> -#include <linux/libcfs/linux/linux-fs.h> #include <linux/libcfs/linux/linux-tcpip.h> #include <linux/libcfs/linux/linux-bitops.h> #include <linux/libcfs/linux/linux-types.h> diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h deleted file mode 100644 index eebf138f21e5..000000000000 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/include/libcfs/linux/linux-fs.h - * - * Basic library routines. - */ - -#ifndef __LIBCFS_LINUX_CFS_FS_H__ -#define __LIBCFS_LINUX_CFS_FS_H__ - -#ifndef __LIBCFS_LIBCFS_H__ -#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead -#endif - - -#include <linux/fs.h> -#include <linux/stat.h> -#include <linux/mount.h> -#include <linux/backing-dev.h> -#include <linux/posix_acl_xattr.h> - -#define filp_size(f) \ - (i_size_read((f)->f_dentry->d_inode)) -#define filp_poff(f) \ - (&(f)->f_pos) - -# define do_fsync(fp, flag) \ - ((fp)->f_op->fsync(fp, 0, LLONG_MAX, flag)) - -#define filp_read(fp, buf, size, pos) \ - ((fp)->f_op->read((fp), (buf), (size), pos)) - -#define filp_write(fp, buf, size, pos) \ - ((fp)->f_op->write((fp), (buf), (size), pos)) - -#define filp_fsync(fp) \ - do_fsync(fp, 1) - -#define flock_type(fl) ((fl)->fl_type) -#define flock_set_type(fl, type) do { (fl)->fl_type = (type); } while (0) -#define flock_pid(fl) ((fl)->fl_pid) -#define flock_set_pid(fl, pid) do { (fl)->fl_pid = (pid); } while (0) -#define flock_start(fl) ((fl)->fl_start) -#define flock_set_start(fl, st) do { (fl)->fl_start = (st); } while (0) -#define flock_end(fl) ((fl)->fl_end) -#define flock_set_end(fl, end) do { (fl)->fl_end = (end); } while (0) - -#ifndef IFSHIFT -#define IFSHIFT 12 -#endif - -#ifndef IFTODT -#define IFTODT(type) (((type) & S_IFMT) >> IFSHIFT) -#endif -#ifndef DTTOIF -#define DTTOIF(dirtype) ((dirtype) << IFSHIFT) -#endif - -#endif diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index bf301048c7ab..3ac2bb5fd2db 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -650,12 +650,13 @@ extern lnet_ni_t *lnet_net2ni(__u32 net); int lnet_notify(lnet_ni_t *ni, lnet_nid_t peer, int alive, cfs_time_t when); void lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when); -int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway_nid); +int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway_nid, + unsigned int priority); int lnet_check_routes(void); int lnet_del_route(__u32 net, lnet_nid_t gw_nid); void lnet_destroy_routes(void); int lnet_get_route(int idx, __u32 *net, __u32 *hops, - lnet_nid_t *gateway, __u32 *alive); + lnet_nid_t *gateway, __u32 *alive, __u32 *priority); void lnet_proc_init(void); void lnet_proc_fini(void); int lnet_rtrpools_alloc(int im_a_router); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index e579e7ed5070..dd8edcf1b5c0 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -478,7 +478,6 @@ typedef struct lnet_peer { lnet_rc_data_t *lp_rcd; /* router checker state */ } lnet_peer_t; - /* peer hash size */ #define LNET_PEER_HASH_BITS 9 #define LNET_PEER_HASH_SIZE (1 << LNET_PEER_HASH_BITS) @@ -504,6 +503,7 @@ typedef struct { int lr_seq; /* sequence for round-robin */ unsigned int lr_downis; /* number of down NIs */ unsigned int lr_hops; /* how far I am */ + unsigned int lr_priority; /* route priority */ } lnet_route_t; #define LNET_REMOTE_NETS_HASH_DEFAULT (1U << 7) diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h index 4f63b7acb9d7..c833ce8544d3 100644 --- a/drivers/staging/lustre/include/linux/lnet/types.h +++ b/drivers/staging/lustre/include/linux/lnet/types.h @@ -383,14 +383,6 @@ typedef enum { typedef unsigned LNET_SEQ_BASETYPE lnet_seq_t; #define LNET_SEQ_GT(a,b) (((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0) -/* XXX - * cygwin need the pragma line, not clear if it's needed in other places. - * checking!!! - */ -#ifdef __CYGWIN__ -#pragma pack(push, 4) -#endif - /** * Information about an event on a MD. */ @@ -462,9 +454,6 @@ typedef struct { */ volatile lnet_seq_t sequence; } lnet_event_t; -#ifdef __CYGWIN__ -#pragma pop -#endif /** * Event queue handler function type. diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 86397f96b033..644a0000130a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -3230,7 +3230,6 @@ void __exit kiblnd_module_fini (void) { lnet_unregister_lnd(&the_o2iblnd); - kiblnd_tunables_fini(); } int __init diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 938df0cf8c64..3f83ce4871cf 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -106,9 +106,6 @@ typedef struct int *kib_fmr_pool_size; /* # FMRs in pool */ int *kib_fmr_flush_trigger; /* When to trigger FMR flush */ int *kib_fmr_cache; /* enable FMR pool cache? */ -#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM - ctl_table_header_t *kib_sysctl; /* sysctl interface */ -#endif int *kib_require_priv_port;/* accept only privileged ports */ int *kib_use_priv_port; /* use privileged port for active connect */ /* # threads on each CPT */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 92dc5672e2dd..cefdfb6b1bec 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -41,95 +41,95 @@ #include "o2iblnd.h" static int service = 987; -CFS_MODULE_PARM(service, "i", int, 0444, - "service number (within RDMA_PS_TCP)"); +module_param(service, int, 0444); +MODULE_PARM_DESC(service, "service number (within RDMA_PS_TCP)"); static int cksum = 0; -CFS_MODULE_PARM(cksum, "i", int, 0644, - "set non-zero to enable message (not RDMA) checksums"); +module_param(cksum, int, 0644); +MODULE_PARM_DESC(cksum, "set non-zero to enable message (not RDMA) checksums"); static int timeout = 50; -CFS_MODULE_PARM(timeout, "i", int, 0644, - "timeout (seconds)"); +module_param(timeout, int, 0644); +MODULE_PARM_DESC(timeout, "timeout (seconds)"); /* Number of threads in each scheduler pool which is percpt, * we will estimate reasonable value based on CPUs if it's set to zero. */ static int nscheds; -CFS_MODULE_PARM(nscheds, "i", int, 0444, - "number of threads in each scheduler pool"); +module_param(nscheds, int, 0444); +MODULE_PARM_DESC(nscheds, "number of threads in each scheduler pool"); /* NB: this value is shared by all CPTs, it can grow at runtime */ static int ntx = 512; -CFS_MODULE_PARM(ntx, "i", int, 0444, - "# of message descriptors allocated for each pool"); +module_param(ntx, int, 0444); +MODULE_PARM_DESC(ntx, "# of message descriptors allocated for each pool"); /* NB: this value is shared by all CPTs */ static int credits = 256; -CFS_MODULE_PARM(credits, "i", int, 0444, - "# concurrent sends"); +module_param(credits, int, 0444); +MODULE_PARM_DESC(credits, "# concurrent sends"); static int peer_credits = 8; -CFS_MODULE_PARM(peer_credits, "i", int, 0444, - "# concurrent sends to 1 peer"); +module_param(peer_credits, int, 0444); +MODULE_PARM_DESC(peer_credits, "# concurrent sends to 1 peer"); static int peer_credits_hiw = 0; -CFS_MODULE_PARM(peer_credits_hiw, "i", int, 0444, - "when eagerly to return credits"); +module_param(peer_credits_hiw, int, 0444); +MODULE_PARM_DESC(peer_credits_hiw, "when eagerly to return credits"); static int peer_buffer_credits = 0; -CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444, - "# per-peer router buffer credits"); +module_param(peer_buffer_credits, int, 0444); +MODULE_PARM_DESC(peer_buffer_credits, "# per-peer router buffer credits"); static int peer_timeout = 180; -CFS_MODULE_PARM(peer_timeout, "i", int, 0444, - "Seconds without aliveness news to declare peer dead (<=0 to disable)"); +module_param(peer_timeout, int, 0444); +MODULE_PARM_DESC(peer_timeout, "Seconds without aliveness news to declare peer dead (<=0 to disable)"); static char *ipif_name = "ib0"; -CFS_MODULE_PARM(ipif_name, "s", charp, 0444, - "IPoIB interface name"); +module_param(ipif_name, charp, 0444); +MODULE_PARM_DESC(ipif_name, "IPoIB interface name"); static int retry_count = 5; -CFS_MODULE_PARM(retry_count, "i", int, 0644, - "Retransmissions when no ACK received"); +module_param(retry_count, int, 0644); +MODULE_PARM_DESC(retry_count, "Retransmissions when no ACK received"); static int rnr_retry_count = 6; -CFS_MODULE_PARM(rnr_retry_count, "i", int, 0644, - "RNR retransmissions"); +module_param(rnr_retry_count, int, 0644); +MODULE_PARM_DESC(rnr_retry_count, "RNR retransmissions"); static int keepalive = 100; -CFS_MODULE_PARM(keepalive, "i", int, 0644, - "Idle time in seconds before sending a keepalive"); +module_param(keepalive, int, 0644); +MODULE_PARM_DESC(keepalive, "Idle time in seconds before sending a keepalive"); static int ib_mtu = 0; -CFS_MODULE_PARM(ib_mtu, "i", int, 0444, - "IB MTU 256/512/1024/2048/4096"); +module_param(ib_mtu, int, 0444); +MODULE_PARM_DESC(ib_mtu, "IB MTU 256/512/1024/2048/4096"); static int concurrent_sends = 0; -CFS_MODULE_PARM(concurrent_sends, "i", int, 0444, - "send work-queue sizing"); +module_param(concurrent_sends, int, 0444); +MODULE_PARM_DESC(concurrent_sends, "send work-queue sizing"); static int map_on_demand = 0; -CFS_MODULE_PARM(map_on_demand, "i", int, 0444, - "map on demand"); +module_param(map_on_demand, int, 0444); +MODULE_PARM_DESC(map_on_demand, "map on demand"); /* NB: this value is shared by all CPTs, it can grow at runtime */ static int fmr_pool_size = 512; -CFS_MODULE_PARM(fmr_pool_size, "i", int, 0444, - "size of fmr pool on each CPT (>= ntx / 4)"); +module_param(fmr_pool_size, int, 0444); +MODULE_PARM_DESC(fmr_pool_size, "size of fmr pool on each CPT (>= ntx / 4)"); /* NB: this value is shared by all CPTs, it can grow at runtime */ static int fmr_flush_trigger = 384; -CFS_MODULE_PARM(fmr_flush_trigger, "i", int, 0444, - "# dirty FMRs that triggers pool flush"); +module_param(fmr_flush_trigger, int, 0444); +MODULE_PARM_DESC(fmr_flush_trigger, "# dirty FMRs that triggers pool flush"); static int fmr_cache = 1; -CFS_MODULE_PARM(fmr_cache, "i", int, 0444, - "non-zero to enable FMR caching"); +module_param(fmr_cache, int, 0444); +MODULE_PARM_DESC(fmr_cache, "non-zero to enable FMR caching"); /* NB: this value is shared by all CPTs, it can grow at runtime */ static int pmr_pool_size = 512; -CFS_MODULE_PARM(pmr_pool_size, "i", int, 0444, - "size of MR cache pmr pool on each CPT"); +module_param(pmr_pool_size, int, 0444); +MODULE_PARM_DESC(pmr_pool_size, "size of MR cache pmr pool on each CPT"); /* * 0: disable failover @@ -137,17 +137,17 @@ CFS_MODULE_PARM(pmr_pool_size, "i", int, 0444, * 2: force to failover (for debug) */ static int dev_failover = 0; -CFS_MODULE_PARM(dev_failover, "i", int, 0444, - "HCA failover for bonding (0 off, 1 on, other values reserved)"); +module_param(dev_failover, int, 0444); +MODULE_PARM_DESC(dev_failover, "HCA failover for bonding (0 off, 1 on, other values reserved)"); static int require_privileged_port = 0; -CFS_MODULE_PARM(require_privileged_port, "i", int, 0644, - "require privileged port when accepting connection"); +module_param(require_privileged_port, int, 0644); +MODULE_PARM_DESC(require_privileged_port, "require privileged port when accepting connection"); static int use_privileged_port = 1; -CFS_MODULE_PARM(use_privileged_port, "i", int, 0644, - "use privileged port when initiating connection"); +module_param(use_privileged_port, int, 0644); +MODULE_PARM_DESC(use_privileged_port, "use privileged port when initiating connection"); kib_tunables_t kiblnd_tunables = { .kib_dev_failover = &dev_failover, @@ -176,261 +176,6 @@ kib_tunables_t kiblnd_tunables = { .kib_nscheds = &nscheds }; -#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM - -static char ipif_basename_space[32]; - - -enum { - O2IBLND_SERVICE = 1, - O2IBLND_CKSUM, - O2IBLND_TIMEOUT, - O2IBLND_NTX, - O2IBLND_CREDITS, - O2IBLND_PEER_TXCREDITS, - O2IBLND_PEER_CREDITS_HIW, - O2IBLND_PEER_RTRCREDITS, - O2IBLND_PEER_TIMEOUT, - O2IBLND_IPIF_BASENAME, - O2IBLND_RETRY_COUNT, - O2IBLND_RNR_RETRY_COUNT, - O2IBLND_KEEPALIVE, - O2IBLND_CONCURRENT_SENDS, - O2IBLND_IB_MTU, - O2IBLND_MAP_ON_DEMAND, - O2IBLND_FMR_POOL_SIZE, - O2IBLND_FMR_FLUSH_TRIGGER, - O2IBLND_FMR_CACHE, - O2IBLND_PMR_POOL_SIZE, - O2IBLND_DEV_FAILOVER -}; - -static ctl_table_t kiblnd_ctl_table[] = { - { - .ctl_name = O2IBLND_SERVICE, - .procname = "service", - .data = &service, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_CKSUM, - .procname = "cksum", - .data = &cksum, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_TIMEOUT, - .procname = "timeout", - .data = &timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_NTX, - .procname = "ntx", - .data = &ntx, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_CREDITS, - .procname = "credits", - .data = &credits, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_PEER_TXCREDITS, - .procname = "peer_credits", - .data = &peer_credits, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_PEER_CREDITS_HIW, - .procname = "peer_credits_hiw", - .data = &peer_credits_hiw, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_PEER_RTRCREDITS, - .procname = "peer_buffer_credits", - .data = &peer_buffer_credits, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_PEER_TIMEOUT, - .procname = "peer_timeout", - .data = &peer_timeout, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_IPIF_BASENAME, - .procname = "ipif_name", - .data = ipif_basename_space, - .maxlen = sizeof(ipif_basename_space), - .mode = 0444, - .proc_handler = &proc_dostring - }, - { - .ctl_name = O2IBLND_RETRY_COUNT, - .procname = "retry_count", - .data = &retry_count, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_RNR_RETRY_COUNT, - .procname = "rnr_retry_count", - .data = &rnr_retry_count, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_KEEPALIVE, - .procname = "keepalive", - .data = &keepalive, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_CONCURRENT_SENDS, - .procname = "concurrent_sends", - .data = &concurrent_sends, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_IB_MTU, - .procname = "ib_mtu", - .data = &ib_mtu, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_MAP_ON_DEMAND, - .procname = "map_on_demand", - .data = &map_on_demand, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - - { - .ctl_name = O2IBLND_FMR_POOL_SIZE, - .procname = "fmr_pool_size", - .data = &fmr_pool_size, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_FMR_FLUSH_TRIGGER, - .procname = "fmr_flush_trigger", - .data = &fmr_flush_trigger, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_FMR_CACHE, - .procname = "fmr_cache", - .data = &fmr_cache, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_PMR_POOL_SIZE, - .procname = "pmr_pool_size", - .data = &pmr_pool_size, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - { - .ctl_name = O2IBLND_DEV_FAILOVER, - .procname = "dev_failover", - .data = &dev_failover, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec - }, - {0} -}; - -static ctl_table_t kiblnd_top_ctl_table[] = { - { - .ctl_name = CTL_O2IBLND, - .procname = "o2iblnd", - .data = NULL, - .maxlen = 0, - .mode = 0555, - .child = kiblnd_ctl_table - }, - {0} -}; - -void -kiblnd_initstrtunable(char *space, char *str, int size) -{ - strncpy(space, str, size); - space[size-1] = 0; -} - -void -kiblnd_sysctl_init (void) -{ - kiblnd_initstrtunable(ipif_basename_space, ipif_name, - sizeof(ipif_basename_space)); - - kiblnd_tunables.kib_sysctl = - register_sysctl_table(kiblnd_top_ctl_table); - - if (kiblnd_tunables.kib_sysctl == NULL) - CWARN("Can't setup /proc tunables\n"); -} - -void -kiblnd_sysctl_fini (void) -{ - if (kiblnd_tunables.kib_sysctl != NULL) - unregister_sysctl_table(kiblnd_tunables.kib_sysctl); -} - -#else - -void -kiblnd_sysctl_init (void) -{ -} - -void -kiblnd_sysctl_fini (void) -{ -} - -#endif - int kiblnd_tunables_init (void) { @@ -482,12 +227,5 @@ kiblnd_tunables_init (void) *kiblnd_tunables.kib_concurrent_sends, *kiblnd_tunables.kib_peertxcredits); } - kiblnd_sysctl_init(); return 0; } - -void -kiblnd_tunables_fini (void) -{ - kiblnd_sysctl_fini(); -} diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 2ddc3aadb8d6..8f74d0be32f1 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2866,7 +2866,6 @@ void __exit ksocknal_module_fini (void) { lnet_unregister_lnd(&the_ksocklnd); - ksocknal_tunables_fini(); } int __init diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index b483e0c3a69a..df2be7a7f46e 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -124,9 +124,6 @@ typedef struct unsigned int *ksnd_zc_min_payload; /* minimum zero copy payload size */ int *ksnd_zc_recv; /* enable ZC receive (for Chelsio TOE) */ int *ksnd_zc_recv_min_nfrags; /* minimum # of fragments to enable ZC receive */ -#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM - ctl_table_header_t *ksnd_sysctl; /* sysctl interface */ -#endif } ksock_tunables_t; typedef struct @@ -592,9 +589,6 @@ extern int ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle); extern int ksocknal_tunables_init(void); -extern void ksocknal_tunables_fini(void); -extern int ksocknal_lib_tunables_init(void); -extern void ksocknal_lib_tunables_fini(void); extern void ksocknal_lib_csum_tx(ksock_tx_t *tx); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c index a1c6a519bf5b..80141aa32c21 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c @@ -36,313 +36,6 @@ #include "socklnd.h" -# if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM - - -enum { - SOCKLND_TIMEOUT = 1, - SOCKLND_CREDITS, - SOCKLND_PEER_TXCREDITS, - SOCKLND_PEER_RTRCREDITS, - SOCKLND_PEER_TIMEOUT, - SOCKLND_NCONNDS, - SOCKLND_RECONNECTS_MIN, - SOCKLND_RECONNECTS_MAX, - SOCKLND_EAGER_ACK, - SOCKLND_ZERO_COPY, - SOCKLND_TYPED, - SOCKLND_BULK_MIN, - SOCKLND_RX_BUFFER_SIZE, - SOCKLND_TX_BUFFER_SIZE, - SOCKLND_NAGLE, - SOCKLND_IRQ_AFFINITY, - SOCKLND_ROUND_ROBIN, - SOCKLND_KEEPALIVE, - SOCKLND_KEEPALIVE_IDLE, - SOCKLND_KEEPALIVE_COUNT, - SOCKLND_KEEPALIVE_INTVL, - SOCKLND_BACKOFF_INIT, - SOCKLND_BACKOFF_MAX, - SOCKLND_PROTOCOL, - SOCKLND_ZERO_COPY_RECV, - SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS -}; - -static ctl_table_t ksocknal_ctl_table[] = { - { - .ctl_name = SOCKLND_TIMEOUT, - .procname = "timeout", - .data = &ksocknal_tunables.ksnd_timeout, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_CREDITS, - .procname = "credits", - .data = &ksocknal_tunables.ksnd_credits, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_PEER_TXCREDITS, - .procname = "peer_credits", - .data = &ksocknal_tunables.ksnd_peertxcredits, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_PEER_RTRCREDITS, - .procname = "peer_buffer_credits", - .data = &ksocknal_tunables.ksnd_peerrtrcredits, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_PEER_TIMEOUT, - .procname = "peer_timeout", - .data = &ksocknal_tunables.ksnd_peertimeout, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_NCONNDS, - .procname = "nconnds", - .data = &ksocknal_tunables.ksnd_nconnds, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_RECONNECTS_MIN, - .procname = "min_reconnectms", - .data = &ksocknal_tunables.ksnd_min_reconnectms, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_RECONNECTS_MAX, - .procname = "max_reconnectms", - .data = &ksocknal_tunables.ksnd_max_reconnectms, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_EAGER_ACK, - .procname = "eager_ack", - .data = &ksocknal_tunables.ksnd_eager_ack, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_ZERO_COPY, - .procname = "zero_copy", - .data = &ksocknal_tunables.ksnd_zc_min_payload, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_ZERO_COPY_RECV, - .procname = "zero_copy_recv", - .data = &ksocknal_tunables.ksnd_zc_recv, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - - { - .ctl_name = SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS, - .procname = "zero_copy_recv", - .data = &ksocknal_tunables.ksnd_zc_recv_min_nfrags, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_TYPED, - .procname = "typed", - .data = &ksocknal_tunables.ksnd_typed_conns, - .maxlen = sizeof (int), - .mode = 0444, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_BULK_MIN, - .procname = "min_bulk", - .data = &ksocknal_tunables.ksnd_min_bulk, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_RX_BUFFER_SIZE, - .procname = "rx_buffer_size", - .data = &ksocknal_tunables.ksnd_rx_buffer_size, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_TX_BUFFER_SIZE, - .procname = "tx_buffer_size", - .data = &ksocknal_tunables.ksnd_tx_buffer_size, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_NAGLE, - .procname = "nagle", - .data = &ksocknal_tunables.ksnd_nagle, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_ROUND_ROBIN, - .procname = "round_robin", - .data = &ksocknal_tunables.ksnd_round_robin, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_KEEPALIVE, - .procname = "keepalive", - .data = &ksocknal_tunables.ksnd_keepalive, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_KEEPALIVE_IDLE, - .procname = "keepalive_idle", - .data = &ksocknal_tunables.ksnd_keepalive_idle, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_KEEPALIVE_COUNT, - .procname = "keepalive_count", - .data = &ksocknal_tunables.ksnd_keepalive_count, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, - { - .ctl_name = SOCKLND_KEEPALIVE_INTVL, - .procname = "keepalive_intvl", - .data = &ksocknal_tunables.ksnd_keepalive_intvl, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, -#if SOCKNAL_VERSION_DEBUG - { - .ctl_name = SOCKLND_PROTOCOL, - .procname = "protocol", - .data = &ksocknal_tunables.ksnd_protocol, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - .strategy = &sysctl_intvec, - }, -#endif - {0} -}; - - -ctl_table_t ksocknal_top_ctl_table[] = { - { - .ctl_name = CTL_SOCKLND, - .procname = "socknal", - .data = NULL, - .maxlen = 0, - .mode = 0555, - .child = ksocknal_ctl_table - }, - { 0 } -}; - -int -ksocknal_lib_tunables_init () -{ - if (!*ksocknal_tunables.ksnd_typed_conns) { - int rc = -EINVAL; -#if SOCKNAL_VERSION_DEBUG - if (*ksocknal_tunables.ksnd_protocol < 3) - rc = 0; -#endif - if (rc != 0) { - CERROR("Protocol V3.x MUST have typed connections\n"); - return rc; - } - } - - if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags < 2) - *ksocknal_tunables.ksnd_zc_recv_min_nfrags = 2; - if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags > LNET_MAX_IOV) - *ksocknal_tunables.ksnd_zc_recv_min_nfrags = LNET_MAX_IOV; - - ksocknal_tunables.ksnd_sysctl = - register_sysctl_table(ksocknal_top_ctl_table); - - if (ksocknal_tunables.ksnd_sysctl == NULL) - CWARN("Can't setup /proc tunables\n"); - - return 0; -} - -void -ksocknal_lib_tunables_fini(void) -{ - if (ksocknal_tunables.ksnd_sysctl != NULL) - unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl); -} -#else -int -ksocknal_lib_tunables_init(void) -{ - return 0; -} - -void -ksocknal_lib_tunables_fini(void) -{ -} -#endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */ - int ksocknal_lib_get_conn_addrs (ksock_conn_t *conn) { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c index 8a474f64abbe..54c0019904ff 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c @@ -22,123 +22,123 @@ #include "socklnd.h" static int sock_timeout = 50; -CFS_MODULE_PARM(sock_timeout, "i", int, 0644, - "dead socket timeout (seconds)"); +module_param(sock_timeout, int, 0644); +MODULE_PARM_DESC(sock_timeout, "dead socket timeout (seconds)"); static int credits = 256; -CFS_MODULE_PARM(credits, "i", int, 0444, - "# concurrent sends"); +module_param(credits, int, 0444); +MODULE_PARM_DESC(credits, "# concurrent sends"); static int peer_credits = 8; -CFS_MODULE_PARM(peer_credits, "i", int, 0444, - "# concurrent sends to 1 peer"); +module_param(peer_credits, int, 0444); +MODULE_PARM_DESC(peer_credits, "# concurrent sends to 1 peer"); static int peer_buffer_credits = 0; -CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444, - "# per-peer router buffer credits"); +module_param(peer_buffer_credits, int, 0444); +MODULE_PARM_DESC(peer_buffer_credits, "# per-peer router buffer credits"); static int peer_timeout = 180; -CFS_MODULE_PARM(peer_timeout, "i", int, 0444, - "Seconds without aliveness news to declare peer dead (<=0 to disable)"); +module_param(peer_timeout, int, 0444); +MODULE_PARM_DESC(peer_timeout, "Seconds without aliveness news to declare peer dead (<=0 to disable)"); /* Number of daemons in each thread pool which is percpt, * we will estimate reasonable value based on CPUs if it's not set. */ static unsigned int nscheds; -CFS_MODULE_PARM(nscheds, "i", int, 0444, - "# scheduler daemons in each pool while starting"); +module_param(nscheds, int, 0444); +MODULE_PARM_DESC(nscheds, "# scheduler daemons in each pool while starting"); static int nconnds = 4; -CFS_MODULE_PARM(nconnds, "i", int, 0444, - "# connection daemons while starting"); +module_param(nconnds, int, 0444); +MODULE_PARM_DESC(nconnds, "# connection daemons while starting"); static int nconnds_max = 64; -CFS_MODULE_PARM(nconnds_max, "i", int, 0444, - "max # connection daemons"); +module_param(nconnds_max, int, 0444); +MODULE_PARM_DESC(nconnds_max, "max # connection daemons"); static int min_reconnectms = 1000; -CFS_MODULE_PARM(min_reconnectms, "i", int, 0644, - "min connection retry interval (mS)"); +module_param(min_reconnectms, int, 0644); +MODULE_PARM_DESC(min_reconnectms, "min connection retry interval (mS)"); static int max_reconnectms = 60000; -CFS_MODULE_PARM(max_reconnectms, "i", int, 0644, - "max connection retry interval (mS)"); +module_param(max_reconnectms, int, 0644); +MODULE_PARM_DESC(max_reconnectms, "max connection retry interval (mS)"); # define DEFAULT_EAGER_ACK 0 static int eager_ack = DEFAULT_EAGER_ACK; -CFS_MODULE_PARM(eager_ack, "i", int, 0644, - "send tcp ack packets eagerly"); +module_param(eager_ack, int, 0644); +MODULE_PARM_DESC(eager_ack, "send tcp ack packets eagerly"); static int typed_conns = 1; -CFS_MODULE_PARM(typed_conns, "i", int, 0444, - "use different sockets for bulk"); +module_param(typed_conns, int, 0444); +MODULE_PARM_DESC(typed_conns, "use different sockets for bulk"); static int min_bulk = (1<<10); -CFS_MODULE_PARM(min_bulk, "i", int, 0644, - "smallest 'large' message"); +module_param(min_bulk, int, 0644); +MODULE_PARM_DESC(min_bulk, "smallest 'large' message"); # define DEFAULT_BUFFER_SIZE 0 static int tx_buffer_size = DEFAULT_BUFFER_SIZE; -CFS_MODULE_PARM(tx_buffer_size, "i", int, 0644, - "socket tx buffer size (0 for system default)"); +module_param(tx_buffer_size, int, 0644); +MODULE_PARM_DESC(tx_buffer_size, "socket tx buffer size (0 for system default)"); static int rx_buffer_size = DEFAULT_BUFFER_SIZE; -CFS_MODULE_PARM(rx_buffer_size, "i", int, 0644, - "socket rx buffer size (0 for system default)"); +module_param(rx_buffer_size, int, 0644); +MODULE_PARM_DESC(rx_buffer_size, "socket rx buffer size (0 for system default)"); static int nagle = 0; -CFS_MODULE_PARM(nagle, "i", int, 0644, - "enable NAGLE?"); +module_param(nagle, int, 0644); +MODULE_PARM_DESC(nagle, "enable NAGLE?"); static int round_robin = 1; -CFS_MODULE_PARM(round_robin, "i", int, 0644, - "Round robin for multiple interfaces"); +module_param(round_robin, int, 0644); +MODULE_PARM_DESC(round_robin, "Round robin for multiple interfaces"); static int keepalive = 30; -CFS_MODULE_PARM(keepalive, "i", int, 0644, - "# seconds before send keepalive"); +module_param(keepalive, int, 0644); +MODULE_PARM_DESC(keepalive, "# seconds before send keepalive"); static int keepalive_idle = 30; -CFS_MODULE_PARM(keepalive_idle, "i", int, 0644, - "# idle seconds before probe"); +module_param(keepalive_idle, int, 0644); +MODULE_PARM_DESC(keepalive_idle, "# idle seconds before probe"); #define DEFAULT_KEEPALIVE_COUNT 5 static int keepalive_count = DEFAULT_KEEPALIVE_COUNT; -CFS_MODULE_PARM(keepalive_count, "i", int, 0644, - "# missed probes == dead"); +module_param(keepalive_count, int, 0644); +MODULE_PARM_DESC(keepalive_count, "# missed probes == dead"); static int keepalive_intvl = 5; -CFS_MODULE_PARM(keepalive_intvl, "i", int, 0644, - "seconds between probes"); +module_param(keepalive_intvl, int, 0644); +MODULE_PARM_DESC(keepalive_intvl, "seconds between probes"); static int enable_csum = 0; -CFS_MODULE_PARM(enable_csum, "i", int, 0644, - "enable check sum"); +module_param(enable_csum, int, 0644); +MODULE_PARM_DESC(enable_csum, "enable check sum"); static int inject_csum_error = 0; -CFS_MODULE_PARM(inject_csum_error, "i", int, 0644, - "set non-zero to inject a checksum error"); +module_param(inject_csum_error, int, 0644); +MODULE_PARM_DESC(inject_csum_error, "set non-zero to inject a checksum error"); static int nonblk_zcack = 1; -CFS_MODULE_PARM(nonblk_zcack, "i", int, 0644, - "always send ZC-ACK on non-blocking connection"); +module_param(nonblk_zcack, int, 0644); +MODULE_PARM_DESC(nonblk_zcack, "always send ZC-ACK on non-blocking connection"); static unsigned int zc_min_payload = (16 << 10); -CFS_MODULE_PARM(zc_min_payload, "i", int, 0644, - "minimum payload size to zero copy"); +module_param(zc_min_payload, int, 0644); +MODULE_PARM_DESC(zc_min_payload, "minimum payload size to zero copy"); static unsigned int zc_recv = 0; -CFS_MODULE_PARM(zc_recv, "i", int, 0644, - "enable ZC recv for Chelsio driver"); +module_param(zc_recv, int, 0644); +MODULE_PARM_DESC(zc_recv, "enable ZC recv for Chelsio driver"); static unsigned int zc_recv_min_nfrags = 16; -CFS_MODULE_PARM(zc_recv_min_nfrags, "i", int, 0644, - "minimum # of fragments to enable ZC recv"); +module_param(zc_recv_min_nfrags, int, 0644); +MODULE_PARM_DESC(zc_recv_min_nfrags, "minimum # of fragments to enable ZC recv"); #if SOCKNAL_VERSION_DEBUG static int protocol = 3; -CFS_MODULE_PARM(protocol, "i", int, 0644, - "protocol version"); +module_param(protocol, int, 0644); +MODULE_PARM_DESC(protocol, "protocol version"); #endif ksock_tunables_t ksocknal_tunables; @@ -181,18 +181,8 @@ int ksocknal_tunables_init(void) ksocknal_tunables.ksnd_protocol = &protocol; #endif -#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM - ksocknal_tunables.ksnd_sysctl = NULL; -#endif - if (*ksocknal_tunables.ksnd_zc_min_payload < (2 << 10)) *ksocknal_tunables.ksnd_zc_min_payload = (2 << 10); - /* initialize platform-sepcific tunables */ - return ksocknal_lib_tunables_init(); + return 0; }; - -void ksocknal_tunables_fini(void) -{ - ksocknal_lib_tunables_fini(); -} diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 92c60a756644..cb2ecd717714 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -64,14 +64,14 @@ lnet_accept_magic(__u32 magic, __u32 constant) static char *accept = "secure"; -CFS_MODULE_PARM(accept, "s", charp, 0444, - "Accept connections (secure|all|none)"); -CFS_MODULE_PARM(accept_port, "i", int, 0444, - "Acceptor's port (same on all nodes)"); -CFS_MODULE_PARM(accept_backlog, "i", int, 0444, - "Acceptor's listen backlog"); -CFS_MODULE_PARM(accept_timeout, "i", int, 0644, - "Acceptor's timeout (seconds)"); +module_param(accept, charp, 0444); +MODULE_PARM_DESC(accept, "Accept connections (secure|all|none)"); +module_param(accept_port, int, 0444); +MODULE_PARM_DESC(accept_port, "Acceptor's port (same on all nodes)"); +module_param(accept_backlog, int, 0444); +MODULE_PARM_DESC(accept_backlog, "Acceptor's listen backlog"); +module_param(accept_timeout, int, 0644); +MODULE_PARM_DESC(accept_timeout, "Acceptor's timeout (seconds)"); static char *accept_type; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 160a4292c6ce..c562ff3e9283 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -45,20 +45,20 @@ EXPORT_SYMBOL(the_lnet); static char *ip2nets = ""; -CFS_MODULE_PARM(ip2nets, "s", charp, 0444, - "LNET network <- IP table"); +module_param(ip2nets, charp, 0444); +MODULE_PARM_DESC(ip2nets, "LNET network <- IP table"); static char *networks = ""; -CFS_MODULE_PARM(networks, "s", charp, 0444, - "local networks"); +module_param(networks, charp, 0444); +MODULE_PARM_DESC(networks, "local networks"); static char *routes = ""; -CFS_MODULE_PARM(routes, "s", charp, 0444, - "routes to non-local networks"); +module_param(routes, charp, 0444); +MODULE_PARM_DESC(routes, "routes to non-local networks"); static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT; -CFS_MODULE_PARM(rnet_htable_size, "i", int, 0444, - "size of remote network hash table"); +module_param(rnet_htable_size, int, 0444); +MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table"); char * lnet_get_routes(void) @@ -1436,7 +1436,7 @@ LNetCtl(unsigned int cmd, void *arg) case IOC_LIBCFS_ADD_ROUTE: rc = lnet_add_route(data->ioc_net, data->ioc_count, - data->ioc_nid); + data->ioc_nid, data->ioc_priority); return (rc != 0) ? rc : lnet_check_routes(); case IOC_LIBCFS_DEL_ROUTE: @@ -1445,7 +1445,8 @@ LNetCtl(unsigned int cmd, void *arg) case IOC_LIBCFS_GET_ROUTE: return lnet_get_route(data->ioc_count, &data->ioc_net, &data->ioc_count, - &data->ioc_nid, &data->ioc_flags); + &data->ioc_nid, &data->ioc_flags, + &data->ioc_priority); case IOC_LIBCFS_NOTIFY_ROUTER: return lnet_notify(NULL, data->ioc_nid, data->ioc_flags, cfs_time_current() - diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index de323f779db8..6a07b0a65d12 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -603,6 +603,37 @@ lnet_parse_hops(char *str, unsigned int *hops) *hops > 0 && *hops < 256); } +#define LNET_PRIORITY_SEPARATOR (':') + +int +lnet_parse_priority(char *str, unsigned int *priority, char **token) +{ + int nob; + char *sep; + int len; + + sep = strchr(str, LNET_PRIORITY_SEPARATOR); + if (sep == NULL) { + *priority = 0; + return 0; + } + len = strlen(sep + 1); + + if ((sscanf((sep+1), "%u%n", priority, &nob) < 1) || (len != nob)) { + /* Update the caller's token pointer so it treats the found + priority as the token to report in the error message. */ + *token += sep - str + 1; + return -1; + } + + CDEBUG(D_NET, "gateway %s, priority %d, nob %d\n", str, *priority, nob); + + /* + * Change priority separator to \0 to be able to parse NID + */ + *sep = '\0'; + return 0; +} int lnet_parse_route(char *str, int *im_a_router) @@ -624,6 +655,7 @@ lnet_parse_route(char *str, int *im_a_router) int myrc = -1; unsigned int hops; int got_hops = 0; + unsigned int priority = 0; INIT_LIST_HEAD(&gateways); INIT_LIST_HEAD(&nets); @@ -691,6 +723,11 @@ lnet_parse_route(char *str, int *im_a_router) LNET_NETTYP(net) == LOLND) goto token_error; } else { + rc = lnet_parse_priority(ltb->ltb_text, + &priority, &token); + if (rc < 0) + goto token_error; + nid = libcfs_str2nid(ltb->ltb_text); if (nid == LNET_NID_ANY || LNET_NETTYP(LNET_NIDNET(nid)) == LOLND) @@ -720,7 +757,7 @@ lnet_parse_route(char *str, int *im_a_router) continue; } - rc = lnet_add_route(net, hops, nid); + rc = lnet_add_route(net, hops, nid, priority); if (rc != 0) { CERROR("Can't create route to %s via %s\n", libcfs_net2str(net), diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b6f8ad38628b..bbf43ae04ed0 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -43,8 +43,8 @@ #include <linux/lnet/lib-lnet.h> static int local_nid_dist_zero = 1; -CFS_MODULE_PARM(local_nid_dist_zero, "i", int, 0444, - "Reserved"); +module_param(local_nid_dist_zero, int, 0444); +MODULE_PARM_DESC(local_nid_dist_zero, "Reserved"); int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold) @@ -1074,6 +1074,12 @@ lnet_compare_routes(lnet_route_t *r1, lnet_route_t *r2) lnet_peer_t *p1 = r1->lr_gateway; lnet_peer_t *p2 = r2->lr_gateway; + if (r1->lr_priority < r2->lr_priority) + return 1; + + if (r1->lr_priority > r2->lr_priority) + return -1; + if (r1->lr_hops < r2->lr_hops) return 1; diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index 61ae88be6f02..761f1e12f847 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -43,7 +43,7 @@ #include <linux/lnet/lib-lnet.h> void -lnet_build_unlink_event (lnet_libmd_t *md, lnet_event_t *ev) +lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev) { memset(ev, 0, sizeof(*ev)); @@ -362,7 +362,7 @@ lnet_complete_msg_locked(lnet_msg_t *msg, int cpt) int rc; int status = msg->msg_ev.status; - LASSERT (msg->msg_onactivelist); + LASSERT(msg->msg_onactivelist); if (status == 0 && msg->msg_ack) { /* Only send an ACK if the PUT completed successfully */ @@ -432,7 +432,7 @@ lnet_complete_msg_locked(lnet_msg_t *msg, int cpt) } void -lnet_finalize (lnet_ni_t *ni, lnet_msg_t *msg, int status) +lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int status) { struct lnet_msg_container *container; int my_slot; @@ -440,7 +440,7 @@ lnet_finalize (lnet_ni_t *ni, lnet_msg_t *msg, int status) int rc; int i; - LASSERT (!in_interrupt ()); + LASSERT(!in_interrupt()); if (msg == NULL) return; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 9b9e7d3139b0..6fffd5e96f9c 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -40,8 +40,8 @@ /* NB: add /proc interfaces in upcoming patches */ int portal_rotor = LNET_PTL_ROTOR_HASH_RT; -CFS_MODULE_PARM(portal_rotor, "i", int, 0644, - "redirect PUTs to different cpu-partitions"); +module_param(portal_rotor, int, 0644); +MODULE_PARM_DESC(portal_rotor, "redirect PUTs to different cpu-partitions"); static int lnet_ptl_match_type(unsigned int index, lnet_process_id_t match_id, diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index 6db8774ff7b7..3bd42a485a32 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -38,8 +38,8 @@ #include <linux/lnet/lib-lnet.h> static int config_on_load; -CFS_MODULE_PARM(config_on_load, "i", int, 0444, - "configure network at module load"); +module_param(config_on_load, int, 0444); +MODULE_PARM_DESC(config_on_load, "configure network at module load"); static struct mutex lnet_config_mutex; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index a326ce06bc76..d1ee44232eef 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -34,25 +34,25 @@ #define LNET_NRB_LARGE (LNET_NRB_LARGE_MIN * 4) static char *forwarding = ""; -CFS_MODULE_PARM(forwarding, "s", charp, 0444, - "Explicitly enable/disable forwarding between networks"); +module_param(forwarding, charp, 0444); +MODULE_PARM_DESC(forwarding, "Explicitly enable/disable forwarding between networks"); static int tiny_router_buffers; -CFS_MODULE_PARM(tiny_router_buffers, "i", int, 0444, - "# of 0 payload messages to buffer in the router"); +module_param(tiny_router_buffers, int, 0444); +MODULE_PARM_DESC(tiny_router_buffers, "# of 0 payload messages to buffer in the router"); static int small_router_buffers; -CFS_MODULE_PARM(small_router_buffers, "i", int, 0444, - "# of small (1 page) messages to buffer in the router"); +module_param(small_router_buffers, int, 0444); +MODULE_PARM_DESC(small_router_buffers, "# of small (1 page) messages to buffer in the router"); static int large_router_buffers; -CFS_MODULE_PARM(large_router_buffers, "i", int, 0444, - "# of large messages to buffer in the router"); +module_param(large_router_buffers, int, 0444); +MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router"); static int peer_buffer_credits = 0; -CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444, - "# router buffer credits per peer"); +module_param(peer_buffer_credits, int, 0444); +MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer"); static int auto_down = 1; -CFS_MODULE_PARM(auto_down, "i", int, 0444, - "Automatically mark peers down on comms error"); +module_param(auto_down, int, 0444); +MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); int lnet_peer_buffer_credits(lnet_ni_t *ni) @@ -81,24 +81,24 @@ lnet_peer_buffer_credits(lnet_ni_t *ni) #endif static int check_routers_before_use = 0; -CFS_MODULE_PARM(check_routers_before_use, "i", int, 0444, - "Assume routers are down and ping them before use"); +module_param(check_routers_before_use, int, 0444); +MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use"); static int avoid_asym_router_failure = 1; -CFS_MODULE_PARM(avoid_asym_router_failure, "i", int, 0644, - "Avoid asymmetrical router failures (0 to disable)"); +module_param(avoid_asym_router_failure, int, 0644); +MODULE_PARM_DESC(avoid_asym_router_failure, "Avoid asymmetrical router failures (0 to disable)"); static int dead_router_check_interval = 60; -CFS_MODULE_PARM(dead_router_check_interval, "i", int, 0644, - "Seconds between dead router health checks (<= 0 to disable)"); +module_param(dead_router_check_interval, int, 0644); +MODULE_PARM_DESC(dead_router_check_interval, "Seconds between dead router health checks (<= 0 to disable)"); static int live_router_check_interval = 60; -CFS_MODULE_PARM(live_router_check_interval, "i", int, 0644, - "Seconds between live router health checks (<= 0 to disable)"); +module_param(live_router_check_interval, int, 0644); +MODULE_PARM_DESC(live_router_check_interval, "Seconds between live router health checks (<= 0 to disable)"); static int router_ping_timeout = 50; -CFS_MODULE_PARM(router_ping_timeout, "i", int, 0644, - "Seconds to wait for the reply to a router health query"); +module_param(router_ping_timeout, int, 0644); +MODULE_PARM_DESC(router_ping_timeout, "Seconds to wait for the reply to a router health query"); int lnet_peers_start_down(void) @@ -301,7 +301,8 @@ lnet_add_route_to_rnet (lnet_remotenet_t *rnet, lnet_route_t *route) } int -lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway) +lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway, + unsigned int priority) { struct list_head *e; lnet_remotenet_t *rnet; @@ -311,8 +312,8 @@ lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway) int add_route; int rc; - CDEBUG(D_NET, "Add route: net %s hops %u gw %s\n", - libcfs_net2str(net), hops, libcfs_nid2str(gateway)); + CDEBUG(D_NET, "Add route: net %s hops %u priority %u gw %s\n", + libcfs_net2str(net), hops, priority, libcfs_nid2str(gateway)); if (gateway == LNET_NID_ANY || LNET_NETTYP(LNET_NIDNET(gateway)) == LOLND || @@ -342,6 +343,7 @@ lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway) rnet->lrn_net = net; route->lr_hops = hops; route->lr_net = net; + route->lr_priority = priority; lnet_net_lock(LNET_LOCK_EX); @@ -552,7 +554,7 @@ lnet_destroy_routes (void) int lnet_get_route(int idx, __u32 *net, __u32 *hops, - lnet_nid_t *gateway, __u32 *alive) + lnet_nid_t *gateway, __u32 *alive, __u32 *priority) { struct list_head *e1; struct list_head *e2; @@ -574,10 +576,11 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, lr_list); if (idx-- == 0) { - *net = rnet->lrn_net; - *hops = route->lr_hops; - *gateway = route->lr_gateway->lp_nid; - *alive = route->lr_gateway->lp_alive; + *net = rnet->lrn_net; + *hops = route->lr_hops; + *priority = route->lr_priority; + *gateway = route->lr_gateway->lp_nid; + *alive = route->lr_gateway->lp_alive; lnet_net_unlock(cpt); return 0; } diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 5e47de36c184..20d53e08705e 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -174,8 +174,8 @@ int LL_PROC_PROTO(proc_lnet_routes) the_lnet.ln_routing ? "enabled" : "disabled"); LASSERT(tmpstr + tmpsiz - s > 0); - s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %7s %s\n", - "net", "hops", "state", "router"); + s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %8s %7s %s\n", + "net", "hops", "priority", "state", "router"); LASSERT(tmpstr + tmpsiz - s > 0); lnet_net_lock(0); @@ -229,14 +229,16 @@ int LL_PROC_PROTO(proc_lnet_routes) } if (route != NULL) { - __u32 net = rnet->lrn_net; - unsigned int hops = route->lr_hops; - lnet_nid_t nid = route->lr_gateway->lp_nid; - int alive = route->lr_gateway->lp_alive; + __u32 net = rnet->lrn_net; + unsigned int hops = route->lr_hops; + unsigned int priority = route->lr_priority; + lnet_nid_t nid = route->lr_gateway->lp_nid; + int alive = route->lr_gateway->lp_alive; s += snprintf(s, tmpstr + tmpsiz - s, - "%-8s %4u %7s %s\n", + "%-8s %4u %8u %7s %s\n", libcfs_net2str(net), hops, + priority, alive ? "up" : "down", libcfs_nid2str(nid)); LASSERT(tmpstr + tmpsiz - s > 0); @@ -855,55 +857,46 @@ static ctl_table_t lnet_table[] = { * to go via /proc for portability. */ { - INIT_CTL_NAME(PSDEV_LNET_STATS) .procname = "stats", .mode = 0644, .proc_handler = &proc_lnet_stats, }, { - INIT_CTL_NAME(PSDEV_LNET_ROUTES) .procname = "routes", .mode = 0444, .proc_handler = &proc_lnet_routes, }, { - INIT_CTL_NAME(PSDEV_LNET_ROUTERS) .procname = "routers", .mode = 0444, .proc_handler = &proc_lnet_routers, }, { - INIT_CTL_NAME(PSDEV_LNET_PEERS) .procname = "peers", .mode = 0444, .proc_handler = &proc_lnet_peers, }, { - INIT_CTL_NAME(PSDEV_LNET_PEERS) .procname = "buffers", .mode = 0444, .proc_handler = &proc_lnet_buffers, }, { - INIT_CTL_NAME(PSDEV_LNET_NIS) .procname = "nis", .mode = 0444, .proc_handler = &proc_lnet_nis, }, { - INIT_CTL_NAME(PSDEV_LNET_PTL_ROTOR) .procname = "portal_rotor", .mode = 0644, .proc_handler = &proc_lnet_portal_rotor, }, { - INIT_CTL_NAME(0) } }; static ctl_table_t top_table[] = { { - INIT_CTL_NAME(CTL_LNET) .procname = "lnet", .mode = 0555, .data = NULL, @@ -911,28 +904,23 @@ static ctl_table_t top_table[] = { .child = lnet_table, }, { - INIT_CTL_NAME(0) } }; void lnet_proc_init(void) { -#ifdef CONFIG_SYSCTL if (lnet_table_header == NULL) lnet_table_header = register_sysctl_table(top_table); -#endif } void lnet_proc_fini(void) { -#ifdef CONFIG_SYSCTL if (lnet_table_header != NULL) unregister_sysctl_table(lnet_table_header); lnet_table_header = NULL; -#endif } #else diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index b7613c828e76..3f8020cb93e6 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -41,11 +41,12 @@ #include "selftest.h" static int brw_srv_workitems = SFW_TEST_WI_MAX; -CFS_MODULE_PARM(brw_srv_workitems, "i", int, 0644, "# BRW server workitems"); +module_param(brw_srv_workitems, int, 0644); +MODULE_PARM_DESC(brw_srv_workitems, "# BRW server workitems"); static int brw_inject_errors; -CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644, - "# data errors to inject randomly, zero by default"); +module_param(brw_inject_errors, int, 0644); +MODULE_PARM_DESC(brw_inject_errors, "# data errors to inject randomly, zero by default"); static void brw_client_fini(sfw_test_instance_t *tsi) diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index bce3d3bde6b2..cbc416de7008 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -723,12 +723,12 @@ lst_stat_query_ioctl(lstio_stat_args_t *args) int lst_test_add_ioctl(lstio_test_args_t *args) { - char *name; - char *srcgrp = NULL; - char *dstgrp = NULL; - void *param = NULL; - int ret = 0; - int rc = -ENOMEM; + char *batch_name; + char *src_name = NULL; + char *dst_name = NULL; + void *param = NULL; + int ret = 0; + int rc = -ENOMEM; if (args->lstio_tes_resultp == NULL || args->lstio_tes_retp == NULL || @@ -755,16 +755,16 @@ int lst_test_add_ioctl(lstio_test_args_t *args) args->lstio_tes_param_len > PAGE_CACHE_SIZE - sizeof(lstcon_test_t))) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_tes_bat_nmlen + 1); - if (name == NULL) + LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1); + if (batch_name == NULL) return rc; - LIBCFS_ALLOC(srcgrp, args->lstio_tes_sgrp_nmlen + 1); - if (srcgrp == NULL) + LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1); + if (src_name == NULL) goto out; - LIBCFS_ALLOC(dstgrp, args->lstio_tes_dgrp_nmlen + 1); - if (dstgrp == NULL) + LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1); + if (dst_name == NULL) goto out; if (args->lstio_tes_param != NULL) { @@ -774,39 +774,37 @@ int lst_test_add_ioctl(lstio_test_args_t *args) } rc = -EFAULT; - if (copy_from_user(name, - args->lstio_tes_bat_name, - args->lstio_tes_bat_nmlen) || - copy_from_user(srcgrp, - args->lstio_tes_sgrp_name, - args->lstio_tes_sgrp_nmlen) || - copy_from_user(dstgrp, - args->lstio_tes_dgrp_name, - args->lstio_tes_dgrp_nmlen) || + if (copy_from_user(batch_name, args->lstio_tes_bat_name, + args->lstio_tes_bat_nmlen) || + copy_from_user(src_name, args->lstio_tes_sgrp_name, + args->lstio_tes_sgrp_nmlen) || + copy_from_user(dst_name, args->lstio_tes_dgrp_name, + args->lstio_tes_dgrp_nmlen) || copy_from_user(param, args->lstio_tes_param, args->lstio_tes_param_len)) goto out; - rc = lstcon_test_add(name, + rc = lstcon_test_add(batch_name, args->lstio_tes_type, args->lstio_tes_loop, args->lstio_tes_concur, args->lstio_tes_dist, args->lstio_tes_span, - srcgrp, dstgrp, param, args->lstio_tes_param_len, + src_name, dst_name, param, + args->lstio_tes_param_len, &ret, args->lstio_tes_resultp); if (ret != 0) rc = (copy_to_user(args->lstio_tes_retp, &ret, sizeof(ret))) ? -EFAULT : 0; out: - if (name != NULL) - LIBCFS_FREE(name, args->lstio_tes_bat_nmlen + 1); + if (batch_name != NULL) + LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1); - if (srcgrp != NULL) - LIBCFS_FREE(srcgrp, args->lstio_tes_sgrp_nmlen + 1); + if (src_name != NULL) + LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1); - if (dstgrp != NULL) - LIBCFS_FREE(dstgrp, args->lstio_tes_dgrp_nmlen + 1); + if (dst_name != NULL) + LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1); if (param != NULL) LIBCFS_FREE(param, args->lstio_tes_param_len); diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 9a52f25b72e9..53d58924737b 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -311,7 +311,7 @@ lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error) sfw_abort_rpc(rpc); - if (error != ETIMEDOUT) + if (error != ETIMEDOUT) continue; nd = crpc->crp_node; diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index f1152e4fbcc4..9556bc0412d6 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -265,7 +265,7 @@ lstcon_group_decref(lstcon_group_t *grp) } static int -lstcon_group_find(char *name, lstcon_group_t **grpp) +lstcon_group_find(const char *name, lstcon_group_t **grpp) { lstcon_group_t *grp; @@ -831,7 +831,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p, } int -lstcon_batch_find(char *name, lstcon_batch_t **batpp) +lstcon_batch_find(const char *name, lstcon_batch_t **batpp) { lstcon_batch_t *bat; @@ -1237,41 +1237,77 @@ again: goto again; } -int -lstcon_test_add(char *name, int type, int loop, int concur, - int dist, int span, char *src_name, char * dst_name, - void *param, int paramlen, int *retp, - struct list_head *result_up) +static int +lstcon_verify_batch(const char *name, lstcon_batch_t **batch) { - lstcon_group_t *src_grp = NULL; - lstcon_group_t *dst_grp = NULL; - lstcon_test_t *test = NULL; - lstcon_batch_t *batch; - int rc; + int rc; - rc = lstcon_batch_find(name, &batch); + rc = lstcon_batch_find(name, batch); if (rc != 0) { CDEBUG(D_NET, "Can't find batch %s\n", name); return rc; } - if (batch->bat_state != LST_BATCH_IDLE) { + if ((*batch)->bat_state != LST_BATCH_IDLE) { CDEBUG(D_NET, "Can't change running batch %s\n", name); - return rc; + return -EINVAL; } - rc = lstcon_group_find(src_name, &src_grp); + return 0; +} + +static int +lstcon_verify_group(const char *name, lstcon_group_t **grp) +{ + int rc; + lstcon_ndlink_t *ndl; + + rc = lstcon_group_find(name, grp); if (rc != 0) { - CDEBUG(D_NET, "Can't find group %s\n", src_name); - goto out; + CDEBUG(D_NET, "can't find group %s\n", name); + return rc; } - rc = lstcon_group_find(dst_name, &dst_grp); - if (rc != 0) { - CDEBUG(D_NET, "Can't find group %s\n", dst_name); - goto out; + list_for_each_entry(ndl, &(*grp)->grp_ndl_list, ndl_link) { + if (ndl->ndl_node->nd_state == LST_NODE_ACTIVE) + return 0; } + CDEBUG(D_NET, "Group %s has no ACTIVE nodes\n", name); + + return -EINVAL; +} + +int +lstcon_test_add(char *batch_name, int type, int loop, + int concur, int dist, int span, + char *src_name, char *dst_name, + void *param, int paramlen, int *retp, + struct list_head *result_up) +{ + lstcon_test_t *test = NULL; + int rc; + lstcon_group_t *src_grp = NULL; + lstcon_group_t *dst_grp = NULL; + lstcon_batch_t *batch = NULL; + + /* + * verify that a batch of the given name exists, and the groups + * that will be part of the batch exist and have at least one + * active node + */ + rc = lstcon_verify_batch(batch_name, &batch); + if (rc != 0) + goto out; + + rc = lstcon_verify_group(src_name, &src_grp); + if (rc != 0) + goto out; + + rc = lstcon_verify_group(dst_name, &dst_grp); + if (rc != 0) + goto out; + if (dst_grp->grp_userland) *retp = 1; @@ -1284,18 +1320,18 @@ lstcon_test_add(char *name, int type, int loop, int concur, } memset(test, 0, offsetof(lstcon_test_t, tes_param[paramlen])); - test->tes_hdr.tsb_id = batch->bat_hdr.tsb_id; - test->tes_batch = batch; - test->tes_type = type; - test->tes_oneside = 0; /* TODO */ - test->tes_loop = loop; + test->tes_hdr.tsb_id = batch->bat_hdr.tsb_id; + test->tes_batch = batch; + test->tes_type = type; + test->tes_oneside = 0; /* TODO */ + test->tes_loop = loop; test->tes_concur = concur; - test->tes_stop_onerr = 1; /* TODO */ - test->tes_span = span; - test->tes_dist = dist; + test->tes_stop_onerr = 1; /* TODO */ + test->tes_span = span; + test->tes_dist = dist; test->tes_cliidx = 0; /* just used for creating RPC */ - test->tes_src_grp = src_grp; - test->tes_dst_grp = dst_grp; + test->tes_src_grp = src_grp; + test->tes_dst_grp = dst_grp; INIT_LIST_HEAD(&test->tes_trans_list); if (param != NULL) { @@ -1310,7 +1346,8 @@ lstcon_test_add(char *name, int type, int loop, int concur, if (lstcon_trans_stat()->trs_rpc_errno != 0 || lstcon_trans_stat()->trs_fwk_errno != 0) - CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type, name); + CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type, + batch_name); /* add to test list anyway, so user can check what's going on */ list_add_tail(&test->tes_link, &batch->bat_test_list); diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h index e61b26687dbb..b57dbd80478a 100644 --- a/drivers/staging/lustre/lnet/selftest/console.h +++ b/drivers/staging/lustre/lnet/selftest/console.h @@ -224,9 +224,9 @@ extern int lstcon_group_stat(char *grp_name, int timeout, struct list_head *result_up); extern int lstcon_nodes_stat(int count, lnet_process_id_t *ids_up, int timeout, struct list_head *result_up); -extern int lstcon_test_add(char *name, int type, int loop, int concur, - int dist, int span, char *src_name, char * dst_name, +extern int lstcon_test_add(char *batch_name, int type, int loop, + int concur, int dist, int span, + char *src_name, char *dst_name, void *param, int paramlen, int *retp, struct list_head *result_up); - #endif diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 483c78564dae..050723a0243a 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -46,12 +46,12 @@ lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1}; static int session_timeout = 100; -CFS_MODULE_PARM(session_timeout, "i", int, 0444, - "test session timeout in seconds (100 by default, 0 == never)"); +module_param(session_timeout, int, 0444); +MODULE_PARM_DESC(session_timeout, "test session timeout in seconds (100 by default, 0 == never)"); static int rpc_timeout = 64; -CFS_MODULE_PARM(rpc_timeout, "i", int, 0644, - "rpc timeout in seconds (64 by default, 0 == never)"); +module_param(rpc_timeout, int, 0644); +MODULE_PARM_DESC(rpc_timeout, "rpc timeout in seconds (64 by default, 0 == never)"); #define sfw_unpack_id(id) \ do { \ diff --git a/drivers/staging/lustre/lnet/selftest/ping_test.c b/drivers/staging/lustre/lnet/selftest/ping_test.c index f0f919482b56..a37c3ff03277 100644 --- a/drivers/staging/lustre/lnet/selftest/ping_test.c +++ b/drivers/staging/lustre/lnet/selftest/ping_test.c @@ -45,7 +45,8 @@ #define LST_PING_TEST_MAGIC 0xbabeface int ping_srv_workitems = SFW_TEST_WI_MAX; -CFS_MODULE_PARM(ping_srv_workitems, "i", int, 0644, "# PING server workitems"); +module_param(ping_srv_workitems, int, 0644); +MODULE_PARM_DESC(ping_srv_workitems, "# PING server workitems"); typedef struct { spinlock_t pnd_lock; /* serialize */ diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 7659a26676bb..5ae59d2a0dad 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -124,7 +124,6 @@ srpc_bulk_t * srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink) { srpc_bulk_t *bk; - struct page **pages; int i; LASSERT(bulk_npg > 0 && bulk_npg <= LNET_MAX_IOV); @@ -140,7 +139,6 @@ srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink) bk->bk_sink = sink; bk->bk_len = bulk_len; bk->bk_niov = bulk_npg; - UNUSED(pages); for (i = 0; i < bulk_npg; i++) { struct page *pg; diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 8053b0563ff3..cd539263201a 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -572,9 +572,6 @@ swi_state2str (int state) #undef STATE2STR } -#define UNUSED(x) ( (void)(x) ) - - #define selftest_wait_events() cfs_pause(cfs_time_seconds(1) / 10) diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c index 82fd363679cb..b8e50ef0bb4e 100644 --- a/drivers/staging/lustre/lnet/selftest/timer.c +++ b/drivers/staging/lustre/lnet/selftest/timer.c @@ -171,19 +171,14 @@ stt_check_timers(cfs_time_t *last) int stt_timer_main(void *arg) { - int rc = 0; - UNUSED(arg); - - SET_BUT_UNUSED(rc); - cfs_block_allsigs(); while (!stt_data.stt_shuttingdown) { stt_check_timers(&stt_data.stt_prev_slot); - rc = wait_event_timeout(stt_data.stt_waitq, - stt_data.stt_shuttingdown, - cfs_time_seconds(STTIMER_SLOTTIME)); + wait_event_timeout(stt_data.stt_waitq, + stt_data.stt_shuttingdown, + cfs_time_seconds(STTIMER_SLOTTIME)); } spin_lock(&stt_data.stt_lock); diff --git a/drivers/staging/lustre/lustre/fid/Makefile b/drivers/staging/lustre/lustre/fid/Makefile index ed21bea162ba..d24f2df7c0af 100644 --- a/drivers/staging/lustre/lustre/fid/Makefile +++ b/drivers/staging/lustre/lustre/fid/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_LUSTRE_FS) += fid.o -fid-y := fid_request.o lproc_fid.o fid_lib.o +fid-y := fid_request.o fid_lib.o +fid-$(CONFIG_PROC_FS) += lproc_fid.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c index 294070da9d43..ddd813cab501 100644 --- a/drivers/staging/lustre/lustre/fid/lproc_fid.c +++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c @@ -54,7 +54,6 @@ #include <lustre_fid.h> #include "fid_internal.h" -#ifdef LPROCFS /* * Note: this function is only used for testing, it is no safe for production * use. @@ -209,4 +208,3 @@ struct lprocfs_vars seq_client_proc_list[] = { { "fid", &lprocfs_fid_fid_fops }, { NULL } }; -#endif diff --git a/drivers/staging/lustre/lustre/fld/Makefile b/drivers/staging/lustre/lustre/fld/Makefile index 90d46d84fbbb..640fba4b827d 100644 --- a/drivers/staging/lustre/lustre/fld/Makefile +++ b/drivers/staging/lustre/lustre/fld/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_LUSTRE_FS) += fld.o -fld-y := fld_request.o fld_cache.o lproc_fld.o +fld-y := fld_request.o fld_cache.o +fld-$(CONFIG_PROC_FS) += lproc_fld.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index 56686b138ac1..5f3935cc0fd7 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -190,5 +190,4 @@ fld_target_name(struct lu_fld_target *tar) return (const char *)tar->ft_exp->exp_obd->obd_name; } -extern struct proc_dir_entry *fld_type_proc_dir; #endif /* __FLD_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index e47fd50b2a2e..896f9fe83ffd 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -274,9 +274,9 @@ int fld_client_del_target(struct lu_client_fld *fld, __u64 idx) } EXPORT_SYMBOL(fld_client_del_target); -#ifdef LPROCFS struct proc_dir_entry *fld_type_proc_dir = NULL; +#ifdef LPROCFS static int fld_client_proc_init(struct lu_client_fld *fld) { int rc; @@ -504,10 +504,7 @@ static int __init fld_mod_init(void) fld_type_proc_dir = lprocfs_register(LUSTRE_FLD_NAME, proc_lustre_root, NULL, NULL); - if (IS_ERR(fld_type_proc_dir)) - return PTR_ERR(fld_type_proc_dir); - - return 0; + return PTR_ERR_OR_ZERO(fld_type_proc_dir); } static void __exit fld_mod_exit(void) diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c index 052f7d51a07c..530adde46963 100644 --- a/drivers/staging/lustre/lustre/fld/lproc_fld.c +++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c @@ -56,7 +56,6 @@ #include <lustre_fid.h> #include "fld_internal.h" -#ifdef LPROCFS static int fld_proc_targets_seq_show(struct seq_file *m, void *unused) { @@ -162,5 +161,3 @@ struct lprocfs_vars fld_client_proc_list[] = { { "hash", &fld_proc_hash_fops }, { "cache_flush", &fld_proc_cache_flush_fops }, { NULL }}; - -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index c485206fc6c2..4d692dcd96cf 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -2388,7 +2388,11 @@ struct cl_io { * Right now, only two opertaions need to verify layout: glimpse * and setattr. */ - ci_verify_layout:1; + ci_verify_layout:1, + /** + * file is released, restore has to to be triggered by vvp layer + */ + ci_restore_needed:1; /** * Number of pages owned by this IO. For invariant checking. */ diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h index e116bb21b529..9304c269afa9 100644 --- a/drivers/staging/lustre/lustre/include/dt_object.h +++ b/drivers/staging/lustre/lustre/include/dt_object.h @@ -692,7 +692,7 @@ struct local_oid_storage { struct dt_object *los_obj; /* data used to generate new fids */ - struct mutex los_id_lock; + struct mutex los_id_lock; __u64 los_seq; __u32 los_last_oid; }; diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_acl.h b/drivers/staging/lustre/lustre/include/linux/lustre_acl.h index ff4fc4ff2894..778b123ce31e 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_acl.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_acl.h @@ -47,17 +47,17 @@ #error Shoud not include direectly. use #include <lustre_acl.h> instead #endif -# include <linux/fs.h> -# include <linux/dcache.h> -# ifdef CONFIG_FS_POSIX_ACL -# include <linux/posix_acl_xattr.h> -# define LUSTRE_POSIX_ACL_MAX_ENTRIES 32 -# define LUSTRE_POSIX_ACL_MAX_SIZE \ +#include <linux/fs.h> +#include <linux/dcache.h> + +#include <linux/posix_acl_xattr.h> +#define LUSTRE_POSIX_ACL_MAX_ENTRIES 32 +#define LUSTRE_POSIX_ACL_MAX_SIZE \ (sizeof(posix_acl_xattr_header) + \ LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(posix_acl_xattr_entry)) -# endif /* CONFIG_FS_POSIX_ACL */ -# include <linux/lustre_intent.h> -# include <linux/xattr.h> /* XATTR_{REPLACE,CREATE} */ + +#include <linux/lustre_intent.h> +#include <linux/xattr.h> /* XATTR_{REPLACE,CREATE} */ #ifndef LUSTRE_POSIX_ACL_MAX_SIZE # define LUSTRE_POSIX_ACL_MAX_SIZE 0 diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_intent.h b/drivers/staging/lustre/lustre/include/linux/lustre_intent.h index b10ddfa7df29..c491d52d86a2 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_intent.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_intent.h @@ -52,8 +52,8 @@ struct lustre_intent_data { struct lookup_intent { int it_op; - int it_flags; int it_create_mode; + __u64 it_flags; union { struct lustre_intent_data lustre; } d; diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h index 9e5df8dabe80..df9391275617 100644 --- a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h +++ b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h @@ -88,6 +88,7 @@ enum { LPROC_LL_ALLOC_INODE, LPROC_LL_SETXATTR, LPROC_LL_GETXATTR, + LPROC_LL_GETXATTR_HITS, LPROC_LL_LISTXATTR, LPROC_LL_REMOVEXATTR, LPROC_LL_INODE_PERM, diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index 56b05728f611..428e3e4ce05c 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -370,6 +370,10 @@ static inline void s2dhms(struct dhms *ts, time_t secs) #define JOBSTATS_DISABLE "disable" #define JOBSTATS_PROCNAME_UID "procname_uid" +extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count, + int *val, int mult); +extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, + long val, int mult); #ifdef LPROCFS extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, @@ -641,11 +645,7 @@ extern int lprocfs_rd_filesfree(struct seq_file *m, void *data); extern int lprocfs_write_helper(const char *buffer, unsigned long count, int *val); -extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count, - int *val, int mult); extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult); -extern int lprocfs_read_frac_helper(char *buffer, unsigned long count, - long val, int mult); extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count, __u64 *val); extern int lprocfs_write_frac_u64_helper(const char *buffer, diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index d5b8225ef1a7..6773bca1e0d8 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -398,17 +398,6 @@ static inline int lu_device_is_md(const struct lu_device *d) } /** - * Flags for the object layers. - */ -enum lu_object_flags { - /** - * this flags is set if lu_object_operations::loo_object_init() has - * been called for this layer. Used by lu_object_alloc(). - */ - LU_OBJECT_ALLOCATED = (1 << 0) -}; - -/** * Common object attributes. */ struct lu_attr { @@ -486,14 +475,6 @@ struct lu_object { */ struct list_head lo_linkage; /** - * Depth. Top level layer depth is 0. - */ - int lo_depth; - /** - * Flags from enum lu_object_flags. - */ - __u32 lo_flags; - /** * Link to the device, for debugging. */ struct lu_ref_link lo_dev_ref; diff --git a/drivers/staging/lustre/lustre/include/lu_target.h b/drivers/staging/lustre/lustre/include/lu_target.h deleted file mode 100644 index 8d48cf4e27ee..000000000000 --- a/drivers/staging/lustre/lustre/include/lu_target.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#ifndef _LUSTRE_LU_TARGET_H -#define _LUSTRE_LU_TARGET_H - -#include <dt_object.h> -#include <lustre_disk.h> - -struct lu_target { - struct obd_device *lut_obd; - struct dt_device *lut_bottom; - /** last_rcvd file */ - struct dt_object *lut_last_rcvd; - /* transaction callbacks */ - struct dt_txn_callback lut_txn_cb; - /** server data in last_rcvd file */ - struct lr_server_data lut_lsd; - /** Server last transaction number */ - __u64 lut_last_transno; - /** Lock protecting last transaction number */ - spinlock_t lut_translock; - /** Lock protecting client bitmap */ - spinlock_t lut_client_bitmap_lock; - /** Bitmap of known clients */ - unsigned long *lut_client_bitmap; -}; - -typedef void (*tgt_cb_t)(struct lu_target *lut, __u64 transno, - void *data, int err); -struct tgt_commit_cb { - tgt_cb_t tgt_cb_func; - void *tgt_cb_data; -}; - -void tgt_boot_epoch_update(struct lu_target *lut); -int tgt_last_commit_cb_add(struct thandle *th, struct lu_target *lut, - struct obd_export *exp, __u64 transno); -int tgt_new_client_cb_add(struct thandle *th, struct obd_export *exp); -int tgt_init(const struct lu_env *env, struct lu_target *lut, - struct obd_device *obd, struct dt_device *dt); -void tgt_fini(const struct lu_env *env, struct lu_target *lut); -int tgt_client_alloc(struct obd_export *exp); -void tgt_client_free(struct obd_export *exp); -int tgt_client_del(const struct lu_env *env, struct obd_export *exp); -int tgt_client_add(const struct lu_env *env, struct obd_export *exp, int); -int tgt_client_new(const struct lu_env *env, struct obd_export *exp); -int tgt_client_data_read(const struct lu_env *env, struct lu_target *tg, - struct lsd_client_data *lcd, loff_t *off, int index); -int tgt_client_data_write(const struct lu_env *env, struct lu_target *tg, - struct lsd_client_data *lcd, loff_t *off, struct thandle *th); -int tgt_server_data_read(const struct lu_env *env, struct lu_target *tg); -int tgt_server_data_write(const struct lu_env *env, struct lu_target *tg, - struct thandle *th); -int tgt_server_data_update(const struct lu_env *env, struct lu_target *tg, int sync); -int tgt_truncate_last_rcvd(const struct lu_env *env, struct lu_target *tg, loff_t off); - -#endif /* __LUSTRE_LU_TARGET_H */ diff --git a/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h b/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h deleted file mode 100644 index 707eb74fdf68..000000000000 --- a/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -/* - * NOTE: This file is DEPRECATED! Please include lustreapi.h directly - * instead of this file. This file will be removed from a future version - * of lustre! - */ - -#ifndef _LIBLUSTREAPI_H_ -#define _LIBLUSTREAPI_H_ - -#include <lustre/lustreapi.h> -#warning "Including liblustreapi.h is deprecated. Include lustreapi.h directly." - -#endif diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 5ca18d016014..5da31c54924a 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -321,8 +321,11 @@ static inline int range_compare_loc(const struct lu_seq_range *r1, * xattr. */ enum lma_compat { - LMAC_HSM = 0x00000001, - LMAC_SOM = 0x00000002, + LMAC_HSM = 0x00000001, + LMAC_SOM = 0x00000002, + LMAC_NOT_IN_OI = 0x00000004, /* the object does NOT need OI mapping */ + LMAC_FID_ON_OST = 0x00000008, /* For OST-object, its OI mapping is + * under /O/<seq>/d<x>. */ }; /** @@ -331,10 +334,10 @@ enum lma_compat { * This information is stored in lustre_mdt_attrs::lma_incompat. */ enum lma_incompat { - LMAI_RELEASED = 0x0000001, /* file is released */ - LMAI_AGENT = 0x00000002, /* agent inode */ - LMAI_REMOTE_PARENT = 0x00000004, /* the parent of the object - is on the remote MDT */ + LMAI_RELEASED = 0x00000001, /* file is released */ + LMAI_AGENT = 0x00000002, /* agent inode */ + LMAI_REMOTE_PARENT = 0x00000004, /* the parent of the object + is on the remote MDT */ }; #define LMA_INCOMPAT_SUPP (LMAI_AGENT | LMAI_REMOTE_PARENT) @@ -1025,6 +1028,18 @@ struct luda_type { __u16 lt_type; }; +#ifndef IFSHIFT +#define IFSHIFT 12 +#endif + +#ifndef IFTODT +#define IFTODT(type) (((type) & S_IFMT) >> IFSHIFT) +#endif +#ifndef DTTOIF +#define DTTOIF(dirtype) ((dirtype) << IFSHIFT) +#endif + + struct lu_dirpage { __u64 ldp_hash_start; __u64 ldp_hash_end; @@ -1353,7 +1368,7 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb); OBD_CONNECT_EINPROGRESS | \ OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_UMASK | \ OBD_CONNECT_LVB_TYPE | OBD_CONNECT_LAYOUTLOCK |\ - OBD_CONNECT_PINGLESS) + OBD_CONNECT_PINGLESS | OBD_CONNECT_MAX_EASIZE) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \ OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \ OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \ @@ -1725,10 +1740,7 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic) #define OBD_MD_MDS (0x0000000100000000ULL) /* where an inode lives on */ #define OBD_MD_REINT (0x0000000200000000ULL) /* reintegrate oa */ #define OBD_MD_MEA (0x0000000400000000ULL) /* CMD split EA */ - -/* OBD_MD_MDTIDX is used to get MDT index, but it is never been used overwire, - * and it is already obsolete since 2.3 */ -/* #define OBD_MD_MDTIDX (0x0000000800000000ULL) */ +#define OBD_MD_TSTATE (0x0000000800000000ULL) /* transient state field */ #define OBD_MD_FLXATTR (0x0000001000000000ULL) /* xattr */ #define OBD_MD_FLXATTRLS (0x0000002000000000ULL) /* xattr list */ @@ -1740,7 +1752,9 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic) #define OBD_MD_FLCKSPLIT (0x0000080000000000ULL) /* Check split on server */ #define OBD_MD_FLCROSSREF (0x0000100000000000ULL) /* Cross-ref case */ #define OBD_MD_FLGETATTRLOCK (0x0000200000000000ULL) /* Get IOEpoch attributes - * under lock */ + * under lock; for xattr + * requests means the + * client holds the lock */ #define OBD_MD_FLOBJCOUNT (0x0000400000000000ULL) /* for multiple destroy */ #define OBD_MD_FLRMTLSETFACL (0x0001000000000000ULL) /* lfs lsetfacl case */ @@ -1749,6 +1763,7 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic) #define OBD_MD_FLRMTRGETFACL (0x0008000000000000ULL) /* lfs rgetfacl case */ #define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */ +#define OBD_MD_FLRELEASED (0x0020000000000000ULL) /* file released */ #define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \ OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ @@ -1756,6 +1771,9 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic) OBD_MD_FLGID | OBD_MD_FLFLAGS | OBD_MD_FLNLINK | \ OBD_MD_FLGENER | OBD_MD_FLRDEV | OBD_MD_FLGROUP) +#define OBD_MD_FLXATTRLOCKED OBD_MD_FLGETATTRLOCK +#define OBD_MD_FLXATTRALL (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS) + /* don't forget obdo_fid which is way down at the bottom so it can * come after the definition of llog_cookie */ @@ -2120,6 +2138,7 @@ extern void lustre_swab_generic_32s (__u32 *val); #define DISP_ENQ_OPEN_REF 0x00800000 #define DISP_ENQ_CREATE_REF 0x01000000 #define DISP_OPEN_LOCK 0x02000000 +#define DISP_OPEN_LEASE 0x04000000 /* INODE LOCK PARTS */ #define MDS_INODELOCK_LOOKUP 0x000001 /* dentry, mode, owner, group */ @@ -2127,8 +2146,9 @@ extern void lustre_swab_generic_32s (__u32 *val); #define MDS_INODELOCK_OPEN 0x000004 /* For opened files */ #define MDS_INODELOCK_LAYOUT 0x000008 /* for layout */ #define MDS_INODELOCK_PERM 0x000010 /* for permission */ +#define MDS_INODELOCK_XATTR 0x000020 /* extended attributes */ -#define MDS_INODELOCK_MAXSHIFT 4 +#define MDS_INODELOCK_MAXSHIFT 5 /* This FULL lock is useful to take on unlink sort of operations */ #define MDS_INODELOCK_FULL ((1<<(MDS_INODELOCK_MAXSHIFT+1))-1) @@ -2207,6 +2227,11 @@ static inline int ll_inode_to_ext_flags(int iflags) ((iflags & S_IMMUTABLE) ? LUSTRE_IMMUTABLE_FL : 0)); } +/* 64 possible states */ +enum md_transient_state { + MS_RESTORE = (1 << 0), /* restore is running */ +}; + struct mdt_body { struct lu_fid fid1; struct lu_fid fid2; @@ -2218,7 +2243,9 @@ struct mdt_body { obd_time ctime; __u64 blocks; /* XID, in the case of MDS_READPAGE */ __u64 ioepoch; - __u64 unused1; /* was "ino" until 2.4.0 */ + __u64 t_state; /* transient file state defined in + * enum md_transient_state + * was "ino" until 2.4.0 */ __u32 fsuid; __u32 fsgid; __u32 capability; @@ -2373,6 +2400,11 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa); * hsm restore) */ #define MDS_OPEN_VOLATILE 0400000000000ULL /* File is volatile = created unlinked */ +#define MDS_OPEN_LEASE 01000000000000ULL /* Open the file and grant lease + * delegation, succeed if it's not + * being opened with conflict mode. + */ +#define MDS_OPEN_RELEASE 02000000000000ULL /* Open the file for HSM release */ /* permission for create non-directory file */ #define MAY_CREATE (1 << 7) @@ -2391,7 +2423,7 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa); /* lfs rgetfacl permission check */ #define MAY_RGETFACL (1 << 14) -enum { +enum mds_op_bias { MDS_CHECK_SPLIT = 1 << 0, MDS_CROSS_REF = 1 << 1, MDS_VTX_BYPASS = 1 << 2, @@ -2404,6 +2436,7 @@ enum { MDS_DATA_MODIFIED = 1 << 9, MDS_CREATE_VOLATILE = 1 << 10, MDS_OWNEROVERRIDE = 1 << 11, + MDS_HSM_RELEASE = 1 << 12, }; /* instance of mdt_reint_rec */ @@ -3727,5 +3760,14 @@ struct mdc_swap_layouts { void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl); +struct close_data { + struct lustre_handle cd_handle; + struct lu_fid cd_fid; + __u64 cd_data_version; + __u64 cd_reserved[8]; +}; + +void lustre_swab_close_data(struct close_data *data); + #endif /** @} lustreidl */ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index c7bd4473a1d0..6b6c0240e824 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h @@ -244,6 +244,9 @@ struct ost_id { #define LL_IOC_LMV_SETSTRIPE _IOWR('f', 240, struct lmv_user_md) #define LL_IOC_LMV_GETSTRIPE _IOWR('f', 241, struct lmv_user_md) #define LL_IOC_REMOVE_ENTRY _IOWR('f', 242, __u64) +#define LL_IOC_SET_LEASE _IOWR('f', 243, long) +#define LL_IOC_GET_LEASE _IO('f', 244) +#define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import) #define LL_STATFS_LMV 1 #define LL_STATFS_LOV 2 @@ -425,8 +428,8 @@ struct obd_uuid { char uuid[UUID_MAX]; }; -static inline int obd_uuid_equals(const struct obd_uuid *u1, - const struct obd_uuid *u2) +static inline bool obd_uuid_equals(const struct obd_uuid *u1, + const struct obd_uuid *u2) { return strcmp((char *)u1->uuid, (char *)u2->uuid) == 0; } @@ -443,7 +446,7 @@ static inline void obd_str2uuid(struct obd_uuid *uuid, const char *tmp) } /* For printf's only, make sure uuid is terminated */ -static inline char *obd_uuid2str(struct obd_uuid *uuid) +static inline char *obd_uuid2str(const struct obd_uuid *uuid) { if (uuid->uuid[sizeof(*uuid) - 1] != '\0') { /* Obviously not safe, but for printfs, no real harm done... @@ -620,10 +623,13 @@ struct if_quotactl { }; /* swap layout flags */ -#define SWAP_LAYOUTS_CHECK_DV1 (1 << 0) -#define SWAP_LAYOUTS_CHECK_DV2 (1 << 1) -#define SWAP_LAYOUTS_KEEP_MTIME (1 << 2) -#define SWAP_LAYOUTS_KEEP_ATIME (1 << 3) +#define SWAP_LAYOUTS_CHECK_DV1 (1 << 0) +#define SWAP_LAYOUTS_CHECK_DV2 (1 << 1) +#define SWAP_LAYOUTS_KEEP_MTIME (1 << 2) +#define SWAP_LAYOUTS_KEEP_ATIME (1 << 3) + +/* Swap XATTR_NAME_HSM as well, only on the MDT so far */ +#define SWAP_LAYOUTS_MDS_HSM (1 << 31) struct lustre_swap_layouts { __u64 sl_flags; __u32 sl_fd; @@ -1118,13 +1124,27 @@ static inline int hal_size(struct hsm_action_list *hal) sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname)); hai = hai_zero(hal); - for (i = 0 ; i < hal->hal_count ; i++) { + for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) sz += cfs_size_round(hai->hai_len); - hai = hai_next(hai); - } - return(sz); + + return sz; } +/* HSM file import + * describe the attributes to be set on imported file + */ +struct hsm_user_import { + __u64 hui_size; + __u64 hui_atime; + __u64 hui_mtime; + __u32 hui_atime_ns; + __u32 hui_mtime_ns; + __u32 hui_uid; + __u32 hui_gid; + __u32 hui_mode; + __u32 hui_archive_id; +}; + /* Copytool progress reporting */ #define HP_FLAG_COMPLETED 0x01 #define HP_FLAG_RETRY 0x02 diff --git a/drivers/staging/lustre/lustre/include/lustre/lustreapi.h b/drivers/staging/lustre/lustre/include/lustre/lustreapi.h deleted file mode 100644 index 63da66506639..000000000000 --- a/drivers/staging/lustre/lustre/include/lustre/lustreapi.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#ifndef _LUSTREAPI_H_ -#define _LUSTREAPI_H_ - -/** \defgroup llapi llapi - * - * @{ - */ - -#include <lustre/lustre_user.h> - -typedef void (*llapi_cb_t)(char *obd_type_name, char *obd_name, char *obd_uuid, void *args); - -/* lustreapi message severity level */ -enum llapi_message_level { - LLAPI_MSG_OFF = 0, - LLAPI_MSG_FATAL = 1, - LLAPI_MSG_ERROR = 2, - LLAPI_MSG_WARN = 3, - LLAPI_MSG_NORMAL = 4, - LLAPI_MSG_INFO = 5, - LLAPI_MSG_DEBUG = 6, - LLAPI_MSG_MAX -}; - -/* the bottom three bits reserved for llapi_message_level */ -#define LLAPI_MSG_MASK 0x00000007 -#define LLAPI_MSG_NO_ERRNO 0x00000010 - -extern void llapi_msg_set_level(int level); -extern void llapi_error(int level, int rc, char *fmt, ...); -#define llapi_err_noerrno(level, fmt, a...) \ - llapi_error((level) | LLAPI_MSG_NO_ERRNO, 0, fmt, ## a) -extern void llapi_printf(int level, char *fmt, ...); -extern int llapi_file_create(const char *name, unsigned long long stripe_size, - int stripe_offset, int stripe_count, - int stripe_pattern); -extern int llapi_file_open(const char *name, int flags, int mode, - unsigned long long stripe_size, int stripe_offset, - int stripe_count, int stripe_pattern); -extern int llapi_file_create_pool(const char *name, - unsigned long long stripe_size, - int stripe_offset, int stripe_count, - int stripe_pattern, char *pool_name); -extern int llapi_file_open_pool(const char *name, int flags, int mode, - unsigned long long stripe_size, - int stripe_offset, int stripe_count, - int stripe_pattern, char *pool_name); -extern int llapi_poollist(const char *name); -extern int llapi_get_poollist(const char *name, char **poollist, int list_size, - char *buffer, int buffer_size); -extern int llapi_get_poolmembers(const char *poolname, char **members, - int list_size, char *buffer, int buffer_size); -extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum); -#define HAVE_LLAPI_FILE_LOOKUP -extern int llapi_file_lookup(int dirfd, const char *name); - -#define VERBOSE_COUNT 0x1 -#define VERBOSE_SIZE 0x2 -#define VERBOSE_OFFSET 0x4 -#define VERBOSE_POOL 0x8 -#define VERBOSE_DETAIL 0x10 -#define VERBOSE_OBJID 0x20 -#define VERBOSE_GENERATION 0x40 -#define VERBOSE_MDTINDEX 0x80 -#define VERBOSE_ALL (VERBOSE_COUNT | VERBOSE_SIZE | VERBOSE_OFFSET | \ - VERBOSE_POOL | VERBOSE_OBJID | VERBOSE_GENERATION) - -struct find_param { - unsigned int maxdepth; - time_t atime; - time_t mtime; - time_t ctime; - int asign; /* cannot be bitfields due to using pointers to */ - int csign; /* access them during argument parsing. */ - int msign; - int type; - int size_sign:2, /* these need to be signed values */ - stripesize_sign:2, - stripecount_sign:2; - unsigned long long size; - unsigned long long size_units; - uid_t uid; - gid_t gid; - - unsigned long zeroend:1, - recursive:1, - exclude_pattern:1, - exclude_type:1, - exclude_obd:1, - exclude_mdt:1, - exclude_gid:1, - exclude_uid:1, - check_gid:1, /* group ID */ - check_uid:1, /* user ID */ - check_pool:1, /* LOV pool name */ - check_size:1, /* file size */ - exclude_pool:1, - exclude_size:1, - exclude_atime:1, - exclude_mtime:1, - exclude_ctime:1, - get_lmv:1, /* get MDT list from LMV */ - raw:1, /* do not fill in defaults */ - check_stripesize:1, /* LOV stripe size */ - exclude_stripesize:1, - check_stripecount:1, /* LOV stripe count */ - exclude_stripecount:1; - - int verbose; - int quiet; - - /* regular expression */ - char *pattern; - - char *print_fmt; - - struct obd_uuid *obduuid; - int num_obds; - int num_alloc_obds; - int obdindex; - int *obdindexes; - - struct obd_uuid *mdtuuid; - int num_mdts; - int num_alloc_mdts; - int mdtindex; - int *mdtindexes; - int file_mdtindex; - - int lumlen; - struct lov_user_mds_data *lmd; - - char poolname[LOV_MAXPOOLNAME + 1]; - - int fp_lmv_count; - struct lmv_user_md *fp_lmv_md; - - unsigned long long stripesize; - unsigned long long stripesize_units; - unsigned long long stripecount; - - /* In-process parameters. */ - unsigned long got_uuids:1, - obds_printed:1, - have_fileinfo:1; /* file attrs and LOV xattr */ - unsigned int depth; - dev_t st_dev; -}; - -extern int llapi_ostlist(char *path, struct find_param *param); -extern int llapi_uuid_match(char *real_uuid, char *search_uuid); -extern int llapi_getstripe(char *path, struct find_param *param); -extern int llapi_find(char *path, struct find_param *param); - -extern int llapi_file_fget_mdtidx(int fd, int *mdtidx); -extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, - int stripe_count, int stripe_pattern, - char *poolname); -int llapi_direntry_remove(char *dname); -extern int llapi_obd_statfs(char *path, __u32 type, __u32 index, - struct obd_statfs *stat_buf, - struct obd_uuid *uuid_buf); -extern int llapi_ping(char *obd_type, char *obd_name); -extern int llapi_target_check(int num_types, char **obd_types, char *dir); -extern int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid); -extern int llapi_file_get_lmv_uuid(const char *path, struct obd_uuid *lmv_uuid); -extern int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid); -extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count); -extern int llapi_lmv_get_uuids(int fd, struct obd_uuid *uuidp, int *mdt_count); -extern int llapi_is_lustre_mnttype(const char *type); -extern int llapi_search_ost(char *fsname, char *poolname, char *ostname); -extern int llapi_get_obd_count(char *mnt, int *count, int is_mdt); -extern int parse_size(char *optarg, unsigned long long *size, - unsigned long long *size_units, int bytes_spec); -extern int llapi_search_mounts(const char *pathname, int index, - char *mntdir, char *fsname); -extern int llapi_search_fsname(const char *pathname, char *fsname); -extern int llapi_getname(const char *path, char *buf, size_t size); - -extern void llapi_ping_target(char *obd_type, char *obd_name, - char *obd_uuid, void *args); - -extern int llapi_search_rootpath(char *pathname, const char *fsname); - -struct mntent; -#define HAVE_LLAPI_IS_LUSTRE_MNT -extern int llapi_is_lustre_mnt(struct mntent *mnt); -extern int llapi_quotachown(char *path, int flag); -extern int llapi_quotacheck(char *mnt, int check_type); -extern int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk); -extern int llapi_quotactl(char *mnt, struct if_quotactl *qctl); -extern int llapi_target_iterate(int type_num, char **obd_type, void *args, - llapi_cb_t cb); -extern int llapi_get_connect_flags(const char *mnt, __u64 *flags); -extern int llapi_lsetfacl(int argc, char *argv[]); -extern int llapi_lgetfacl(int argc, char *argv[]); -extern int llapi_rsetfacl(int argc, char *argv[]); -extern int llapi_rgetfacl(int argc, char *argv[]); -extern int llapi_cp(int argc, char *argv[]); -extern int llapi_ls(int argc, char *argv[]); -extern int llapi_fid2path(const char *device, const char *fidstr, char *path, - int pathlen, long long *recno, int *linkno); -extern int llapi_path2fid(const char *path, lustre_fid *fid); -extern int llapi_fd2fid(const int fd, lustre_fid *fid); - -extern int llapi_get_version(char *buffer, int buffer_size, char **version); -extern int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags); -extern int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus); -extern int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask, - __u32 archive_id); - -extern int llapi_create_volatile_idx(char *directory, int idx, int mode); -static inline int llapi_create_volatile(char *directory, int mode) -{ - return llapi_create_volatile_idx(directory, -1, mode); -} - - -extern int llapi_fswap_layouts(const int fd1, const int fd2, - __u64 dv1, __u64 dv2, __u64 flags); -extern int llapi_swap_layouts(const char *path1, const char *path2, - __u64 dv1, __u64 dv2, __u64 flags); - -/* Changelog interface. priv is private state, managed internally - by these functions */ -#define CHANGELOG_FLAG_FOLLOW 0x01 /* Not yet implemented */ -#define CHANGELOG_FLAG_BLOCK 0x02 /* Blocking IO makes sense in case of - slow user parsing of the records, but it also prevents us from cleaning - up if the records are not consumed. */ - -/* Records received are in extentded format now, though most of them are still - * written in disk in changelog_rec format (to save space and time), it's - * converted to extented format in the lustre api to ease changelog analysis. */ -#define HAVE_CHANGELOG_EXTEND_REC 1 - -extern int llapi_changelog_start(void **priv, int flags, const char *mdtname, - long long startrec); -extern int llapi_changelog_fini(void **priv); -extern int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech); -extern int llapi_changelog_free(struct changelog_ext_rec **rech); -/* Allow records up to endrec to be destroyed; requires registered id. */ -extern int llapi_changelog_clear(const char *mdtname, const char *idstr, - long long endrec); - -/* HSM copytool interface. - * priv is private state, managed internally by these functions - */ -struct hsm_copytool_private; -extern int llapi_hsm_copytool_start(struct hsm_copytool_private **priv, - char *fsname, int flags, - int archive_count, int *archives); -extern int llapi_hsm_copytool_fini(struct hsm_copytool_private **priv); -extern int llapi_hsm_copytool_recv(struct hsm_copytool_private *priv, - struct hsm_action_list **hal, int *msgsize); -extern int llapi_hsm_copytool_free(struct hsm_action_list **hal); -extern int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy, - const struct hsm_action_item *hai); -extern int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy, - const struct hsm_progress *hp); -extern int llapi_hsm_progress(char *mnt, struct hsm_progress *hp); -extern int llapi_hsm_import(const char *dst, int archive, struct stat *st, - unsigned long long stripe_size, int stripe_offset, - int stripe_count, int stripe_pattern, - char *pool_name, lustre_fid *newfid); - -/* HSM user interface */ -extern struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount, - int data_len); -extern int llapi_hsm_request(char *mnt, struct hsm_user_request *request); -extern int llapi_hsm_current_action(const char *path, - struct hsm_current_action *hca); -/** @} llapi */ - -#endif diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 9228b165b258..1de9a8bed497 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -50,6 +50,7 @@ #include <linux/libcfs/libcfs.h> #include <linux/lnet/types.h> +#include <linux/backing-dev.h> /****************** on-disk files *********************/ diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index bc2b82ffae92..ec4bb5e3c13e 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -1285,10 +1285,11 @@ void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client); void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client); void ldlm_namespace_get(struct ldlm_namespace *ns); void ldlm_namespace_put(struct ldlm_namespace *ns); -int ldlm_proc_setup(void); #ifdef LPROCFS +int ldlm_proc_setup(void); void ldlm_proc_cleanup(void); #else +static inline int ldlm_proc_setup(void) { return 0; } static inline void ldlm_proc_cleanup(void) {} #endif diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h index 8c34d9d4d258..75716f17f64b 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h @@ -35,7 +35,7 @@ #ifndef LDLM_ALL_FLAGS_MASK /** l_flags bits marked as "all_flags" bits */ -#define LDLM_FL_ALL_FLAGS_MASK 0x007FFFFFC08F132FULL +#define LDLM_FL_ALL_FLAGS_MASK 0x00FFFFFFC08F132FULL /** l_flags bits marked as "ast" bits */ #define LDLM_FL_AST_MASK 0x0000000080000000ULL @@ -53,7 +53,7 @@ #define LDLM_FL_INHERIT_MASK 0x0000000000800000ULL /** l_flags bits marked as "local_only" bits */ -#define LDLM_FL_LOCAL_ONLY_MASK 0x007FFFFF00000000ULL +#define LDLM_FL_LOCAL_ONLY_MASK 0x00FFFFFF00000000ULL /** l_flags bits marked as "on_wire" bits */ #define LDLM_FL_ON_WIRE_MASK 0x00000000C08F132FULL @@ -358,6 +358,12 @@ #define ldlm_set_ns_srv(_l) LDLM_SET_FLAG(( _l), 1ULL << 54) #define ldlm_clear_ns_srv(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 54) +/** Flag whether this lock can be reused. Used by exclusive open. */ +#define LDLM_FL_EXCL 0x0080000000000000ULL /* bit 55 */ +#define ldlm_is_excl(_l) LDLM_TEST_FLAG((_l), 1ULL << 55) +#define ldlm_set_excl(_l) LDLM_SET_FLAG((_l), 1ULL << 55) +#define ldlm_clear_excl(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 55) + /** test for ldlm_lock flag bit set */ #define LDLM_TEST_FLAG(_l, _b) (((_l)->l_flags & (_b)) != 0) @@ -414,47 +420,49 @@ static int hf_lustre_ldlm_fl_server_lock = -1; static int hf_lustre_ldlm_fl_res_locked = -1; static int hf_lustre_ldlm_fl_waited = -1; static int hf_lustre_ldlm_fl_ns_srv = -1; +static int hf_lustre_ldlm_fl_excl = -1; const value_string lustre_ldlm_flags_vals[] = { - {LDLM_FL_LOCK_CHANGED, "LDLM_FL_LOCK_CHANGED"}, - {LDLM_FL_BLOCK_GRANTED, "LDLM_FL_BLOCK_GRANTED"}, - {LDLM_FL_BLOCK_CONV, "LDLM_FL_BLOCK_CONV"}, - {LDLM_FL_BLOCK_WAIT, "LDLM_FL_BLOCK_WAIT"}, - {LDLM_FL_AST_SENT, "LDLM_FL_AST_SENT"}, - {LDLM_FL_REPLAY, "LDLM_FL_REPLAY"}, - {LDLM_FL_INTENT_ONLY, "LDLM_FL_INTENT_ONLY"}, - {LDLM_FL_HAS_INTENT, "LDLM_FL_HAS_INTENT"}, - {LDLM_FL_DISCARD_DATA, "LDLM_FL_DISCARD_DATA"}, - {LDLM_FL_NO_TIMEOUT, "LDLM_FL_NO_TIMEOUT"}, - {LDLM_FL_BLOCK_NOWAIT, "LDLM_FL_BLOCK_NOWAIT"}, - {LDLM_FL_TEST_LOCK, "LDLM_FL_TEST_LOCK"}, - {LDLM_FL_CANCEL_ON_BLOCK, "LDLM_FL_CANCEL_ON_BLOCK"}, - {LDLM_FL_DENY_ON_CONTENTION, "LDLM_FL_DENY_ON_CONTENTION"}, - {LDLM_FL_AST_DISCARD_DATA, "LDLM_FL_AST_DISCARD_DATA"}, - {LDLM_FL_FAIL_LOC, "LDLM_FL_FAIL_LOC"}, - {LDLM_FL_SKIPPED, "LDLM_FL_SKIPPED"}, - {LDLM_FL_CBPENDING, "LDLM_FL_CBPENDING"}, - {LDLM_FL_WAIT_NOREPROC, "LDLM_FL_WAIT_NOREPROC"}, - {LDLM_FL_CANCEL, "LDLM_FL_CANCEL"}, - {LDLM_FL_LOCAL_ONLY, "LDLM_FL_LOCAL_ONLY"}, - {LDLM_FL_FAILED, "LDLM_FL_FAILED"}, - {LDLM_FL_CANCELING, "LDLM_FL_CANCELING"}, - {LDLM_FL_LOCAL, "LDLM_FL_LOCAL"}, - {LDLM_FL_LVB_READY, "LDLM_FL_LVB_READY"}, - {LDLM_FL_KMS_IGNORE, "LDLM_FL_KMS_IGNORE"}, - {LDLM_FL_CP_REQD, "LDLM_FL_CP_REQD"}, - {LDLM_FL_CLEANED, "LDLM_FL_CLEANED"}, - {LDLM_FL_ATOMIC_CB, "LDLM_FL_ATOMIC_CB"}, - {LDLM_FL_BL_AST, "LDLM_FL_BL_AST"}, - {LDLM_FL_BL_DONE, "LDLM_FL_BL_DONE"}, - {LDLM_FL_NO_LRU, "LDLM_FL_NO_LRU"}, - {LDLM_FL_FAIL_NOTIFIED, "LDLM_FL_FAIL_NOTIFIED"}, - {LDLM_FL_DESTROYED, "LDLM_FL_DESTROYED"}, - {LDLM_FL_SERVER_LOCK, "LDLM_FL_SERVER_LOCK"}, - {LDLM_FL_RES_LOCKED, "LDLM_FL_RES_LOCKED"}, - {LDLM_FL_WAITED, "LDLM_FL_WAITED"}, - {LDLM_FL_NS_SRV, "LDLM_FL_NS_SRV"}, - { 0, NULL } + {LDLM_FL_LOCK_CHANGED, "LDLM_FL_LOCK_CHANGED"}, + {LDLM_FL_BLOCK_GRANTED, "LDLM_FL_BLOCK_GRANTED"}, + {LDLM_FL_BLOCK_CONV, "LDLM_FL_BLOCK_CONV"}, + {LDLM_FL_BLOCK_WAIT, "LDLM_FL_BLOCK_WAIT"}, + {LDLM_FL_AST_SENT, "LDLM_FL_AST_SENT"}, + {LDLM_FL_REPLAY, "LDLM_FL_REPLAY"}, + {LDLM_FL_INTENT_ONLY, "LDLM_FL_INTENT_ONLY"}, + {LDLM_FL_HAS_INTENT, "LDLM_FL_HAS_INTENT"}, + {LDLM_FL_DISCARD_DATA, "LDLM_FL_DISCARD_DATA"}, + {LDLM_FL_NO_TIMEOUT, "LDLM_FL_NO_TIMEOUT"}, + {LDLM_FL_BLOCK_NOWAIT, "LDLM_FL_BLOCK_NOWAIT"}, + {LDLM_FL_TEST_LOCK, "LDLM_FL_TEST_LOCK"}, + {LDLM_FL_CANCEL_ON_BLOCK, "LDLM_FL_CANCEL_ON_BLOCK"}, + {LDLM_FL_DENY_ON_CONTENTION, "LDLM_FL_DENY_ON_CONTENTION"}, + {LDLM_FL_AST_DISCARD_DATA, "LDLM_FL_AST_DISCARD_DATA"}, + {LDLM_FL_FAIL_LOC, "LDLM_FL_FAIL_LOC"}, + {LDLM_FL_SKIPPED, "LDLM_FL_SKIPPED"}, + {LDLM_FL_CBPENDING, "LDLM_FL_CBPENDING"}, + {LDLM_FL_WAIT_NOREPROC, "LDLM_FL_WAIT_NOREPROC"}, + {LDLM_FL_CANCEL, "LDLM_FL_CANCEL"}, + {LDLM_FL_LOCAL_ONLY, "LDLM_FL_LOCAL_ONLY"}, + {LDLM_FL_FAILED, "LDLM_FL_FAILED"}, + {LDLM_FL_CANCELING, "LDLM_FL_CANCELING"}, + {LDLM_FL_LOCAL, "LDLM_FL_LOCAL"}, + {LDLM_FL_LVB_READY, "LDLM_FL_LVB_READY"}, + {LDLM_FL_KMS_IGNORE, "LDLM_FL_KMS_IGNORE"}, + {LDLM_FL_CP_REQD, "LDLM_FL_CP_REQD"}, + {LDLM_FL_CLEANED, "LDLM_FL_CLEANED"}, + {LDLM_FL_ATOMIC_CB, "LDLM_FL_ATOMIC_CB"}, + {LDLM_FL_BL_AST, "LDLM_FL_BL_AST"}, + {LDLM_FL_BL_DONE, "LDLM_FL_BL_DONE"}, + {LDLM_FL_NO_LRU, "LDLM_FL_NO_LRU"}, + {LDLM_FL_FAIL_NOTIFIED, "LDLM_FL_FAIL_NOTIFIED"}, + {LDLM_FL_DESTROYED, "LDLM_FL_DESTROYED"}, + {LDLM_FL_SERVER_LOCK, "LDLM_FL_SERVER_LOCK"}, + {LDLM_FL_RES_LOCKED, "LDLM_FL_RES_LOCKED"}, + {LDLM_FL_WAITED, "LDLM_FL_WAITED"}, + {LDLM_FL_NS_SRV, "LDLM_FL_NS_SRV"}, + {LDLM_FL_EXCL, "LDLM_FL_EXCL"}, + { 0, NULL } }; #endif /* WIRESHARK_COMPILE */ #endif /* LDLM_ALL_FLAGS_MASK */ diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h index ff119532dafb..84a897eed1df 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fid.h +++ b/drivers/staging/lustre/lustre/include/lustre_fid.h @@ -431,12 +431,6 @@ struct lu_server_seq { struct seq_server_site *lss_site; }; -struct com_thread_info; -int seq_query(struct com_thread_info *info); - -struct ptlrpc_request; -int seq_handle(struct ptlrpc_request *req); - /* Server methods */ int seq_server_init(struct lu_server_seq *seq, diff --git a/drivers/staging/lustre/lustre/include/lustre_ha.h b/drivers/staging/lustre/lustre/include/lustre_ha.h index 105f6d61eef0..f3ae02b3eef3 100644 --- a/drivers/staging/lustre/lustre/include/lustre_ha.h +++ b/drivers/staging/lustre/lustre/include/lustre_ha.h @@ -58,9 +58,6 @@ void ptlrpc_activate_import(struct obd_import *imp); void ptlrpc_deactivate_import(struct obd_import *imp); void ptlrpc_invalidate_import(struct obd_import *imp); void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt); -int ptlrpc_check_suspend(void); -void ptlrpc_activate_timeouts(struct obd_import *imp); -void ptlrpc_deactivate_timeouts(struct obd_import *imp); /** @} ha */ diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index 5e11107d4c66..609a090484a6 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -81,11 +81,12 @@ struct client_obd *client_conn2cli(struct lustre_handle *conn); struct md_open_data; struct obd_client_handle { - struct lustre_handle och_fh; - struct lu_fid och_fid; - struct md_open_data *och_mod; - __u32 och_magic; - int och_flags; + struct lustre_handle och_fh; + struct lu_fid och_fid; + struct md_open_data *och_mod; + struct lustre_handle och_lease_handle; /* open lock for lease */ + __u32 och_magic; + fmode_t och_flags; }; #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h index 721aa05dff3b..896c7576aa0f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_log.h +++ b/drivers/staging/lustre/lustre/include/lustre_log.h @@ -136,7 +136,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param); int llog_close(const struct lu_env *env, struct llog_handle *cathandle); -int llog_get_size(struct llog_handle *loghandle); +int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt, + char *name); +int llog_backup(const struct lu_env *env, struct obd_device *obd, + struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt, + char *name, char *backup); /* llog_process flags */ #define LLOG_FLAG_NODEAMON 0x0001 @@ -382,6 +386,13 @@ static inline int llog_data_len(int len) return cfs_size_round(len); } +static inline int llog_get_size(struct llog_handle *loghandle) +{ + if (loghandle && loghandle->lgh_hdr) + return loghandle->lgh_hdr->llh_count; + return 0; +} + static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt) { atomic_inc(&ctxt->loc_refcount); diff --git a/drivers/staging/lustre/lustre/include/lustre_mdc.h b/drivers/staging/lustre/lustre/include/lustre_mdc.h index 19000259a5e4..c1e02702b931 100644 --- a/drivers/staging/lustre/lustre/include/lustre_mdc.h +++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h @@ -48,12 +48,9 @@ * @{ */ -# include <linux/fs.h> -# include <linux/dcache.h> -# ifdef CONFIG_FS_POSIX_ACL -# include <linux/posix_acl_xattr.h> -# endif /* CONFIG_FS_POSIX_ACL */ -# include <linux/lustre_intent.h> +#include <linux/fs.h> +#include <linux/dcache.h> +#include <linux/lustre_intent.h> #include <lustre_handles.h> #include <linux/libcfs/libcfs.h> #include <obd_class.h> diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 72edf01b58a2..d8d088035428 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -264,241 +264,7 @@ #define LDLM_MAXREQSIZE (5 * 1024) #define LDLM_MAXREPSIZE (1024) - /* - * MDS threads constants: - * - * Please see examples in "Thread Constants", MDS threads number will be at - * the comparable level of old versions, unless the server has many cores. - */ -#ifndef MDS_MAX_THREADS -#define MDS_MAX_THREADS 1024 -#define MDS_MAX_OTHR_THREADS 256 - -#else /* MDS_MAX_THREADS */ -#if MDS_MAX_THREADS < PTLRPC_NTHRS_INIT -#undef MDS_MAX_THREADS -#define MDS_MAX_THREADS PTLRPC_NTHRS_INIT -#endif -#define MDS_MAX_OTHR_THREADS max(PTLRPC_NTHRS_INIT, MDS_MAX_THREADS / 2) -#endif - -/* default service */ -#define MDS_THR_FACTOR 8 -#define MDS_NTHRS_INIT PTLRPC_NTHRS_INIT -#define MDS_NTHRS_MAX MDS_MAX_THREADS -#define MDS_NTHRS_BASE min(64, MDS_NTHRS_MAX) - -/* read-page service */ -#define MDS_RDPG_THR_FACTOR 4 -#define MDS_RDPG_NTHRS_INIT PTLRPC_NTHRS_INIT -#define MDS_RDPG_NTHRS_MAX MDS_MAX_OTHR_THREADS -#define MDS_RDPG_NTHRS_BASE min(48, MDS_RDPG_NTHRS_MAX) - -/* these should be removed when we remove setattr service in the future */ -#define MDS_SETA_THR_FACTOR 4 -#define MDS_SETA_NTHRS_INIT PTLRPC_NTHRS_INIT -#define MDS_SETA_NTHRS_MAX MDS_MAX_OTHR_THREADS -#define MDS_SETA_NTHRS_BASE min(48, MDS_SETA_NTHRS_MAX) - -/* non-affinity threads */ -#define MDS_OTHR_NTHRS_INIT PTLRPC_NTHRS_INIT -#define MDS_OTHR_NTHRS_MAX MDS_MAX_OTHR_THREADS - -#define MDS_NBUFS 64 - -/** - * Assume file name length = FNAME_MAX = 256 (true for ext3). - * path name length = PATH_MAX = 4096 - * LOV MD size max = EA_MAX = 24 * 2000 - * (NB: 24 is size of lov_ost_data) - * LOV LOGCOOKIE size max = 32 * 2000 - * (NB: 32 is size of llog_cookie) - * symlink: FNAME_MAX + PATH_MAX <- largest - * link: FNAME_MAX + PATH_MAX (mds_rec_link < mds_rec_create) - * rename: FNAME_MAX + FNAME_MAX - * open: FNAME_MAX + EA_MAX - * - * MDS_MAXREQSIZE ~= 4736 bytes = - * lustre_msg + ldlm_request + mdt_body + mds_rec_create + FNAME_MAX + PATH_MAX - * MDS_MAXREPSIZE ~= 8300 bytes = lustre_msg + llog_header - * - * Realistic size is about 512 bytes (20 character name + 128 char symlink), - * except in the open case where there are a large number of OSTs in a LOV. - */ -#define MDS_MAXREQSIZE (5 * 1024) /* >= 4736 */ -#define MDS_MAXREPSIZE (9 * 1024) /* >= 8300 */ - -/** - * MDS incoming request with LOV EA - * 24 = sizeof(struct lov_ost_data), i.e: replay of opencreate - */ -#define MDS_LOV_MAXREQSIZE max(MDS_MAXREQSIZE, \ - 362 + LOV_MAX_STRIPE_COUNT * 24) -/** - * MDS outgoing reply with LOV EA - * - * NB: max reply size Lustre 2.4+ client can get from old MDS is: - * LOV_MAX_STRIPE_COUNT * (llog_cookie + lov_ost_data) + extra bytes - * - * but 2.4 or later MDS will never send reply with llog_cookie to any - * version client. This macro is defined for server side reply buffer size. - */ -#define MDS_LOV_MAXREPSIZE MDS_LOV_MAXREQSIZE - -/** - * This is the size of a maximum REINT_SETXATTR request: - * - * lustre_msg 56 (32 + 4 x 5 + 4) - * ptlrpc_body 184 - * mdt_rec_setxattr 136 - * lustre_capa 120 - * name 256 (XATTR_NAME_MAX) - * value 65536 (XATTR_SIZE_MAX) - */ -#define MDS_EA_MAXREQSIZE 66288 - -/** - * These are the maximum request and reply sizes (rounded up to 1 KB - * boundaries) for the "regular" MDS_REQUEST_PORTAL and MDS_REPLY_PORTAL. - */ -#define MDS_REG_MAXREQSIZE (((max(MDS_EA_MAXREQSIZE, \ - MDS_LOV_MAXREQSIZE) + 1023) >> 10) << 10) -#define MDS_REG_MAXREPSIZE MDS_REG_MAXREQSIZE - -/** - * The update request includes all of updates from the create, which might - * include linkea (4K maxim), together with other updates, we set it to 9K: - * lustre_msg + ptlrpc_body + UPDATE_BUF_SIZE (8K) - */ -#define MDS_OUT_MAXREQSIZE (9 * 1024) -#define MDS_OUT_MAXREPSIZE MDS_MAXREPSIZE - -/** MDS_BUFSIZE = max_reqsize (w/o LOV EA) + max sptlrpc payload size */ -#define MDS_BUFSIZE max(MDS_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \ - 8 * 1024) - -/** - * MDS_REG_BUFSIZE should at least be MDS_REG_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD. - * However, we need to allocate a much larger buffer for it because LNet - * requires each MD(rqbd) has at least MDS_REQ_MAXREQSIZE bytes left to avoid - * dropping of maximum-sized incoming request. So if MDS_REG_BUFSIZE is only a - * little larger than MDS_REG_MAXREQSIZE, then it can only fit in one request - * even there are about MDS_REG_MAX_REQSIZE bytes left in a rqbd, and memory - * utilization is very low. - * - * In the meanwhile, size of rqbd can't be too large, because rqbd can't be - * reused until all requests fit in it have been processed and released, - * which means one long blocked request can prevent the rqbd be reused. - * Now we set request buffer size to 160 KB, so even each rqbd is unlinked - * from LNet with unused 65 KB, buffer utilization will be about 59%. - * Please check LU-2432 for details. - */ -#define MDS_REG_BUFSIZE max(MDS_REG_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \ - 160 * 1024) - -/** - * MDS_OUT_BUFSIZE = max_out_reqsize + max sptlrpc payload (~1K) which is - * about 10K, for the same reason as MDS_REG_BUFSIZE, we also give some - * extra bytes to each request buffer to improve buffer utilization rate. - */ -#define MDS_OUT_BUFSIZE max(MDS_OUT_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \ - 24 * 1024) - -/** FLD_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc */ -#define FLD_MAXREQSIZE (160) - -/** FLD_MAXREPSIZE == lustre_msg + ptlrpc_body */ -#define FLD_MAXREPSIZE (152) -#define FLD_BUFSIZE (1 << 12) - -/** - * SEQ_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc + lu_range + - * __u32 padding */ -#define SEQ_MAXREQSIZE (160) - -/** SEQ_MAXREPSIZE == lustre_msg + ptlrpc_body + lu_range */ -#define SEQ_MAXREPSIZE (152) -#define SEQ_BUFSIZE (1 << 12) - -/** MGS threads must be >= 3, see bug 22458 comment #28 */ -#define MGS_NTHRS_INIT (PTLRPC_NTHRS_INIT + 1) -#define MGS_NTHRS_MAX 32 - -#define MGS_NBUFS 64 -#define MGS_BUFSIZE (8 * 1024) -#define MGS_MAXREQSIZE (7 * 1024) -#define MGS_MAXREPSIZE (9 * 1024) - - /* - * OSS threads constants: - * - * Given 8 as factor and 64 as base threads number - * - * example 1): - * On 8-core server configured to 2 partitions, we will have - * 64 + 8 * 4 = 96 threads for each partition, 192 total threads. - * - * example 2): - * On 32-core machine configured to 4 partitions, we will have - * 64 + 8 * 8 = 112 threads for each partition, so total threads number - * will be 112 * 4 = 448. - * - * example 3): - * On 64-core machine configured to 4 partitions, we will have - * 64 + 16 * 8 = 192 threads for each partition, so total threads number - * will be 192 * 4 = 768 which is above limit OSS_NTHRS_MAX(512), so we - * cut off the value to OSS_NTHRS_MAX(512) / 4 which is 128 threads - * for each partition. - * - * So we can see that with these constants, threads number wil be at the - * similar level of old versions, unless the server has many cores. - */ - /* depress threads factor for VM with small memory size */ -#define OSS_THR_FACTOR min_t(int, 8, \ - NUM_CACHEPAGES >> (28 - PAGE_CACHE_SHIFT)) -#define OSS_NTHRS_INIT (PTLRPC_NTHRS_INIT + 1) -#define OSS_NTHRS_BASE 64 -#define OSS_NTHRS_MAX 512 - -/* threads for handling "create" request */ -#define OSS_CR_THR_FACTOR 1 -#define OSS_CR_NTHRS_INIT PTLRPC_NTHRS_INIT -#define OSS_CR_NTHRS_BASE 8 -#define OSS_CR_NTHRS_MAX 64 - -/** - * OST_IO_MAXREQSIZE ~= - * lustre_msg + ptlrpc_body + obdo + obd_ioobj + - * DT_MAX_BRW_PAGES * niobuf_remote - * - * - single object with 16 pages is 512 bytes - * - OST_IO_MAXREQSIZE must be at least 1 page of cookies plus some spillover - * - Must be a multiple of 1024 - * - actual size is about 18K - */ -#define _OST_MAXREQSIZE_SUM (sizeof(struct lustre_msg) + \ - sizeof(struct ptlrpc_body) + \ - sizeof(struct obdo) + \ - sizeof(struct obd_ioobj) + \ - sizeof(struct niobuf_remote) * DT_MAX_BRW_PAGES) -/** - * FIEMAP request can be 4K+ for now - */ #define OST_MAXREQSIZE (5 * 1024) -#define OST_IO_MAXREQSIZE max_t(int, OST_MAXREQSIZE, \ - (((_OST_MAXREQSIZE_SUM - 1) | (1024 - 1)) + 1)) - -#define OST_MAXREPSIZE (9 * 1024) -#define OST_IO_MAXREPSIZE OST_MAXREPSIZE - -#define OST_NBUFS 64 -/** OST_BUFSIZE = max_reqsize + max sptlrpc payload size */ -#define OST_BUFSIZE max_t(int, OST_MAXREQSIZE + 1024, 16 * 1024) -/** - * OST_IO_MAXREQSIZE is 18K, giving extra 46K can increase buffer utilization - * rate of request buffer, please check comment of MDS_LOV_BUFSIZE for details. - */ -#define OST_IO_BUFSIZE max_t(int, OST_IO_MAXREQSIZE + 1024, 64 * 1024) /* Macro to hide a typecast. */ #define ptlrpc_req_async_args(req) ((void *)&req->rq_async_args) @@ -3403,10 +3169,8 @@ int ptlrpc_del_timeout_client(struct list_head *obd_list, enum timeout_event event); struct ptlrpc_request * ptlrpc_prep_ping(struct obd_import *imp); int ptlrpc_obd_ping(struct obd_device *obd); -cfs_time_t ptlrpc_suspend_wakeup_time(void); void ping_evictor_start(void); void ping_evictor_stop(void); -int ptlrpc_check_and_wait_suspend(struct ptlrpc_request *req); void ptlrpc_pinger_ir_up(void); void ptlrpc_pinger_ir_down(void); /** @} */ @@ -3470,15 +3234,6 @@ static inline void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes) {} #endif /** @} */ -/* ptlrpc/llog_server.c */ -int llog_origin_handle_open(struct ptlrpc_request *req); -int llog_origin_handle_destroy(struct ptlrpc_request *req); -int llog_origin_handle_prev_block(struct ptlrpc_request *req); -int llog_origin_handle_next_block(struct ptlrpc_request *req); -int llog_origin_handle_read_header(struct ptlrpc_request *req); -int llog_origin_handle_close(struct ptlrpc_request *req); -int llog_origin_handle_cancel(struct ptlrpc_request *req); - /* ptlrpc/llog_client.c */ extern struct llog_operations llog_client_ops; diff --git a/drivers/staging/lustre/lustre/include/lustre_req_layout.h b/drivers/staging/lustre/lustre/include/lustre_req_layout.h index f4d3820865f1..a83db61a30be 100644 --- a/drivers/staging/lustre/lustre/include/lustre_req_layout.h +++ b/drivers/staging/lustre/lustre/include/lustre_req_layout.h @@ -164,6 +164,7 @@ extern struct req_format RQF_UPDATE_OBJ; */ extern struct req_format RQF_MDS_GETATTR_NAME; extern struct req_format RQF_MDS_CLOSE; +extern struct req_format RQF_MDS_RELEASE_CLOSE; extern struct req_format RQF_MDS_PIN; extern struct req_format RQF_MDS_UNPIN; extern struct req_format RQF_MDS_CONNECT; @@ -229,6 +230,7 @@ extern struct req_format RQF_LDLM_INTENT_GETATTR; extern struct req_format RQF_LDLM_INTENT_OPEN; extern struct req_format RQF_LDLM_INTENT_CREATE; extern struct req_format RQF_LDLM_INTENT_UNLINK; +extern struct req_format RQF_LDLM_INTENT_GETXATTR; extern struct req_format RQF_LDLM_INTENT_QUOTA; extern struct req_format RQF_LDLM_CANCEL; extern struct req_format RQF_LDLM_CALLBACK; @@ -245,6 +247,8 @@ extern struct req_format RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK; extern struct req_format RQF_LLOG_ORIGIN_HANDLE_READ_HEADER; extern struct req_format RQF_LLOG_ORIGIN_CONNECT; +extern struct req_format RQF_CONNECT; + extern struct req_msg_field RMF_GENERIC_DATA; extern struct req_msg_field RMF_PTLRPC_BODY; extern struct req_msg_field RMF_MDT_BODY; @@ -260,6 +264,7 @@ extern struct req_msg_field RMF_GETINFO_VAL; extern struct req_msg_field RMF_GETINFO_VALLEN; extern struct req_msg_field RMF_GETINFO_KEY; extern struct req_msg_field RMF_IDX_INFO; +extern struct req_msg_field RMF_CLOSE_DATA; /* * connection handle received in MDS_CONNECT request. @@ -275,6 +280,8 @@ extern struct req_msg_field RMF_LAYOUT_INTENT; extern struct req_msg_field RMF_MDT_MD; extern struct req_msg_field RMF_REC_REINT; extern struct req_msg_field RMF_EADATA; +extern struct req_msg_field RMF_EAVALS; +extern struct req_msg_field RMF_EAVALS_LENS; extern struct req_msg_field RMF_ACL; extern struct req_msg_field RMF_LOGCOOKIES; extern struct req_msg_field RMF_CAPA1; diff --git a/drivers/staging/lustre/lustre/include/lustre_sec.h b/drivers/staging/lustre/lustre/include/lustre_sec.h index 70b8b133a5c3..885247d28b3a 100644 --- a/drivers/staging/lustre/lustre/include/lustre_sec.h +++ b/drivers/staging/lustre/lustre/include/lustre_sec.h @@ -903,12 +903,6 @@ struct ptlrpc_bulk_sec_desc { /* - * lprocfs - */ -struct proc_dir_entry; -extern struct proc_dir_entry *sptlrpc_proc_root; - -/* * round size up to next power of 2, for slab allocation. * @size must be sane (can't overflow after round up) */ @@ -1067,7 +1061,18 @@ void sptlrpc_gc_add_ctx(struct ptlrpc_cli_ctx *ctx); /* misc */ const char * sec2target_str(struct ptlrpc_sec *sec); +/* + * lprocfs + */ +#ifdef LPROCFS +struct proc_dir_entry; +extern struct proc_dir_entry *sptlrpc_proc_root; int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev); +#else +#define sptlrpc_proc_root NULL +static inline int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev) +{ return 0; } +#endif /* * server side diff --git a/drivers/staging/lustre/lustre/include/md_object.h b/drivers/staging/lustre/lustre/include/md_object.h index daf93afe3feb..7b45b47b48f9 100644 --- a/drivers/staging/lustre/lustre/include/md_object.h +++ b/drivers/staging/lustre/lustre/include/md_object.h @@ -352,8 +352,8 @@ struct md_device_operations { int (*mdo_root_get)(const struct lu_env *env, struct md_device *m, struct lu_fid *f); - int (*mdo_maxsize_get)(const struct lu_env *env, struct md_device *m, - int *md_size, int *cookie_size); + int (*mdo_maxeasize_get)(const struct lu_env *env, struct md_device *m, + int *easize); int (*mdo_statfs)(const struct lu_env *env, struct md_device *m, struct obd_statfs *sfs); diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index d0aea15b7c39..c3470ce62cff 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -399,8 +399,8 @@ struct client_obd { /* mgc datastruct */ struct semaphore cl_mgc_sem; - struct vfsmount *cl_mgc_vfsmnt; - struct dentry *cl_mgc_configs_dir; + struct local_oid_storage *cl_mgc_los; + struct dt_object *cl_mgc_configs_dir; atomic_t cl_mgc_refcount; struct obd_export *cl_mgc_mgsexp; @@ -1022,6 +1022,7 @@ struct lu_context; #define IT_LAYOUT (1 << 10) #define IT_QUOTA_DQACQ (1 << 11) #define IT_QUOTA_CONN (1 << 12) +#define IT_SETXATTR (1 << 13) static inline int it_to_lock_mode(struct lookup_intent *it) { @@ -1031,6 +1032,10 @@ static inline int it_to_lock_mode(struct lookup_intent *it) else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP | IT_LAYOUT)) return LCK_CR; + else if (it->it_op & IT_GETXATTR) + return LCK_PR; + else if (it->it_op & IT_SETXATTR) + return LCK_PW; LASSERTF(0, "Invalid it_op: %d\n", it->it_op); return -EINVAL; @@ -1070,7 +1075,7 @@ struct md_op_data { struct obd_capa *op_capa2; /* Various operation flags. */ - __u32 op_bias; + enum mds_op_bias op_bias; /* Operation type */ __u32 op_opc; @@ -1084,6 +1089,10 @@ struct md_op_data { /* used to transfer info between the stacks of MD client * see enum op_cli_flags */ __u32 op_cli_flags; + + /* File object data version for HSM release, on client */ + __u64 op_data_version; + struct lustre_handle op_lease_handle; }; enum op_cli_flags { diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h index 9697e7faff2f..977bc231df9d 100644 --- a/drivers/staging/lustre/lustre/include/obd_support.h +++ b/drivers/staging/lustre/lustre/include/obd_support.h @@ -256,6 +256,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_OSD_SCRUB_FATAL 0x192 #define OBD_FAIL_OSD_FID_MAPPING 0x193 #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194 +#define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY 0x195 #define OBD_FAIL_OST 0x200 #define OBD_FAIL_OST_CONNECT_NET 0x201 @@ -416,6 +417,13 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG 0x903 #define OBD_FAIL_MGS_PAUSE_REQ 0x904 #define OBD_FAIL_MGS_PAUSE_TARGET_REG 0x905 +#define OBD_FAIL_MGS_CONNECT_NET 0x906 +#define OBD_FAIL_MGS_DISCONNECT_NET 0x907 +#define OBD_FAIL_MGS_SET_INFO_NET 0x908 +#define OBD_FAIL_MGS_EXCEPTION_NET 0x909 +#define OBD_FAIL_MGS_TARGET_REG_NET 0x90a +#define OBD_FAIL_MGS_TARGET_DEL_NET 0x90b +#define OBD_FAIL_MGS_CONFIG_READ_NET 0x90c #define OBD_FAIL_QUOTA_DQACQ_NET 0xA01 #define OBD_FAIL_QUOTA_EDQUOT 0xA02 @@ -457,6 +465,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_LOCK_STATE_WAIT_INTR 0x1402 #define OBD_FAIL_LOV_INIT 0x1403 #define OBD_FAIL_GLIMPSE_DELAY 0x1404 +#define OBD_FAIL_LLITE_XATTR_ENOMEM 0x1405 #define OBD_FAIL_FID_INDIR 0x1501 #define OBD_FAIL_FID_INLMA 0x1502 @@ -498,6 +507,8 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, extern atomic_t libcfs_kmemory; +extern void obd_update_maxusage(void); + #ifdef LPROCFS #define obd_memory_add(size) \ lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size)) @@ -516,7 +527,6 @@ extern atomic_t libcfs_kmemory; lprocfs_stats_collector(obd_memory, OBD_MEMORY_PAGES_STAT, \ LPROCFS_FIELDS_FLAGS_SUM) -extern void obd_update_maxusage(void); extern __u64 obd_memory_max(void); extern __u64 obd_pages_max(void); diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index e60c04d5393a..1c628e325750 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -1006,6 +1006,12 @@ again: cl_io_fini(env, io); if (unlikely(io->ci_need_restart)) goto again; + /* HSM import case: file is released, cannot be restored + * no need to fail except if restore registration failed + * with -ENODATA */ + if (result == -ENODATA && io->ci_restore_needed && + io->ci_result != -ENODATA) + result = 0; cl_env_put(env, &refcheck); return result; } diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c b/drivers/staging/lustre/lustre/lclient/lcommon_misc.c index 2b4dbeebcd5d..e04c2d37c249 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_misc.c @@ -140,7 +140,9 @@ int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock, rc = cl_io_init(env, io, CIT_MISC, io->ci_obj); if (rc) { - LASSERT(rc < 0); + /* Does not make sense to take GL for released layout */ + if (rc > 0) + rc = -ENOTSUPP; cl_env_put(env, &refcheck); return rc; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c index 39fcdacc51ed..c9aae132f98a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c @@ -95,20 +95,12 @@ ldlm_flocks_overlap(struct ldlm_lock *lock, struct ldlm_lock *new) lock->l_policy_data.l_flock.start)); } -static inline int ldlm_flock_blocking_link(struct ldlm_lock *req, - struct ldlm_lock *lock) +static inline void ldlm_flock_blocking_link(struct ldlm_lock *req, + struct ldlm_lock *lock) { - int rc = 0; - /* For server only */ if (req->l_export == NULL) - return 0; - - if (unlikely(req->l_export->exp_flock_hash == NULL)) { - rc = ldlm_init_flock_export(req->l_export); - if (rc) - goto error; - } + return; LASSERT(hlist_unhashed(&req->l_exp_flock_hash)); @@ -121,8 +113,6 @@ static inline int ldlm_flock_blocking_link(struct ldlm_lock *req, cfs_hash_add(req->l_export->exp_flock_hash, &req->l_policy_data.l_flock.owner, &req->l_exp_flock_hash); -error: - return rc; } static inline void ldlm_flock_blocking_unlink(struct ldlm_lock *req) @@ -250,7 +240,6 @@ ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq, int overlaps = 0; int splitted = 0; const struct ldlm_callback_suite null_cbs = { NULL }; - int rc; CDEBUG(D_DLMTRACE, "flags %#llx owner "LPU64" pid %u mode %u start " LPU64" end "LPU64"\n", *flags, @@ -328,12 +317,8 @@ reprocess: /* add lock to blocking list before deadlock * check to prevent race */ - rc = ldlm_flock_blocking_link(req, lock); - if (rc) { - ldlm_flock_destroy(req, mode, *flags); - *err = rc; - return LDLM_ITER_STOP; - } + ldlm_flock_blocking_link(req, lock); + if (ldlm_flock_deadlock(req, lock)) { ldlm_flock_blocking_unlink(req); ldlm_flock_destroy(req, mode, *flags); @@ -665,23 +650,20 @@ granted: /* fcntl(F_GETLK) request */ /* The old mode was saved in getlk->fl_type so that if the mode * in the lock changes we can decref the appropriate refcount.*/ - ldlm_flock_destroy(lock, flock_type(getlk), - LDLM_FL_WAIT_NOREPROC); + ldlm_flock_destroy(lock, getlk->fl_type, LDLM_FL_WAIT_NOREPROC); switch (lock->l_granted_mode) { case LCK_PR: - flock_set_type(getlk, F_RDLCK); + getlk->fl_type = F_RDLCK; break; case LCK_PW: - flock_set_type(getlk, F_WRLCK); + getlk->fl_type = F_WRLCK; break; default: - flock_set_type(getlk, F_UNLCK); + getlk->fl_type = F_UNLCK; } - flock_set_pid(getlk, (pid_t)lock->l_policy_data.l_flock.pid); - flock_set_start(getlk, - (loff_t)lock->l_policy_data.l_flock.start); - flock_set_end(getlk, - (loff_t)lock->l_policy_data.l_flock.end); + getlk->fl_pid = (pid_t)lock->l_policy_data.l_flock.pid; + getlk->fl_start = (loff_t)lock->l_policy_data.l_flock.start; + getlk->fl_end = (loff_t)lock->l_policy_data.l_flock.end; } else { __u64 noreproc = LDLM_FL_WAIT_NOREPROC; @@ -816,6 +798,9 @@ static cfs_hash_ops_t ldlm_export_flock_ops = { int ldlm_init_flock_export(struct obd_export *exp) { + if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_MDT_NAME) != 0) + return 0; + exp->exp_flock_hash = cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid), HASH_EXP_LOCK_CUR_BITS, diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 3900a69742fc..95eff79d5752 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -145,6 +145,8 @@ char *ldlm_it2str(int it) return "getxattr"; case IT_LAYOUT: return "layout"; + case IT_SETXATTR: + return "setxattr"; default: CERROR("Unknown intent %d\n", it); return "UNKNOWN"; @@ -1129,6 +1131,11 @@ static struct ldlm_lock *search_queue(struct list_head *queue, if (lock == old_lock) break; + /* Check if this lock can be matched. + * Used by LU-2919(exclusive open) for open lease lock */ + if (ldlm_is_excl(lock)) + continue; + /* llite sometimes wants to match locks that will be * canceled when their users drop, but we allow it to match * if it passes in CBPENDING and the lock still has users. diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index fde9bcd1d48d..3ed020eb89c0 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -49,12 +49,12 @@ #include "ldlm_internal.h" static int ldlm_num_threads; -CFS_MODULE_PARM(ldlm_num_threads, "i", int, 0444, - "number of DLM service threads to start"); +module_param(ldlm_num_threads, int, 0444); +MODULE_PARM_DESC(ldlm_num_threads, "number of DLM service threads to start"); static char *ldlm_cpts; -CFS_MODULE_PARM(ldlm_cpts, "s", charp, 0444, - "CPU partitions ldlm threads should run on"); +module_param(ldlm_cpts, charp, 0444); +MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on"); extern struct kmem_cache *ldlm_resource_slab; extern struct kmem_cache *ldlm_lock_slab; @@ -597,45 +597,6 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) rc = ldlm_handle_setinfo(req); ldlm_callback_reply(req, rc); return 0; - case OBD_LOG_CANCEL: /* remove this eventually - for 1.4.0 compat */ - CERROR("shouldn't be handling OBD_LOG_CANCEL on DLM thread\n"); - req_capsule_set(&req->rq_pill, &RQF_LOG_CANCEL); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_NET)) - return 0; - rc = llog_origin_handle_cancel(req); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_REP)) - return 0; - ldlm_callback_reply(req, rc); - return 0; - case LLOG_ORIGIN_HANDLE_CREATE: - req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET)) - return 0; - rc = llog_origin_handle_open(req); - ldlm_callback_reply(req, rc); - return 0; - case LLOG_ORIGIN_HANDLE_NEXT_BLOCK: - req_capsule_set(&req->rq_pill, - &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET)) - return 0; - rc = llog_origin_handle_next_block(req); - ldlm_callback_reply(req, rc); - return 0; - case LLOG_ORIGIN_HANDLE_READ_HEADER: - req_capsule_set(&req->rq_pill, - &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET)) - return 0; - rc = llog_origin_handle_read_header(req); - ldlm_callback_reply(req, rc); - return 0; - case LLOG_ORIGIN_HANDLE_CLOSE: - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET)) - return 0; - rc = llog_origin_handle_close(req); - ldlm_callback_reply(req, rc); - return 0; case OBD_QC_CALLBACK: req_capsule_set(&req->rq_pill, &RQF_QC_CALLBACK); if (OBD_FAIL_CHECK(OBD_FAIL_OBD_QC_CALLBACK_NET)) @@ -1003,6 +964,7 @@ static cfs_hash_ops_t ldlm_export_lock_ops = { int ldlm_init_export(struct obd_export *exp) { + int rc; exp->exp_lock_hash = cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid), HASH_EXP_LOCK_CUR_BITS, @@ -1016,7 +978,14 @@ int ldlm_init_export(struct obd_export *exp) if (!exp->exp_lock_hash) return -ENOMEM; + rc = ldlm_init_flock_export(exp); + if (rc) + GOTO(err, rc); + return 0; +err: + ldlm_destroy_export(exp); + return rc; } EXPORT_SYMBOL(ldlm_init_export); @@ -1043,11 +1012,9 @@ static int ldlm_setup(void) if (ldlm_state == NULL) return -ENOMEM; -#ifdef LPROCFS rc = ldlm_proc_setup(); if (rc != 0) GOTO(out, rc); -#endif memset(&conf, 0, sizeof(conf)); conf = (typeof(conf)) { diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index 0025ee6356da..6758646f575f 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -638,6 +638,7 @@ int ldlm_pool_setup(struct ldlm_pool *pl, int limit) } EXPORT_SYMBOL(ldlm_pool_setup); +#ifdef LPROCFS static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused) { int granted, grant_rate, cancel_rate, grant_step; @@ -822,6 +823,14 @@ static void ldlm_pool_proc_fini(struct ldlm_pool *pl) pl->pl_proc_dir = NULL; } } +#else /* !LPROCFS */ +static int ldlm_pool_proc_init(struct ldlm_pool *pl) +{ + return 0; +} + +static void ldlm_pool_proc_fini(struct ldlm_pool *pl) {} +#endif /* LPROCFS */ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns, int idx, ldlm_side_t client) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index dcc278403136..a8f8c1cace27 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -68,8 +68,8 @@ #include "ldlm_internal.h" int ldlm_enqueue_min = OBD_TIMEOUT_DEFAULT; -CFS_MODULE_PARM(ldlm_enqueue_min, "i", int, 0644, - "lock enqueue timeout minimum"); +module_param(ldlm_enqueue_min, int, 0644); +MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum"); /* in client side, whether the cached locks will be canceled before replay */ unsigned int ldlm_cancel_unused_locks_before_replay = 1; @@ -97,9 +97,6 @@ int ldlm_expired_completion_wait(void *data) if (lock->l_conn_export == NULL) { static cfs_time_t next_dump = 0, last_dump = 0; - if (ptlrpc_check_suspend()) - return 0; - LCONSOLE_WARN("lock timed out (enqueued at "CFS_TIME_T", " CFS_DURATION_T"s ago)\n", lock->l_last_activity, @@ -610,18 +607,12 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, lock->l_req_mode = newmode; } - if (memcmp(reply->lock_desc.l_resource.lr_name.name, - lock->l_resource->lr_name.name, - sizeof(struct ldlm_res_id))) { - CDEBUG(D_INFO, "remote intent success, locking " - "(%ld,%ld,%ld) instead of " - "(%ld,%ld,%ld)\n", - (long)reply->lock_desc.l_resource.lr_name.name[0], - (long)reply->lock_desc.l_resource.lr_name.name[1], - (long)reply->lock_desc.l_resource.lr_name.name[2], - (long)lock->l_resource->lr_name.name[0], - (long)lock->l_resource->lr_name.name[1], - (long)lock->l_resource->lr_name.name[2]); + if (!ldlm_res_eq(&reply->lock_desc.l_resource.lr_name, + &lock->l_resource->lr_name)) { + CDEBUG(D_INFO, "remote intent success, locking "DLDLMRES + " instead of "DLDLMRES"\n", + PLDLMRES(&reply->lock_desc.l_resource), + PLDLMRES(lock->l_resource)); rc = ldlm_lock_change_resource(ns, lock, &reply->lock_desc.l_resource.lr_name); @@ -910,7 +901,7 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp, lock->l_conn_export = exp; lock->l_export = NULL; lock->l_blocking_ast = einfo->ei_cb_bl; - lock->l_flags |= (*flags & LDLM_FL_NO_LRU); + lock->l_flags |= (*flags & (LDLM_FL_NO_LRU | LDLM_FL_EXCL)); /* lock not sent to server yet */ @@ -1333,7 +1324,7 @@ int ldlm_cli_cancel(struct lustre_handle *lockh, } rc = ldlm_cli_cancel_local(lock); - if (rc == LDLM_FL_LOCAL_ONLY) { + if (rc == LDLM_FL_LOCAL_ONLY || cancel_flags & LCF_LOCAL) { LDLM_LOCK_RELEASE(lock); return 0; } @@ -1912,7 +1903,8 @@ int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns, 0, flags | LCF_BL_AST, opaque); rc = ldlm_cli_cancel_list(&cancels, count, NULL, flags); if (rc != ELDLM_OK) - CERROR("ldlm_cli_cancel_unused_resource: %d\n", rc); + CERROR("canceling unused lock "DLDLMRES": rc = %d\n", + PLDLMRES(res), rc); LDLM_RESOURCE_DELREF(res); ldlm_resource_putref(res); @@ -1930,15 +1922,10 @@ static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs, struct cfs_hash_bd * { struct ldlm_resource *res = cfs_hash_object(hs, hnode); struct ldlm_cli_cancel_arg *lc = arg; - int rc; - rc = ldlm_cli_cancel_unused_resource(ldlm_res_to_ns(res), &res->lr_name, - NULL, LCK_MINMODE, - lc->lc_flags, lc->lc_opaque); - if (rc != 0) { - CERROR("ldlm_cli_cancel_unused ("LPU64"): %d\n", - res->lr_name.name[0], rc); - } + ldlm_cli_cancel_unused_resource(ldlm_res_to_ns(res), &res->lr_name, + NULL, LCK_MINMODE, + lc->lc_flags, lc->lc_opaque); /* must return 0 for hash iteration */ return 0; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 77e022bf8bcc..25e14e1b3659 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -762,16 +762,9 @@ static int ldlm_resource_complain(struct cfs_hash *hs, struct cfs_hash_bd *bd, struct ldlm_resource *res = cfs_hash_object(hs, hnode); lock_res(res); - CERROR("Namespace %s resource refcount nonzero " - "(%d) after lock cleanup; forcing " - "cleanup.\n", - ldlm_ns_name(ldlm_res_to_ns(res)), - atomic_read(&res->lr_refcount) - 1); - - CERROR("Resource: %p ("LPU64"/"LPU64"/"LPU64"/" - LPU64") (rc: %d)\n", res, - res->lr_name.name[0], res->lr_name.name[1], - res->lr_name.name[2], res->lr_name.name[3], + CERROR("%s: namespace resource "DLDLMRES + " (%p) refcount nonzero (%d) after lock cleanup; forcing cleanup.\n", + ldlm_ns_name(ldlm_res_to_ns(res)), PLDLMRES(res), res, atomic_read(&res->lr_refcount) - 1); ldlm_resource_dump(D_ERROR, res); @@ -1403,10 +1396,8 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res) if (!((libcfs_debug | D_ERROR) & level)) return; - CDEBUG(level, "--- Resource: %p ("LPU64"/"LPU64"/"LPU64"/"LPU64 - ") (rc: %d)\n", res, res->lr_name.name[0], res->lr_name.name[1], - res->lr_name.name[2], res->lr_name.name[3], - atomic_read(&res->lr_refcount)); + CDEBUG(level, "--- Resource: "DLDLMRES" (%p) refcount = %d\n", + PLDLMRES(res), res, atomic_read(&res->lr_refcount)); if (!list_empty(&res->lr_granted)) { CDEBUG(level, "Granted locks (in reverse order):\n"); diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 9b9c45116eee..f30c84f195aa 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -47,44 +47,44 @@ static char debug_file_name[1024]; unsigned int libcfs_subsystem_debug = ~0; -CFS_MODULE_PARM(libcfs_subsystem_debug, "i", int, 0644, - "Lustre kernel debug subsystem mask"); +module_param(libcfs_subsystem_debug, int, 0644); +MODULE_PARM_DESC(libcfs_subsystem_debug, "Lustre kernel debug subsystem mask"); EXPORT_SYMBOL(libcfs_subsystem_debug); unsigned int libcfs_debug = (D_CANTMASK | D_NETERROR | D_HA | D_CONFIG | D_IOCTL); -CFS_MODULE_PARM(libcfs_debug, "i", int, 0644, - "Lustre kernel debug mask"); +module_param(libcfs_debug, int, 0644); +MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask"); EXPORT_SYMBOL(libcfs_debug); unsigned int libcfs_debug_mb = 0; -CFS_MODULE_PARM(libcfs_debug_mb, "i", uint, 0644, - "Total debug buffer size."); +module_param(libcfs_debug_mb, uint, 0644); +MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size."); EXPORT_SYMBOL(libcfs_debug_mb); unsigned int libcfs_printk = D_CANTMASK; -CFS_MODULE_PARM(libcfs_printk, "i", uint, 0644, - "Lustre kernel debug console mask"); +module_param(libcfs_printk, uint, 0644); +MODULE_PARM_DESC(libcfs_printk, "Lustre kernel debug console mask"); EXPORT_SYMBOL(libcfs_printk); unsigned int libcfs_console_ratelimit = 1; -CFS_MODULE_PARM(libcfs_console_ratelimit, "i", uint, 0644, - "Lustre kernel debug console ratelimit (0 to disable)"); +module_param(libcfs_console_ratelimit, uint, 0644); +MODULE_PARM_DESC(libcfs_console_ratelimit, "Lustre kernel debug console ratelimit (0 to disable)"); EXPORT_SYMBOL(libcfs_console_ratelimit); unsigned int libcfs_console_max_delay; -CFS_MODULE_PARM(libcfs_console_max_delay, "l", uint, 0644, - "Lustre kernel debug console max delay (jiffies)"); +module_param(libcfs_console_max_delay, uint, 0644); +MODULE_PARM_DESC(libcfs_console_max_delay, "Lustre kernel debug console max delay (jiffies)"); EXPORT_SYMBOL(libcfs_console_max_delay); unsigned int libcfs_console_min_delay; -CFS_MODULE_PARM(libcfs_console_min_delay, "l", uint, 0644, - "Lustre kernel debug console min delay (jiffies)"); +module_param(libcfs_console_min_delay, uint, 0644); +MODULE_PARM_DESC(libcfs_console_min_delay, "Lustre kernel debug console min delay (jiffies)"); EXPORT_SYMBOL(libcfs_console_min_delay); unsigned int libcfs_console_backoff = CDEBUG_DEFAULT_BACKOFF; -CFS_MODULE_PARM(libcfs_console_backoff, "i", uint, 0644, - "Lustre kernel debug console backoff factor"); +module_param(libcfs_console_backoff, uint, 0644); +MODULE_PARM_DESC(libcfs_console_backoff, "Lustre kernel debug console backoff factor"); EXPORT_SYMBOL(libcfs_console_backoff); unsigned int libcfs_debug_binary = 1; @@ -103,8 +103,8 @@ unsigned int libcfs_watchdog_ratelimit = 300; EXPORT_SYMBOL(libcfs_watchdog_ratelimit); unsigned int libcfs_panic_on_lbug = 1; -CFS_MODULE_PARM(libcfs_panic_on_lbug, "i", uint, 0644, - "Lustre kernel panic on LBUG"); +module_param(libcfs_panic_on_lbug, uint, 0644); +MODULE_PARM_DESC(libcfs_panic_on_lbug, "Lustre kernel panic on LBUG"); EXPORT_SYMBOL(libcfs_panic_on_lbug); atomic_t libcfs_kmemory = ATOMIC_INIT(0); @@ -116,9 +116,9 @@ char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT; /* We need to pass a pointer here, but elsewhere this must be a const */ char *libcfs_debug_file_path; -CFS_MODULE_PARM(libcfs_debug_file_path, "s", charp, 0644, - "Path for dumping debug logs, " - "set 'NONE' to prevent log dumping"); +module_param(libcfs_debug_file_path, charp, 0644); +MODULE_PARM_DESC(libcfs_debug_file_path, + "Path for dumping debug logs, set 'NONE' to prevent log dumping"); int libcfs_panic_in_progress; diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index e3e0578b27f9..85cbe91c29b9 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -112,8 +112,8 @@ #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 static unsigned int warn_on_depth = 8; -CFS_MODULE_PARM(warn_on_depth, "i", uint, 0644, - "warning when hash depth is high."); +module_param(warn_on_depth, uint, 0644); +MODULE_PARM_DESC(warn_on_depth, "warning when hash depth is high."); #endif struct cfs_wi_sched *cfs_sched_rehash; diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c index 00ab8fdc1053..58bb256ee047 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c @@ -47,7 +47,8 @@ * >1 : specify number of partitions */ static int cpu_npartitions; -CFS_MODULE_PARM(cpu_npartitions, "i", int, 0444, "# of CPU partitions"); +module_param(cpu_npartitions, int, 0444); +MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions"); /** * modparam for setting CPU partitions patterns: @@ -61,7 +62,8 @@ CFS_MODULE_PARM(cpu_npartitions, "i", int, 0444, "# of CPU partitions"); * NB: If user specified cpu_pattern, cpu_npartitions will be ignored */ static char *cpu_pattern = ""; -CFS_MODULE_PARM(cpu_pattern, "s", charp, 0444, "CPU partitions pattern"); +module_param(cpu_pattern, charp, 0444); +MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern"); struct cfs_cpt_data { /* serialize hotplug etc */ diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c index 0bf8e5d87f1a..a2ef64c3403d 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c @@ -140,18 +140,6 @@ int cfs_capable(cfs_cap_t cap) return capable(cfs_cap_unpack(cap)); } -/* Check if task is running in 32-bit API mode, for the purpose of - * userspace binary interfaces. On 32-bit Linux this is (unfortunately) - * always true, even if the application is using LARGEFILE64 and 64-bit - * APIs, because Linux provides no way for the filesystem to know if it - * is called via 32-bit or 64-bit APIs. Other clients may vary. On - * 64-bit systems, this will only be true if the binary is calling a - * 32-bit system call. */ -int current_is_32bit(void) -{ - return is_compat_task(); -} - static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) { @@ -311,7 +299,6 @@ EXPORT_SYMBOL(cfs_cap_raised); EXPORT_SYMBOL(cfs_curproc_cap_pack); EXPORT_SYMBOL(cfs_curproc_cap_unpack); EXPORT_SYMBOL(cfs_capable); -EXPORT_SYMBOL(current_is_32bit); /* * Local variables: diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c index cc9829ffbdcb..c7bc7fcccb8e 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c @@ -46,13 +46,10 @@ #include <asm/kgdb.h> #endif -#define LINUX_WAITQ(w) ((wait_queue_t *) w) -#define LINUX_WAITQ_HEAD(w) ((wait_queue_head_t *) w) - void init_waitqueue_entry_current(wait_queue_t *link) { - init_waitqueue_entry(LINUX_WAITQ(link), current); + init_waitqueue_entry(link, current); } EXPORT_SYMBOL(init_waitqueue_entry_current); @@ -74,9 +71,9 @@ add_wait_queue_exclusive_head(wait_queue_head_t *waitq, wait_queue_t *link) { unsigned long flags; - spin_lock_irqsave(&LINUX_WAITQ_HEAD(waitq)->lock, flags); - __add_wait_queue_exclusive(LINUX_WAITQ_HEAD(waitq), LINUX_WAITQ(link)); - spin_unlock_irqrestore(&LINUX_WAITQ_HEAD(waitq)->lock, flags); + spin_lock_irqsave(&waitq->lock, flags); + __add_wait_queue_exclusive(waitq, link); + spin_unlock_irqrestore(&waitq->lock, flags); } EXPORT_SYMBOL(add_wait_queue_exclusive_head); diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c index fc6c97749487..e947b9128c58 100644 --- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c +++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c @@ -65,9 +65,7 @@ #include <asm/div64.h> #include "tracefile.h" -#ifdef CONFIG_SYSCTL static ctl_table_header_t *lnet_table_header = NULL; -#endif extern char lnet_upcall[1024]; /** * The path of debug log dump upcall script. @@ -371,7 +369,6 @@ static ctl_table_t lnet_table[] = { * to go via /proc for portability. */ { - INIT_CTL_NAME(PSDEV_DEBUG) .procname = "debug", .data = &libcfs_debug, .maxlen = sizeof(int), @@ -379,7 +376,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dobitmasks, }, { - INIT_CTL_NAME(PSDEV_SUBSYSTEM_DEBUG) .procname = "subsystem_debug", .data = &libcfs_subsystem_debug, .maxlen = sizeof(int), @@ -387,7 +383,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dobitmasks, }, { - INIT_CTL_NAME(PSDEV_PRINTK) .procname = "printk", .data = &libcfs_printk, .maxlen = sizeof(int), @@ -395,7 +390,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dobitmasks, }, { - INIT_CTL_NAME(PSDEV_CONSOLE_RATELIMIT) .procname = "console_ratelimit", .data = &libcfs_console_ratelimit, .maxlen = sizeof(int), @@ -403,21 +397,18 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dointvec }, { - INIT_CTL_NAME(PSDEV_CONSOLE_MAX_DELAY_CS) .procname = "console_max_delay_centisecs", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_console_max_delay_cs }, { - INIT_CTL_NAME(PSDEV_CONSOLE_MIN_DELAY_CS) .procname = "console_min_delay_centisecs", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_console_min_delay_cs }, { - INIT_CTL_NAME(PSDEV_CONSOLE_BACKOFF) .procname = "console_backoff", .maxlen = sizeof(int), .mode = 0644, @@ -425,7 +416,6 @@ static ctl_table_t lnet_table[] = { }, { - INIT_CTL_NAME(PSDEV_DEBUG_PATH) .procname = "debug_path", .data = libcfs_debug_file_path_arr, .maxlen = sizeof(libcfs_debug_file_path_arr), @@ -434,7 +424,6 @@ static ctl_table_t lnet_table[] = { }, { - INIT_CTL_NAME(PSDEV_CPT_TABLE) .procname = "cpu_partition_table", .maxlen = 128, .mode = 0444, @@ -442,7 +431,6 @@ static ctl_table_t lnet_table[] = { }, { - INIT_CTL_NAME(PSDEV_LNET_UPCALL) .procname = "upcall", .data = lnet_upcall, .maxlen = sizeof(lnet_upcall), @@ -450,7 +438,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dostring, }, { - INIT_CTL_NAME(PSDEV_LNET_DEBUG_LOG_UPCALL) .procname = "debug_log_upcall", .data = lnet_debug_log_upcall, .maxlen = sizeof(lnet_debug_log_upcall), @@ -458,54 +445,44 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dostring, }, { - INIT_CTL_NAME(PSDEV_LNET_MEMUSED) .procname = "lnet_memused", .data = (int *)&libcfs_kmemory.counter, .maxlen = sizeof(int), .mode = 0444, .proc_handler = &proc_dointvec, - INIT_STRATEGY(&sysctl_intvec) }, { - INIT_CTL_NAME(PSDEV_LNET_CATASTROPHE) .procname = "catastrophe", .data = &libcfs_catastrophe, .maxlen = sizeof(int), .mode = 0444, .proc_handler = &proc_dointvec, - INIT_STRATEGY(&sysctl_intvec) }, { - INIT_CTL_NAME(PSDEV_LNET_PANIC_ON_LBUG) .procname = "panic_on_lbug", .data = &libcfs_panic_on_lbug, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec, - INIT_STRATEGY(&sysctl_intvec) }, { - INIT_CTL_NAME(PSDEV_LNET_DUMP_KERNEL) .procname = "dump_kernel", .maxlen = 256, .mode = 0200, .proc_handler = &proc_dump_kernel, }, { - INIT_CTL_NAME(PSDEV_LNET_DAEMON_FILE) .procname = "daemon_file", .mode = 0644, .maxlen = 256, .proc_handler = &proc_daemon_file, }, { - INIT_CTL_NAME(PSDEV_LNET_DEBUG_MB) .procname = "debug_mb", .mode = 0644, .proc_handler = &proc_debug_mb, }, { - INIT_CTL_NAME(PSDEV_LNET_WATCHDOG_RATELIMIT) .procname = "watchdog_ratelimit", .data = &libcfs_watchdog_ratelimit, .maxlen = sizeof(int), @@ -514,7 +491,7 @@ static ctl_table_t lnet_table[] = { .extra1 = &min_watchdog_ratelimit, .extra2 = &max_watchdog_ratelimit, }, - { INIT_CTL_NAME(PSDEV_LNET_FORCE_LBUG) + { .procname = "force_lbug", .data = NULL, .maxlen = 0, @@ -522,7 +499,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &libcfs_force_lbug }, { - INIT_CTL_NAME(PSDEV_LNET_FAIL_LOC) .procname = "fail_loc", .data = &cfs_fail_loc, .maxlen = sizeof(cfs_fail_loc), @@ -530,7 +506,6 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_fail_loc }, { - INIT_CTL_NAME(PSDEV_LNET_FAIL_VAL) .procname = "fail_val", .data = &cfs_fail_val, .maxlen = sizeof(int), @@ -538,14 +513,11 @@ static ctl_table_t lnet_table[] = { .proc_handler = &proc_dointvec }, { - INIT_CTL_NAME(0) } }; -#ifdef CONFIG_SYSCTL static ctl_table_t top_table[] = { { - INIT_CTL_NAME(CTL_LNET) .procname = "lnet", .mode = 0555, .data = NULL, @@ -553,26 +525,20 @@ static ctl_table_t top_table[] = { .child = lnet_table, }, { - INIT_CTL_NAME(0) } }; -#endif int insert_proc(void) { -#ifdef CONFIG_SYSCTL if (lnet_table_header == NULL) lnet_table_header = register_sysctl_table(top_table); -#endif return 0; } void remove_proc(void) { -#ifdef CONFIG_SYSCTL if (lnet_table_header != NULL) unregister_sysctl_table(lnet_table_header); lnet_table_header = NULL; -#endif } diff --git a/drivers/staging/lustre/lustre/libcfs/lwt.c b/drivers/staging/lustre/lustre/libcfs/lwt.c deleted file mode 100644 index b631f7dde8e7..000000000000 --- a/drivers/staging/lustre/lustre/libcfs/lwt.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/libcfs/lwt.c - * - * Author: Eric Barton <eeb@clusterfs.com> - */ - -#define DEBUG_SUBSYSTEM S_LNET - -#include <linux/libcfs/libcfs.h> - -#if LWT_SUPPORT - -#if !KLWT_SUPPORT -int lwt_enabled; -lwt_cpu_t lwt_cpus[NR_CPUS]; -#endif - -int lwt_pages_per_cpu; - -/* NB only root is allowed to retrieve LWT info; it's an open door into the - * kernel... */ - -int -lwt_lookup_string (int *size, char *knl_ptr, - char *user_ptr, int user_size) -{ - int maxsize = 128; - - /* knl_ptr was retrieved from an LWT snapshot and the caller wants to - * turn it into a string. NB we can crash with an access violation - * trying to determine the string length, so we're trusting our - * caller... */ - - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) - return (-EPERM); - - if (user_size > 0 && - maxsize > user_size) - maxsize = user_size; - - *size = strnlen (knl_ptr, maxsize - 1) + 1; - - if (user_ptr != NULL) { - if (user_size < 4) - return (-EINVAL); - - if (copy_to_user (user_ptr, knl_ptr, *size)) - return (-EFAULT); - - /* Did I truncate the string? */ - if (knl_ptr[*size - 1] != 0) - copy_to_user (user_ptr + *size - 4, "...", 4); - } - - return (0); -} - -int -lwt_control (int enable, int clear) -{ - lwt_page_t *p; - int i; - int j; - - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) - return (-EPERM); - - if (!enable) { - LWT_EVENT(0,0,0,0); - lwt_enabled = 0; - mb(); - /* give people some time to stop adding traces */ - schedule_timeout(10); - } - - for (i = 0; i < num_online_cpus(); i++) { - p = lwt_cpus[i].lwtc_current_page; - - if (p == NULL) - return (-ENODATA); - - if (!clear) - continue; - - for (j = 0; j < lwt_pages_per_cpu; j++) { - memset (p->lwtp_events, 0, PAGE_CACHE_SIZE); - - p = list_entry (p->lwtp_list.next, - lwt_page_t, lwtp_list); - } - } - - if (enable) { - lwt_enabled = 1; - mb(); - LWT_EVENT(0,0,0,0); - } - - return (0); -} - -int -lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size, - void *user_ptr, int user_size) -{ - const int events_per_page = PAGE_CACHE_SIZE / sizeof(lwt_event_t); - const int bytes_per_page = events_per_page * sizeof(lwt_event_t); - lwt_page_t *p; - int i; - int j; - - if (!cfs_capable(CFS_CAP_SYS_ADMIN)) - return (-EPERM); - - *ncpu = num_online_cpus(); - *total_size = num_online_cpus() * lwt_pages_per_cpu * - bytes_per_page; - *now = get_cycles(); - - if (user_ptr == NULL) - return (0); - - for (i = 0; i < num_online_cpus(); i++) { - p = lwt_cpus[i].lwtc_current_page; - - if (p == NULL) - return (-ENODATA); - - for (j = 0; j < lwt_pages_per_cpu; j++) { - if (copy_to_user(user_ptr, p->lwtp_events, - bytes_per_page)) - return (-EFAULT); - - user_ptr = ((char *)user_ptr) + bytes_per_page; - p = list_entry(p->lwtp_list.next, - lwt_page_t, lwtp_list); - } - } - - return (0); -} - -int -lwt_init () -{ - int i; - int j; - - for (i = 0; i < num_online_cpus(); i++) - if (lwt_cpus[i].lwtc_current_page != NULL) - return (-EALREADY); - - LASSERT (!lwt_enabled); - - /* NULL pointers, zero scalars */ - memset (lwt_cpus, 0, sizeof (lwt_cpus)); - lwt_pages_per_cpu = - LWT_MEMORY / (num_online_cpus() * PAGE_CACHE_SIZE); - - for (i = 0; i < num_online_cpus(); i++) - for (j = 0; j < lwt_pages_per_cpu; j++) { - struct page *page = alloc_page (GFP_KERNEL); - lwt_page_t *lwtp; - - if (page == NULL) { - CERROR ("Can't allocate page\n"); - lwt_fini (); - return (-ENOMEM); - } - - LIBCFS_ALLOC(lwtp, sizeof (*lwtp)); - if (lwtp == NULL) { - CERROR ("Can't allocate lwtp\n"); - __free_page(page); - lwt_fini (); - return (-ENOMEM); - } - - lwtp->lwtp_page = page; - lwtp->lwtp_events = page_address(page); - memset (lwtp->lwtp_events, 0, PAGE_CACHE_SIZE); - - if (j == 0) { - INIT_LIST_HEAD (&lwtp->lwtp_list); - lwt_cpus[i].lwtc_current_page = lwtp; - } else { - list_add (&lwtp->lwtp_list, - &lwt_cpus[i].lwtc_current_page->lwtp_list); - } - } - - lwt_enabled = 1; - mb(); - - LWT_EVENT(0,0,0,0); - - return (0); -} - -void -lwt_fini () -{ - int i; - - lwt_control(0, 0); - - for (i = 0; i < num_online_cpus(); i++) - while (lwt_cpus[i].lwtc_current_page != NULL) { - lwt_page_t *lwtp = lwt_cpus[i].lwtc_current_page; - - if (list_empty (&lwtp->lwtp_list)) { - lwt_cpus[i].lwtc_current_page = NULL; - } else { - lwt_cpus[i].lwtc_current_page = - list_entry (lwtp->lwtp_list.next, - lwt_page_t, lwtp_list); - - list_del (&lwtp->lwtp_list); - } - - __free_page (lwtp->lwtp_page); - LIBCFS_FREE (lwtp, sizeof (*lwtp)); - } -} - -EXPORT_SYMBOL(lwt_enabled); -EXPORT_SYMBOL(lwt_cpus); - -EXPORT_SYMBOL(lwt_init); -EXPORT_SYMBOL(lwt_fini); -EXPORT_SYMBOL(lwt_lookup_string); -EXPORT_SYMBOL(lwt_control); -EXPORT_SYMBOL(lwt_snapshot); -#endif diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c index f3108c7f818e..463b3e17e282 100644 --- a/drivers/staging/lustre/lustre/libcfs/module.c +++ b/drivers/staging/lustre/lustre/libcfs/module.c @@ -235,41 +235,6 @@ static int libcfs_ioctl_int(struct cfs_psdev_file *pfile,unsigned long cmd, return -EINVAL; libcfs_debug_mark_buffer(data->ioc_inlbuf1); return 0; -#if LWT_SUPPORT - case IOC_LIBCFS_LWT_CONTROL: - err = lwt_control ((data->ioc_flags & 1) != 0, - (data->ioc_flags & 2) != 0); - break; - - case IOC_LIBCFS_LWT_SNAPSHOT: { - cfs_cycles_t now; - int ncpu; - int total_size; - - err = lwt_snapshot (&now, &ncpu, &total_size, - data->ioc_pbuf1, data->ioc_plen1); - data->ioc_u64[0] = now; - data->ioc_u32[0] = ncpu; - data->ioc_u32[1] = total_size; - - /* Hedge against broken user/kernel typedefs (e.g. cycles_t) */ - data->ioc_u32[2] = sizeof(lwt_event_t); - data->ioc_u32[3] = offsetof(lwt_event_t, lwte_where); - - if (err == 0 && - libcfs_ioctl_popdata(arg, data, sizeof (*data))) - err = -EFAULT; - break; - } - - case IOC_LIBCFS_LWT_LOOKUP_STRING: - err = lwt_lookup_string (&data->ioc_count, data->ioc_pbuf1, - data->ioc_pbuf2, data->ioc_plen2); - if (err == 0 && - libcfs_ioctl_popdata(arg, data, sizeof (*data))) - err = -EFAULT; - break; -#endif case IOC_LIBCFS_MEMHOG: if (pfile->private_data == NULL) { err = -EINVAL; @@ -392,17 +357,10 @@ static int init_libcfs_module(void) if (rc != 0) goto cleanup_debug; -#if LWT_SUPPORT - rc = lwt_init(); - if (rc != 0) { - CERROR("lwt_init: error %d\n", rc); - goto cleanup_debug; - } -#endif rc = misc_register(&libcfs_dev); if (rc) { CERROR("misc_register: error %d\n", rc); - goto cleanup_lwt; + goto cleanup_cpu; } rc = cfs_wi_startup(); @@ -441,10 +399,8 @@ static int init_libcfs_module(void) cfs_wi_shutdown(); cleanup_deregister: misc_deregister(&libcfs_dev); - cleanup_lwt: -#if LWT_SUPPORT - lwt_fini(); -#endif +cleanup_cpu: + cfs_cpu_fini(); cleanup_debug: libcfs_debug_cleanup(); return rc; @@ -471,9 +427,6 @@ static void exit_libcfs_module(void) if (rc) CERROR("misc_deregister error %d\n", rc); -#if LWT_SUPPORT - lwt_fini(); -#endif cfs_cpu_fini(); if (atomic_read(&libcfs_kmemory) != 0) diff --git a/drivers/staging/lustre/lustre/libcfs/nidstrings.c b/drivers/staging/lustre/lustre/libcfs/nidstrings.c index 99c9e9d2493f..732ae5540bf4 100644 --- a/drivers/staging/lustre/lustre/libcfs/nidstrings.c +++ b/drivers/staging/lustre/lustre/libcfs/nidstrings.c @@ -56,11 +56,11 @@ */ static char libcfs_nidstrings[LNET_NIDSTR_COUNT][LNET_NIDSTR_SIZE]; -static int libcfs_nidstring_idx = 0; +static int libcfs_nidstring_idx; static spinlock_t libcfs_nidstring_lock; -void libcfs_init_nidstrings (void) +void libcfs_init_nidstrings(void) { spin_lock_init(&libcfs_nidstring_lock); } @@ -69,7 +69,7 @@ void libcfs_init_nidstrings (void) # define NIDSTR_UNLOCK(f) spin_unlock_irqrestore(&libcfs_nidstring_lock, f) static char * -libcfs_next_nidstring (void) +libcfs_next_nidstring(void) { char *str; unsigned long flags; @@ -326,6 +326,7 @@ libcfs_isknown_lnd(int type) { return libcfs_lnd2netstrfns(type) != NULL; } +EXPORT_SYMBOL(libcfs_isknown_lnd); char * libcfs_lnd2modname(int lnd) @@ -334,6 +335,7 @@ libcfs_lnd2modname(int lnd) return (nf == NULL) ? NULL : nf->nf_modname; } +EXPORT_SYMBOL(libcfs_lnd2modname); char * libcfs_lnd2str(int lnd) @@ -348,6 +350,7 @@ libcfs_lnd2str(int lnd) snprintf(str, LNET_NIDSTR_SIZE, "?%u?", lnd); return str; } +EXPORT_SYMBOL(libcfs_lnd2str); int libcfs_str2lnd(const char *str) @@ -359,6 +362,7 @@ libcfs_str2lnd(const char *str) return -1; } +EXPORT_SYMBOL(libcfs_str2lnd); char * libcfs_net2str(__u32 net) @@ -377,6 +381,7 @@ libcfs_net2str(__u32 net) return str; } +EXPORT_SYMBOL(libcfs_net2str); char * libcfs_nid2str(lnet_nid_t nid) @@ -410,6 +415,7 @@ libcfs_nid2str(lnet_nid_t nid) return str; } +EXPORT_SYMBOL(libcfs_nid2str); static struct netstrfns * libcfs_str2net_internal(const char *str, __u32 *net) @@ -458,6 +464,7 @@ libcfs_str2net(const char *str) return LNET_NIDNET(LNET_NID_ANY); } +EXPORT_SYMBOL(libcfs_str2net); lnet_nid_t libcfs_str2nid(const char *str) @@ -475,7 +482,7 @@ libcfs_str2nid(const char *str) sep = str + strlen(str); net = LNET_MKNET(SOCKLND, 0); nf = libcfs_lnd2netstrfns(SOCKLND); - LASSERT (nf != NULL); + LASSERT(nf != NULL); } if (!nf->nf_str2addr(str, (int)(sep - str), &addr)) @@ -483,6 +490,7 @@ libcfs_str2nid(const char *str) return LNET_MKNID(net, addr); } +EXPORT_SYMBOL(libcfs_str2nid); char * libcfs_id2str(lnet_process_id_t id) @@ -500,6 +508,7 @@ libcfs_id2str(lnet_process_id_t id) (id.pid & ~LNET_PID_USERFLAG), libcfs_nid2str(id.nid)); return str; } +EXPORT_SYMBOL(libcfs_id2str); int libcfs_str2anynid(lnet_nid_t *nidp, const char *str) @@ -512,6 +521,7 @@ libcfs_str2anynid(lnet_nid_t *nidp, const char *str) *nidp = libcfs_str2nid(str); return *nidp != LNET_NID_ANY; } +EXPORT_SYMBOL(libcfs_str2anynid); /** * Nid range list syntax. @@ -765,6 +775,7 @@ cfs_free_nidlist(struct list_head *list) LIBCFS_FREE(nr, sizeof(struct nidrange)); } } +EXPORT_SYMBOL(cfs_free_nidlist); /** * Parses nid range list. @@ -803,6 +814,7 @@ cfs_parse_nidlist(char *str, int len, struct list_head *nidlist) } return 1; } +EXPORT_SYMBOL(cfs_parse_nidlist); /* * Nf_match_addr method for networks using numeric addresses @@ -848,18 +860,4 @@ int cfs_match_nid(lnet_nid_t nid, struct list_head *nidlist) } return 0; } - - -EXPORT_SYMBOL(libcfs_isknown_lnd); -EXPORT_SYMBOL(libcfs_lnd2modname); -EXPORT_SYMBOL(libcfs_lnd2str); -EXPORT_SYMBOL(libcfs_str2lnd); -EXPORT_SYMBOL(libcfs_net2str); -EXPORT_SYMBOL(libcfs_nid2str); -EXPORT_SYMBOL(libcfs_str2net); -EXPORT_SYMBOL(libcfs_str2nid); -EXPORT_SYMBOL(libcfs_id2str); -EXPORT_SYMBOL(libcfs_str2anynid); -EXPORT_SYMBOL(cfs_free_nidlist); -EXPORT_SYMBOL(cfs_parse_nidlist); EXPORT_SYMBOL(cfs_match_nid); diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c index f71a3cc63ad8..54290ce6bb43 100644 --- a/drivers/staging/lustre/lustre/libcfs/tracefile.c +++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c @@ -678,6 +678,7 @@ int cfs_tracefile_dump_all_pages(char *filename) struct file *filp; struct cfs_trace_page *tage; struct cfs_trace_page *tmp; + char *buf; int rc; DECL_MMSPACE; @@ -708,8 +709,11 @@ int cfs_tracefile_dump_all_pages(char *filename) __LASSERT_TAGE_INVARIANT(tage); - rc = filp_write(filp, page_address(tage->page), - tage->used, filp_poff(filp)); + buf = kmap(tage->page); + rc = vfs_write(filp, (__force const char __user *)buf, + tage->used, &filp->f_pos); + kunmap(tage->page); + if (rc != (int)tage->used) { printk(KERN_WARNING "wanted to write %u but wrote " "%d\n", tage->used, rc); @@ -721,7 +725,7 @@ int cfs_tracefile_dump_all_pages(char *filename) cfs_tage_free(tage); } MMSPACE_CLOSE; - rc = filp_fsync(filp); + rc = vfs_fsync(filp, 1); if (rc) printk(KERN_ERR "sync returns %d\n", rc); close: @@ -971,6 +975,7 @@ static int tracefiled(void *arg) struct cfs_trace_page *tage; struct cfs_trace_page *tmp; struct file *filp; + char *buf; int last_loop = 0; int rc; @@ -1020,11 +1025,14 @@ static int tracefiled(void *arg) if (f_pos >= (off_t)cfs_tracefile_size) f_pos = 0; - else if (f_pos > (off_t)filp_size(filp)) - f_pos = filp_size(filp); + else if (f_pos > i_size_read(filp->f_dentry->d_inode)) + f_pos = i_size_read(filp->f_dentry->d_inode); + + buf = kmap(tage->page); + rc = vfs_write(filp, (__force const char __user *)buf, + tage->used, &f_pos); + kunmap(tage->page); - rc = filp_write(filp, page_address(tage->page), - tage->used, &f_pos); if (rc != (int)tage->used) { printk(KERN_WARNING "wanted to write %u " "but wrote %d\n", tage->used, rc); diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile index f493e0740004..c76f3cfedab0 100644 --- a/drivers/staging/lustre/lustre/llite/Makefile +++ b/drivers/staging/lustre/lustre/llite/Makefile @@ -1,12 +1,13 @@ obj-$(CONFIG_LUSTRE_FS) += lustre.o obj-$(CONFIG_LUSTRE_LLITE_LLOOP) += llite_lloop.o lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \ - rw.o lproc_llite.o namei.o symlink.o llite_mmap.o \ - xattr.o remote_perm.o llite_rmtacl.o llite_capa.o \ + rw.o namei.o symlink.o llite_mmap.o \ + xattr.o xattr_cache.o remote_perm.o llite_rmtacl.o llite_capa.o \ rw26.o super25.o statahead.o \ ../lclient/glimpse.o ../lclient/lcommon_cl.o ../lclient/lcommon_misc.o \ vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o +lustre-$(CONFIG_PROC_FS) += lproc_llite.o llite_lloop-y := lloop.o diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index e7629be39739..cbd663ed030c 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -404,7 +404,6 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, struct inode *inode = de->d_inode; struct ll_inode_info *lli = ll_i2info(inode); struct obd_client_handle **och_p; - __u64 *och_usecount; __u64 ibits; /* @@ -418,37 +417,32 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, */ - if (it->it_flags & FMODE_WRITE) { + if (it->it_flags & FMODE_WRITE) och_p = &lli->lli_mds_write_och; - och_usecount = &lli->lli_open_fd_write_count; - } else if (it->it_flags & FMODE_EXEC) { + else if (it->it_flags & FMODE_EXEC) och_p = &lli->lli_mds_exec_och; - och_usecount = &lli->lli_open_fd_exec_count; - } else { + else och_p = &lli->lli_mds_read_och; - och_usecount = &lli->lli_open_fd_read_count; - } + /* Check for the proper lock. */ ibits = MDS_INODELOCK_LOOKUP; if (!ll_have_md_lock(inode, &ibits, LCK_MINMODE)) goto do_lock; mutex_lock(&lli->lli_och_mutex); if (*och_p) { /* Everything is open already, do nothing */ - /*(*och_usecount)++; Do not let them steal our open - handle from under us */ - SET_BUT_UNUSED(och_usecount); - /* XXX The code above was my original idea, but in case - we have the handle, but we cannot use it due to later - checks (e.g. O_CREAT|O_EXCL flags set), nobody - would decrement counter increased here. So we just - hope the lock won't be invalidated in between. But - if it would be, we'll reopen the open request to - MDS later during file open path */ + /* Originally it was idea to do not let them steal our + * open handle from under us by (*och_usecount)++ here. + * But in case we have the handle, but we cannot use it + * due to later checks (e.g. O_CREAT|O_EXCL flags set), + * nobody would decrement counter increased here. So we + * just hope the lock won't be invalidated in between. + * But if it would be, we'll reopen the open request to + * MDS later during file open path. + */ mutex_unlock(&lli->lli_och_mutex); return 1; - } else { - mutex_unlock(&lli->lli_och_mutex); } + mutex_unlock(&lli->lli_och_mutex); } if (it->it_op == IT_GETATTR) { diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 1f079034bd8f..22d0acc95bc5 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1809,8 +1809,28 @@ out_rmdir: return -EFAULT; } - rc = obd_iocontrol(cmd, ll_i2mdexp(inode), totalsize, - hur, NULL); + if (hur->hur_request.hr_action == HUA_RELEASE) { + const struct lu_fid *fid; + struct inode *f; + int i; + + for (i = 0; i < hur->hur_request.hr_itemcount; i++) { + fid = &hur->hur_user_item[i].hui_fid; + f = search_inode_for_lustre(inode->i_sb, fid); + if (IS_ERR(f)) { + rc = PTR_ERR(f); + break; + } + + rc = ll_hsm_release(f); + iput(f); + if (rc != 0) + break; + } + } else { + rc = obd_iocontrol(cmd, ll_i2mdexp(inode), totalsize, + hur, NULL); + } OBD_FREE_LARGE(hur, totalsize); diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index fb85a58db058..c12821aedc2f 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -115,7 +115,8 @@ out: static int ll_close_inode_openhandle(struct obd_export *md_exp, struct inode *inode, - struct obd_client_handle *och) + struct obd_client_handle *och, + const __u64 *data_version) { struct obd_export *exp = ll_i2mdexp(inode); struct md_op_data *op_data; @@ -139,6 +140,13 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, GOTO(out, rc = -ENOMEM); // XXX We leak openhandle and request here. ll_prepare_close(inode, op_data, och); + if (data_version != NULL) { + /* Pass in data_version implies release. */ + op_data->op_bias |= MDS_HSM_RELEASE; + op_data->op_data_version = *data_version; + op_data->op_lease_handle = och->och_lease_handle; + op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS; + } epoch_close = (op_data->op_flags & MF_EPOCH_CLOSE); rc = md_close(md_exp, op_data, och->och_mod, &req); if (rc == -EAGAIN) { @@ -167,14 +175,20 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp, spin_unlock(&lli->lli_lock); } - ll_finish_md_op_data(op_data); - if (rc == 0) { rc = ll_objects_destroy(req, inode); if (rc) CERROR("inode %lu ll_objects destroy: rc = %d\n", inode->i_ino, rc); } + if (rc == 0 && op_data->op_bias & MDS_HSM_RELEASE) { + struct mdt_body *body; + body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); + if (!(body->valid & OBD_MD_FLRELEASED)) + rc = -EBUSY; + } + + ll_finish_md_op_data(op_data); out: if (exp_connect_som(exp) && !epoch_close && @@ -224,7 +238,7 @@ int ll_md_real_close(struct inode *inode, int flags) if (och) { /* There might be a race and somebody have freed this och already */ rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, - inode, och); + inode, och, NULL); } return rc; @@ -241,6 +255,24 @@ int ll_md_close(struct obd_export *md_exp, struct inode *inode, if (unlikely(fd->fd_flags & LL_FILE_GROUP_LOCKED)) ll_put_grouplock(inode, file, fd->fd_grouplock.cg_gid); + if (fd->fd_lease_och != NULL) { + bool lease_broken; + + /* Usually the lease is not released when the + * application crashed, we need to release here. */ + rc = ll_lease_close(fd->fd_lease_och, inode, &lease_broken); + CDEBUG(rc ? D_ERROR : D_INODE, "Clean up lease "DFID" %d/%d\n", + PFID(&lli->lli_fid), rc, lease_broken); + + fd->fd_lease_och = NULL; + } + + if (fd->fd_och != NULL) { + rc = ll_close_inode_openhandle(md_exp, inode, fd->fd_och, NULL); + fd->fd_och = NULL; + GOTO(out, rc); + } + /* Let's see if we have good enough OPEN lock on the file and if we can skip talking to MDS */ if (file->f_dentry->d_inode) { /* Can this ever be false? */ @@ -277,6 +309,7 @@ int ll_md_close(struct obd_export *md_exp, struct inode *inode, file, file->f_dentry, file->f_dentry->d_name.name); } +out: LUSTRE_FPRIVATE(file) = NULL; ll_file_data_put(fd); ll_capa_close(inode); @@ -431,22 +464,18 @@ void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch) } } -static int ll_och_fill(struct obd_export *md_exp, struct ll_inode_info *lli, - struct lookup_intent *it, struct obd_client_handle *och) +static int ll_och_fill(struct obd_export *md_exp, struct lookup_intent *it, + struct obd_client_handle *och) { struct ptlrpc_request *req = it->d.lustre.it_data; struct mdt_body *body; - LASSERT(och); - body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); - LASSERT(body != NULL); /* reply already checked out */ - - memcpy(&och->och_fh, &body->handle, sizeof(body->handle)); + och->och_fh = body->handle; + och->och_fid = body->fid1; + och->och_lease_handle.cookie = it->d.lustre.it_lock_handle; och->och_magic = OBD_CLIENT_HANDLE_MAGIC; - och->och_fid = lli->lli_fid; och->och_flags = it->it_flags; - ll_ioepoch_open(lli, body->ioepoch); return md_set_open_replay_data(md_exp, och, req); } @@ -466,20 +495,17 @@ int ll_local_open(struct file *file, struct lookup_intent *it, struct mdt_body *body; int rc; - rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, lli, it, och); - if (rc) + rc = ll_och_fill(ll_i2sbi(inode)->ll_md_exp, it, och); + if (rc != 0) return rc; body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); - if ((it->it_flags & FMODE_WRITE) && - (body->valid & OBD_MD_FLSIZE)) - CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID"\n", - lli->lli_ioepoch, PFID(&lli->lli_fid)); + ll_ioepoch_open(lli, body->ioepoch); } LUSTRE_FPRIVATE(file) = fd; ll_readahead_init(inode, &fd->fd_ras); - fd->fd_omode = it->it_flags; + fd->fd_omode = it->it_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC); return 0; } @@ -681,6 +707,198 @@ out_openerr: return rc; } +static int ll_md_blocking_lease_ast(struct ldlm_lock *lock, + struct ldlm_lock_desc *desc, void *data, int flag) +{ + int rc; + struct lustre_handle lockh; + + switch (flag) { + case LDLM_CB_BLOCKING: + ldlm_lock2handle(lock, &lockh); + rc = ldlm_cli_cancel(&lockh, LCF_ASYNC); + if (rc < 0) { + CDEBUG(D_INODE, "ldlm_cli_cancel: %d\n", rc); + return rc; + } + break; + case LDLM_CB_CANCELING: + /* do nothing */ + break; + } + return 0; +} + +/** + * Acquire a lease and open the file. + */ +struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file, + fmode_t fmode, __u64 open_flags) +{ + struct lookup_intent it = { .it_op = IT_OPEN }; + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct md_op_data *op_data; + struct ptlrpc_request *req; + struct lustre_handle old_handle = { 0 }; + struct obd_client_handle *och = NULL; + int rc; + int rc2; + + if (fmode != FMODE_WRITE && fmode != FMODE_READ) + return ERR_PTR(-EINVAL); + + if (file != NULL) { + struct ll_inode_info *lli = ll_i2info(inode); + struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + struct obd_client_handle **och_p; + __u64 *och_usecount; + + if (!(fmode & file->f_mode) || (file->f_mode & FMODE_EXEC)) + return ERR_PTR(-EPERM); + + /* Get the openhandle of the file */ + rc = -EBUSY; + mutex_lock(&lli->lli_och_mutex); + if (fd->fd_lease_och != NULL) { + mutex_unlock(&lli->lli_och_mutex); + return ERR_PTR(rc); + } + + if (fd->fd_och == NULL) { + if (file->f_mode & FMODE_WRITE) { + LASSERT(lli->lli_mds_write_och != NULL); + och_p = &lli->lli_mds_write_och; + och_usecount = &lli->lli_open_fd_write_count; + } else { + LASSERT(lli->lli_mds_read_och != NULL); + och_p = &lli->lli_mds_read_och; + och_usecount = &lli->lli_open_fd_read_count; + } + if (*och_usecount == 1) { + fd->fd_och = *och_p; + *och_p = NULL; + *och_usecount = 0; + rc = 0; + } + } + mutex_unlock(&lli->lli_och_mutex); + if (rc < 0) /* more than 1 opener */ + return ERR_PTR(rc); + + LASSERT(fd->fd_och != NULL); + old_handle = fd->fd_och->och_fh; + } + + OBD_ALLOC_PTR(och); + if (och == NULL) + return ERR_PTR(-ENOMEM); + + op_data = ll_prep_md_op_data(NULL, inode, inode, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) + GOTO(out, rc = PTR_ERR(op_data)); + + /* To tell the MDT this openhandle is from the same owner */ + op_data->op_handle = old_handle; + + it.it_flags = fmode | open_flags; + it.it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID | MDS_OPEN_LEASE; + rc = md_intent_lock(sbi->ll_md_exp, op_data, NULL, 0, &it, 0, &req, + ll_md_blocking_lease_ast, + /* LDLM_FL_NO_LRU: To not put the lease lock into LRU list, otherwise + * it can be cancelled which may mislead applications that the lease is + * broken; + * LDLM_FL_EXCL: Set this flag so that it won't be matched by normal + * open in ll_md_blocking_ast(). Otherwise as ll_md_blocking_lease_ast + * doesn't deal with openhandle, so normal openhandle will be leaked. */ + LDLM_FL_NO_LRU | LDLM_FL_EXCL); + ll_finish_md_op_data(op_data); + if (req != NULL) { + ptlrpc_req_finished(req); + it_clear_disposition(&it, DISP_ENQ_COMPLETE); + } + if (rc < 0) + GOTO(out_release_it, rc); + + if (it_disposition(&it, DISP_LOOKUP_NEG)) + GOTO(out_release_it, rc = -ENOENT); + + rc = it_open_error(DISP_OPEN_OPEN, &it); + if (rc) + GOTO(out_release_it, rc); + + LASSERT(it_disposition(&it, DISP_ENQ_OPEN_REF)); + ll_och_fill(sbi->ll_md_exp, &it, och); + + if (!it_disposition(&it, DISP_OPEN_LEASE)) /* old server? */ + GOTO(out_close, rc = -EOPNOTSUPP); + + /* already get lease, handle lease lock */ + ll_set_lock_data(sbi->ll_md_exp, inode, &it, NULL); + if (it.d.lustre.it_lock_mode == 0 || + it.d.lustre.it_lock_bits != MDS_INODELOCK_OPEN) { + /* open lock must return for lease */ + CERROR(DFID "lease granted but no open lock, %d/%llu.\n", + PFID(ll_inode2fid(inode)), it.d.lustre.it_lock_mode, + it.d.lustre.it_lock_bits); + GOTO(out_close, rc = -EPROTO); + } + + ll_intent_release(&it); + return och; + +out_close: + rc2 = ll_close_inode_openhandle(sbi->ll_md_exp, inode, och, NULL); + if (rc2) + CERROR("Close openhandle returned %d\n", rc2); + + /* cancel open lock */ + if (it.d.lustre.it_lock_mode != 0) { + ldlm_lock_decref_and_cancel(&och->och_lease_handle, + it.d.lustre.it_lock_mode); + it.d.lustre.it_lock_mode = 0; + } +out_release_it: + ll_intent_release(&it); +out: + OBD_FREE_PTR(och); + return ERR_PTR(rc); +} +EXPORT_SYMBOL(ll_lease_open); + +/** + * Release lease and close the file. + * It will check if the lease has ever broken. + */ +int ll_lease_close(struct obd_client_handle *och, struct inode *inode, + bool *lease_broken) +{ + struct ldlm_lock *lock; + bool cancelled = true; + int rc; + + lock = ldlm_handle2lock(&och->och_lease_handle); + if (lock != NULL) { + lock_res_and_lock(lock); + cancelled = ldlm_is_cancel(lock); + unlock_res_and_lock(lock); + ldlm_lock_put(lock); + } + + CDEBUG(D_INODE, "lease for "DFID" broken? %d\n", + PFID(&ll_i2info(inode)->lli_fid), cancelled); + + if (!cancelled) + ldlm_cli_cancel(&och->och_lease_handle, 0); + if (lease_broken != NULL) + *lease_broken = cancelled; + + rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och, + NULL); + return rc; +} +EXPORT_SYMBOL(ll_lease_close); + /* Fills the obdo with the attributes for the lsm */ static int ll_lsm_getattr(struct lov_stripe_md *lsm, struct obd_export *exp, struct obd_capa *capa, struct obdo *obdo, @@ -905,7 +1123,7 @@ out: cl_io_fini(env, io); /* If any bit been read/written (result != 0), we just return * short read/write instead of restart io. */ - if (result == 0 && io->ci_need_restart) { + if ((result == 0 || result == -ENODATA) && io->ci_need_restart) { CDEBUG(D_VFSTRACE, "Restart %s on %s from %lld, count:%zd\n", iot == CIT_READ ? "read" : "write", file->f_dentry->d_name.name, *ppos, count); @@ -930,48 +1148,16 @@ out: return result; } - -/* - * XXX: exact copy from kernel code (__generic_file_aio_write_nolock) - */ -static int ll_file_get_iov_count(const struct iovec *iov, - unsigned long *nr_segs, size_t *count) -{ - size_t cnt = 0; - unsigned long seg; - - for (seg = 0; seg < *nr_segs; seg++) { - const struct iovec *iv = &iov[seg]; - - /* - * If any segment has a negative length, or the cumulative - * length ever wraps negative then return -EINVAL. - */ - cnt += iv->iov_len; - if (unlikely((ssize_t)(cnt|iv->iov_len) < 0)) - return -EINVAL; - if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len)) - continue; - if (seg == 0) - return -EFAULT; - *nr_segs = seg; - cnt -= iv->iov_len; /* This segment is no good */ - break; - } - *count = cnt; - return 0; -} - static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct lu_env *env; struct vvp_io_args *args; - size_t count; + size_t count = 0; ssize_t result; int refcheck; - result = ll_file_get_iov_count(iov, &nr_segs, &count); + result = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); if (result) return result; @@ -1026,11 +1212,11 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov, { struct lu_env *env; struct vvp_io_args *args; - size_t count; + size_t count = 0; ssize_t result; int refcheck; - result = ll_file_get_iov_count(iov, &nr_segs, &count); + result = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); if (result) return result; @@ -1482,12 +1668,11 @@ int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it) if (!och) GOTO(out, rc = -ENOMEM); - ll_och_fill(ll_i2sbi(inode)->ll_md_exp, - ll_i2info(inode), it, och); + ll_och_fill(ll_i2sbi(inode)->ll_md_exp, it, och); rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, - inode, och); - out: + inode, och, NULL); +out: /* this one is in place of ll_file_open */ if (it_disposition(it, DISP_ENQ_OPEN_REF)) { ptlrpc_req_finished(it->d.lustre.it_data); @@ -1692,6 +1877,53 @@ out: return rc; } +/* + * Trigger a HSM release request for the provided inode. + */ +int ll_hsm_release(struct inode *inode) +{ + struct cl_env_nest nest; + struct lu_env *env; + struct obd_client_handle *och = NULL; + __u64 data_version = 0; + int rc; + + + CDEBUG(D_INODE, "%s: Releasing file "DFID".\n", + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(&ll_i2info(inode)->lli_fid)); + + och = ll_lease_open(inode, NULL, FMODE_WRITE, MDS_OPEN_RELEASE); + if (IS_ERR(och)) + GOTO(out, rc = PTR_ERR(och)); + + /* Grab latest data_version and [am]time values */ + rc = ll_data_version(inode, &data_version, 1); + if (rc != 0) + GOTO(out, rc); + + env = cl_env_nested_get(&nest); + if (IS_ERR(env)) + GOTO(out, rc = PTR_ERR(env)); + + ll_merge_lvb(env, inode); + cl_env_nested_put(&nest, env); + + /* Release the file. + * NB: lease lock handle is released in mdc_hsm_release_pack() because + * we still need it to pack l_remote_handle to MDT. */ + rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och, + &data_version); + och = NULL; + + +out: + if (och != NULL && !IS_ERR(och)) /* close the file */ + ll_lease_close(och, inode, NULL); + + return rc; +} + struct ll_swap_stack { struct iattr ia1, ia2; __u64 dv1, dv2; @@ -1853,6 +2085,86 @@ free: return rc; } +static int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss) +{ + struct md_op_data *op_data; + int rc; + + /* Non-root users are forbidden to set or clear flags which are + * NOT defined in HSM_USER_MASK. */ + if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) && + !cfs_capable(CFS_CAP_SYS_ADMIN)) + return -EPERM; + + op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, + LUSTRE_OPC_ANY, hss); + if (IS_ERR(op_data)) + return PTR_ERR(op_data); + + rc = obd_iocontrol(LL_IOC_HSM_STATE_SET, ll_i2mdexp(inode), + sizeof(*op_data), op_data, NULL); + + ll_finish_md_op_data(op_data); + + return rc; +} + +static int ll_hsm_import(struct inode *inode, struct file *file, + struct hsm_user_import *hui) +{ + struct hsm_state_set *hss = NULL; + struct iattr *attr = NULL; + int rc; + + + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + /* set HSM flags */ + OBD_ALLOC_PTR(hss); + if (hss == NULL) + GOTO(out, rc = -ENOMEM); + + hss->hss_valid = HSS_SETMASK | HSS_ARCHIVE_ID; + hss->hss_archive_id = hui->hui_archive_id; + hss->hss_setmask = HS_ARCHIVED | HS_EXISTS | HS_RELEASED; + rc = ll_hsm_state_set(inode, hss); + if (rc != 0) + GOTO(out, rc); + + OBD_ALLOC_PTR(attr); + if (attr == NULL) + GOTO(out, rc = -ENOMEM); + + attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + attr->ia_mode |= S_IFREG; + attr->ia_uid = make_kuid(&init_user_ns, hui->hui_uid); + attr->ia_gid = make_kgid(&init_user_ns, hui->hui_gid); + attr->ia_size = hui->hui_size; + attr->ia_mtime.tv_sec = hui->hui_mtime; + attr->ia_mtime.tv_nsec = hui->hui_mtime_ns; + attr->ia_atime.tv_sec = hui->hui_atime; + attr->ia_atime.tv_nsec = hui->hui_atime_ns; + + attr->ia_valid = ATTR_SIZE | ATTR_MODE | ATTR_FORCE | + ATTR_UID | ATTR_GID | + ATTR_MTIME | ATTR_MTIME_SET | + ATTR_ATIME | ATTR_ATIME_SET; + + rc = ll_setattr_raw(file->f_dentry, attr, true); + if (rc == -ENODATA) + rc = 0; + +out: + if (hss != NULL) + OBD_FREE_PTR(hss); + + if (attr != NULL) + OBD_FREE_PTR(attr); + + return rc; +} + long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode = file->f_dentry->d_inode; @@ -2014,37 +2326,19 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return rc; } case LL_IOC_HSM_STATE_SET: { - struct md_op_data *op_data; struct hsm_state_set *hss; int rc; OBD_ALLOC_PTR(hss); if (hss == NULL) return -ENOMEM; + if (copy_from_user(hss, (char *)arg, sizeof(*hss))) { OBD_FREE_PTR(hss); return -EFAULT; } - /* Non-root users are forbidden to set or clear flags which are - * NOT defined in HSM_USER_MASK. */ - if (((hss->hss_setmask | hss->hss_clearmask) & ~HSM_USER_MASK) - && !cfs_capable(CFS_CAP_SYS_ADMIN)) { - OBD_FREE_PTR(hss); - return -EPERM; - } - - op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, - LUSTRE_OPC_ANY, hss); - if (IS_ERR(op_data)) { - OBD_FREE_PTR(hss); - return PTR_ERR(op_data); - } - - rc = obd_iocontrol(cmd, ll_i2mdexp(inode), sizeof(*op_data), - op_data, NULL); - - ll_finish_md_op_data(op_data); + rc = ll_hsm_state_set(inode, hss); OBD_FREE_PTR(hss); return rc; @@ -2075,6 +2369,107 @@ long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) OBD_FREE_PTR(hca); return rc; } + case LL_IOC_SET_LEASE: { + struct ll_inode_info *lli = ll_i2info(inode); + struct obd_client_handle *och = NULL; + bool lease_broken; + fmode_t mode = 0; + + switch (arg) { + case F_WRLCK: + if (!(file->f_mode & FMODE_WRITE)) + return -EPERM; + mode = FMODE_WRITE; + break; + case F_RDLCK: + if (!(file->f_mode & FMODE_READ)) + return -EPERM; + mode = FMODE_READ; + break; + case F_UNLCK: + mutex_lock(&lli->lli_och_mutex); + if (fd->fd_lease_och != NULL) { + och = fd->fd_lease_och; + fd->fd_lease_och = NULL; + } + mutex_unlock(&lli->lli_och_mutex); + + if (och != NULL) { + mode = och->och_flags & + (FMODE_READ|FMODE_WRITE); + rc = ll_lease_close(och, inode, &lease_broken); + if (rc == 0 && lease_broken) + mode = 0; + } else { + rc = -ENOLCK; + } + + /* return the type of lease or error */ + return rc < 0 ? rc : (int)mode; + default: + return -EINVAL; + } + + CDEBUG(D_INODE, "Set lease with mode %d\n", mode); + + /* apply for lease */ + och = ll_lease_open(inode, file, mode, 0); + if (IS_ERR(och)) + return PTR_ERR(och); + + rc = 0; + mutex_lock(&lli->lli_och_mutex); + if (fd->fd_lease_och == NULL) { + fd->fd_lease_och = och; + och = NULL; + } + mutex_unlock(&lli->lli_och_mutex); + if (och != NULL) { + /* impossible now that only excl is supported for now */ + ll_lease_close(och, inode, &lease_broken); + rc = -EBUSY; + } + return rc; + } + case LL_IOC_GET_LEASE: { + struct ll_inode_info *lli = ll_i2info(inode); + struct ldlm_lock *lock = NULL; + + rc = 0; + mutex_lock(&lli->lli_och_mutex); + if (fd->fd_lease_och != NULL) { + struct obd_client_handle *och = fd->fd_lease_och; + + lock = ldlm_handle2lock(&och->och_lease_handle); + if (lock != NULL) { + lock_res_and_lock(lock); + if (!ldlm_is_cancel(lock)) + rc = och->och_flags & + (FMODE_READ | FMODE_WRITE); + unlock_res_and_lock(lock); + ldlm_lock_put(lock); + } + } + mutex_unlock(&lli->lli_och_mutex); + return rc; + } + case LL_IOC_HSM_IMPORT: { + struct hsm_user_import *hui; + + OBD_ALLOC_PTR(hui); + if (hui == NULL) + return -ENOMEM; + + if (copy_from_user(hui, (void *)arg, sizeof(*hui))) { + OBD_FREE_PTR(hui); + return -EFAULT; + } + + rc = ll_hsm_import(inode, file, hui); + + OBD_FREE_PTR(hui); + return rc; + } default: { int err; @@ -2435,7 +2830,8 @@ int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode) } ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, - struct lustre_handle *lockh, __u64 flags) + struct lustre_handle *lockh, __u64 flags, + ldlm_mode_t mode) { ldlm_policy_data_t policy = { .l_inodebits = {bits}}; struct lu_fid *fid; @@ -2445,8 +2841,8 @@ ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid)); rc = md_lock_match(ll_i2mdexp(inode), LDLM_FL_BLOCK_GRANTED|flags, - fid, LDLM_IBITS, &policy, - LCK_CR|LCK_CW|LCK_PR|LCK_PW, lockh); + fid, LDLM_IBITS, &policy, mode, lockh); + return rc; } @@ -2581,7 +2977,15 @@ int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it, LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_lvb.lvb_mtime; LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_lvb.lvb_ctime; } else { - rc = ll_glimpse_size(inode); + /* In case of restore, the MDT has the right size and has + * already send it back without granting the layout lock, + * inode is up-to-date so glimpse is useless. + * Also to glimpse we need the layout, in case of a running + * restore the MDT holds the layout lock so the glimpse will + * block up to the end of restore (getattr will block) + */ + if (!(ll_i2info(inode)->lli_flags & LLIF_FILE_RESTORING)) + rc = ll_glimpse_size(inode); } return rc; } @@ -2628,6 +3032,38 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat) return ll_getattr_it(mnt, de, &it, stat); } +int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + __u64 start, __u64 len) +{ + int rc; + size_t num_bytes; + struct ll_user_fiemap *fiemap; + unsigned int extent_count = fieinfo->fi_extents_max; + + num_bytes = sizeof(*fiemap) + (extent_count * + sizeof(struct ll_fiemap_extent)); + OBD_ALLOC_LARGE(fiemap, num_bytes); + + if (fiemap == NULL) + return -ENOMEM; + + fiemap->fm_flags = fieinfo->fi_flags; + fiemap->fm_extent_count = fieinfo->fi_extents_max; + fiemap->fm_start = start; + fiemap->fm_length = len; + memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start, + sizeof(struct ll_fiemap_extent)); + + rc = ll_do_fiemap(inode, fiemap, num_bytes); + + fieinfo->fi_flags = fiemap->fm_flags; + fieinfo->fi_extents_mapped = fiemap->fm_mapped_extents; + memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0], + fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent)); + + OBD_FREE_LARGE(fiemap, num_bytes); + return rc; +} struct posix_acl * ll_get_acl(struct inode *inode, int type) { @@ -2676,17 +3112,12 @@ int ll_inode_permission(struct inode *inode, int mask) return rc; } -#define READ_METHOD aio_read -#define READ_FUNCTION ll_file_aio_read -#define WRITE_METHOD aio_write -#define WRITE_FUNCTION ll_file_aio_write - /* -o localflock - only provides locally consistent flock locks */ struct file_operations ll_file_operations = { .read = ll_file_read, - .READ_METHOD = READ_FUNCTION, + .aio_read = ll_file_aio_read, .write = ll_file_write, - .WRITE_METHOD = WRITE_FUNCTION, + .aio_write = ll_file_aio_write, .unlocked_ioctl = ll_file_ioctl, .open = ll_file_open, .release = ll_file_release, @@ -2699,9 +3130,9 @@ struct file_operations ll_file_operations = { struct file_operations ll_file_operations_flock = { .read = ll_file_read, - .READ_METHOD = READ_FUNCTION, + .aio_read = ll_file_aio_read, .write = ll_file_write, - .WRITE_METHOD = WRITE_FUNCTION, + .aio_write = ll_file_aio_write, .unlocked_ioctl = ll_file_ioctl, .open = ll_file_open, .release = ll_file_release, @@ -2717,9 +3148,9 @@ struct file_operations ll_file_operations_flock = { /* These are for -o noflock - to return ENOSYS on flock calls */ struct file_operations ll_file_operations_noflock = { .read = ll_file_read, - .READ_METHOD = READ_FUNCTION, + .aio_read = ll_file_aio_read, .write = ll_file_write, - .WRITE_METHOD = WRITE_FUNCTION, + .aio_write = ll_file_aio_write, .unlocked_ioctl = ll_file_ioctl, .open = ll_file_open, .release = ll_file_release, @@ -2740,6 +3171,7 @@ struct inode_operations ll_file_inode_operations = { .getxattr = ll_getxattr, .listxattr = ll_listxattr, .removexattr = ll_removexattr, + .fiemap = ll_fiemap, .get_acl = ll_get_acl, }; @@ -3086,7 +3518,8 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen) /* mostly layout lock is caching on the local side, so try to match * it before grabbing layout lock mutex. */ - mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0); + mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0, + LCK_CR | LCK_CW | LCK_PR | LCK_PW); if (mode != 0) { /* hit cached lock */ rc = ll_layout_lock_set(&lockh, mode, inode, gen, false); if (rc == 0) @@ -3101,7 +3534,8 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen) again: /* try again. Maybe somebody else has done this. */ - mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0); + mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0, + LCK_CR | LCK_CW | LCK_PR | LCK_PW); if (mode != 0) { /* hit cached lock */ rc = ll_layout_lock_set(&lockh, mode, inode, gen, true); if (rc == -EAGAIN) @@ -3150,3 +3584,30 @@ again: return rc; } + +/** + * This function send a restore request to the MDT + */ +int ll_layout_restore(struct inode *inode) +{ + struct hsm_user_request *hur; + int len, rc; + + len = sizeof(struct hsm_user_request) + + sizeof(struct hsm_user_item); + OBD_ALLOC(hur, len); + if (hur == NULL) + return -ENOMEM; + + hur->hur_request.hr_action = HUA_RESTORE; + hur->hur_request.hr_archive_id = 0; + hur->hur_request.hr_flags = 0; + memcpy(&hur->hur_user_item[0].hui_fid, &ll_i2info(inode)->lli_fid, + sizeof(hur->hur_user_item[0].hui_fid)); + hur->hur_user_item[0].hui_extent.length = -1; + hur->hur_request.hr_itemcount = 1; + rc = obd_iocontrol(LL_IOC_HSM_REQUEST, cl_i2sbi(inode)->ll_md_exp, + len, hur, NULL); + OBD_FREE(hur, len); + return rc; +} diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 47e443d90fe1..7ee5c02783f9 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -46,6 +46,8 @@ #include <lclient.h> #include <lustre_mdc.h> #include <linux/lustre_intent.h> +#include <linux/compat.h> +#include <linux/posix_acl_xattr.h> #ifndef FMODE_EXEC #define FMODE_EXEC 0 @@ -124,6 +126,10 @@ enum lli_flags { LLIF_SRVLOCK = (1 << 5), /* File data is modified. */ LLIF_DATA_MODIFIED = (1 << 6), + /* File is being restored */ + LLIF_FILE_RESTORING = (1 << 7), + /* Xattr cache is attached to the file */ + LLIF_XATTR_CACHE = (1 << 8), }; struct ll_inode_info { @@ -276,8 +282,27 @@ struct ll_inode_info { struct mutex lli_layout_mutex; /* valid only inside LAYOUT ibits lock, protected by lli_layout_mutex */ __u32 lli_layout_gen; + + struct rw_semaphore lli_xattrs_list_rwsem; + struct mutex lli_xattrs_enq_lock; + struct list_head lli_xattrs;/* ll_xattr_entry->xe_list */ }; +int ll_xattr_cache_destroy(struct inode *inode); + +int ll_xattr_cache_get(struct inode *inode, + const char *name, + char *buffer, + size_t size, + __u64 valid); + +int ll_xattr_cache_update(struct inode *inode, + const char *name, + const char *newval, + size_t size, + __u64 valid, + int flags); + /* * Locking to guarantee consistency of non-atomic updates to long long i_size, * consistency between file size and KMS. @@ -399,6 +424,7 @@ enum stats_track_type { #define LL_SBI_VERBOSE 0x10000 /* verbose mount/umount */ #define LL_SBI_LAYOUT_LOCK 0x20000 /* layout lock support */ #define LL_SBI_USER_FID2PATH 0x40000 /* allow fid2path by unprivileged users */ +#define LL_SBI_XATTR_CACHE 0x80000 /* support for xattr cache */ #define LL_SBI_FLAGS { \ "nolck", \ @@ -406,6 +432,7 @@ enum stats_track_type { "flock", \ "xattr", \ "acl", \ + "???", \ "rmt_client", \ "mds_capa", \ "oss_capa", \ @@ -418,7 +445,9 @@ enum stats_track_type { "agl", \ "verbose", \ "layout", \ - "user_fid2path" } + "user_fid2path",\ + "xattr", \ +} /* default value for ll_sb_info->contention_time */ #define SBI_DEFAULT_CONTENTION_SECONDS 60 @@ -458,7 +487,8 @@ struct ll_sb_info { struct lu_fid ll_root_fid; /* root object fid */ int ll_flags; - int ll_umounting:1; + unsigned int ll_umounting:1, + ll_xattr_cache_enabled:1; struct list_head ll_conn_chain; /* per-conn chain of SBs */ struct lustre_client_ocd ll_lco; @@ -607,10 +637,14 @@ extern struct kmem_cache *ll_file_data_slab; struct lustre_handle; struct ll_file_data { struct ll_readahead_state fd_ras; - int fd_omode; struct ccc_grouplock fd_grouplock; __u64 lfd_pos; __u32 fd_flags; + fmode_t fd_omode; + /* openhandle if lease exists for this file. + * Borrow lli->lli_och_mutex to protect assignment */ + struct obd_client_handle *fd_lease_och; + struct obd_client_handle *fd_och; struct file *fd_file; /* Indicate whether need to report failure when close. * true: failure is known, not report again. @@ -643,7 +677,12 @@ static inline int ll_need_32bit_api(struct ll_sb_info *sbi) #if BITS_PER_LONG == 32 return 1; #else - return unlikely(current_is_32bit() || (sbi->ll_flags & LL_SBI_32BIT_API)); + return unlikely( +#ifdef CONFIG_COMPAT + is_compat_task() || +#endif + (sbi->ll_flags & LL_SBI_32BIT_API) + ); #endif } @@ -663,15 +702,22 @@ int lprocfs_register_mountpoint(struct proc_dir_entry *parent, void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi); void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count); void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars); +void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, + struct ll_file_data *file, loff_t pos, + size_t count, int rw); #else static inline int lprocfs_register_mountpoint(struct proc_dir_entry *parent, struct super_block *sb, char *osc, char *mdc){return 0;} static inline void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi) {} -static void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) {} -static void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars) +static inline +void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) {} +static inline void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars) { memset(lvars, 0, sizeof(*lvars)); } +static inline void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, + struct ll_file_data *file, loff_t pos, + size_t count, int rw) {} #endif @@ -720,7 +766,8 @@ extern int ll_inode_revalidate_it(struct dentry *, struct lookup_intent *, extern int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode); extern ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, - struct lustre_handle *lockh, __u64 flags); + struct lustre_handle *lockh, __u64 flags, + ldlm_mode_t mode); int __ll_inode_revalidate_it(struct dentry *, struct lookup_intent *, __u64 bits); int ll_revalidate_nd(struct dentry *dentry, unsigned int flags); @@ -746,9 +793,6 @@ int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data, struct md_open_data **mod); void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data, struct lustre_handle *fh); -extern void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, - struct ll_file_data *file, loff_t pos, - size_t count, int rw); int ll_getattr_it(struct vfsmount *mnt, struct dentry *de, struct lookup_intent *it, struct kstat *stat); int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat); @@ -775,6 +819,12 @@ int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg); int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg); int ll_fid2path(struct inode *inode, void *arg); int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock); +int ll_hsm_release(struct inode *inode); + +struct obd_client_handle *ll_lease_open(struct inode *inode, struct file *file, + fmode_t mode, __u64 flags); +int ll_lease_close(struct obd_client_handle *och, struct inode *inode, + bool *lease_broken); /* llite/dcache.c */ @@ -801,7 +851,7 @@ void ll_kill_super(struct super_block *sb); struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock); struct inode *ll_inode_from_lock(struct ldlm_lock *lock); void ll_clear_inode(struct inode *inode); -int ll_setattr_raw(struct dentry *dentry, struct iattr *attr); +int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import); int ll_setattr(struct dentry *de, struct iattr *attr); int ll_statfs(struct dentry *de, struct kstatfs *sfs); int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, @@ -1578,5 +1628,9 @@ enum { int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf); int ll_layout_refresh(struct inode *inode, __u32 *gen); +int ll_layout_restore(struct inode *inode); + +int ll_xattr_init(void); +void ll_xattr_fini(void); #endif /* LLITE_INTERNAL_H */ diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index fd584ff7e2df..6cfdb9e4b74b 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -56,6 +56,7 @@ #include "llite_internal.h" struct kmem_cache *ll_file_data_slab; +struct proc_dir_entry *proc_lustre_fs_root; LIST_HEAD(ll_super_blocks); DEFINE_SPINLOCK(ll_sb_lock); @@ -209,7 +210,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH| OBD_CONNECT_EINPROGRESS | OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE | - OBD_CONNECT_LAYOUTLOCK | OBD_CONNECT_PINGLESS; + OBD_CONNECT_LAYOUTLOCK | + OBD_CONNECT_PINGLESS | OBD_CONNECT_MAX_EASIZE; if (sbi->ll_flags & LL_SBI_SOM_PREVIEW) data->ocd_connect_flags |= OBD_CONNECT_SOM; @@ -383,6 +385,17 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, sbi->ll_flags |= LL_SBI_LAYOUT_LOCK; } + if (data->ocd_ibits_known & MDS_INODELOCK_XATTR) { + if (!(data->ocd_connect_flags & OBD_CONNECT_MAX_EASIZE)) { + LCONSOLE_INFO( + "%s: disabling xattr cache due to unknown maximum xattr size.\n", + dt); + } else { + sbi->ll_flags |= LL_SBI_XATTR_CACHE; + sbi->ll_xattr_cache_enabled = 1; + } + } + obd = class_name2obd(dt); if (!obd) { CERROR("DT %s: not setup or attached\n", dt); @@ -922,6 +935,9 @@ void ll_lli_init(struct ll_inode_info *lli) lli->lli_layout_gen = LL_LAYOUT_GEN_NONE; lli->lli_clob = NULL; + init_rwsem(&lli->lli_xattrs_list_rwsem); + mutex_init(&lli->lli_xattrs_enq_lock); + LASSERT(lli->lli_vfs_inode.i_mode != 0); if (S_ISDIR(lli->lli_vfs_inode.i_mode)) { mutex_init(&lli->lli_readdir_mutex); @@ -1194,6 +1210,8 @@ void ll_clear_inode(struct inode *inode) lli->lli_symlink_name = NULL; } + ll_xattr_cache_destroy(inode); + if (sbi->ll_flags & LL_SBI_RMT_CLIENT) { LASSERT(lli->lli_posix_acl == NULL); if (lli->lli_remote_perms) { @@ -1346,19 +1364,24 @@ static int ll_setattr_ost(struct inode *inode, struct iattr *attr) * to the OST with the punch RPC, otherwise we do an explicit setattr RPC. * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE * at the same time. + * + * In case of HSMimport, we only set attr on MDS. */ -int ll_setattr_raw(struct dentry *dentry, struct iattr *attr) +int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import) { struct inode *inode = dentry->d_inode; struct ll_inode_info *lli = ll_i2info(inode); struct md_op_data *op_data = NULL; struct md_open_data *mod = NULL; + bool file_is_released = false; int rc = 0, rc1 = 0; - CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, " - "valid %x\n", ll_get_fsname(inode->i_sb, NULL, 0), inode, + CDEBUG(D_VFSTRACE, + "%s: setattr inode %p/fid:"DFID + " from %llu to %llu, valid %x, hsm_import %d\n", + ll_get_fsname(inode->i_sb, NULL, 0), inode, PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size, - attr->ia_valid); + attr->ia_valid, hsm_import); if (attr->ia_valid & ATTR_SIZE) { /* Check new size against VFS/VM file size limit and rlimit */ @@ -1436,10 +1459,40 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr) (attr->ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET))) op_data->op_flags = MF_EPOCH_OPEN; + /* truncate on a released file must failed with -ENODATA, + * so size must not be set on MDS for released file + * but other attributes must be set + */ + if (S_ISREG(inode->i_mode)) { + struct lov_stripe_md *lsm; + __u32 gen; + + ll_layout_refresh(inode, &gen); + lsm = ccc_inode_lsm_get(inode); + if (lsm && lsm->lsm_pattern & LOV_PATTERN_F_RELEASED) + file_is_released = true; + ccc_inode_lsm_put(inode, lsm); + } + + /* if not in HSM import mode, clear size attr for released file + * we clear the attribute send to MDT in op_data, not the original + * received from caller in attr which is used later to + * decide return code */ + if (file_is_released && (attr->ia_valid & ATTR_SIZE) && !hsm_import) + op_data->op_attr.ia_valid &= ~ATTR_SIZE; + rc = ll_md_setattr(dentry, op_data, &mod); if (rc) GOTO(out, rc); + /* truncate failed (only when non HSM import), others succeed */ + if (file_is_released) { + if ((attr->ia_valid & ATTR_SIZE) && !hsm_import) + GOTO(out, rc = -ENODATA); + else + GOTO(out, rc = 0); + } + /* RPC to MDT is sent, cancel data modification flag */ if (rc == 0 && (op_data->op_bias & MDS_DATA_MODIFIED)) { spin_lock(&lli->lli_lock); @@ -1473,7 +1526,7 @@ out: if (!S_ISDIR(inode->i_mode)) { up_write(&lli->lli_trunc_sem); mutex_lock(&inode->i_mutex); - if (attr->ia_valid & ATTR_SIZE) + if ((attr->ia_valid & ATTR_SIZE) && !hsm_import) inode_dio_wait(inode); } @@ -1508,7 +1561,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr) !(attr->ia_valid & ATTR_KILL_SGID)) attr->ia_valid |= ATTR_KILL_SGID; - return ll_setattr_raw(de, attr); + return ll_setattr_raw(de, attr, false); } int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, @@ -1721,7 +1774,9 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) * lock on the client and set LLIF_MDS_SIZE_LOCK holding * it. */ mode = ll_take_md_lock(inode, MDS_INODELOCK_UPDATE, - &lockh, LDLM_FL_CBPENDING); + &lockh, LDLM_FL_CBPENDING, + LCK_CR | LCK_CW | + LCK_PR | LCK_PW); if (mode) { if (lli->lli_flags & (LLIF_DONE_WRITING | LLIF_EPOCH_PENDING | @@ -1761,6 +1816,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) LASSERT(md->oss_capa); ll_add_capa(inode, md->oss_capa); } + + if (body->valid & OBD_MD_TSTATE) { + if (body->t_state & MS_RESTORE) + lli->lli_flags |= LLIF_FILE_RESTORING; + } } void ll_read_inode2(struct inode *inode, void *opaque) diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index e2421ea61352..5338e8d4c50f 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -856,7 +856,8 @@ static void lloop_exit(void) module_init(lloop_init); module_exit(lloop_exit); -CFS_MODULE_PARM(max_loop, "i", int, 0444, "maximum of lloop_device"); +module_param(max_loop, int, 0444); +MODULE_PARM_DESC(max_loop, "maximum of lloop_device"); MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>"); MODULE_DESCRIPTION("Lustre virtual block device"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index 4bf09c4a0c9d..a9a104a6a4ee 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -42,9 +42,6 @@ #include "llite_internal.h" -struct proc_dir_entry *proc_lustre_fs_root; - -#ifdef LPROCFS /* /proc/lustre/llite mount point registration */ extern struct file_operations vvp_dump_pgcache_file_ops; struct file_operations ll_rw_extents_stats_fops; @@ -723,6 +720,41 @@ static int ll_sbi_flags_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(ll_sbi_flags); +static int ll_xattr_cache_seq_show(struct seq_file *m, void *v) +{ + struct super_block *sb = m->private; + struct ll_sb_info *sbi = ll_s2sbi(sb); + int rc; + + rc = seq_printf(m, "%u\n", sbi->ll_xattr_cache_enabled); + + return rc; +} + +static ssize_t ll_xattr_cache_seq_write(struct file *file, const char *buffer, + size_t count, loff_t *off) +{ + struct seq_file *seq = file->private_data; + struct super_block *sb = seq->private; + struct ll_sb_info *sbi = ll_s2sbi(sb); + int val, rc; + + rc = lprocfs_write_helper(buffer, count, &val); + if (rc) + return rc; + + if (val != 0 && val != 1) + return -ERANGE; + + if (val == 1 && !(sbi->ll_flags & LL_SBI_XATTR_CACHE)) + return -ENOTSUPP; + + sbi->ll_xattr_cache_enabled = val; + + return count; +} +LPROC_SEQ_FOPS(ll_xattr_cache); + static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "uuid", &ll_sb_uuid_fops, 0, 0 }, //{ "mntpt_path", ll_rd_path, 0, 0 }, @@ -751,6 +783,7 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = { { "lazystatfs", &ll_lazystatfs_fops, 0 }, { "max_easize", &ll_maxea_size_fops, 0, 0 }, { "sbi_flags", &ll_sbi_flags_fops, 0, 0 }, + { "xattr_cache", &ll_xattr_cache_fops, 0, 0 }, { 0 } }; @@ -802,6 +835,7 @@ struct llite_file_opcode { { LPROC_LL_ALLOC_INODE, LPROCFS_TYPE_REGS, "alloc_inode" }, { LPROC_LL_SETXATTR, LPROCFS_TYPE_REGS, "setxattr" }, { LPROC_LL_GETXATTR, LPROCFS_TYPE_REGS, "getxattr" }, + { LPROC_LL_GETXATTR_HITS, LPROCFS_TYPE_REGS, "getxattr_hits" }, { LPROC_LL_LISTXATTR, LPROCFS_TYPE_REGS, "listxattr" }, { LPROC_LL_REMOVEXATTR, LPROCFS_TYPE_REGS, "removexattr" }, { LPROC_LL_INODE_PERM, LPROCFS_TYPE_REGS, "inode_permission" }, @@ -1367,4 +1401,3 @@ void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars) lvars->module_vars = NULL; lvars->obd_vars = lprocfs_llite_obd_vars; } -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 90bbdae824ac..fc8d264f6c9a 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -223,6 +223,10 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, break; LASSERT(lock->l_flags & LDLM_FL_CANCELING); + + if (bits & MDS_INODELOCK_XATTR) + ll_xattr_cache_destroy(inode); + /* For OPEN locks we differentiate between lock modes * LCK_CR, LCK_CW, LCK_PR - bug 22891 */ if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | @@ -233,12 +237,9 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, ll_have_md_lock(inode, &bits, mode); fid = ll_inode2fid(inode); - if (lock->l_resource->lr_name.name[0] != fid_seq(fid) || - lock->l_resource->lr_name.name[1] != fid_oid(fid) || - lock->l_resource->lr_name.name[2] != fid_ver(fid)) { + if (!fid_res_name_eq(fid, &lock->l_resource->lr_name)) LDLM_ERROR(lock, "data mismatch with object " DFID" (%p)", PFID(fid), inode); - } if (bits & MDS_INODELOCK_OPEN) { int flags = 0; @@ -526,8 +527,7 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, icbd.icbd_childp = &dentry; icbd.icbd_parent = parent; - if (it->it_op & IT_CREAT || - (it->it_op & IT_OPEN && it->it_create_mode & O_CREAT)) + if (it->it_op & IT_CREAT) opc = LUSTRE_OPC_CREATE; else opc = LUSTRE_OPC_ANY; @@ -626,7 +626,7 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, return -ENOMEM; it->it_op = IT_OPEN; - if (mode) { + if (open_flags & O_CREAT) { it->it_op |= IT_CREAT; lookup_flags |= LOOKUP_CREATE; } diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 0beaf4e76b4b..e21e1c760a8e 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -187,11 +187,15 @@ static int __init init_lustre_lite(void) if (rc == 0) rc = vvp_global_init(); + if (rc == 0) + rc = ll_xattr_init(); + return rc; } static void __exit exit_lustre_lite(void) { + ll_xattr_fini(); vvp_global_fini(); del_timer(&ll_capa_timer); ll_capa_thread_stop(); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 3ff664ce7503..f69e3aa98022 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -121,8 +121,38 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) CLOBINVRNT(env, obj, ccc_object_invariant(obj)); - CDEBUG(D_VFSTRACE, "ignore/verify layout %d/%d, layout version %d.\n", - io->ci_ignore_layout, io->ci_verify_layout, cio->cui_layout_gen); + CDEBUG(D_VFSTRACE, DFID + " ignore/verify layout %d/%d, layout version %d restore needed %d\n", + PFID(lu_object_fid(&obj->co_lu)), + io->ci_ignore_layout, io->ci_verify_layout, + cio->cui_layout_gen, io->ci_restore_needed); + + if (io->ci_restore_needed == 1) { + int rc; + + /* file was detected release, we need to restore it + * before finishing the io + */ + rc = ll_layout_restore(ccc_object_inode(obj)); + /* if restore registration failed, no restart, + * we will return -ENODATA */ + /* The layout will change after restore, so we need to + * block on layout lock hold by the MDT + * as MDT will not send new layout in lvb (see LU-3124) + * we have to explicitly fetch it, all this will be done + * by ll_layout_refresh() + */ + if (rc == 0) { + io->ci_restore_needed = 0; + io->ci_need_restart = 1; + io->ci_verify_layout = 1; + } else { + io->ci_restore_needed = 1; + io->ci_need_restart = 0; + io->ci_verify_layout = 0; + io->ci_result = rc; + } + } if (!io->ci_ignore_layout && io->ci_verify_layout) { __u32 gen = 0; @@ -130,9 +160,17 @@ static void vvp_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) /* check layout version */ ll_layout_refresh(ccc_object_inode(obj), &gen); io->ci_need_restart = cio->cui_layout_gen != gen; - if (io->ci_need_restart) - CDEBUG(D_VFSTRACE, "layout changed from %d to %d.\n", - cio->cui_layout_gen, gen); + if (io->ci_need_restart) { + CDEBUG(D_VFSTRACE, + DFID" layout changed from %d to %d.\n", + PFID(lu_object_fid(&obj->co_lu)), + cio->cui_layout_gen, gen); + /* today successful restore is the only possible + * case */ + /* restore was done, clear restoring state */ + ll_i2info(ccc_object_inode(obj))->lli_flags &= + ~LLIF_FILE_RESTORING; + } } } @@ -1111,6 +1149,12 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj, CLOBINVRNT(env, obj, ccc_object_invariant(obj)); + CDEBUG(D_VFSTRACE, DFID + " ignore/verify layout %d/%d, layout version %d restore needed %d\n", + PFID(lu_object_fid(&obj->co_lu)), + io->ci_ignore_layout, io->ci_verify_layout, + cio->cui_layout_gen, io->ci_restore_needed); + CL_IO_SLICE_CLEAN(cio, cui_cl); cl_io_slice_add(io, &cio->cui_cl, obj, &vvp_io_ops); vio->cui_ra_window_set = 0; diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c index 33173fce478f..25973dedd9a2 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_object.c +++ b/drivers/staging/lustre/lustre/llite/vvp_object.c @@ -138,7 +138,7 @@ int vvp_conf_set(const struct lu_env *env, struct cl_object *obj, lli->lli_layout_gen, conf->u.coc_md->lsm->lsm_layout_gen); - lli->lli_has_smd = true; + lli->lli_has_smd = lsm_has_objects(conf->u.coc_md->lsm); lli->lli_layout_gen = conf->u.coc_md->lsm->lsm_layout_gen; } else { CDEBUG(D_VFSTRACE, "layout lock destroyed: %u.\n", diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c index bcf86bac30a9..3a7d03c12dd9 100644 --- a/drivers/staging/lustre/lustre/llite/xattr.c +++ b/drivers/staging/lustre/lustre/llite/xattr.c @@ -109,12 +109,12 @@ int ll_setxattr_common(struct inode *inode, const char *name, int flags, __u64 valid) { struct ll_sb_info *sbi = ll_i2sbi(inode); - struct ptlrpc_request *req; + struct ptlrpc_request *req = NULL; int xattr_type, rc; struct obd_capa *oc; + struct rmtacl_ctl_entry *rce = NULL; #ifdef CONFIG_FS_POSIX_ACL posix_acl_xattr_header *new_value = NULL; - struct rmtacl_ctl_entry *rce = NULL; ext_acl_xattr_header *acl = NULL; #endif const char *pv = value; @@ -183,11 +183,17 @@ int ll_setxattr_common(struct inode *inode, const char *name, valid |= rce_ops2valid(rce->rce_ops); } #endif - oc = ll_mdscapa_get(inode); - rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid, name, pv, size, 0, flags, ll_i2suppgid(inode), - &req); - capa_put(oc); + if (sbi->ll_xattr_cache_enabled && + (rce == NULL || rce->rce_ops == RMT_LSETFACL)) { + rc = ll_xattr_cache_update(inode, name, pv, size, valid, flags); + } else { + oc = ll_mdscapa_get(inode); + rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, + valid, name, pv, size, 0, flags, + ll_i2suppgid(inode), &req); + capa_put(oc); + } + #ifdef CONFIG_FS_POSIX_ACL if (new_value != NULL) lustre_posix_acl_xattr_free(new_value, size); @@ -352,48 +358,54 @@ int ll_getxattr_common(struct inode *inode, const char *name, #endif do_getxattr: - oc = ll_mdscapa_get(inode); - rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid | (rce ? rce_ops2valid(rce->rce_ops) : 0), - name, NULL, 0, size, 0, &req); - capa_put(oc); - if (rc) { - if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { - LCONSOLE_INFO("Disabling user_xattr feature because " - "it is not supported on the server\n"); - sbi->ll_flags &= ~LL_SBI_USER_XATTR; - } - return rc; - } + if (sbi->ll_xattr_cache_enabled && (rce == NULL || + rce->rce_ops == RMT_LGETFACL || + rce->rce_ops == RMT_LSETFACL)) { + rc = ll_xattr_cache_get(inode, name, buffer, size, valid); + if (rc < 0) + GOTO(out_xattr, rc); + } else { + oc = ll_mdscapa_get(inode); + rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, + valid | (rce ? rce_ops2valid(rce->rce_ops) : 0), + name, NULL, 0, size, 0, &req); + capa_put(oc); - body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); - LASSERT(body); + if (rc < 0) + GOTO(out_xattr, rc); - /* only detect the xattr size */ - if (size == 0) - GOTO(out, rc = body->eadatasize); + body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); + LASSERT(body); - if (size < body->eadatasize) { - CERROR("server bug: replied size %u > %u\n", - body->eadatasize, (int)size); - GOTO(out, rc = -ERANGE); - } + /* only detect the xattr size */ + if (size == 0) + GOTO(out, rc = body->eadatasize); + + if (size < body->eadatasize) { + CERROR("server bug: replied size %u > %u\n", + body->eadatasize, (int)size); + GOTO(out, rc = -ERANGE); + } - if (body->eadatasize == 0) - GOTO(out, rc = -ENODATA); + if (body->eadatasize == 0) + GOTO(out, rc = -ENODATA); - /* do not need swab xattr data */ - xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA, - body->eadatasize); - if (!xdata) - GOTO(out, rc = -EFAULT); + /* do not need swab xattr data */ + xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA, + body->eadatasize); + if (!xdata) + GOTO(out, rc = -EFAULT); + + memcpy(buffer, xdata, body->eadatasize); + rc = body->eadatasize; + } #ifdef CONFIG_FS_POSIX_ACL - if (body->eadatasize >= 0 && rce && rce->rce_ops == RMT_LSETFACL) { + if (rce && rce->rce_ops == RMT_LSETFACL) { ext_acl_xattr_header *acl; - acl = lustre_posix_acl_xattr_2ext((posix_acl_xattr_header *)xdata, - body->eadatasize); + acl = lustre_posix_acl_xattr_2ext( + (posix_acl_xattr_header *)buffer, rc); if (IS_ERR(acl)) GOTO(out, rc = PTR_ERR(acl)); @@ -406,12 +418,12 @@ do_getxattr: } #endif - if (body->eadatasize == 0) { - rc = -ENODATA; - } else { - LASSERT(buffer); - memcpy(buffer, xdata, body->eadatasize); - rc = body->eadatasize; +out_xattr: + if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { + LCONSOLE_INFO( + "%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n", + ll_get_fsname(inode->i_sb, NULL, 0), rc); + sbi->ll_flags &= ~LL_SBI_USER_XATTR; } out: ptlrpc_req_finished(req); diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c new file mode 100644 index 000000000000..3e3be1f13502 --- /dev/null +++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c @@ -0,0 +1,617 @@ +/* + * Copyright 2012 Xyratex Technology Limited + * + * Author: Andrew Perepechko <Andrew_Perepechko@xyratex.com> + * + */ + +#define DEBUG_SUBSYSTEM S_LLITE + +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <obd_support.h> +#include <lustre_lite.h> +#include <lustre_dlm.h> +#include <lustre_ver.h> +#include "llite_internal.h" + +/* If we ever have hundreds of extended attributes, we might want to consider + * using a hash or a tree structure instead of list for faster lookups. + */ +struct ll_xattr_entry { + struct list_head xe_list; /* protected with + * lli_xattrs_list_rwsem */ + char *xe_name; /* xattr name, \0-terminated */ + char *xe_value; /* xattr value */ + unsigned xe_namelen; /* strlen(xe_name) + 1 */ + unsigned xe_vallen; /* xattr value length */ +}; + +static struct kmem_cache *xattr_kmem; +static struct lu_kmem_descr xattr_caches[] = { + { + .ckd_cache = &xattr_kmem, + .ckd_name = "xattr_kmem", + .ckd_size = sizeof(struct ll_xattr_entry) + }, + { + .ckd_cache = NULL + } +}; + +int ll_xattr_init(void) +{ + return lu_kmem_init(xattr_caches); +} + +void ll_xattr_fini(void) +{ + lu_kmem_fini(xattr_caches); +} + +/** + * Initializes xattr cache for an inode. + * + * This initializes the xattr list and marks cache presence. + */ +static void ll_xattr_cache_init(struct ll_inode_info *lli) +{ + + + LASSERT(lli != NULL); + + INIT_LIST_HEAD(&lli->lli_xattrs); + lli->lli_flags |= LLIF_XATTR_CACHE; +} + +/** + * This looks for a specific extended attribute. + * + * Find in @cache and return @xattr_name attribute in @xattr, + * for the NULL @xattr_name return the first cached @xattr. + * + * \retval 0 success + * \retval -ENODATA if not found + */ +static int ll_xattr_cache_find(struct list_head *cache, + const char *xattr_name, + struct ll_xattr_entry **xattr) +{ + struct ll_xattr_entry *entry; + + + + list_for_each_entry(entry, cache, xe_list) { + /* xattr_name == NULL means look for any entry */ + if (xattr_name == NULL || + strcmp(xattr_name, entry->xe_name) == 0) { + *xattr = entry; + CDEBUG(D_CACHE, "find: [%s]=%.*s\n", + entry->xe_name, entry->xe_vallen, + entry->xe_value); + return 0; + } + } + + return -ENODATA; +} + +/** + * This adds or updates an xattr. + * + * Add @xattr_name attr with @xattr_val value and @xattr_val_len length, + * if the attribute already exists, then update its value. + * + * \retval 0 success + * \retval -ENOMEM if no memory could be allocated for the cached attr + */ +static int ll_xattr_cache_add(struct list_head *cache, + const char *xattr_name, + const char *xattr_val, + unsigned xattr_val_len) +{ + struct ll_xattr_entry *xattr; + + + + if (ll_xattr_cache_find(cache, xattr_name, &xattr) == 0) { + /* Found a cached EA, update it */ + + if (xattr_val_len != xattr->xe_vallen) { + char *val; + OBD_ALLOC(val, xattr_val_len); + if (val == NULL) { + CDEBUG(D_CACHE, + "failed to allocate %u bytes for xattr %s update\n", + xattr_val_len, xattr_name); + return -ENOMEM; + } + OBD_FREE(xattr->xe_value, xattr->xe_vallen); + xattr->xe_value = val; + xattr->xe_vallen = xattr_val_len; + } + memcpy(xattr->xe_value, xattr_val, xattr_val_len); + + CDEBUG(D_CACHE, "update: [%s]=%.*s\n", xattr_name, + xattr_val_len, xattr_val); + + return 0; + } + + OBD_SLAB_ALLOC_PTR_GFP(xattr, xattr_kmem, __GFP_IO); + if (xattr == NULL) { + CDEBUG(D_CACHE, "failed to allocate xattr\n"); + return -ENOMEM; + } + + xattr->xe_namelen = strlen(xattr_name) + 1; + + OBD_ALLOC(xattr->xe_name, xattr->xe_namelen); + if (!xattr->xe_name) { + CDEBUG(D_CACHE, "failed to alloc xattr name %u\n", + xattr->xe_namelen); + goto err_name; + } + OBD_ALLOC(xattr->xe_value, xattr_val_len); + if (!xattr->xe_value) { + CDEBUG(D_CACHE, "failed to alloc xattr value %d\n", + xattr_val_len); + goto err_value; + } + + memcpy(xattr->xe_name, xattr_name, xattr->xe_namelen); + memcpy(xattr->xe_value, xattr_val, xattr_val_len); + xattr->xe_vallen = xattr_val_len; + list_add(&xattr->xe_list, cache); + + CDEBUG(D_CACHE, "set: [%s]=%.*s\n", xattr_name, + xattr_val_len, xattr_val); + + return 0; +err_value: + OBD_FREE(xattr->xe_name, xattr->xe_namelen); +err_name: + OBD_SLAB_FREE_PTR(xattr, xattr_kmem); + + return -ENOMEM; +} + +/** + * This removes an extended attribute from cache. + * + * Remove @xattr_name attribute from @cache. + * + * \retval 0 success + * \retval -ENODATA if @xattr_name is not cached + */ +static int ll_xattr_cache_del(struct list_head *cache, + const char *xattr_name) +{ + struct ll_xattr_entry *xattr; + + + + CDEBUG(D_CACHE, "del xattr: %s\n", xattr_name); + + if (ll_xattr_cache_find(cache, xattr_name, &xattr) == 0) { + list_del(&xattr->xe_list); + OBD_FREE(xattr->xe_name, xattr->xe_namelen); + OBD_FREE(xattr->xe_value, xattr->xe_vallen); + OBD_SLAB_FREE_PTR(xattr, xattr_kmem); + + return 0; + } + + return -ENODATA; +} + +/** + * This iterates cached extended attributes. + * + * Walk over cached attributes in @cache and + * fill in @xld_buffer or only calculate buffer + * size if @xld_buffer is NULL. + * + * \retval >= 0 buffer list size + * \retval -ENODATA if the list cannot fit @xld_size buffer + */ +static int ll_xattr_cache_list(struct list_head *cache, + char *xld_buffer, + int xld_size) +{ + struct ll_xattr_entry *xattr, *tmp; + int xld_tail = 0; + + + + list_for_each_entry_safe(xattr, tmp, cache, xe_list) { + CDEBUG(D_CACHE, "list: buffer=%p[%d] name=%s\n", + xld_buffer, xld_tail, xattr->xe_name); + + if (xld_buffer) { + xld_size -= xattr->xe_namelen; + if (xld_size < 0) + break; + memcpy(&xld_buffer[xld_tail], + xattr->xe_name, xattr->xe_namelen); + } + xld_tail += xattr->xe_namelen; + } + + if (xld_size < 0) + return -ERANGE; + + return xld_tail; +} + +/** + * Check if the xattr cache is initialized (filled). + * + * \retval 0 @cache is not initialized + * \retval 1 @cache is initialized + */ +int ll_xattr_cache_valid(struct ll_inode_info *lli) +{ + return !!(lli->lli_flags & LLIF_XATTR_CACHE); +} + +/** + * This finalizes the xattr cache. + * + * Free all xattr memory. @lli is the inode info pointer. + * + * \retval 0 no error occured + */ +static int ll_xattr_cache_destroy_locked(struct ll_inode_info *lli) +{ + + + if (!ll_xattr_cache_valid(lli)) + return 0; + + while (ll_xattr_cache_del(&lli->lli_xattrs, NULL) == 0) + ; /* empty loop */ + lli->lli_flags &= ~LLIF_XATTR_CACHE; + + return 0; +} + +int ll_xattr_cache_destroy(struct inode *inode) +{ + struct ll_inode_info *lli = ll_i2info(inode); + int rc; + + + + down_write(&lli->lli_xattrs_list_rwsem); + rc = ll_xattr_cache_destroy_locked(lli); + up_write(&lli->lli_xattrs_list_rwsem); + + return rc; +} + +/** + * Match or enqueue a PR or PW LDLM lock. + * + * Find or request an LDLM lock with xattr data. + * Since LDLM does not provide API for atomic match_or_enqueue, + * the function handles it with a separate enq lock. + * If successful, the function exits with the list lock held. + * + * \retval 0 no error occured + * \retval -ENOMEM not enough memory + */ +static int ll_xattr_find_get_lock(struct inode *inode, + struct lookup_intent *oit, + struct ptlrpc_request **req) +{ + ldlm_mode_t mode; + struct lustre_handle lockh = { 0 }; + struct md_op_data *op_data; + struct ll_inode_info *lli = ll_i2info(inode); + struct ldlm_enqueue_info einfo = { .ei_type = LDLM_IBITS, + .ei_mode = it_to_lock_mode(oit), + .ei_cb_bl = ll_md_blocking_ast, + .ei_cb_cp = ldlm_completion_ast }; + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct obd_export *exp = sbi->ll_md_exp; + int rc; + + + + mutex_lock(&lli->lli_xattrs_enq_lock); + /* Try matching first. */ + mode = ll_take_md_lock(inode, MDS_INODELOCK_XATTR, &lockh, 0, + oit->it_op == IT_SETXATTR ? LCK_PW : + (LCK_PR | LCK_PW)); + if (mode != 0) { + /* fake oit in mdc_revalidate_lock() manner */ + oit->d.lustre.it_lock_handle = lockh.cookie; + oit->d.lustre.it_lock_mode = mode; + goto out; + } + + /* Enqueue if the lock isn't cached locally. */ + op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, + LUSTRE_OPC_ANY, NULL); + if (IS_ERR(op_data)) { + mutex_unlock(&lli->lli_xattrs_enq_lock); + return PTR_ERR(op_data); + } + + op_data->op_valid = OBD_MD_FLXATTR | OBD_MD_FLXATTRLS | + OBD_MD_FLXATTRLOCKED; +#ifdef CONFIG_FS_POSIX_ACL + /* If working with ACLs, we would like to cache local ACLs */ + if (sbi->ll_flags & LL_SBI_RMT_CLIENT) + op_data->op_valid |= OBD_MD_FLRMTLGETFACL; +#endif + + rc = md_enqueue(exp, &einfo, oit, op_data, &lockh, NULL, 0, NULL, 0); + ll_finish_md_op_data(op_data); + + if (rc < 0) { + CDEBUG(D_CACHE, + "md_intent_lock failed with %d for fid "DFID"\n", + rc, PFID(ll_inode2fid(inode))); + mutex_unlock(&lli->lli_xattrs_enq_lock); + return rc; + } + + *req = (struct ptlrpc_request *)oit->d.lustre.it_data; +out: + down_write(&lli->lli_xattrs_list_rwsem); + mutex_unlock(&lli->lli_xattrs_enq_lock); + + return 0; +} + +/** + * Refill the xattr cache. + * + * Fetch and cache the whole of xattrs for @inode, acquiring + * a read or a write xattr lock depending on operation in @oit. + * Intent is dropped on exit unless the operation is setxattr. + * + * \retval 0 no error occured + * \retval -EPROTO network protocol error + * \retval -ENOMEM not enough memory for the cache + */ +static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit) +{ + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct ptlrpc_request *req = NULL; + const char *xdata, *xval, *xtail, *xvtail; + struct ll_inode_info *lli = ll_i2info(inode); + struct mdt_body *body; + __u32 *xsizes; + int rc = 0, i; + + + + rc = ll_xattr_find_get_lock(inode, oit, &req); + if (rc) + GOTO(out_no_unlock, rc); + + /* Do we have the data at this point? */ + if (ll_xattr_cache_valid(lli)) { + ll_stats_ops_tally(sbi, LPROC_LL_GETXATTR_HITS, 1); + GOTO(out_maybe_drop, rc = 0); + } + + /* Matched but no cache? Cancelled on error by a parallel refill. */ + if (unlikely(req == NULL)) { + CDEBUG(D_CACHE, "cancelled by a parallel getxattr\n"); + GOTO(out_maybe_drop, rc = -EIO); + } + + if (oit->d.lustre.it_status < 0) { + CDEBUG(D_CACHE, "getxattr intent returned %d for fid "DFID"\n", + oit->d.lustre.it_status, PFID(ll_inode2fid(inode))); + GOTO(out_destroy, rc = oit->d.lustre.it_status); + } + + body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); + if (body == NULL) { + CERROR("no MDT BODY in the refill xattr reply\n"); + GOTO(out_destroy, rc = -EPROTO); + } + /* do not need swab xattr data */ + xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA, + body->eadatasize); + xval = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS, + body->aclsize); + xsizes = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS_LENS, + body->max_mdsize * sizeof(__u32)); + if (xdata == NULL || xval == NULL || xsizes == NULL) { + CERROR("wrong setxattr reply\n"); + GOTO(out_destroy, rc = -EPROTO); + } + + xtail = xdata + body->eadatasize; + xvtail = xval + body->aclsize; + + CDEBUG(D_CACHE, "caching: xdata=%p xtail=%p\n", xdata, xtail); + + ll_xattr_cache_init(lli); + + for (i = 0; i < body->max_mdsize; i++) { + CDEBUG(D_CACHE, "caching [%s]=%.*s\n", xdata, *xsizes, xval); + /* Perform consistency checks: attr names and vals in pill */ + if (memchr(xdata, 0, xtail - xdata) == NULL) { + CERROR("xattr protocol violation (names are broken)\n"); + rc = -EPROTO; + } else if (xval + *xsizes > xvtail) { + CERROR("xattr protocol violation (vals are broken)\n"); + rc = -EPROTO; + } else if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_XATTR_ENOMEM)) { + rc = -ENOMEM; + } else { + rc = ll_xattr_cache_add(&lli->lli_xattrs, xdata, xval, + *xsizes); + } + if (rc < 0) { + ll_xattr_cache_destroy_locked(lli); + GOTO(out_destroy, rc); + } + xdata += strlen(xdata) + 1; + xval += *xsizes; + xsizes++; + } + + if (xdata != xtail || xval != xvtail) + CERROR("a hole in xattr data\n"); + + ll_set_lock_data(sbi->ll_md_exp, inode, oit, NULL); + + GOTO(out_maybe_drop, rc); +out_maybe_drop: + /* drop lock on error or getxattr */ + if (rc != 0 || oit->it_op != IT_SETXATTR) + ll_intent_drop_lock(oit); + + if (rc != 0) + up_write(&lli->lli_xattrs_list_rwsem); +out_no_unlock: + ptlrpc_req_finished(req); + + return rc; + +out_destroy: + up_write(&lli->lli_xattrs_list_rwsem); + + ldlm_lock_decref_and_cancel((struct lustre_handle *) + &oit->d.lustre.it_lock_handle, + oit->d.lustre.it_lock_mode); + + goto out_no_unlock; +} + +/** + * Get an xattr value or list xattrs using the write-through cache. + * + * Get the xattr value (@valid has OBD_MD_FLXATTR set) of @name or + * list xattr names (@valid has OBD_MD_FLXATTRLS set) for @inode. + * The resulting value/list is stored in @buffer if the former + * is not larger than @size. + * + * \retval 0 no error occured + * \retval -EPROTO network protocol error + * \retval -ENOMEM not enough memory for the cache + * \retval -ERANGE the buffer is not large enough + * \retval -ENODATA no such attr or the list is empty + */ +int ll_xattr_cache_get(struct inode *inode, + const char *name, + char *buffer, + size_t size, + __u64 valid) +{ + struct lookup_intent oit = { .it_op = IT_GETXATTR }; + struct ll_inode_info *lli = ll_i2info(inode); + int rc = 0; + + + + LASSERT(!!(valid & OBD_MD_FLXATTR) ^ !!(valid & OBD_MD_FLXATTRLS)); + + down_read(&lli->lli_xattrs_list_rwsem); + if (!ll_xattr_cache_valid(lli)) { + up_read(&lli->lli_xattrs_list_rwsem); + rc = ll_xattr_cache_refill(inode, &oit); + if (rc) + return rc; + downgrade_write(&lli->lli_xattrs_list_rwsem); + } else { + ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR_HITS, 1); + } + + if (valid & OBD_MD_FLXATTR) { + struct ll_xattr_entry *xattr; + + rc = ll_xattr_cache_find(&lli->lli_xattrs, name, &xattr); + if (rc == 0) { + rc = xattr->xe_vallen; + /* zero size means we are only requested size in rc */ + if (size != 0) { + if (size >= xattr->xe_vallen) + memcpy(buffer, xattr->xe_value, + xattr->xe_vallen); + else + rc = -ERANGE; + } + } + } else if (valid & OBD_MD_FLXATTRLS) { + rc = ll_xattr_cache_list(&lli->lli_xattrs, + size ? buffer : NULL, size); + } + + GOTO(out, rc); +out: + up_read(&lli->lli_xattrs_list_rwsem); + + return rc; +} + + +/** + * Set/update an xattr value or remove xattr using the write-through cache. + * + * Set/update the xattr value (if @valid has OBD_MD_FLXATTR) of @name to @newval + * or + * remove the xattr @name (@valid has OBD_MD_FLXATTRRM set) from @inode. + * @flags is either XATTR_CREATE or XATTR_REPLACE as defined by setxattr(2) + * + * \retval 0 no error occured + * \retval -EPROTO network protocol error + * \retval -ENOMEM not enough memory for the cache + * \retval -ERANGE the buffer is not large enough + * \retval -ENODATA no such attr (in the removal case) + */ +int ll_xattr_cache_update(struct inode *inode, + const char *name, + const char *newval, + size_t size, + __u64 valid, + int flags) +{ + struct lookup_intent oit = { .it_op = IT_SETXATTR }; + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct ptlrpc_request *req = NULL; + struct ll_inode_info *lli = ll_i2info(inode); + struct obd_capa *oc; + int rc; + + + + LASSERT(!!(valid & OBD_MD_FLXATTR) ^ !!(valid & OBD_MD_FLXATTRRM)); + + rc = ll_xattr_cache_refill(inode, &oit); + if (rc) + return rc; + + oc = ll_mdscapa_get(inode); + rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, + valid | OBD_MD_FLXATTRLOCKED, name, newval, + size, 0, flags, ll_i2suppgid(inode), &req); + capa_put(oc); + + if (rc) { + ll_intent_drop_lock(&oit); + GOTO(out, rc); + } + + if (valid & OBD_MD_FLXATTR) + rc = ll_xattr_cache_add(&lli->lli_xattrs, name, newval, size); + else if (valid & OBD_MD_FLXATTRRM) + rc = ll_xattr_cache_del(&lli->lli_xattrs, name); + + ll_intent_drop_lock(&oit); + GOTO(out, rc); +out: + up_write(&lli->lli_xattrs_list_rwsem); + ptlrpc_req_finished(req); + + return rc; +} diff --git a/drivers/staging/lustre/lustre/lmv/Makefile b/drivers/staging/lustre/lustre/lmv/Makefile index 8cc81ade126c..9162ef724aea 100644 --- a/drivers/staging/lustre/lustre/lmv/Makefile +++ b/drivers/staging/lustre/lustre/lmv/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_LUSTRE_FS) += lmv.o -lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o lproc_lmv.o - +lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o +lmv-$(CONFIG_PROC_FS) += lproc_lmv.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c index edb5a3a99d57..b355d01410e4 100644 --- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c +++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c @@ -41,10 +41,6 @@ #include <lprocfs_status.h> #include <obd_class.h> -#ifndef LPROCFS -static struct lprocfs_vars lprocfs_module_vars[] = { {0} }; -static struct lprocfs_vars lprocfs_obd_vars[] = { {0} }; -#else static int lmv_numobd_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = (struct obd_device *)m->private; @@ -226,7 +222,6 @@ struct file_operations lmv_proc_target_fops = { .release = seq_release, }; -#endif /* LPROCFS */ void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars) { lvars->module_vars = lprocfs_lmv_module_vars; diff --git a/drivers/staging/lustre/lustre/lov/Makefile b/drivers/staging/lustre/lustre/lov/Makefile index 67eaec29bef1..9a5f26d5558d 100644 --- a/drivers/staging/lustre/lustre/lov/Makefile +++ b/drivers/staging/lustre/lustre/lov/Makefile @@ -1,8 +1,9 @@ obj-$(CONFIG_LUSTRE_FS) += lov.o -lov-y := lov_log.o lov_obd.o lov_pack.o lproc_lov.o lov_offset.o lov_merge.o \ +lov-y := lov_log.o lov_obd.o lov_pack.o lov_offset.o lov_merge.o \ lov_request.o lov_ea.o lov_dev.o lov_object.o lov_page.o \ lov_lock.o lov_io.o lovsub_dev.o lovsub_object.o lovsub_page.o \ lovsub_lock.o lovsub_io.o lov_pool.o +lov-$(CONFIG_PROC_FS) += lproc_lov.o diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 4276124d92e9..3965d5e4e725 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -168,6 +168,22 @@ enum lov_layout_type { LLT_NR }; +static inline char *llt2str(enum lov_layout_type llt) +{ + switch (llt) { + case LLT_EMPTY: + return "EMPTY"; + case LLT_RAID0: + return "RAID0"; + case LLT_RELEASED: + return "RELEASED"; + case LLT_NR: + LBUG(); + } + LBUG(); + return ""; +} + /** * lov-specific file state. * diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index 796da8930876..2b22a03c038e 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -283,8 +283,8 @@ void lsm_free_plain(struct lov_stripe_md *lsm); int lovea_destroy_object(struct lov_obd *lov, struct lov_stripe_md *lsm, struct obdo *oa, void *data); /* lproc_lov.c */ -extern struct file_operations lov_proc_target_fops; #ifdef LPROCFS +extern const struct file_operations lov_proc_target_fops; void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars); #else static inline void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars) diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index 2792fa5c4be2..5a6ab70ed0a1 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -947,14 +947,23 @@ int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, LASSERTF(0, "invalid type %d\n", io->ci_type); case CIT_MISC: case CIT_FSYNC: - result = +1; + result = 1; break; case CIT_SETATTR: + /* the truncate to 0 is managed by MDT: + * - in open, for open O_TRUNC + * - in setattr, for truncate + */ + /* the truncate is for size > 0 so triggers a restore */ + if (cl_io_is_trunc(io)) + io->ci_restore_needed = 1; + result = -ENODATA; + break; case CIT_READ: case CIT_WRITE: case CIT_FAULT: - /* TODO: need to restore the file. */ - result = -EBADF; + io->ci_restore_needed = 1; + result = -ENODATA; break; } if (result == 0) { diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index cf2fa8abfb1d..df8b5b5b7cf4 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -393,13 +393,13 @@ static int lov_print_empty(const struct lu_env *env, void *cookie, static int lov_print_raid0(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *o) { - struct lov_object *lov = lu2lov(o); - struct lov_layout_raid0 *r0 = lov_r0(lov); - struct lov_stripe_md *lsm = lov->lo_lsm; - int i; + struct lov_object *lov = lu2lov(o); + struct lov_layout_raid0 *r0 = lov_r0(lov); + struct lov_stripe_md *lsm = lov->lo_lsm; + int i; - (*p)(env, cookie, "stripes: %d, %svalid, lsm{%p 0x%08X %d %u %u}: \n", - r0->lo_nr, lov->lo_layout_invalid ? "in" : "", lsm, + (*p)(env, cookie, "stripes: %d, %s, lsm{%p 0x%08X %d %u %u}:\n", + r0->lo_nr, lov->lo_layout_invalid ? "invalid" : "valid", lsm, lsm->lsm_magic, atomic_read(&lsm->lsm_refc), lsm->lsm_stripe_count, lsm->lsm_layout_gen); for (i = 0; i < r0->lo_nr; ++i) { @@ -408,8 +408,9 @@ static int lov_print_raid0(const struct lu_env *env, void *cookie, if (r0->lo_sub[i] != NULL) { sub = lovsub2lu(r0->lo_sub[i]); lu_object_print(env, cookie, p, sub); - } else + } else { (*p)(env, cookie, "sub %d absent\n", i); + } } return 0; } @@ -417,7 +418,14 @@ static int lov_print_raid0(const struct lu_env *env, void *cookie, static int lov_print_released(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *o) { - (*p)(env, cookie, "released\n"); + struct lov_object *lov = lu2lov(o); + struct lov_stripe_md *lsm = lov->lo_lsm; + + (*p)(env, cookie, + "released: %s, lsm{%p 0x%08X %d %u %u}:\n", + lov->lo_layout_invalid ? "invalid" : "valid", lsm, + lsm->lsm_magic, atomic_read(&lsm->lsm_refc), + lsm->lsm_stripe_count, lsm->lsm_layout_gen); return 0; } @@ -662,6 +670,10 @@ static int lov_layout_change(const struct lu_env *unused, return PTR_ERR(env); } + CDEBUG(D_INODE, DFID" from %s to %s\n", + PFID(lu_object_fid(lov2lu(lov))), + llt2str(lov->lo_type), llt2str(llt)); + old_ops = &lov_dispatch[lov->lo_type]; new_ops = &lov_dispatch[llt]; @@ -750,8 +762,9 @@ static int lov_conf_set(const struct lu_env *env, struct cl_object *obj, if (conf->u.coc_md != NULL) lsm = conf->u.coc_md->lsm; if ((lsm == NULL && lov->lo_lsm == NULL) || - (lsm != NULL && lov->lo_lsm != NULL && - lov->lo_lsm->lsm_layout_gen == lsm->lsm_layout_gen)) { + ((lsm != NULL && lov->lo_lsm != NULL) && + (lov->lo_lsm->lsm_layout_gen == lsm->lsm_layout_gen) && + (lov->lo_lsm->lsm_pattern == lsm->lsm_pattern))) { /* same version of layout */ lov->lo_layout_invalid = false; GOTO(out, result = 0); @@ -767,6 +780,8 @@ static int lov_conf_set(const struct lu_env *env, struct cl_object *obj, out: lov_conf_unlock(lov); + CDEBUG(D_INODE, DFID" lo_layout_invalid=%d\n", + PFID(lu_object_fid(lov2lu(lov))), lov->lo_layout_invalid); return result; } diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index ec6f6e0572ae..27ed27e6fa6a 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -105,24 +105,22 @@ void lov_dump_lmm(int level, void *lmm) { int magic; - magic = ((struct lov_mds_md_v1 *)(lmm))->lmm_magic; + magic = le32_to_cpu(((struct lov_mds_md *)lmm)->lmm_magic); switch (magic) { case LOV_MAGIC_V1: - return lov_dump_lmm_v1(level, (struct lov_mds_md_v1 *)(lmm)); + lov_dump_lmm_v1(level, (struct lov_mds_md_v1 *)lmm); + break; case LOV_MAGIC_V3: - return lov_dump_lmm_v3(level, (struct lov_mds_md_v3 *)(lmm)); + lov_dump_lmm_v3(level, (struct lov_mds_md_v3 *)lmm); + break; default: - CERROR("Cannot recognize lmm_magic %x", magic); + CDEBUG(level, "unrecognized lmm_magic %x, assuming %x\n", + magic, LOV_MAGIC_V1); + lov_dump_lmm_common(level, lmm); + break; } - return; } -#define LMM_ASSERT(test) \ -do { \ - if (!(test)) lov_dump_lmm(D_ERROR, lmm); \ - LASSERT(test); /* so we know what assertion failed */ \ -} while (0) - /* Pack LOV object metadata for disk storage. It is packed in LE byte * order and is opaque to the networking layer. * diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c index 15744e13a3f2..bd7da56b0713 100644 --- a/drivers/staging/lustre/lustre/lov/lproc_lov.c +++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c @@ -41,7 +41,6 @@ #include <linux/seq_file.h> #include "lov_internal.h" -#ifdef LPROCFS static int lov_stripesize_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = (struct obd_device *)m->private; @@ -260,29 +259,29 @@ LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesfree); LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesavail); struct lprocfs_vars lprocfs_lov_obd_vars[] = { - { "uuid", &lov_uuid_fops, 0, 0 }, - { "stripesize", &lov_stripesize_fops, 0 }, - { "stripeoffset", &lov_stripeoffset_fops, 0 }, - { "stripecount", &lov_stripecount_fops, 0 }, - { "stripetype", &lov_stripetype_fops, 0 }, - { "numobd", &lov_numobd_fops, 0, 0 }, - { "activeobd", &lov_activeobd_fops, 0, 0 }, - { "filestotal", &lov_filestotal_fops, 0, 0 }, - { "filesfree", &lov_filesfree_fops, 0, 0 }, - /*{ "filegroups", lprocfs_rd_filegroups, 0, 0 },*/ - { "blocksize", &lov_blksize_fops, 0, 0 }, - { "kbytestotal", &lov_kbytestotal_fops, 0, 0 }, - { "kbytesfree", &lov_kbytesfree_fops, 0, 0 }, - { "kbytesavail", &lov_kbytesavail_fops, 0, 0 }, - { "desc_uuid", &lov_desc_uuid_fops, 0, 0 }, - { 0 } + { "uuid", &lov_uuid_fops, NULL, 0 }, + { "stripesize", &lov_stripesize_fops, NULL }, + { "stripeoffset", &lov_stripeoffset_fops, NULL }, + { "stripecount", &lov_stripecount_fops, NULL }, + { "stripetype", &lov_stripetype_fops, NULL }, + { "numobd", &lov_numobd_fops, NULL, 0 }, + { "activeobd", &lov_activeobd_fops, NULL, 0 }, + { "filestotal", &lov_filestotal_fops, NULL, 0 }, + { "filesfree", &lov_filesfree_fops, NULL, 0 }, + /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/ + { "blocksize", &lov_blksize_fops, NULL, 0 }, + { "kbytestotal", &lov_kbytestotal_fops, NULL, 0 }, + { "kbytesfree", &lov_kbytesfree_fops, NULL, 0 }, + { "kbytesavail", &lov_kbytesavail_fops, NULL, 0 }, + { "desc_uuid", &lov_desc_uuid_fops, NULL, 0 }, + { NULL } }; LPROC_SEQ_FOPS_RO_TYPE(lov, numrefs); static struct lprocfs_vars lprocfs_lov_module_vars[] = { - { "num_refs", &lov_numrefs_fops, 0, 0 }, - { 0 } + { "num_refs", &lov_numrefs_fops, NULL, 0 }, + { NULL } }; void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars) @@ -291,11 +290,10 @@ void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars) lvars->obd_vars = lprocfs_lov_obd_vars; } -struct file_operations lov_proc_target_fops = { +const struct file_operations lov_proc_target_fops = { .owner = THIS_MODULE, .open = lov_target_seq_open, .read = seq_read, .llseek = seq_lseek, .release = lprocfs_seq_release, }; -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/lvfs/Makefile b/drivers/staging/lustre/lustre/lvfs/Makefile index f50b1c574385..e0367c3fc416 100644 --- a/drivers/staging/lustre/lustre/lvfs/Makefile +++ b/drivers/staging/lustre/lustre/lvfs/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_LUSTRE_FS) += lvfs.o -lvfs-y := lvfs_linux.o fsfilt.o lvfs_lib.o +lvfs-y := lvfs_linux.o fsfilt.o +lvfs-$(CONFIG_PROC_FS) += lvfs_lib.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c b/drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c deleted file mode 100644 index ee75994003e1..000000000000 --- a/drivers/staging/lustre/lustre/lvfs/fsfilt_ext3.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/lvfs/fsfilt_ext3.c - * - * Author: Andreas Dilger <adilger@clusterfs.com> - */ - -#define DEBUG_SUBSYSTEM S_FILTER - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/pagemap.h> -#include <ldiskfs/ldiskfs_config.h> -#include <ext4/ext4.h> -#include <ext4/ext4_jbd2.h> -#include <linux/bitops.h> -#include <linux/quota.h> - -#include <linux/libcfs/libcfs.h> -#include <lustre_fsfilt.h> -#include <obd.h> -#include <linux/lustre_compat25.h> -#include <linux/lprocfs_status.h> - -#include <ext4/ext4_extents.h> - -#ifdef HAVE_EXT_PBLOCK /* Name changed to ext4_ext_pblock for kernel 2.6.35 */ -#define ext3_ext_pblock(ex) ext_pblock((ex)) -#endif - -/* for kernels 2.6.18 and later */ -#define FSFILT_SINGLEDATA_TRANS_BLOCKS(sb) EXT3_SINGLEDATA_TRANS_BLOCKS(sb) - -#define fsfilt_ext3_ext_insert_extent(handle, inode, path, newext, flag) \ - ext3_ext_insert_extent(handle, inode, path, newext, flag) - -#define ext3_mb_discard_inode_preallocations(inode) \ - ext3_discard_preallocations(inode) - -#define fsfilt_log_start_commit(journal, tid) jbd2_log_start_commit(journal, tid) -#define fsfilt_log_wait_commit(journal, tid) jbd2_log_wait_commit(journal, tid) - -static struct kmem_cache *fcb_cache; - -struct fsfilt_cb_data { - struct ext4_journal_cb_entry cb_jcb; /* private data - MUST BE FIRST */ - fsfilt_cb_t cb_func; /* MDS/OBD completion function */ - struct obd_device *cb_obd; /* MDS/OBD completion device */ - __u64 cb_last_rcvd; /* MDS/OST last committed operation */ - void *cb_data; /* MDS/OST completion function data */ -}; - -static char *fsfilt_ext3_get_label(struct super_block *sb) -{ - return EXT3_SB(sb)->s_es->s_volume_name; -} - -/* kernel has ext4_blocks_for_truncate since linux-3.1.1 */ -# include <ext4/truncate.h> - -/* - * We don't currently need any additional blocks for rmdir and - * unlink transactions because we are storing the OST oa_id inside - * the inode (which we will be changing anyways as part of this - * transaction). - */ -static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, - int logs) -{ - /* For updates to the last received file */ - int nblocks = FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb); - journal_t *journal; - void *handle; - - if (current->journal_info) { - CDEBUG(D_INODE, "increasing refcount on %p\n", - current->journal_info); - goto journal_start; - } - - switch(op) { - case FSFILT_OP_UNLINK: - /* delete one file + create/update logs for each stripe */ - nblocks += EXT3_DELETE_TRANS_BLOCKS(inode->i_sb); - nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + - FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs; - break; - case FSFILT_OP_CANCEL_UNLINK: - LASSERT(logs == 1); - - /* blocks for log header bitmap update OR - * blocks for catalog header bitmap update + unlink of logs + - * blocks for delete the inode (include blocks truncating). */ - nblocks = (LLOG_CHUNK_SIZE >> inode->i_blkbits) + - EXT3_DELETE_TRANS_BLOCKS(inode->i_sb) + - ext4_blocks_for_truncate(inode) + 3; - break; - default: CERROR("unknown transaction start op %d\n", op); - LBUG(); - } - - LASSERT(current->journal_info == desc_private); - journal = EXT3_SB(inode->i_sb)->s_journal; - if (nblocks > journal->j_max_transaction_buffers) { - CWARN("too many credits %d for op %ux%u using %d instead\n", - nblocks, op, logs, journal->j_max_transaction_buffers); - nblocks = journal->j_max_transaction_buffers; - } - - journal_start: - LASSERTF(nblocks > 0, "can't start %d credit transaction\n", nblocks); - handle = ext3_journal_start(inode, nblocks); - - if (!IS_ERR(handle)) - LASSERT(current->journal_info == handle); - else - CERROR("error starting handle for op %u (%u credits): rc %ld\n", - op, nblocks, PTR_ERR(handle)); - return handle; -} - -static int fsfilt_ext3_commit(struct inode *inode, void *h, int force_sync) -{ - int rc; - handle_t *handle = h; - - LASSERT(current->journal_info == handle); - if (force_sync) - handle->h_sync = 1; /* recovery likes this */ - - rc = ext3_journal_stop(handle); - - return rc; -} - -#ifndef EXT3_EXTENTS_FL -#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ -#endif - -#ifndef EXT_ASSERT -#define EXT_ASSERT(cond) BUG_ON(!(cond)) -#endif - -#define EXT_GENERATION(inode) (EXT4_I(inode)->i_ext_generation) -#define ext3_ext_base inode -#define ext3_ext_base2inode(inode) (inode) -#define EXT_DEPTH(inode) ext_depth(inode) -#define fsfilt_ext3_ext_walk_space(inode, block, num, cb, cbdata) \ - ext3_ext_walk_space(inode, block, num, cb, cbdata); - -struct bpointers { - unsigned long *blocks; - unsigned long start; - int num; - int init_num; - int create; -}; - -static long ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, - unsigned long block, int *aflags) -{ - struct ext3_inode_info *ei = EXT3_I(inode); - unsigned long bg_start; - unsigned long colour; - int depth; - - if (path) { - struct ext3_extent *ex; - depth = path->p_depth; - - /* try to predict block placement */ - if ((ex = path[depth].p_ext)) - return ext4_ext_pblock(ex) + (block - le32_to_cpu(ex->ee_block)); - - /* it looks index is empty - * try to find starting from index itself */ - if (path[depth].p_bh) - return path[depth].p_bh->b_blocknr; - } - - /* OK. use inode's group */ - bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + - le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); - colour = (current->pid % 16) * - (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); - return bg_start + colour + block; -} - -#define ll_unmap_underlying_metadata(sb, blocknr) \ - unmap_underlying_metadata((sb)->s_bdev, blocknr) - -#ifndef EXT3_MB_HINT_GROUP_ALLOC -static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base, - struct ext3_ext_path *path, unsigned long block, - unsigned long *count, int *err) -{ - unsigned long pblock, goal; - int aflags = 0; - struct inode *inode = ext3_ext_base2inode(base); - - goal = ext3_ext_find_goal(inode, path, block, &aflags); - aflags |= 2; /* block have been already reserved */ - pblock = ext3_mb_new_blocks(handle, inode, goal, count, aflags, err); - return pblock; - -} -#else -static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base, - struct ext3_ext_path *path, unsigned long block, - unsigned long *count, int *err) -{ - struct inode *inode = ext3_ext_base2inode(base); - struct ext3_allocation_request ar; - unsigned long pblock; - int aflags; - - /* find neighbour allocated blocks */ - ar.lleft = block; - *err = ext3_ext_search_left(base, path, &ar.lleft, &ar.pleft); - if (*err) - return 0; - ar.lright = block; - *err = ext3_ext_search_right(base, path, &ar.lright, &ar.pright); - if (*err) - return 0; - - /* allocate new block */ - ar.goal = ext3_ext_find_goal(inode, path, block, &aflags); - ar.inode = inode; - ar.logical = block; - ar.len = *count; - ar.flags = EXT3_MB_HINT_DATA; - pblock = ext3_mb_new_blocks(handle, &ar, err); - *count = ar.len; - return pblock; -} -#endif - -static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, - struct ext3_ext_path *path, - struct ext3_ext_cache *cex, -#ifdef HAVE_EXT_PREPARE_CB_EXTENT - struct ext3_extent *ex, -#endif - void *cbdata) -{ - struct bpointers *bp = cbdata; - struct inode *inode = ext3_ext_base2inode(base); - struct ext3_extent nex; - unsigned long pblock; - unsigned long tgen; - int err, i; - unsigned long count; - handle_t *handle; - -#ifdef EXT3_EXT_CACHE_EXTENT - if (cex->ec_type == EXT3_EXT_CACHE_EXTENT) -#else - if ((cex->ec_len != 0) && (cex->ec_start != 0)) -#endif - { - err = EXT_CONTINUE; - goto map; - } - - if (bp->create == 0) { - i = 0; - if (cex->ec_block < bp->start) - i = bp->start - cex->ec_block; - if (i >= cex->ec_len) - CERROR("nothing to do?! i = %d, e_num = %u\n", - i, cex->ec_len); - for (; i < cex->ec_len && bp->num; i++) { - *(bp->blocks) = 0; - bp->blocks++; - bp->num--; - bp->start++; - } - - return EXT_CONTINUE; - } - - tgen = EXT_GENERATION(base); - count = ext3_ext_calc_credits_for_insert(base, path); - - handle = ext3_journal_start(inode, count+EXT3_ALLOC_NEEDED+1); - if (IS_ERR(handle)) { - return PTR_ERR(handle); - } - - if (tgen != EXT_GENERATION(base)) { - /* the tree has changed. so path can be invalid at moment */ - ext3_journal_stop(handle); - return EXT_REPEAT; - } - - /* In 2.6.32 kernel, ext4_ext_walk_space()'s callback func is not - * protected by i_data_sem as whole. so we patch it to store - * generation to path and now verify the tree hasn't changed */ - down_write((&EXT4_I(inode)->i_data_sem)); - - /* validate extent, make sure the extent tree does not changed */ - if (EXT_GENERATION(base) != path[0].p_generation) { - /* cex is invalid, try again */ - up_write(&EXT4_I(inode)->i_data_sem); - ext3_journal_stop(handle); - return EXT_REPEAT; - } - - count = cex->ec_len; - pblock = new_blocks(handle, base, path, cex->ec_block, &count, &err); - if (!pblock) - goto out; - EXT_ASSERT(count <= cex->ec_len); - - /* insert new extent */ - nex.ee_block = cpu_to_le32(cex->ec_block); - ext3_ext_store_pblock(&nex, pblock); - nex.ee_len = cpu_to_le16(count); - err = fsfilt_ext3_ext_insert_extent(handle, base, path, &nex, 0); - if (err) { - /* free data blocks we just allocated */ - /* not a good idea to call discard here directly, - * but otherwise we'd need to call it every free() */ -#ifdef EXT3_MB_HINT_GROUP_ALLOC - ext3_mb_discard_inode_preallocations(inode); -#endif -#ifdef HAVE_EXT_FREE_BLOCK_WITH_BUFFER_HEAD /* Introduced in 2.6.32-rc7 */ - ext3_free_blocks(handle, inode, NULL, ext4_ext_pblock(&nex), - cpu_to_le16(nex.ee_len), 0); -#else - ext3_free_blocks(handle, inode, ext4_ext_pblock(&nex), - cpu_to_le16(nex.ee_len), 0); -#endif - goto out; - } - - /* - * Putting len of the actual extent we just inserted, - * we are asking ext3_ext_walk_space() to continue - * scaning after that block - */ - cex->ec_len = le16_to_cpu(nex.ee_len); - cex->ec_start = ext4_ext_pblock(&nex); - BUG_ON(le16_to_cpu(nex.ee_len) == 0); - BUG_ON(le32_to_cpu(nex.ee_block) != cex->ec_block); - -out: - up_write((&EXT4_I(inode)->i_data_sem)); - ext3_journal_stop(handle); -map: - if (err >= 0) { - /* map blocks */ - if (bp->num == 0) { - CERROR("hmm. why do we find this extent?\n"); - CERROR("initial space: %lu:%u\n", - bp->start, bp->init_num); -#ifdef EXT3_EXT_CACHE_EXTENT - CERROR("current extent: %u/%u/%llu %d\n", - cex->ec_block, cex->ec_len, - (unsigned long long)cex->ec_start, - cex->ec_type); -#else - CERROR("current extent: %u/%u/%llu\n", - cex->ec_block, cex->ec_len, - (unsigned long long)cex->ec_start); -#endif - } - i = 0; - if (cex->ec_block < bp->start) - i = bp->start - cex->ec_block; - if (i >= cex->ec_len) - CERROR("nothing to do?! i = %d, e_num = %u\n", - i, cex->ec_len); - for (; i < cex->ec_len && bp->num; i++) { - *(bp->blocks) = cex->ec_start + i; -#ifdef EXT3_EXT_CACHE_EXTENT - if (cex->ec_type != EXT3_EXT_CACHE_EXTENT) -#else - if ((cex->ec_len == 0) || (cex->ec_start == 0)) -#endif - { - /* unmap any possible underlying metadata from - * the block device mapping. bug 6998. */ - ll_unmap_underlying_metadata(inode->i_sb, - *(bp->blocks)); - } - bp->blocks++; - bp->num--; - bp->start++; - } - } - return err; -} - -int fsfilt_map_nblocks(struct inode *inode, unsigned long block, - unsigned long num, unsigned long *blocks, - int create) -{ - struct ext3_ext_base *base = inode; - struct bpointers bp; - int err; - - CDEBUG(D_OTHER, "blocks %lu-%lu requested for inode %u\n", - block, block + num - 1, (unsigned) inode->i_ino); - - bp.blocks = blocks; - bp.start = block; - bp.init_num = bp.num = num; - bp.create = create; - - err = fsfilt_ext3_ext_walk_space(base, block, num, - ext3_ext_new_extent_cb, &bp); - ext3_ext_invalidate_cache(base); - - return err; -} - -int fsfilt_ext3_map_ext_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, - int create) -{ - int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; - int rc = 0, i = 0; - struct page *fp = NULL; - int clen = 0; - - CDEBUG(D_OTHER, "inode %lu: map %d pages from %lu\n", - inode->i_ino, pages, (*page)->index); - - /* pages are sorted already. so, we just have to find - * contig. space and process them properly */ - while (i < pages) { - if (fp == NULL) { - /* start new extent */ - fp = *page++; - clen = 1; - i++; - continue; - } else if (fp->index + clen == (*page)->index) { - /* continue the extent */ - page++; - clen++; - i++; - continue; - } - - /* process found extent */ - rc = fsfilt_map_nblocks(inode, fp->index * blocks_per_page, - clen * blocks_per_page, blocks, - create); - if (rc) - GOTO(cleanup, rc); - - /* look for next extent */ - fp = NULL; - blocks += blocks_per_page * clen; - } - - if (fp) - rc = fsfilt_map_nblocks(inode, fp->index * blocks_per_page, - clen * blocks_per_page, blocks, - create); -cleanup: - return rc; -} - -int fsfilt_ext3_map_bm_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, - int create) -{ - int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits; - unsigned long *b; - int rc = 0, i; - - for (i = 0, b = blocks; i < pages; i++, page++) { - rc = ext3_map_inode_page(inode, *page, b, create); - if (rc) { - CERROR("ino %lu, blk %lu create %d: rc %d\n", - inode->i_ino, *b, create, rc); - break; - } - - b += blocks_per_page; - } - return rc; -} - -int fsfilt_ext3_map_inode_pages(struct inode *inode, struct page **page, - int pages, unsigned long *blocks, - int create, struct mutex *optional_mutex) -{ - int rc; - - if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { - rc = fsfilt_ext3_map_ext_inode_pages(inode, page, pages, - blocks, create); - return rc; - } - if (optional_mutex != NULL) - mutex_lock(optional_mutex); - rc = fsfilt_ext3_map_bm_inode_pages(inode, page, pages, blocks, create); - if (optional_mutex != NULL) - mutex_unlock(optional_mutex); - - return rc; -} - -int fsfilt_ext3_read(struct inode *inode, void *buf, int size, loff_t *offs) -{ - unsigned long block; - struct buffer_head *bh; - int err, blocksize, csize, boffs, osize = size; - - /* prevent reading after eof */ - spin_lock(&inode->i_lock); - if (i_size_read(inode) < *offs + size) { - size = i_size_read(inode) - *offs; - spin_unlock(&inode->i_lock); - if (size < 0) { - CDEBUG(D_EXT2, "size %llu is too short for read @%llu\n", - i_size_read(inode), *offs); - return -EBADR; - } else if (size == 0) { - return 0; - } - } else { - spin_unlock(&inode->i_lock); - } - - blocksize = 1 << inode->i_blkbits; - - while (size > 0) { - block = *offs >> inode->i_blkbits; - boffs = *offs & (blocksize - 1); - csize = min(blocksize - boffs, size); - bh = ext3_bread(NULL, inode, block, 0, &err); - if (!bh) { - CERROR("can't read block: %d\n", err); - return err; - } - - memcpy(buf, bh->b_data + boffs, csize); - brelse(bh); - - *offs += csize; - buf += csize; - size -= csize; - } - return osize; -} -EXPORT_SYMBOL(fsfilt_ext3_read); - -static int fsfilt_ext3_read_record(struct file * file, void *buf, - int size, loff_t *offs) -{ - int rc; - rc = fsfilt_ext3_read(file->f_dentry->d_inode, buf, size, offs); - if (rc > 0) - rc = 0; - return rc; -} - -int fsfilt_ext3_write_handle(struct inode *inode, void *buf, int bufsize, - loff_t *offs, handle_t *handle) -{ - struct buffer_head *bh = NULL; - loff_t old_size = i_size_read(inode), offset = *offs; - loff_t new_size = i_size_read(inode); - unsigned long block; - int err = 0, blocksize = 1 << inode->i_blkbits, size, boffs; - - while (bufsize > 0) { - if (bh != NULL) - brelse(bh); - - block = offset >> inode->i_blkbits; - boffs = offset & (blocksize - 1); - size = min(blocksize - boffs, bufsize); - bh = ext3_bread(handle, inode, block, 1, &err); - if (!bh) { - CERROR("can't read/create block: %d\n", err); - break; - } - - err = ext3_journal_get_write_access(handle, bh); - if (err) { - CERROR("journal_get_write_access() returned error %d\n", - err); - break; - } - LASSERT(bh->b_data + boffs + size <= bh->b_data + bh->b_size); - memcpy(bh->b_data + boffs, buf, size); - err = ext3_journal_dirty_metadata(handle, bh); - if (err) { - CERROR("journal_dirty_metadata() returned error %d\n", - err); - break; - } - if (offset + size > new_size) - new_size = offset + size; - offset += size; - bufsize -= size; - buf += size; - } - if (bh) - brelse(bh); - - /* correct in-core and on-disk sizes */ - if (new_size > i_size_read(inode)) { - spin_lock(&inode->i_lock); - if (new_size > i_size_read(inode)) - i_size_write(inode, new_size); - if (i_size_read(inode) > EXT3_I(inode)->i_disksize) - EXT3_I(inode)->i_disksize = i_size_read(inode); - if (i_size_read(inode) > old_size) { - spin_unlock(&inode->i_lock); - mark_inode_dirty(inode); - } else { - spin_unlock(&inode->i_lock); - } - } - - if (err == 0) - *offs = offset; - return err; -} -EXPORT_SYMBOL(fsfilt_ext3_write_handle); - -static int fsfilt_ext3_write_record(struct file *file, void *buf, int bufsize, - loff_t *offs, int force_sync) -{ - struct inode *inode = file->f_dentry->d_inode; - handle_t *handle; - int err, block_count = 0, blocksize; - - /* Determine how many transaction credits are needed */ - blocksize = 1 << inode->i_blkbits; - block_count = (*offs & (blocksize - 1)) + bufsize; - block_count = (block_count + blocksize - 1) >> inode->i_blkbits; - - handle = ext3_journal_start(inode, - block_count * EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + 2); - if (IS_ERR(handle)) { - CERROR("can't start transaction for %d blocks (%d bytes)\n", - block_count * EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + 2, - bufsize); - return PTR_ERR(handle); - } - - err = fsfilt_ext3_write_handle(inode, buf, bufsize, offs, handle); - - if (!err && force_sync) - handle->h_sync = 1; /* recovery likes this */ - - ext3_journal_stop(handle); - - return err; -} - -static int fsfilt_ext3_setup(struct super_block *sb) -{ - if (!EXT3_HAS_COMPAT_FEATURE(sb, - EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { - CERROR("ext3 mounted without journal\n"); - return -EINVAL; - } - -#ifdef S_PDIROPS - CWARN("Enabling PDIROPS\n"); - set_opt(EXT3_SB(sb)->s_mount_opt, PDIROPS); - sb->s_flags |= S_PDIROPS; -#endif - if (!EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) - CWARN("filesystem doesn't have dir_index feature enabled\n"); - return 0; -} -static struct fsfilt_operations fsfilt_ext3_ops = { - .fs_type = "ext3", - .fs_owner = THIS_MODULE, - .fs_getlabel = fsfilt_ext3_get_label, - .fs_start = fsfilt_ext3_start, - .fs_commit = fsfilt_ext3_commit, - .fs_map_inode_pages = fsfilt_ext3_map_inode_pages, - .fs_write_record = fsfilt_ext3_write_record, - .fs_read_record = fsfilt_ext3_read_record, - .fs_setup = fsfilt_ext3_setup, -}; - -static int __init fsfilt_ext3_init(void) -{ - int rc; - - fcb_cache = kmem_cache_create("fsfilt_ext3_fcb", - sizeof(struct fsfilt_cb_data), 0, 0); - if (!fcb_cache) { - CERROR("error allocating fsfilt journal callback cache\n"); - GOTO(out, rc = -ENOMEM); - } - - rc = fsfilt_register_ops(&fsfilt_ext3_ops); - - if (rc) { - int err = kmem_cache_destroy(fcb_cache); - LASSERTF(err == 0, "error destroying new cache: rc %d\n", err); - } -out: - return rc; -} - -static void __exit fsfilt_ext3_exit(void) -{ - int rc; - - fsfilt_unregister_ops(&fsfilt_ext3_ops); - rc = kmem_cache_destroy(fcb_cache); - LASSERTF(rc == 0, "couldn't destroy fcb_cache slab\n"); -} - -module_init(fsfilt_ext3_init); -module_exit(fsfilt_ext3_exit); - -MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>"); -MODULE_DESCRIPTION("Lustre ext3 Filesystem Helper v0.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c b/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c index b21e40cdacab..7e47fc4a7e4e 100644 --- a/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c +++ b/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c @@ -43,7 +43,6 @@ #include <lustre_lib.h> #include <lprocfs_status.h> -#ifdef LPROCFS void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount) { struct lprocfs_counter *percpu_cntr; @@ -169,4 +168,3 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid) return rc; } EXPORT_SYMBOL(lprocfs_stats_alloc_one); -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/mdc/Makefile b/drivers/staging/lustre/lustre/mdc/Makefile index 93bae242e761..4c0bed14de80 100644 --- a/drivers/staging/lustre/lustre/mdc/Makefile +++ b/drivers/staging/lustre/lustre/mdc/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_LUSTRE_FS) += mdc.o -mdc-y := mdc_request.o mdc_reint.o lproc_mdc.o mdc_lib.o mdc_locks.o +mdc-y := mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o +mdc-$(CONFIG_PROC_FS) += lproc_mdc.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index e0b8f1866253..2663480a68c5 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -39,8 +39,6 @@ #include <obd_class.h> #include <lprocfs_status.h> -#ifdef LPROCFS - static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -214,4 +212,3 @@ void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars) lvars->module_vars = lprocfs_mdc_module_vars; lvars->obd_vars = lprocfs_mdc_obd_vars; } -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index 2aeff0ecec34..506982996c0e 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -69,9 +69,10 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, const void *data, int datalen, __u32 mode, __u32 uid, __u32 gid, cfs_cap_t capability, __u64 rdev); void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, - __u32 mode, __u64 rdev, __u32 flags, const void *data, + __u32 mode, __u64 rdev, __u64 flags, const void *data, int datalen); void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data); +void mdc_getxattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data); void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data); void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data, const char *old, int oldlen, const char *new, int newlen); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index b2de47803679..91f6876dac3f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -174,12 +174,13 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, } } -static __u64 mds_pack_open_flags(__u32 flags, __u32 mode) +static __u64 mds_pack_open_flags(__u64 flags, __u32 mode) { __u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE | MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS | MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK | - MDS_OPEN_BY_FID)); + MDS_OPEN_BY_FID | MDS_OPEN_LEASE | + MDS_OPEN_RELEASE)); if (flags & O_CREAT) cr_flags |= MDS_OPEN_CREAT; if (flags & O_EXCL) @@ -207,7 +208,7 @@ static __u64 mds_pack_open_flags(__u32 flags, __u32 mode) /* packing of MDS records */ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, - __u32 mode, __u64 rdev, __u32 flags, const void *lmm, + __u32 mode, __u64 rdev, __u64 flags, const void *lmm, int lmmlen) { struct mdt_rec_create *rec; @@ -234,6 +235,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, rec->cr_suppgid2 = op_data->op_suppgids[1]; rec->cr_bias = op_data->op_bias; rec->cr_umask = current_umask(); + rec->cr_old_handle = op_data->op_handle; mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1); /* the next buffer is child capa, which is used for replay, @@ -489,6 +491,28 @@ void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags, } } +static void mdc_hsm_release_pack(struct ptlrpc_request *req, + struct md_op_data *op_data) +{ + if (op_data->op_bias & MDS_HSM_RELEASE) { + struct close_data *data; + struct ldlm_lock *lock; + + data = req_capsule_client_get(&req->rq_pill, &RMF_CLOSE_DATA); + LASSERT(data != NULL); + + lock = ldlm_handle2lock(&op_data->op_lease_handle); + if (lock != NULL) { + data->cd_handle = lock->l_remote_handle; + ldlm_lock_put(lock); + } + ldlm_cli_cancel(&op_data->op_lease_handle, LCF_LOCAL); + + data->cd_data_version = op_data->op_data_version; + data->cd_fid = op_data->op_fid2; + } +} + void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { struct mdt_ioepoch *epoch; @@ -500,6 +524,7 @@ void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data) mdc_setattr_pack_rec(rec, op_data); mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1); mdc_ioepoch_pack(epoch, op_data); + mdc_hsm_release_pack(req, op_data); } static int mdc_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index fb5a9959bf7a..cc5490c3a603 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -75,6 +75,12 @@ EXPORT_SYMBOL(it_clear_disposition); int it_open_error(int phase, struct lookup_intent *it) { + if (it_disposition(it, DISP_OPEN_LEASE)) { + if (phase >= DISP_OPEN_LEASE) + return it->d.lustre.it_status; + else + return 0; + } if (it_disposition(it, DISP_OPEN_OPEN)) { if (phase >= DISP_OPEN_OPEN) return it->d.lustre.it_status; @@ -281,14 +287,21 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp, /* XXX: openlock is not cancelled for cross-refs. */ /* If inode is known, cancel conflicting OPEN locks. */ if (fid_is_sane(&op_data->op_fid2)) { - if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC)) - mode = LCK_CW; + if (it->it_flags & MDS_OPEN_LEASE) { /* try to get lease */ + if (it->it_flags & FMODE_WRITE) + mode = LCK_EX; + else + mode = LCK_PR; + } else { + if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC)) + mode = LCK_CW; #ifdef FMODE_EXEC - else if (it->it_flags & FMODE_EXEC) - mode = LCK_PR; + else if (it->it_flags & FMODE_EXEC) + mode = LCK_PR; #endif - else - mode = LCK_CR; + else + mode = LCK_CR; + } count = mdc_resource_get_unused(exp, &op_data->op_fid2, &cancels, mode, MDS_INODELOCK_OPEN); @@ -347,6 +360,62 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp, return req; } +static struct ptlrpc_request * +mdc_intent_getxattr_pack(struct obd_export *exp, + struct lookup_intent *it, + struct md_op_data *op_data) +{ + struct ptlrpc_request *req; + struct ldlm_intent *lit; + int rc, count = 0, maxdata; + LIST_HEAD(cancels); + + + + req = ptlrpc_request_alloc(class_exp2cliimp(exp), + &RQF_LDLM_INTENT_GETXATTR); + if (req == NULL) + return ERR_PTR(-ENOMEM); + + mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1); + + if (it->it_op == IT_SETXATTR) + /* If we want to upgrade to LCK_PW, let's cancel LCK_PR + * locks now. This avoids unnecessary ASTs. */ + count = mdc_resource_get_unused(exp, &op_data->op_fid1, + &cancels, LCK_PW, + MDS_INODELOCK_XATTR); + + rc = ldlm_prep_enqueue_req(exp, req, &cancels, count); + if (rc) { + ptlrpc_request_free(req); + return ERR_PTR(rc); + } + + /* pack the intent */ + lit = req_capsule_client_get(&req->rq_pill, &RMF_LDLM_INTENT); + lit->opc = IT_GETXATTR; + + maxdata = class_exp2cliimp(exp)->imp_connect_data.ocd_max_easize; + + /* pack the intended request */ + mdc_pack_body(req, &op_data->op_fid1, op_data->op_capa1, + op_data->op_valid, maxdata, -1, 0); + + req_capsule_set_size(&req->rq_pill, &RMF_EADATA, + RCL_SERVER, maxdata); + + req_capsule_set_size(&req->rq_pill, &RMF_EAVALS, + RCL_SERVER, maxdata); + + req_capsule_set_size(&req->rq_pill, &RMF_EAVALS_LENS, + RCL_SERVER, maxdata); + + ptlrpc_request_set_replen(req); + + return req; +} + static struct ptlrpc_request *mdc_intent_unlink_pack(struct obd_export *exp, struct lookup_intent *it, struct md_op_data *op_data) @@ -722,6 +791,8 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, { .l_inodebits = { MDS_INODELOCK_UPDATE } }; static const ldlm_policy_data_t layout_policy = { .l_inodebits = { MDS_INODELOCK_LAYOUT } }; + static const ldlm_policy_data_t getxattr_policy = { + .l_inodebits = { MDS_INODELOCK_XATTR } }; ldlm_policy_data_t const *policy = &lookup_policy; int generation, resends = 0; struct ldlm_reply *lockrep; @@ -738,6 +809,8 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, policy = &update_policy; else if (it->it_op & IT_LAYOUT) policy = &layout_policy; + else if (it->it_op & (IT_GETXATTR | IT_SETXATTR)) + policy = &getxattr_policy; } LASSERT(reqp == NULL); @@ -768,9 +841,10 @@ resend: } else if (it->it_op & IT_LAYOUT) { if (!imp_connect_lvb_type(class_exp2cliimp(exp))) return -EOPNOTSUPP; - req = mdc_intent_layout_pack(exp, it, op_data); lvb_type = LVB_T_LAYOUT; + } else if (it->it_op & (IT_GETXATTR | IT_SETXATTR)) { + req = mdc_intent_getxattr_pack(exp, it, op_data); } else { LBUG(); return -EINVAL; @@ -958,13 +1032,8 @@ static int mdc_finish_intent_lock(struct obd_export *exp, LASSERTF(fid_res_name_eq(&mdt_body->fid1, &lock->l_resource->lr_name), - "Lock res_id: %lu/%lu/%lu, fid: %lu/%lu/%lu.\n", - (unsigned long)lock->l_resource->lr_name.name[0], - (unsigned long)lock->l_resource->lr_name.name[1], - (unsigned long)lock->l_resource->lr_name.name[2], - (unsigned long)fid_seq(&mdt_body->fid1), - (unsigned long)fid_oid(&mdt_body->fid1), - (unsigned long)fid_ver(&mdt_body->fid1)); + "Lock res_id: "DLDLMRES", fid: "DFID"\n", + PLDLMRES(lock->l_resource), PFID(&mdt_body->fid1)); LDLM_LOCK_PUT(lock); memcpy(&old_lock, lockh, sizeof(*lockh)); @@ -1065,10 +1134,10 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data, LASSERT(it); CDEBUG(D_DLMTRACE, "(name: %.*s,"DFID") in obj "DFID - ", intent: %s flags %#o\n", op_data->op_namelen, - op_data->op_name, PFID(&op_data->op_fid2), - PFID(&op_data->op_fid1), ldlm_it2str(it->it_op), - it->it_flags); + ", intent: %s flags %#Lo\n", op_data->op_namelen, + op_data->op_name, PFID(&op_data->op_fid2), + PFID(&op_data->op_fid1), ldlm_it2str(it->it_op), + it->it_flags); lockh.cookie = 0; if (fid_is_sane(&op_data->op_fid2) && @@ -1194,9 +1263,10 @@ int mdc_intent_getattr_async(struct obd_export *exp, int rc = 0; __u64 flags = LDLM_FL_HAS_INTENT; - CDEBUG(D_DLMTRACE,"name: %.*s in inode "DFID", intent: %s flags %#o\n", - op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1), - ldlm_it2str(it->it_op), it->it_flags); + CDEBUG(D_DLMTRACE, + "name: %.*s in inode "DFID", intent: %s flags %#Lo\n", + op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1), + ldlm_it2str(it->it_op), it->it_flags); fid_build_reg_res_name(&op_data->op_fid1, &res_id); req = mdc_intent_getattr_pack(exp, it, op_data); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index ed3a7a05557f..d1ad91c34ddc 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -800,10 +800,27 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data, { struct obd_device *obd = class_exp2obd(exp); struct ptlrpc_request *req; - int rc; + struct req_format *req_fmt; + int rc; + int saved_rc = 0; + + + req_fmt = &RQF_MDS_CLOSE; + if (op_data->op_bias & MDS_HSM_RELEASE) { + req_fmt = &RQF_MDS_RELEASE_CLOSE; + + /* allocate a FID for volatile file */ + rc = mdc_fid_alloc(exp, &op_data->op_fid2, op_data); + if (rc < 0) { + CERROR("%s: "DFID" failed to allocate FID: %d\n", + obd->obd_name, PFID(&op_data->op_fid1), rc); + /* save the errcode and proceed to close */ + saved_rc = rc; + } + } *request = NULL; - req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_CLOSE); + req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt); if (req == NULL) return -ENOMEM; @@ -893,7 +910,7 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data, } *request = req; mdc_close_handle_reply(req, op_data, rc); - return rc; + return rc < 0 ? rc : saved_rc; } int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data, @@ -1743,6 +1760,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, GOTO(out, rc); case LL_IOC_HSM_STATE_SET: rc = mdc_ioc_hsm_state_set(exp, karg); + GOTO(out, rc); case LL_IOC_HSM_ACTION: rc = mdc_ioc_hsm_current_action(exp, karg); GOTO(out, rc); @@ -1814,8 +1832,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, struct obd_quotactl *oqctl; OBD_ALLOC_PTR(oqctl); - if (!oqctl) - return -ENOMEM; + if (oqctl == NULL) + GOTO(out, rc = -ENOMEM); QCTL_COPY(oqctl, qctl); rc = obd_quotactl(exp, oqctl); @@ -1824,23 +1842,21 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, qctl->qc_valid = QC_MDTIDX; qctl->obd_uuid = obd->u.cli.cl_target_uuid; } + OBD_FREE_PTR(oqctl); - break; + GOTO(out, rc); } - case LL_IOC_GET_CONNECT_FLAGS: { - if (copy_to_user(uarg, - exp_connect_flags_ptr(exp), - sizeof(__u64))) + case LL_IOC_GET_CONNECT_FLAGS: + if (copy_to_user(uarg, exp_connect_flags_ptr(exp), + sizeof(*exp_connect_flags_ptr(exp)))) GOTO(out, rc = -EFAULT); - else - GOTO(out, rc = 0); - } - case LL_IOC_LOV_SWAP_LAYOUTS: { + + GOTO(out, rc = 0); + case LL_IOC_LOV_SWAP_LAYOUTS: rc = mdc_ioc_swap_layouts(exp, karg); - break; - } + GOTO(out, rc); default: - CERROR("mdc_ioctl(): unrecognised ioctl %#x\n", cmd); + CERROR("unrecognised ioctl: cmd = %#x\n", cmd); GOTO(out, rc = -ENOTTY); } out: @@ -1920,10 +1936,8 @@ static void lustre_swab_hal(struct hsm_action_list *h) __swab32s(&h->hal_archive_id); __swab64s(&h->hal_flags); hai = hai_zero(h); - for (i = 0; i < h->hal_count; i++) { + for (i = 0; i < h->hal_count; i++, hai = hai_next(hai)) lustre_swab_hai(hai); - hai = hai_next(hai); - } } static void lustre_swab_kuch(struct kuc_hdr *l) @@ -2062,15 +2076,6 @@ int mdc_set_info_async(const struct lu_env *env, sptlrpc_import_flush_my_ctx(imp); return 0; } - if (KEY_IS(KEY_MDS_CONN)) { - /* mds-mds import */ - spin_lock(&imp->imp_lock); - imp->imp_server_timeout = 1; - spin_unlock(&imp->imp_lock); - imp->imp_client->cli_request_portal = MDS_MDS_PORTAL; - CDEBUG(D_OTHER, "%s: timeout / 2\n", exp->exp_obd->obd_name); - return 0; - } if (KEY_IS(KEY_CHANGELOG_CLEAR)) { rc = do_set_info_async(imp, MDS_SET_INFO, LUSTRE_MDS_VERSION, keylen, key, vallen, val, set); @@ -2580,27 +2585,6 @@ static int mdc_renew_capa(struct obd_export *exp, struct obd_capa *oc, return 0; } -static int mdc_connect(const struct lu_env *env, - struct obd_export **exp, - struct obd_device *obd, struct obd_uuid *cluuid, - struct obd_connect_data *data, - void *localdata) -{ - struct obd_import *imp = obd->u.cli.cl_import; - - /* mds-mds import features */ - if (data && (data->ocd_connect_flags & OBD_CONNECT_MDS_MDS)) { - spin_lock(&imp->imp_lock); - imp->imp_server_timeout = 1; - spin_unlock(&imp->imp_lock); - imp->imp_client->cli_request_portal = MDS_MDS_PORTAL; - CDEBUG(D_OTHER, "%s: Set 'mds' portal and timeout\n", - obd->obd_name); - } - - return client_connect_import(env, exp, obd, cluuid, data, NULL); -} - struct obd_ops mdc_obd_ops = { .o_owner = THIS_MODULE, .o_setup = mdc_setup, @@ -2608,7 +2592,7 @@ struct obd_ops mdc_obd_ops = { .o_cleanup = mdc_cleanup, .o_add_conn = client_import_add_conn, .o_del_conn = client_import_del_conn, - .o_connect = mdc_connect, + .o_connect = client_connect_import, .o_disconnect = client_disconnect_export, .o_iocontrol = mdc_iocontrol, .o_set_info_async = mdc_set_info_async, diff --git a/drivers/staging/lustre/lustre/mgc/Makefile b/drivers/staging/lustre/lustre/mgc/Makefile index 267246344e1c..2f5ee649456d 100644 --- a/drivers/staging/lustre/lustre/mgc/Makefile +++ b/drivers/staging/lustre/lustre/mgc/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_LUSTRE_FS) += mgc.o -mgc-y := mgc_request.o lproc_mgc.o +mgc-y := mgc_request.o +mgc-$(CONFIG_PROC_FS) += lproc_mgc.o ccflags-y := -I$(src)/../include diff --git a/drivers/staging/lustre/lustre/mgc/libmgc.c b/drivers/staging/lustre/lustre/mgc/libmgc.c index 7b4947cec3a8..9b40c57d3cd4 100644 --- a/drivers/staging/lustre/lustre/mgc/libmgc.c +++ b/drivers/staging/lustre/lustre/mgc/libmgc.c @@ -99,11 +99,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) static int mgc_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; int rc; - LASSERT(cli->cl_mgc_vfsmnt == NULL); - ptlrpcd_decref(); rc = client_obd_cleanup(obd); diff --git a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c index ebecec2b0078..1506af13f1bf 100644 --- a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c +++ b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c @@ -40,8 +40,6 @@ #include <lprocfs_status.h> #include "mgc_internal.h" -#ifdef LPROCFS - LPROC_SEQ_FOPS_RO_TYPE(mgc, uuid); LPROC_SEQ_FOPS_RO_TYPE(mgc, connect_flags); LPROC_SEQ_FOPS_RO_TYPE(mgc, server_uuid); @@ -80,4 +78,3 @@ void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars) lvars->module_vars = lprocfs_mgc_module_vars; lvars->obd_vars = lprocfs_mgc_obd_vars; } -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/mgc/mgc_internal.h b/drivers/staging/lustre/lustre/mgc/mgc_internal.h index dbd698272a84..73b454898844 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_internal.h +++ b/drivers/staging/lustre/lustre/mgc/mgc_internal.h @@ -48,7 +48,7 @@ void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars); int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data); #else -static void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars) +static inline void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars) { memset(lvars, 0, sizeof(*lvars)); } diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 12a9ede21a85..b32382088e96 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -41,17 +41,14 @@ #define DEBUG_SUBSYSTEM S_MGC #define D_MGC D_CONFIG /*|D_WARNING*/ -# include <linux/module.h> -# include <linux/pagemap.h> -# include <linux/miscdevice.h> -# include <linux/init.h> - +#include <linux/module.h> #include <obd_class.h> #include <lustre_dlm.h> #include <lprocfs_status.h> #include <lustre_log.h> -#include <lustre_fsfilt.h> #include <lustre_disk.h> +#include <dt_object.h> + #include "mgc_internal.h" static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id, @@ -400,6 +397,7 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) return rc; } +#ifdef LPROCFS int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) { struct obd_device *obd = data; @@ -423,6 +421,7 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) return 0; } +#endif /* reenqueue any lost locks */ #define RQ_RUNNING 0x1 @@ -578,97 +577,175 @@ static void mgc_requeue_add(struct config_llog_data *cld) } /********************** class fns **********************/ +static int mgc_local_llog_init(const struct lu_env *env, + struct obd_device *obd, + struct obd_device *disk) +{ + struct llog_ctxt *ctxt; + int rc; + + rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk, + &llog_osd_ops); + if (rc) + return rc; + + ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + LASSERT(ctxt); + ctxt->loc_dir = obd->u.cli.cl_mgc_configs_dir; + llog_ctxt_put(ctxt); -static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, - struct vfsmount *mnt) + return 0; +} + +static int mgc_local_llog_fini(const struct lu_env *env, + struct obd_device *obd) { - struct lvfs_run_ctxt saved; - struct lustre_sb_info *lsi = s2lsi(sb); - struct client_obd *cli = &obd->u.cli; - struct dentry *dentry; - char *label; - int err = 0; + struct llog_ctxt *ctxt; + + ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + llog_cleanup(env, ctxt); + + return 0; +} + +static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb) +{ + struct lustre_sb_info *lsi = s2lsi(sb); + struct client_obd *cli = &obd->u.cli; + struct lu_fid rfid, fid; + struct dt_object *root, *dto; + struct lu_env *env; + int rc = 0; LASSERT(lsi); - LASSERT(lsi->lsi_srv_mnt == mnt); + LASSERT(lsi->lsi_dt_dev); + + OBD_ALLOC_PTR(env); + if (env == NULL) + return -ENOMEM; /* The mgc fs exclusion sem. Only one fs can be setup at a time. */ down(&cli->cl_mgc_sem); cfs_cleanup_group_info(); - obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); - if (IS_ERR(obd->obd_fsops)) { - up(&cli->cl_mgc_sem); - CERROR("%s: No fstype %s: rc = %ld\n", lsi->lsi_fstype, - obd->obd_name, PTR_ERR(obd->obd_fsops)); - return PTR_ERR(obd->obd_fsops); - } + /* Setup the configs dir */ + rc = lu_env_init(env, LCT_MG_THREAD); + if (rc) + GOTO(out_err, rc); - cli->cl_mgc_vfsmnt = mnt; - err = fsfilt_setup(obd, mnt->mnt_sb); - if (err) - GOTO(err_ops, err); - - OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); - obd->obd_lvfs_ctxt.pwdmnt = mnt; - obd->obd_lvfs_ctxt.pwd = mnt->mnt_root; - obd->obd_lvfs_ctxt.fs = get_ds(); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs), - strlen(MOUNT_CONFIGS_DIR)); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - CERROR("cannot lookup %s directory: rc = %d\n", - MOUNT_CONFIGS_DIR, err); - GOTO(err_ops, err); - } - cli->cl_mgc_configs_dir = dentry; + fid.f_seq = FID_SEQ_LOCAL_NAME; + fid.f_oid = 1; + fid.f_ver = 0; + rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid, + &cli->cl_mgc_los); + if (rc) + GOTO(out_env, rc); + + rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid); + if (rc) + GOTO(out_env, rc); + + root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid, + &cli->cl_mgc_los->los_dev->dd_lu_dev); + if (unlikely(IS_ERR(root))) + GOTO(out_los, rc = PTR_ERR(root)); + + dto = local_file_find_or_create(env, cli->cl_mgc_los, root, + MOUNT_CONFIGS_DIR, + S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); + lu_object_put_nocache(env, &root->do_lu); + if (IS_ERR(dto)) + GOTO(out_los, rc = PTR_ERR(dto)); + + cli->cl_mgc_configs_dir = dto; + + LASSERT(lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt); + rc = mgc_local_llog_init(env, obd, lsi->lsi_osd_exp->exp_obd); + if (rc) + GOTO(out_llog, rc); /* We take an obd ref to insure that we can't get to mgc_cleanup - without calling mgc_fs_cleanup first. */ + * without calling mgc_fs_cleanup first. */ class_incref(obd, "mgc_fs", obd); - label = fsfilt_get_label(obd, mnt->mnt_sb); - if (label) - CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label); - /* We keep the cl_mgc_sem until mgc_fs_cleanup */ - return 0; - -err_ops: - fsfilt_put_ops(obd->obd_fsops); - obd->obd_fsops = NULL; - cli->cl_mgc_vfsmnt = NULL; - up(&cli->cl_mgc_sem); - return err; +out_llog: + if (rc) { + lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu); + cli->cl_mgc_configs_dir = NULL; + } +out_los: + if (rc < 0) { + local_oid_storage_fini(env, cli->cl_mgc_los); + cli->cl_mgc_los = NULL; + up(&cli->cl_mgc_sem); + } +out_env: + lu_env_fini(env); +out_err: + OBD_FREE_PTR(env); + return rc; } static int mgc_fs_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; - int rc = 0; + struct lu_env env; + struct client_obd *cli = &obd->u.cli; + int rc; - LASSERT(cli->cl_mgc_vfsmnt != NULL); + LASSERT(cli->cl_mgc_los != NULL); - if (cli->cl_mgc_configs_dir != NULL) { - struct lvfs_run_ctxt saved; - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - l_dput(cli->cl_mgc_configs_dir); - cli->cl_mgc_configs_dir = NULL; - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - class_decref(obd, "mgc_fs", obd); - } + rc = lu_env_init(&env, LCT_MG_THREAD); + if (rc) + GOTO(unlock, rc); + + mgc_local_llog_fini(&env, obd); - cli->cl_mgc_vfsmnt = NULL; - if (obd->obd_fsops) - fsfilt_put_ops(obd->obd_fsops); + lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu); + cli->cl_mgc_configs_dir = NULL; + local_oid_storage_fini(&env, cli->cl_mgc_los); + cli->cl_mgc_los = NULL; + lu_env_fini(&env); + +unlock: + class_decref(obd, "mgc_fs", obd); up(&cli->cl_mgc_sem); - return rc; + return 0; +} + +static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd) +{ + struct llog_ctxt *ctxt; + int rc; + + /* setup only remote ctxt, the local disk context is switched per each + * filesystem during mgc_fs_setup() */ + rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_REPL_CTXT, obd, + &llog_client_ops); + if (rc) + return rc; + + ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); + LASSERT(ctxt); + + llog_initiator_connect(ctxt); + llog_ctxt_put(ctxt); + + return 0; +} + +static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd) +{ + struct llog_ctxt *ctxt; + + ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); + if (ctxt) + llog_cleanup(env, ctxt); + + return 0; } static atomic_t mgc_count = ATOMIC_INIT(0); @@ -694,7 +771,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) } } obd_cleanup_client_import(obd); - rc = obd_llog_finish(obd, 0); + rc = mgc_llog_fini(NULL, obd); if (rc != 0) CERROR("failed to cleanup llogging subsystems\n"); break; @@ -704,11 +781,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) static int mgc_cleanup(struct obd_device *obd) { - struct client_obd *cli = &obd->u.cli; int rc; - LASSERT(cli->cl_mgc_vfsmnt == NULL); - /* COMPAT_146 - old config logs may have added profiles we don't know about */ if (obd->obd_type->typ_refcnt <= 1) @@ -733,7 +807,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) if (rc) GOTO(err_decref, rc); - rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL); + rc = mgc_llog_init(NULL, obd); if (rc) { CERROR("failed to setup llogging subsystems\n"); GOTO(err_cleanup, rc); @@ -788,8 +862,8 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, /* We've given up the lock, prepare ourselves to update. */ LDLM_DEBUG(lock, "MGC cancel CB"); - CDEBUG(D_MGC, "Lock res "LPX64" (%.8s)\n", - lock->l_resource->lr_name.name[0], + CDEBUG(D_MGC, "Lock res "DLDLMRES" (%.8s)\n", + PLDLMRES(lock->l_resource), (char *)&lock->l_resource->lr_name.name[0]); if (!cld) { @@ -1011,11 +1085,11 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, } if (KEY_IS(KEY_SET_FS)) { struct super_block *sb = (struct super_block *)val; - struct lustre_sb_info *lsi; + if (vallen != sizeof(struct super_block)) return -EINVAL; - lsi = s2lsi(sb); - rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt); + + rc = mgc_fs_setup(exp->exp_obd, sb); if (rc) { CERROR("set_fs got %d\n", rc); } @@ -1145,49 +1219,6 @@ static int mgc_import_event(struct obd_device *obd, return rc; } -static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg, - struct obd_device *tgt, int *index) -{ - struct llog_ctxt *ctxt; - int rc; - - LASSERT(olg == &obd->obd_olg); - - - rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_REPL_CTXT, tgt, - &llog_client_ops); - if (rc) - GOTO(out, rc); - - ctxt = llog_group_get_ctxt(olg, LLOG_CONFIG_REPL_CTXT); - if (!ctxt) - GOTO(out, rc = -ENODEV); - - llog_initiator_connect(ctxt); - llog_ctxt_put(ctxt); - - return 0; -out: - ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); - if (ctxt) - llog_cleanup(NULL, ctxt); - return rc; -} - -static int mgc_llog_finish(struct obd_device *obd, int count) -{ - struct llog_ctxt *ctxt; - - ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); - if (ctxt) - llog_cleanup(NULL, ctxt); - - ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); - if (ctxt) - llog_cleanup(NULL, ctxt); - return 0; -} - enum { CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT), CONFIG_READ_NRPAGES = 4 @@ -1540,17 +1571,58 @@ out: return rc; } +static int mgc_llog_local_copy(const struct lu_env *env, + struct obd_device *obd, + struct llog_ctxt *rctxt, + struct llog_ctxt *lctxt, char *logname) +{ + char *temp_log; + int rc; + + + + /* + * - copy it to backup using llog_backup() + * - copy remote llog to logname using llog_backup() + * - if failed then move bakup to logname again + */ + + OBD_ALLOC(temp_log, strlen(logname) + 1); + if (!temp_log) + return -ENOMEM; + sprintf(temp_log, "%sT", logname); + + /* make a copy of local llog at first */ + rc = llog_backup(env, obd, lctxt, lctxt, logname, temp_log); + if (rc < 0 && rc != -ENOENT) + GOTO(out, rc); + /* copy remote llog to the local copy */ + rc = llog_backup(env, obd, rctxt, lctxt, logname, logname); + if (rc == -ENOENT) { + /* no remote llog, delete local one too */ + llog_erase(env, lctxt, NULL, logname); + } else if (rc < 0) { + /* error during backup, get local one back from the copy */ + llog_backup(env, obd, lctxt, lctxt, temp_log, logname); +out: + CERROR("%s: failed to copy remote log %s: rc = %d\n", + obd->obd_name, logname, rc); + } + llog_erase(env, lctxt, NULL, temp_log); + OBD_FREE(temp_log, strlen(logname) + 1); + return rc; +} /* local_only means it cannot get remote llogs */ static int mgc_process_cfg_log(struct obd_device *mgc, - struct config_llog_data *cld, - int local_only) + struct config_llog_data *cld, int local_only) { - struct llog_ctxt *ctxt, *lctxt = NULL; - struct lvfs_run_ctxt *saved_ctxt; - struct lustre_sb_info *lsi = NULL; - int rc = 0, must_pop = 0; - bool sptlrpc_started = false; + struct llog_ctxt *ctxt, *lctxt = NULL; + struct dt_object *cl_mgc_dir = mgc->u.cli.cl_mgc_configs_dir; + struct lustre_sb_info *lsi = NULL; + int rc = 0; + bool sptlrpc_started = false; + struct lu_env *env; LASSERT(cld); LASSERT(mutex_is_locked(&cld->cld_lock)); @@ -1565,20 +1637,48 @@ static int mgc_process_cfg_log(struct obd_device *mgc, if (cld->cld_cfg.cfg_sb) lsi = s2lsi(cld->cld_cfg.cfg_sb); - ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); - if (!ctxt) { - CERROR("missing llog context\n"); - return -EINVAL; - } - - OBD_ALLOC_PTR(saved_ctxt); - if (saved_ctxt == NULL) + OBD_ALLOC_PTR(env); + if (env == NULL) return -ENOMEM; + rc = lu_env_init(env, LCT_MG_THREAD); + if (rc) + GOTO(out_free, rc); + + ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); + LASSERT(ctxt); + lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT); - if (local_only) { /* no local log at client side */ - GOTO(out_pop, rc = -EIO); + /* Copy the setup log locally if we can. Don't mess around if we're + * running an MGS though (logs are already local). */ + if (lctxt && lsi && IS_SERVER(lsi) && !IS_MGS(lsi) && + cl_mgc_dir != NULL && + lu2dt_dev(cl_mgc_dir->do_lu.lo_dev) == lsi->lsi_dt_dev) { + if (!local_only) + /* Only try to copy log if we have the lock. */ + rc = mgc_llog_local_copy(env, mgc, ctxt, lctxt, + cld->cld_logname); + if (local_only || rc) { + if (llog_is_empty(env, lctxt, cld->cld_logname)) { + LCONSOLE_ERROR_MSG(0x13a, + "Failed to get MGS log %s and no local copy.\n", + cld->cld_logname); + GOTO(out_pop, rc = -ENOTCONN); + } + CDEBUG(D_MGC, + "Failed to get MGS log %s, using local copy for now, will try to update later.\n", + cld->cld_logname); + } + /* Now, whether we copied or not, start using the local llog. + * If we failed to copy, we'll start using whatever the old + * log has. */ + llog_ctxt_put(ctxt); + ctxt = lctxt; + lctxt = NULL; + } else { + if (local_only) /* no local log at client side */ + GOTO(out_pop, rc = -EIO); } if (cld_is_sptlrpc(cld)) { @@ -1587,19 +1687,16 @@ static int mgc_process_cfg_log(struct obd_device *mgc, } /* logname and instance info should be the same, so use our - copy of the instance for the update. The cfg_last_idx will - be updated here. */ - rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname, + * copy of the instance for the update. The cfg_last_idx will + * be updated here. */ + rc = class_config_parse_llog(env, ctxt, cld->cld_logname, &cld->cld_cfg); out_pop: - llog_ctxt_put(ctxt); + __llog_ctxt_put(env, ctxt); if (lctxt) - llog_ctxt_put(lctxt); - if (must_pop) - pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); + __llog_ctxt_put(env, lctxt); - OBD_FREE_PTR(saved_ctxt); /* * update settings on existing OBDs. doing it inside * of llog_process_lock so no device is attaching/detaching @@ -1614,6 +1711,9 @@ out_pop: strlen("-sptlrpc")); } + lu_env_fini(env); +out_free: + OBD_FREE_PTR(env); return rc; } @@ -1801,8 +1901,6 @@ struct obd_ops mgc_obd_ops = { .o_set_info_async = mgc_set_info_async, .o_get_info = mgc_get_info, .o_import_event = mgc_import_event, - .o_llog_init = mgc_llog_init, - .o_llog_finish = mgc_llog_finish, .o_process_config = mgc_process_config, }; diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 4afd962cdb64..c93131e0d2da 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -54,7 +54,13 @@ struct list_head obd_types; DEFINE_RWLOCK(obd_dev_lock); __u64 obd_max_pages = 0; +EXPORT_SYMBOL(obd_max_pages); __u64 obd_max_alloc = 0; +EXPORT_SYMBOL(obd_max_alloc); +__u64 obd_alloc; +EXPORT_SYMBOL(obd_alloc); +__u64 obd_pages; +EXPORT_SYMBOL(obd_pages); DEFINE_SPINLOCK(obd_updatemax_lock); /* The following are visible and mutable through /proc/sys/lustre/. */ @@ -501,8 +507,15 @@ int obd_init_checks(void) } extern spinlock_t obd_types_lock; +#ifdef LPROCFS extern int class_procfs_init(void); extern int class_procfs_clean(void); +#else +static inline int class_procfs_init(void) +{ return 0; } +static inline int class_procfs_clean(void) +{ return 0; } +#endif static int __init init_obdclass(void) { @@ -516,7 +529,7 @@ static int __init init_obdclass(void) spin_lock_init(&obd_types_lock); obd_zombie_impexp_init(); -#ifdef LPROCFS + obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM, LPROCFS_STATS_FLAG_NONE | LPROCFS_STATS_FLAG_IRQ_SAFE); @@ -531,7 +544,7 @@ static int __init init_obdclass(void) lprocfs_counter_init(obd_memory, OBD_MEMORY_PAGES_STAT, LPROCFS_CNTR_AVGMINMAX, "pagesused", "pages"); -#endif + err = obd_init_checks(); if (err == -EOVERFLOW) return err; @@ -564,6 +577,9 @@ static int __init init_obdclass(void) err = obd_init_caches(); if (err) return err; + + obd_sysctl_init(); + err = class_procfs_init(); if (err) return err; diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index f6fae16fc7f7..d9f750d42c80 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -193,7 +193,6 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, strcpy(type->typ_name, name); spin_lock_init(&type->obd_type_lock); -#ifdef LPROCFS type->typ_procroot = lprocfs_register(type->typ_name, proc_lustre_root, vars, type); if (IS_ERR(type->typ_procroot)) { @@ -201,7 +200,7 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, type->typ_procroot = NULL; GOTO (failed, rc); } -#endif + if (ldt != NULL) { type->typ_lu = ldt; rc = lu_device_type_init(ldt); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index d1a57ebfda95..a70ead1be6a9 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -295,9 +295,6 @@ struct lprocfs_vars lprocfs_base[] = { { "jobid_var", &obd_proc_jobid_var_fops }, { 0 } }; -#else -#define lprocfs_base NULL -#endif /* LPROCFS */ static void *obd_device_list_seq_start(struct seq_file *p, loff_t *pos) { @@ -380,7 +377,6 @@ int class_procfs_init(void) { int rc = 0; - obd_sysctl_init(); proc_lustre_root = lprocfs_register("fs/lustre", NULL, lprocfs_base, NULL); if (IS_ERR(proc_lustre_root)) { @@ -404,3 +400,4 @@ int class_procfs_clean(void) } return 0; } +#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c index acd2619227df..c1ef0c9b5a1a 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c @@ -282,7 +282,6 @@ int LL_PROC_PROTO(proc_at_history) #ifdef CONFIG_SYSCTL static ctl_table_t obd_table[] = { { - INIT_CTL_NAME(OBD_TIMEOUT) .procname = "timeout", .data = &obd_timeout, .maxlen = sizeof(int), @@ -290,7 +289,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_set_timeout }, { - INIT_CTL_NAME(OBD_DEBUG_PEER_ON_TIMEOUT) .procname = "debug_peer_on_timeout", .data = &obd_debug_peer_on_timeout, .maxlen = sizeof(int), @@ -298,7 +296,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_dointvec }, { - INIT_CTL_NAME(OBD_DUMP_ON_TIMEOUT) .procname = "dump_on_timeout", .data = &obd_dump_on_timeout, .maxlen = sizeof(int), @@ -306,7 +303,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_dointvec }, { - INIT_CTL_NAME(OBD_DUMP_ON_EVICTION) .procname = "dump_on_eviction", .data = &obd_dump_on_eviction, .maxlen = sizeof(int), @@ -314,7 +310,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_dointvec }, { - INIT_CTL_NAME(OBD_MEMUSED) .procname = "memused", .data = NULL, .maxlen = 0, @@ -322,7 +317,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_memory_alloc }, { - INIT_CTL_NAME(OBD_PAGESUSED) .procname = "pagesused", .data = NULL, .maxlen = 0, @@ -330,7 +324,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_pages_alloc }, { - INIT_CTL_NAME(OBD_MAXMEMUSED) .procname = "memused_max", .data = NULL, .maxlen = 0, @@ -338,7 +331,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_mem_max }, { - INIT_CTL_NAME(OBD_MAXPAGESUSED) .procname = "pagesused_max", .data = NULL, .maxlen = 0, @@ -346,7 +338,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_pages_max }, { - INIT_CTL_NAME(OBD_LDLM_TIMEOUT) .procname = "ldlm_timeout", .data = &ldlm_timeout, .maxlen = sizeof(int), @@ -354,7 +345,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_set_timeout }, { - INIT_CTL_NAME(OBD_ALLOC_FAIL_RATE) .procname = "alloc_fail_rate", .data = &obd_alloc_fail_rate, .maxlen = sizeof(int), @@ -362,7 +352,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_alloc_fail_rate }, { - INIT_CTL_NAME(OBD_MAX_DIRTY_PAGES) .procname = "max_dirty_mb", .data = &obd_max_dirty_pages, .maxlen = sizeof(int), @@ -370,7 +359,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_max_dirty_pages_in_mb }, { - INIT_CTL_NAME(OBD_AT_MIN) .procname = "at_min", .data = &at_min, .maxlen = sizeof(int), @@ -378,7 +366,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_at_min }, { - INIT_CTL_NAME(OBD_AT_MAX) .procname = "at_max", .data = &at_max, .maxlen = sizeof(int), @@ -386,7 +373,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_at_max }, { - INIT_CTL_NAME(OBD_AT_EXTRA) .procname = "at_extra", .data = &at_extra, .maxlen = sizeof(int), @@ -394,7 +380,6 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_at_extra }, { - INIT_CTL_NAME(OBD_AT_EARLY_MARGIN) .procname = "at_early_margin", .data = &at_early_margin, .maxlen = sizeof(int), @@ -402,26 +387,24 @@ static ctl_table_t obd_table[] = { .proc_handler = &proc_at_early_margin }, { - INIT_CTL_NAME(OBD_AT_HISTORY) .procname = "at_history", .data = &at_history, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_at_history }, - { INIT_CTL_NAME(0) } + {} }; static ctl_table_t parent_table[] = { { - INIT_CTL_NAME(OBD_SYSCTL) .procname = "lustre", .data = NULL, .maxlen = 0, .mode = 0555, .child = obd_table }, - { INIT_CTL_NAME(0) } + {} }; #endif diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c index 0cb44287502b..e0dfb089dd90 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog.c +++ b/drivers/staging/lustre/lustre/obdclass/llog.c @@ -62,7 +62,7 @@ struct llog_handle *llog_alloc_handle(void) OBD_ALLOC_PTR(loghandle); if (loghandle == NULL) - return ERR_PTR(-ENOMEM); + return NULL; init_rwsem(&loghandle->lgh_lock); spin_lock_init(&loghandle->lgh_hdr_lock); @@ -265,31 +265,6 @@ out: } EXPORT_SYMBOL(llog_init_handle); -int llog_copy_handler(const struct lu_env *env, - struct llog_handle *llh, - struct llog_rec_hdr *rec, - void *data) -{ - struct llog_rec_hdr local_rec = *rec; - struct llog_handle *local_llh = (struct llog_handle *)data; - char *cfg_buf = (char*) (rec + 1); - struct lustre_cfg *lcfg; - int rc = 0; - - /* Append all records */ - local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail); - rc = llog_write(env, local_llh, &local_rec, NULL, 0, - (void *)cfg_buf, -1); - - lcfg = (struct lustre_cfg *)cfg_buf; - CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", - rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, - lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); - - return rc; -} -EXPORT_SYMBOL(llog_copy_handler); - static int llog_process_thread(void *arg) { struct llog_process_info *lpi = arg; @@ -493,14 +468,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle, } EXPORT_SYMBOL(llog_process); -inline int llog_get_size(struct llog_handle *loghandle) -{ - if (loghandle && loghandle->lgh_hdr) - return loghandle->lgh_hdr->llh_count; - return 0; -} -EXPORT_SYMBOL(llog_get_size); - int llog_reverse_process(const struct lu_env *env, struct llog_handle *loghandle, llog_cb_t cb, void *data, void *catdata) @@ -767,8 +734,9 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **res, struct llog_logid *logid, char *name) { - struct thandle *th; - int rc; + struct dt_device *d; + struct thandle *th; + int rc; rc = llog_open(env, ctxt, res, logid, name, LLOG_OPEN_NEW); if (rc) @@ -777,27 +745,21 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt, if (llog_exist(*res)) return 0; - if ((*res)->lgh_obj != NULL) { - struct dt_device *d; + LASSERT((*res)->lgh_obj != NULL); - d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev); + d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev); - th = dt_trans_create(env, d); - if (IS_ERR(th)) - GOTO(out, rc = PTR_ERR(th)); + th = dt_trans_create(env, d); + if (IS_ERR(th)) + GOTO(out, rc = PTR_ERR(th)); - rc = llog_declare_create(env, *res, th); - if (rc == 0) { - rc = dt_trans_start_local(env, d, th); - if (rc == 0) - rc = llog_create(env, *res, th); - } - dt_trans_stop(env, d, th); - } else { - /* lvfs compat code */ - LASSERT((*res)->lgh_file == NULL); - rc = llog_create(env, *res, NULL); + rc = llog_declare_create(env, *res, th); + if (rc == 0) { + rc = dt_trans_start_local(env, d, th); + if (rc == 0) + rc = llog_create(env, *res, th); } + dt_trans_stop(env, d, th); out: if (rc) llog_close(env, *res); @@ -842,41 +804,34 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle, struct llog_rec_hdr *rec, struct llog_cookie *reccookie, int cookiecount, void *buf, int idx) { - int rc; + struct dt_device *dt; + struct thandle *th; + int rc; LASSERT(loghandle); LASSERT(loghandle->lgh_ctxt); + LASSERT(loghandle->lgh_obj != NULL); - if (loghandle->lgh_obj != NULL) { - struct dt_device *dt; - struct thandle *th; - - dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev); + dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev); - th = dt_trans_create(env, dt); - if (IS_ERR(th)) - return PTR_ERR(th); + th = dt_trans_create(env, dt); + if (IS_ERR(th)) + return PTR_ERR(th); - rc = llog_declare_write_rec(env, loghandle, rec, idx, th); - if (rc) - GOTO(out_trans, rc); + rc = llog_declare_write_rec(env, loghandle, rec, idx, th); + if (rc) + GOTO(out_trans, rc); - rc = dt_trans_start_local(env, dt, th); - if (rc) - GOTO(out_trans, rc); + rc = dt_trans_start_local(env, dt, th); + if (rc) + GOTO(out_trans, rc); - down_write(&loghandle->lgh_lock); - rc = llog_write_rec(env, loghandle, rec, reccookie, - cookiecount, buf, idx, th); - up_write(&loghandle->lgh_lock); + down_write(&loghandle->lgh_lock); + rc = llog_write_rec(env, loghandle, rec, reccookie, + cookiecount, buf, idx, th); + up_write(&loghandle->lgh_lock); out_trans: - dt_trans_stop(env, dt, th); - } else { /* lvfs compatibility */ - down_write(&loghandle->lgh_lock); - rc = llog_write_rec(env, loghandle, rec, reccookie, - cookiecount, buf, idx, NULL); - up_write(&loghandle->lgh_lock); - } + dt_trans_stop(env, dt, th); return rc; } EXPORT_SYMBOL(llog_write); @@ -932,3 +887,104 @@ out: return rc; } EXPORT_SYMBOL(llog_close); + +int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt, + char *name) +{ + struct llog_handle *llh; + int rc = 0; + + rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); + if (rc < 0) { + if (likely(rc == -ENOENT)) + rc = 0; + GOTO(out, rc); + } + + rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); + if (rc) + GOTO(out_close, rc); + rc = llog_get_size(llh); + +out_close: + llog_close(env, llh); +out: + /* header is record 1 */ + return rc <= 1; +} +EXPORT_SYMBOL(llog_is_empty); + +int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh, + struct llog_rec_hdr *rec, void *data) +{ + struct llog_handle *copy_llh = data; + + /* Append all records */ + return llog_write(env, copy_llh, rec, NULL, 0, NULL, -1); +} +EXPORT_SYMBOL(llog_copy_handler); + +/* backup plain llog */ +int llog_backup(const struct lu_env *env, struct obd_device *obd, + struct llog_ctxt *ctxt, struct llog_ctxt *bctxt, + char *name, char *backup) +{ + struct llog_handle *llh, *bllh; + int rc; + + + + /* open original log */ + rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); + if (rc < 0) { + /* the -ENOENT case is also reported to the caller + * but silently so it should handle that if needed. + */ + if (rc != -ENOENT) + CERROR("%s: failed to open log %s: rc = %d\n", + obd->obd_name, name, rc); + return rc; + } + + rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); + if (rc) + GOTO(out_close, rc); + + /* Make sure there's no old backup log */ + rc = llog_erase(env, bctxt, NULL, backup); + if (rc < 0 && rc != -ENOENT) + GOTO(out_close, rc); + + /* open backup log */ + rc = llog_open_create(env, bctxt, &bllh, NULL, backup); + if (rc) { + CERROR("%s: failed to open backup logfile %s: rc = %d\n", + obd->obd_name, backup, rc); + GOTO(out_close, rc); + } + + /* check that backup llog is not the same object as original one */ + if (llh->lgh_obj == bllh->lgh_obj) { + CERROR("%s: backup llog %s to itself (%s), objects %p/%p\n", + obd->obd_name, name, backup, llh->lgh_obj, + bllh->lgh_obj); + GOTO(out_backup, rc = -EEXIST); + } + + rc = llog_init_handle(env, bllh, LLOG_F_IS_PLAIN, NULL); + if (rc) + GOTO(out_backup, rc); + + /* Copy log record by record */ + rc = llog_process_or_fork(env, llh, llog_copy_handler, (void *)bllh, + NULL, false); + if (rc) + CERROR("%s: failed to backup log %s: rc = %d\n", + obd->obd_name, name, rc); +out_backup: + llog_close(env, bllh); +out_close: + llog_close(env, llh); + return rc; +} +EXPORT_SYMBOL(llog_backup); diff --git a/drivers/staging/lustre/lustre/obdclass/llog_test.c b/drivers/staging/lustre/lustre/obdclass/llog_test.c index 178f89eccab1..764068fc4ef7 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_test.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_test.c @@ -947,6 +947,10 @@ static void lprocfs_llog_test_init_vars(struct lprocfs_static_vars *lvars) lvars->module_vars = lprocfs_llog_test_module_vars; lvars->obd_vars = lprocfs_llog_test_obd_vars; } +#else +static void lprocfs_llog_test_init_vars(struct lprocfs_static_vars *lvars) +{ +} #endif static int llog_test_cleanup(struct obd_device *obd) @@ -1048,7 +1052,7 @@ static struct obd_ops llog_obd_ops = { static int __init llog_test_init(void) { - struct lprocfs_static_vars lvars; + struct lprocfs_static_vars uninitialized_var(lvars); lprocfs_llog_test_init_vars(&lvars); return class_register_type(&llog_obd_ops, NULL, diff --git a/drivers/staging/lustre/lustre/obdclass/local_storage.c b/drivers/staging/lustre/lustre/obdclass/local_storage.c index cc19fbab0207..e79e4beb3628 100644 --- a/drivers/staging/lustre/lustre/obdclass/local_storage.c +++ b/drivers/staging/lustre/lustre/obdclass/local_storage.c @@ -246,7 +246,7 @@ int local_object_create(const struct lu_env *env, struct dt_object_format *dof, struct thandle *th) { struct dt_thread_info *dti = dt_info(env); - obd_id lastid; + __le64 lastid; int rc; rc = dt_create(env, o, attr, NULL, dof, th); @@ -855,9 +855,12 @@ out_los: (*los)->los_seq = fid_seq(first_fid); (*los)->los_last_oid = le64_to_cpu(lastid); (*los)->los_obj = o; - /* read value should not be less than initial one */ - LASSERTF((*los)->los_last_oid >= first_oid, "%u < %u\n", - (*los)->los_last_oid, first_oid); + /* Read value should not be less than initial one + * but possible after upgrade from older fs. + * In this case just switch to the first_oid in memory and + * it will be updated on disk with first object generated */ + if ((*los)->los_last_oid < first_oid) + (*los)->los_last_oid = first_oid; } out: mutex_unlock(&ls->ls_los_mutex); diff --git a/drivers/staging/lustre/lustre/obdclass/local_storage.h b/drivers/staging/lustre/lustre/obdclass/local_storage.h index d553c3752703..0f63b8c073b4 100644 --- a/drivers/staging/lustre/lustre/obdclass/local_storage.h +++ b/drivers/staging/lustre/lustre/obdclass/local_storage.h @@ -29,6 +29,8 @@ * * Author: Mikhail Pershin <mike.pershin@intel.com> */ +#ifndef __LOCAL_STORAGE_H +#define __LOCAL_STORAGE_H #include <dt_object.h> #include <obd.h> @@ -86,3 +88,4 @@ struct los_ondisk { }; #define LOS_MAGIC 0xdecafbee +#endif diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 02d76f8dbcb9..ec3b605dae6b 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -46,11 +46,183 @@ #include <lustre/lustre_idl.h> #include <linux/seq_file.h> -#if defined(LPROCFS) +static const char * const obd_connect_names[] = { + "read_only", + "lov_index", + "unused", + "write_grant", + "server_lock", + "version", + "request_portal", + "acl", + "xattr", + "create_on_write", + "truncate_lock", + "initial_transno", + "inode_bit_locks", + "join_file(obsolete)", + "getattr_by_fid", + "no_oh_for_devices", + "remote_client", + "remote_client_by_force", + "max_byte_per_rpc", + "64bit_qdata", + "mds_capability", + "oss_capability", + "early_lock_cancel", + "som", + "adaptive_timeouts", + "lru_resize", + "mds_mds_connection", + "real_conn", + "change_qunit_size", + "alt_checksum_algorithm", + "fid_is_enabled", + "version_recovery", + "pools", + "grant_shrink", + "skip_orphan", + "large_ea", + "full20", + "layout_lock", + "64bithash", + "object_max_bytes", + "imp_recov", + "jobstats", + "umask", + "einprogress", + "grant_param", + "flock_owner", + "lvb_type", + "nanoseconds_times", + "lightweight_conn", + "short_io", + "pingless", + "unknown", + NULL +}; + +int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep) +{ + __u64 mask = 1; + int i, ret = 0; + + for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) { + if (flags & mask) + ret += snprintf(page + ret, count - ret, "%s%s", + ret ? sep : "", obd_connect_names[i]); + } + if (flags & ~(mask - 1)) + ret += snprintf(page + ret, count - ret, + "%sunknown flags "LPX64, + ret ? sep : "", flags & ~(mask - 1)); + return ret; +} +EXPORT_SYMBOL(obd_connect_flags2str); + +int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, + int mult) +{ + long decimal_val, frac_val; + int prtn; + + if (count < 10) + return -EINVAL; + + decimal_val = val / mult; + prtn = snprintf(buffer, count, "%ld", decimal_val); + frac_val = val % mult; + + if (prtn < (count - 4) && frac_val > 0) { + long temp_frac; + int i, temp_mult = 1, frac_bits = 0; + + temp_frac = frac_val * 10; + buffer[prtn++] = '.'; + while (frac_bits < 2 && (temp_frac / mult) < 1) { + /* only reserved 2 bits fraction */ + buffer[prtn++] = '0'; + temp_frac *= 10; + frac_bits++; + } + /* + * Need to think these cases : + * 1. #echo x.00 > /proc/xxx output result : x + * 2. #echo x.0x > /proc/xxx output result : x.0x + * 3. #echo x.x0 > /proc/xxx output result : x.x + * 4. #echo x.xx > /proc/xxx output result : x.xx + * Only reserved 2 bits fraction. + */ + for (i = 0; i < (5 - prtn); i++) + temp_mult *= 10; + + frac_bits = min((int)count - prtn, 3 - frac_bits); + prtn += snprintf(buffer + prtn, frac_bits, "%ld", + frac_val * temp_mult / mult); + + prtn--; + while (buffer[prtn] < '1' || buffer[prtn] > '9') { + prtn--; + if (buffer[prtn] == '.') { + prtn--; + break; + } + } + prtn++; + } + buffer[prtn++] = '\n'; + return prtn; +} +EXPORT_SYMBOL(lprocfs_read_frac_helper); + +int lprocfs_write_frac_helper(const char *buffer, unsigned long count, + int *val, int mult) +{ + char kernbuf[20], *end, *pbuf; + + if (count > (sizeof(kernbuf) - 1)) + return -EINVAL; + + if (copy_from_user(kernbuf, buffer, count)) + return -EFAULT; + + kernbuf[count] = '\0'; + pbuf = kernbuf; + if (*pbuf == '-') { + mult = -mult; + pbuf++; + } + + *val = (int)simple_strtoul(pbuf, &end, 10) * mult; + if (pbuf == end) + return -EINVAL; + + if (end != NULL && *end == '.') { + int temp_val, pow = 1; + int i; + + pbuf = end + 1; + if (strlen(pbuf) > 5) + pbuf[5] = '\0'; /*only allow 5bits fractional*/ + + temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult; + + if (pbuf < end) { + for (i = 0; i < (end - pbuf); i++) + pow *= 10; + + *val += temp_val / pow; + } + } + return 0; +} +EXPORT_SYMBOL(lprocfs_write_frac_helper); + +#ifdef LPROCFS static int lprocfs_no_percpu_stats = 0; -CFS_MODULE_PARM(lprocfs_no_percpu_stats, "i", int, 0644, - "Do not alloc percpu data for lprocfs stats"); +module_param(lprocfs_no_percpu_stats, int, 0644); +MODULE_PARM_DESC(lprocfs_no_percpu_stats, "Do not alloc percpu data for lprocfs stats"); #define MAX_STRING_SIZE 128 @@ -420,7 +592,6 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, { unsigned int num_entry; struct lprocfs_counter *percpu_cntr; - struct lprocfs_counter_header *cntr_header; int i; unsigned long flags = 0; @@ -439,7 +610,6 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, for (i = 0; i < num_entry; i++) { if (stats->ls_percpu[i] == NULL) continue; - cntr_header = &stats->ls_cnt_header[idx]; percpu_cntr = lprocfs_stats_counter_get(stats, i, idx); cnt->lc_count += percpu_cntr->lc_count; @@ -481,62 +651,6 @@ static int obd_import_flags2str(struct obd_import *imp, struct seq_file *m) } #undef flags2str -static const char *obd_connect_names[] = { - "read_only", - "lov_index", - "unused", - "write_grant", - "server_lock", - "version", - "request_portal", - "acl", - "xattr", - "create_on_write", - "truncate_lock", - "initial_transno", - "inode_bit_locks", - "join_file(obsolete)", - "getattr_by_fid", - "no_oh_for_devices", - "remote_client", - "remote_client_by_force", - "max_byte_per_rpc", - "64bit_qdata", - "mds_capability", - "oss_capability", - "early_lock_cancel", - "som", - "adaptive_timeouts", - "lru_resize", - "mds_mds_connection", - "real_conn", - "change_qunit_size", - "alt_checksum_algorithm", - "fid_is_enabled", - "version_recovery", - "pools", - "grant_shrink", - "skip_orphan", - "large_ea", - "full20", - "layout_lock", - "64bithash", - "object_max_bytes", - "imp_recov", - "jobstats", - "umask", - "einprogress", - "grant_param", - "flock_owner", - "lvb_type", - "nanoseconds_times", - "lightweight_conn", - "short_io", - "pingless", - "unknown", - NULL -}; - static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags, char *sep) { __u64 mask = 1; @@ -555,24 +669,6 @@ static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags, char *sep first ? sep : "", flags & ~(mask - 1)); } -int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep) -{ - __u64 mask = 1; - int i, ret = 0; - - for (i = 0; obd_connect_names[i] != NULL; i++, mask <<= 1) { - if (flags & mask) - ret += snprintf(page + ret, count - ret, "%s%s", - ret ? sep : "", obd_connect_names[i]); - } - if (flags & ~(mask - 1)) - ret += snprintf(page + ret, count - ret, - "%sunknown flags "LPX64, - ret ? sep : "", flags & ~(mask - 1)); - return ret; -} -EXPORT_SYMBOL(obd_connect_flags2str); - int lprocfs_rd_import(struct seq_file *m, void *data) { struct lprocfs_counter ret; @@ -999,7 +1095,6 @@ EXPORT_SYMBOL(lprocfs_free_stats); void lprocfs_clear_stats(struct lprocfs_stats *stats) { struct lprocfs_counter *percpu_cntr; - struct lprocfs_counter_header *header; int i; int j; unsigned int num_entry; @@ -1011,7 +1106,6 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats) if (stats->ls_percpu[i] == NULL) continue; for (j = 0; j < stats->ls_num; j++) { - header = &stats->ls_cnt_header[j]; percpu_cntr = lprocfs_stats_counter_get(stats, i, j); percpu_cntr->lc_count = 0; percpu_cntr->lc_min = LC_MIN_INIT; @@ -1662,104 +1756,6 @@ int lprocfs_write_helper(const char *buffer, unsigned long count, } EXPORT_SYMBOL(lprocfs_write_helper); -int lprocfs_write_frac_helper(const char *buffer, unsigned long count, - int *val, int mult) -{ - char kernbuf[20], *end, *pbuf; - - if (count > (sizeof(kernbuf) - 1)) - return -EINVAL; - - if (copy_from_user(kernbuf, buffer, count)) - return -EFAULT; - - kernbuf[count] = '\0'; - pbuf = kernbuf; - if (*pbuf == '-') { - mult = -mult; - pbuf++; - } - - *val = (int)simple_strtoul(pbuf, &end, 10) * mult; - if (pbuf == end) - return -EINVAL; - - if (end != NULL && *end == '.') { - int temp_val, pow = 1; - int i; - - pbuf = end + 1; - if (strlen(pbuf) > 5) - pbuf[5] = '\0'; /*only allow 5bits fractional*/ - - temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult; - - if (pbuf < end) { - for (i = 0; i < (end - pbuf); i++) - pow *= 10; - - *val += temp_val / pow; - } - } - return 0; -} -EXPORT_SYMBOL(lprocfs_write_frac_helper); - -int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, - int mult) -{ - long decimal_val, frac_val; - int prtn; - - if (count < 10) - return -EINVAL; - - decimal_val = val / mult; - prtn = snprintf(buffer, count, "%ld", decimal_val); - frac_val = val % mult; - - if (prtn < (count - 4) && frac_val > 0) { - long temp_frac; - int i, temp_mult = 1, frac_bits = 0; - - temp_frac = frac_val * 10; - buffer[prtn++] = '.'; - while (frac_bits < 2 && (temp_frac / mult) < 1 ) { - /* only reserved 2 bits fraction */ - buffer[prtn++] ='0'; - temp_frac *= 10; - frac_bits++; - } - /* - * Need to think these cases : - * 1. #echo x.00 > /proc/xxx output result : x - * 2. #echo x.0x > /proc/xxx output result : x.0x - * 3. #echo x.x0 > /proc/xxx output result : x.x - * 4. #echo x.xx > /proc/xxx output result : x.xx - * Only reserved 2 bits fraction. - */ - for (i = 0; i < (5 - prtn); i++) - temp_mult *= 10; - - frac_bits = min((int)count - prtn, 3 - frac_bits); - prtn += snprintf(buffer + prtn, frac_bits, "%ld", - frac_val * temp_mult / mult); - - prtn--; - while(buffer[prtn] < '1' || buffer[prtn] > '9') { - prtn--; - if (buffer[prtn] == '.') { - prtn--; - break; - } - } - prtn++; - } - buffer[prtn++] ='\n'; - return prtn; -} -EXPORT_SYMBOL(lprocfs_read_frac_helper); - int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult) { long decimal_val, frac_val; @@ -1983,4 +1979,4 @@ int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data) } EXPORT_SYMBOL(lprocfs_obd_rd_max_pages_per_rpc); -#endif /* LPROCFS*/ +#endif diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 212823ab937b..9887d8fffb6e 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -200,6 +200,8 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env, struct lu_object *scan; struct lu_object *top; struct list_head *layers; + unsigned int init_mask = 0; + unsigned int init_flag; int clean; int result; @@ -218,15 +220,17 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env, */ top->lo_header->loh_fid = *f; layers = &top->lo_header->loh_layers; + do { /* * Call ->loo_object_init() repeatedly, until no more new * object slices are created. */ clean = 1; + init_flag = 1; list_for_each_entry(scan, layers, lo_linkage) { - if (scan->lo_flags & LU_OBJECT_ALLOCATED) - continue; + if (init_mask & init_flag) + goto next; clean = 0; scan->lo_header = top->lo_header; result = scan->lo_ops->loo_object_init(env, scan, conf); @@ -234,7 +238,9 @@ static struct lu_object *lu_object_alloc(const struct lu_env *env, lu_object_free(env, top); return ERR_PTR(result); } - scan->lo_flags |= LU_OBJECT_ALLOCATED; + init_mask |= init_flag; +next: + init_flag <<= 1; } } while (!clean); @@ -423,7 +429,7 @@ LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data); */ struct lu_context_key lu_global_key = { .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | - LCT_MG_THREAD | LCT_CL_THREAD, + LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL, .lct_init = lu_global_key_init, .lct_fini = lu_global_key_fini }; @@ -487,23 +493,25 @@ void lu_object_print(const struct lu_env *env, void *cookie, { static const char ruler[] = "........................................"; struct lu_object_header *top; - int depth; + int depth = 4; top = o->lo_header; lu_object_header_print(env, cookie, printer, top); - (*printer)(env, cookie, "{ \n"); - list_for_each_entry(o, &top->loh_layers, lo_linkage) { - depth = o->lo_depth + 4; + (*printer)(env, cookie, "{\n"); + list_for_each_entry(o, &top->loh_layers, lo_linkage) { /* * print `.' \a depth times followed by type name and address */ (*printer)(env, cookie, "%*.*s%s@%p", depth, depth, ruler, o->lo_dev->ld_type->ldt_name, o); + if (o->lo_ops->loo_object_print != NULL) - o->lo_ops->loo_object_print(env, cookie, printer, o); + (*o->lo_ops->loo_object_print)(env, cookie, printer, o); + (*printer)(env, cookie, "\n"); } + (*printer)(env, cookie, "} header@%p\n", top); } EXPORT_SYMBOL(lu_object_print); @@ -830,8 +838,8 @@ enum { }; static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT; -CFS_MODULE_PARM(lu_cache_percent, "i", int, 0644, - "Percentage of memory to be used as lu_object cache"); +module_param(lu_cache_percent, int, 0644); +MODULE_PARM_DESC(lu_cache_percent, "Percentage of memory to be used as lu_object cache"); /** * Return desired hash table order. diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 68a4d6a0eb03..a69a630b596e 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -631,6 +631,9 @@ int lustre_put_lsi(struct super_block *sb) CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts)); if (atomic_dec_and_test(&lsi->lsi_mounts)) { if (IS_SERVER(lsi) && lsi->lsi_osd_exp) { + lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev); + lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL; + lsi->lsi_dt_dev = NULL; obd_disconnect(lsi->lsi_osd_exp); /* wait till OSD is gone */ obd_zombie_barrier(); diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index 1fb0ac4e920d..9b2dea292363 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -1106,7 +1106,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d, /* coverity[overrun-buffer-val] */ obj = cl_object_find(env, echo_dev2cl(d), fid, &conf->eoc_cl); if (IS_ERR(obj)) - GOTO(out, eco = (void*)obj); + GOTO(out, eco = (void *)obj); eco = cl2echo_obj(obj); if (eco->eo_deleted) { diff --git a/drivers/staging/lustre/lustre/osc/Makefile b/drivers/staging/lustre/lustre/osc/Makefile index bbd2f7707e9f..4488162d228a 100644 --- a/drivers/staging/lustre/lustre/osc/Makefile +++ b/drivers/staging/lustre/lustre/osc/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_LUSTRE_FS) += osc.o -osc-y := osc_request.o lproc_osc.o osc_dev.o osc_object.o \ +osc-y := osc_request.o osc_dev.o osc_object.o \ osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o +osc-$(CONFIG_PROC_FS) += lproc_osc.o diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index ef10e2af787f..0b59fc16c50c 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -42,7 +42,6 @@ #include <linux/seq_file.h> #include "osc_internal.h" -#ifdef LPROCFS static int osc_active_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -724,4 +723,3 @@ void lprocfs_osc_init_vars(struct lprocfs_static_vars *lvars) lvars->module_vars = lprocfs_osc_module_vars; lvars->obd_vars = lprocfs_osc_obd_vars; } -#endif /* LPROCFS */ diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index cb197782d9a3..c837a0d71e0f 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -46,10 +46,6 @@ #include <obd_ost.h> #include <obd_lov.h> -#ifdef __CYGWIN__ -# include <ctype.h> -#endif - #include <lustre_ha.h> #include <lprocfs_status.h> #include <lustre_log.h> diff --git a/drivers/staging/lustre/lustre/ptlrpc/Makefile b/drivers/staging/lustre/lustre/ptlrpc/Makefile index 6d78b80487f2..1c338aaf18a6 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/Makefile +++ b/drivers/staging/lustre/lustre/ptlrpc/Makefile @@ -10,12 +10,13 @@ ldlm_objs += $(LDLM)ldlm_pool.o ldlm_objs += $(LDLM)interval_tree.o ptlrpc_objs := client.o recover.o connection.o niobuf.o pack_generic.o ptlrpc_objs += events.o ptlrpc_module.o service.o pinger.o -ptlrpc_objs += llog_net.o llog_client.o llog_server.o import.o ptlrpcd.o +ptlrpc_objs += llog_net.o llog_client.o import.o ptlrpcd.o ptlrpc_objs += pers.o lproc_ptlrpc.o wiretest.o layout.o -ptlrpc_objs += sec.o sec_bulk.o sec_gc.o sec_config.o sec_lproc.o +ptlrpc_objs += sec.o sec_bulk.o sec_gc.o sec_config.o ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs) +ptlrpc-$(CONFIG_PROC_FS) += sec_lproc.o ptlrpc-$(CONFIG_LUSTRE_TRANSLATE_ERRNOS) += errno.o obj-$(CONFIG_PTLRPC_GSS) += gss/ diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index c2ab0c8c4d42..d90efe408414 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -200,7 +200,7 @@ void __ptlrpc_free_bulk(struct ptlrpc_bulk_desc *desc, int unpin) class_import_put(desc->bd_import); if (unpin) { - for (i = 0; i < desc->bd_iov_count ; i++) + for (i = 0; i < desc->bd_iov_count; i++) page_cache_release(desc->bd_iov[i].kiov_page); } @@ -459,7 +459,7 @@ ptlrpc_init_rq_pool(int num_rq, int msgsize, { struct ptlrpc_request_pool *pool; - OBD_ALLOC(pool, sizeof (struct ptlrpc_request_pool)); + OBD_ALLOC(pool, sizeof(struct ptlrpc_request_pool)); if (!pool) return NULL; @@ -475,7 +475,7 @@ ptlrpc_init_rq_pool(int num_rq, int msgsize, if (list_empty(&pool->prp_req_list)) { /* have not allocated a single request for the pool */ - OBD_FREE(pool, sizeof (struct ptlrpc_request_pool)); + OBD_FREE(pool, sizeof(struct ptlrpc_request_pool)); pool = NULL; } return pool; @@ -881,7 +881,7 @@ void ptlrpc_set_destroy(struct ptlrpc_request_set *set) /* Requests on the set should either all be completed, or all be new */ expected_phase = (atomic_read(&set->set_remaining) == 0) ? RQ_PHASE_COMPLETE : RQ_PHASE_NEW; - list_for_each (tmp, &set->set_requests) { + list_for_each(tmp, &set->set_requests) { struct ptlrpc_request *req = list_entry(tmp, struct ptlrpc_request, rq_set_chain); @@ -912,7 +912,7 @@ void ptlrpc_set_destroy(struct ptlrpc_request_set *set) req->rq_invalid_rqset = 0; spin_unlock(&req->rq_lock); - ptlrpc_req_finished (req); + ptlrpc_req_finished(req); } LASSERT(atomic_read(&set->set_remaining) == 0); @@ -1020,7 +1020,7 @@ static int ptlrpc_import_delay_req(struct obd_import *imp, { int delay = 0; - LASSERT (status != NULL); + LASSERT(status != NULL); *status = 0; if (req->rq_ctx_init || req->rq_ctx_fini) { @@ -1039,7 +1039,7 @@ static int ptlrpc_import_delay_req(struct obd_import *imp, *status = -EIO; } else if (req->rq_send_state == LUSTRE_IMP_CONNECTING && imp->imp_state == LUSTRE_IMP_CONNECTING) { - /* allow CONNECT even if import is invalid */ ; + /* allow CONNECT even if import is invalid */ if (atomic_read(&imp->imp_inval_count) != 0) { DEBUG_REQ(D_ERROR, req, "invalidate in flight"); *status = -EIO; @@ -1596,7 +1596,8 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) continue; spin_lock(&imp->imp_lock); - if (ptlrpc_import_delay_req(imp, req, &status)){ + if (ptlrpc_import_delay_req(imp, req, + &status)) { /* put on delay list - only if we wait * recovery finished - before send */ list_del_init(&req->rq_list); @@ -1752,7 +1753,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) ptlrpc_rqphase_move(req, RQ_PHASE_INTERPRET); - interpret: +interpret: LASSERT(req->rq_phase == RQ_PHASE_INTERPRET); /* This moves to "unregistering" phase we need to wait for @@ -1907,7 +1908,7 @@ int ptlrpc_expired_set(void *data) /* * A timeout expired. See which reqs it applies to... */ - list_for_each (tmp, &set->set_requests) { + list_for_each(tmp, &set->set_requests) { struct ptlrpc_request *req = list_entry(tmp, struct ptlrpc_request, rq_set_chain); @@ -2688,7 +2689,7 @@ int ptlrpc_replay_req(struct ptlrpc_request *req) LASSERT(req->rq_import->imp_state == LUSTRE_IMP_REPLAY); - LASSERT (sizeof (*aa) <= sizeof (req->rq_async_args)); + LASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); aa = ptlrpc_req_async_args(req); memset(aa, 0, sizeof(*aa)); @@ -2962,7 +2963,7 @@ void *ptlrpcd_alloc_work(struct obd_import *imp, init_waitqueue_head(&req->rq_set_waitq); atomic_set(&req->rq_refcount, 1); - CLASSERT (sizeof(*args) <= sizeof(req->rq_async_args)); + CLASSERT(sizeof(*args) <= sizeof(req->rq_async_args)); args = ptlrpc_req_async_args(req); args->magic = PTLRPC_WORK_MAGIC; args->cb = cb; diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index 58d089c3fef4..f66cfea87acf 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -56,9 +56,9 @@ void request_out_callback(lnet_event_t *ev) struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request *req = cbid->cbid_arg; - LASSERT (ev->type == LNET_EVENT_SEND || - ev->type == LNET_EVENT_UNLINK); - LASSERT (ev->unlinked); + LASSERT(ev->type == LNET_EVENT_SEND || + ev->type == LNET_EVENT_UNLINK); + LASSERT(ev->unlinked); DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status); @@ -90,9 +90,9 @@ void reply_in_callback(lnet_event_t *ev) DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status); - LASSERT (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK); - LASSERT (ev->md.start == req->rq_repbuf); - LASSERT (ev->offset + ev->mlength <= req->rq_repbuf_len); + LASSERT(ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK); + LASSERT(ev->md.start == req->rq_repbuf); + LASSERT(ev->offset + ev->mlength <= req->rq_repbuf_len); /* We've set LNET_MD_MANAGE_REMOTE for all outgoing requests for adaptive timeouts' early reply. */ LASSERT((ev->md.options & LNET_MD_MANAGE_REMOTE) != 0); @@ -113,7 +113,7 @@ void reply_in_callback(lnet_event_t *ev) goto out_wake; } - if (ev->mlength < ev->rlength ) { + if (ev->mlength < ev->rlength) { CDEBUG(D_RPCTRACE, "truncate req %p rpc %d - %d+%d\n", req, req->rq_replen, ev->rlength, ev->offset); req->rq_reply_truncate = 1; @@ -167,18 +167,18 @@ out_wake: /* * Client's bulk has been written/read */ -void client_bulk_callback (lnet_event_t *ev) +void client_bulk_callback(lnet_event_t *ev) { struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_bulk_desc *desc = cbid->cbid_arg; struct ptlrpc_request *req; - LASSERT ((desc->bd_type == BULK_PUT_SINK && - ev->type == LNET_EVENT_PUT) || - (desc->bd_type == BULK_GET_SOURCE && - ev->type == LNET_EVENT_GET) || - ev->type == LNET_EVENT_UNLINK); - LASSERT (ev->unlinked); + LASSERT((desc->bd_type == BULK_PUT_SINK && + ev->type == LNET_EVENT_PUT) || + (desc->bd_type == BULK_GET_SOURCE && + ev->type == LNET_EVENT_GET) || + ev->type == LNET_EVENT_UNLINK); + LASSERT(ev->unlinked); if (CFS_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_CLIENT_BULK_CB, CFS_FAIL_ONCE)) ev->status = -EIO; @@ -283,11 +283,11 @@ void request_in_callback(lnet_event_t *ev) struct ptlrpc_service *service = svcpt->scp_service; struct ptlrpc_request *req; - LASSERT (ev->type == LNET_EVENT_PUT || - ev->type == LNET_EVENT_UNLINK); - LASSERT ((char *)ev->md.start >= rqbd->rqbd_buffer); - LASSERT ((char *)ev->md.start + ev->offset + ev->mlength <= - rqbd->rqbd_buffer + service->srv_buf_size); + LASSERT(ev->type == LNET_EVENT_PUT || + ev->type == LNET_EVENT_UNLINK); + LASSERT((char *)ev->md.start >= rqbd->rqbd_buffer); + LASSERT((char *)ev->md.start + ev->offset + ev->mlength <= + rqbd->rqbd_buffer + service->srv_buf_size); CDEBUG((ev->status == 0) ? D_NET : D_ERROR, "event type %d, status %d, service %s\n", @@ -300,9 +300,9 @@ void request_in_callback(lnet_event_t *ev) * we'd have to re-post the rqbd, which we can't do in this * context. */ req = &rqbd->rqbd_req; - memset(req, 0, sizeof (*req)); + memset(req, 0, sizeof(*req)); } else { - LASSERT (ev->type == LNET_EVENT_PUT); + LASSERT(ev->type == LNET_EVENT_PUT); if (ev->status != 0) { /* We moaned above already... */ return; @@ -381,19 +381,19 @@ void reply_out_callback(lnet_event_t *ev) struct ptlrpc_reply_state *rs = cbid->cbid_arg; struct ptlrpc_service_part *svcpt = rs->rs_svcpt; - LASSERT (ev->type == LNET_EVENT_SEND || - ev->type == LNET_EVENT_ACK || - ev->type == LNET_EVENT_UNLINK); + LASSERT(ev->type == LNET_EVENT_SEND || + ev->type == LNET_EVENT_ACK || + ev->type == LNET_EVENT_UNLINK); if (!rs->rs_difficult) { /* 'Easy' replies have no further processing so I drop the * net's ref on 'rs' */ - LASSERT (ev->unlinked); + LASSERT(ev->unlinked); ptlrpc_rs_decref(rs); return; } - LASSERT (rs->rs_on_net); + LASSERT(rs->rs_on_net); if (ev->unlinked) { /* Last network callback. The net's ref on 'rs' stays put @@ -419,18 +419,17 @@ static void ptlrpc_master_callback(lnet_event_t *ev) void (*callback)(lnet_event_t *ev) = cbid->cbid_fn; /* Honestly, it's best to find out early. */ - LASSERT (cbid->cbid_arg != LP_POISON); - LASSERT (callback == request_out_callback || - callback == reply_in_callback || - callback == client_bulk_callback || - callback == request_in_callback || - callback == reply_out_callback - ); - - callback (ev); + LASSERT(cbid->cbid_arg != LP_POISON); + LASSERT(callback == request_out_callback || + callback == reply_in_callback || + callback == client_bulk_callback || + callback == request_in_callback || + callback == reply_out_callback); + + callback(ev); } -int ptlrpc_uuid_to_peer (struct obd_uuid *uuid, +int ptlrpc_uuid_to_peer(struct obd_uuid *uuid, lnet_process_id_t *peer, lnet_nid_t *self) { int best_dist = 0; @@ -538,7 +537,7 @@ int ptlrpc_ni_init(void) /* We're not passing any limits yet... */ rc = LNetNIInit(pid); if (rc < 0) { - CDEBUG (D_NET, "Can't init network interface: %d\n", rc); + CDEBUG(D_NET, "Can't init network interface: %d\n", rc); return (-ENOENT); } @@ -552,7 +551,7 @@ int ptlrpc_ni_init(void) if (rc == 0) return 0; - CERROR ("Failed to allocate event queue: %d\n", rc); + CERROR("Failed to allocate event queue: %d\n", rc); LNetNIFini(); return (-ENOMEM); diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h index c70eb00796f9..bdfd83880422 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h +++ b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h @@ -64,9 +64,9 @@ #define G_REFLECT (-2045022961L) #define G_WRONG_TOKID (-2045022960L) -#define g_OID_equal(o1,o2) \ - (((o1)->len == (o2)->len) && \ - (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0)) +#define g_OID_equal(o1, o2) \ + (((o1)->len == (o2)->len) && \ + (memcmp((o1)->data, (o2)->data, (int) (o1)->len) == 0)) __u32 g_verify_token_header(rawobj_t *mech, int *body_size, diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h index 13425796fa33..37ec101e14e5 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h +++ b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h @@ -106,14 +106,14 @@ typedef unsigned int OM_uint32; * evaluates its argument only once. */ #define GSS_CALLING_ERROR(x) \ - ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) + ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) #define GSS_ROUTINE_ERROR(x) \ - ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) + ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) #define GSS_SUPPLEMENTARY_INFO(x) \ - ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) + ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) #define GSS_ERROR(x) \ - ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ - (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) + ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ + (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) /* * Now the actual status code definitions diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c index 188dbbfbd2f4..d43a13c69669 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c +++ b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c @@ -165,7 +165,7 @@ void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout) init_timer(timer); timer->expires = timeout; - timer->data = (unsigned long ) ctx; + timer->data = (unsigned long) ctx; timer->function = ctx_upcall_timeout_kr; add_timer(timer); diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c index c106a9e049a7..b9fa3b4a40db 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c +++ b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c @@ -1276,7 +1276,7 @@ arc4_out_tfm: arc4_out_key: rawobj_free(&arc4_keye); arc4_out: - do {} while(0); /* just to avoid compile warning */ + do {} while (0); /* just to avoid compile warning */ } else { rc = krb5_encrypt_rawobjs(kctx->kc_keye.kb_tfm, 0, 3, data_desc, &cipher, 1); diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c b/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c index b42ddda9ee25..8ce6271a5daa 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c +++ b/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c @@ -483,7 +483,7 @@ int gss_do_check_seq(unsigned long *window, __u32 win_size, __u32 *max_seq, memset(window, 0, win_size / 8); *max_seq = seq_num; } else { - while(*max_seq < seq_num) { + while (*max_seq < seq_num) { (*max_seq)++; __clear_bit((*max_seq) % win_size, window); } @@ -804,7 +804,8 @@ int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx, case PTLRPC_GSS_PROC_DATA: pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK; - if (!req->rq_early && !equi(req->rq_pack_bulk == 1, pack_bulk)){ + if (!req->rq_early && + !equi(req->rq_pack_bulk == 1, pack_bulk)) { CERROR("%s bulk flag in reply\n", req->rq_pack_bulk ? "missing" : "unexpected"); return -EPROTO; @@ -1009,7 +1010,8 @@ int gss_cli_ctx_unseal(struct ptlrpc_cli_ctx *ctx, case PTLRPC_GSS_PROC_DATA: pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK; - if (!req->rq_early && !equi(req->rq_pack_bulk == 1, pack_bulk)){ + if (!req->rq_early && + !equi(req->rq_pack_bulk == 1, pack_bulk)) { CERROR("%s bulk flag in reply\n", req->rq_pack_bulk ? "missing" : "unexpected"); return -EPROTO; @@ -1979,7 +1981,7 @@ int gss_svc_handle_init(struct ptlrpc_request *req, return SECSVC_DROP; } - if (reqbuf->lm_bufcount < 3 || reqbuf->lm_bufcount > 4){ + if (reqbuf->lm_bufcount < 3 || reqbuf->lm_bufcount > 4) { CERROR("Invalid bufcount %d\n", reqbuf->lm_bufcount); return SECSVC_DROP; } @@ -2369,7 +2371,7 @@ int gss_svc_accept(struct ptlrpc_sec_policy *policy, struct ptlrpc_request *req) if (swabbed) gss_header_swabber(ghdr); - switch(ghdr->gh_proc) { + switch (ghdr->gh_proc) { case PTLRPC_GSS_PROC_INIT: case PTLRPC_GSS_PROC_CONTINUE_INIT: rc = gss_svc_handle_init(req, gw); @@ -2388,7 +2390,7 @@ int gss_svc_accept(struct ptlrpc_sec_policy *policy, struct ptlrpc_request *req) switch (rc) { case SECSVC_OK: - LASSERT (grctx->src_ctx); + LASSERT(grctx->src_ctx); req->rq_auth_gss = 1; req->rq_auth_remote = grctx->src_ctx->gsc_remote; diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index 7b96a0e88cdb..f465547eb95e 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -72,23 +72,23 @@ static void __import_set_state(struct obd_import *imp, } /* A CLOSED import should remain so. */ -#define IMPORT_SET_STATE_NOLOCK(imp, state) \ -do { \ - if (imp->imp_state != LUSTRE_IMP_CLOSED) { \ - CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n", \ - imp, obd2cli_tgt(imp->imp_obd), \ - ptlrpc_import_state_name(imp->imp_state), \ - ptlrpc_import_state_name(state)); \ - __import_set_state(imp, state); \ - } \ -} while(0) +#define IMPORT_SET_STATE_NOLOCK(imp, state) \ +do { \ + if (imp->imp_state != LUSTRE_IMP_CLOSED) { \ + CDEBUG(D_HA, "%p %s: changing import state from %s to %s\n", \ + imp, obd2cli_tgt(imp->imp_obd), \ + ptlrpc_import_state_name(imp->imp_state), \ + ptlrpc_import_state_name(state)); \ + __import_set_state(imp, state); \ + } \ +} while (0) #define IMPORT_SET_STATE(imp, state) \ do { \ spin_lock(&imp->imp_lock); \ IMPORT_SET_STATE_NOLOCK(imp, state); \ spin_unlock(&imp->imp_lock); \ -} while(0) +} while (0) static int ptlrpc_connect_interpret(const struct lu_env *env, @@ -170,7 +170,6 @@ int ptlrpc_set_import_discon(struct obd_import *imp, __u32 conn_cnt) target_len, target_start, libcfs_nid2str(imp->imp_connection->c_peer.nid)); } - ptlrpc_deactivate_timeouts(imp); IMPORT_SET_STATE_NOLOCK(imp, LUSTRE_IMP_DISCON); spin_unlock(&imp->imp_lock); @@ -383,7 +382,6 @@ void ptlrpc_activate_import(struct obd_import *imp) spin_lock(&imp->imp_lock); imp->imp_invalid = 0; - ptlrpc_activate_timeouts(imp); spin_unlock(&imp->imp_lock); obd_import_event(obd, imp, IMP_EVENT_ACTIVE); } @@ -680,7 +678,7 @@ int ptlrpc_connect_import(struct obd_import *imp) ptlrpc_request_set_replen(request); request->rq_interpret_reply = ptlrpc_connect_interpret; - CLASSERT(sizeof (*aa) <= sizeof (request->rq_async_args)); + CLASSERT(sizeof(*aa) <= sizeof(request->rq_async_args)); aa = ptlrpc_req_async_args(request); memset(aa, 0, sizeof(*aa)); @@ -859,7 +857,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, if (MSG_CONNECT_RECONNECT & msg_flags) { memset(&old_hdl, 0, sizeof(old_hdl)); if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg), - sizeof (old_hdl))) { + sizeof(old_hdl))) { LCONSOLE_WARN("Reconnect to %s (at @%s) failed due " "bad handle "LPX64"\n", obd2cli_tgt(imp->imp_obd), @@ -1135,9 +1133,11 @@ out: if (ocd && (ocd->ocd_connect_flags & OBD_CONNECT_VERSION) && (ocd->ocd_version != LUSTRE_VERSION_CODE)) { - /* Actually servers are only supposed to refuse - connection from liblustre clients, so we should - never see this from VFS context */ + /* + * Actually servers are only supposed to refuse + * connection from liblustre clients, so we + * should never see this from VFS context + */ LCONSOLE_ERROR_MSG(0x16a, "Server %s version " "(%d.%d.%d.%d)" " refused connection from this client " @@ -1507,7 +1507,7 @@ int at_measured(struct adaptive_timeout *at, unsigned int val) at->at_worst_time = now; at->at_hist[0] = val; at->at_binstart = now; - } else if (now - at->at_binstart < binlimit ) { + } else if (now - at->at_binstart < binlimit) { /* in bin 0 */ at->at_hist[0] = max(val, at->at_hist[0]); at->at_current = max(val, at->at_current); @@ -1517,7 +1517,7 @@ int at_measured(struct adaptive_timeout *at, unsigned int val) /* move bins over */ shift = (now - at->at_binstart) / binlimit; LASSERT(shift > 0); - for(i = AT_BINS - 1; i >= 0; i--) { + for (i = AT_BINS - 1; i >= 0; i--) { if (i >= shift) { at->at_hist[i] = at->at_hist[i - shift]; maxv = max(maxv, at->at_hist[i]); diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index d0a6e5689227..dfcb410fe485 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -145,6 +145,14 @@ static const struct req_msg_field *mdt_close_client[] = { &RMF_CAPA1 }; +static const struct req_msg_field *mdt_release_close_client[] = { + &RMF_PTLRPC_BODY, + &RMF_MDT_EPOCH, + &RMF_REC_REINT, + &RMF_CAPA1, + &RMF_CLOSE_DATA +}; + static const struct req_msg_field *obd_statfs_server[] = { &RMF_PTLRPC_BODY, &RMF_OBD_STATFS @@ -454,6 +462,25 @@ static const struct req_msg_field *ldlm_intent_unlink_client[] = { &RMF_NAME }; +static const struct req_msg_field *ldlm_intent_getxattr_client[] = { + &RMF_PTLRPC_BODY, + &RMF_DLM_REQ, + &RMF_LDLM_INTENT, + &RMF_MDT_BODY, + &RMF_CAPA1, +}; + +static const struct req_msg_field *ldlm_intent_getxattr_server[] = { + &RMF_PTLRPC_BODY, + &RMF_DLM_REP, + &RMF_MDT_BODY, + &RMF_MDT_MD, + &RMF_ACL, /* for req_capsule_extend/mdt_intent_policy */ + &RMF_EADATA, + &RMF_EAVALS, + &RMF_EAVALS_LENS +}; + static const struct req_msg_field *mds_getxattr_client[] = { &RMF_PTLRPC_BODY, &RMF_MDT_BODY, @@ -666,6 +693,7 @@ static struct req_format *req_formats[] = { &RQF_MDS_GETXATTR, &RQF_MDS_SYNC, &RQF_MDS_CLOSE, + &RQF_MDS_RELEASE_CLOSE, &RQF_MDS_PIN, &RQF_MDS_UNPIN, &RQF_MDS_READPAGE, @@ -730,6 +758,7 @@ static struct req_format *req_formats[] = { &RQF_LDLM_INTENT_OPEN, &RQF_LDLM_INTENT_CREATE, &RQF_LDLM_INTENT_UNLINK, + &RQF_LDLM_INTENT_GETXATTR, &RQF_LDLM_INTENT_QUOTA, &RQF_QUOTA_DQACQ, &RQF_LOG_CANCEL, @@ -738,7 +767,8 @@ static struct req_format *req_formats[] = { &RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK, &RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK, &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER, - &RQF_LLOG_ORIGIN_CONNECT + &RQF_LLOG_ORIGIN_CONNECT, + &RQF_CONNECT, }; struct req_msg_field { @@ -884,6 +914,11 @@ struct req_msg_field RMF_PTLRPC_BODY = sizeof(struct ptlrpc_body), lustre_swab_ptlrpc_body, NULL); EXPORT_SYMBOL(RMF_PTLRPC_BODY); +struct req_msg_field RMF_CLOSE_DATA = + DEFINE_MSGF("data_version", 0, + sizeof(struct close_data), lustre_swab_close_data, NULL); +EXPORT_SYMBOL(RMF_CLOSE_DATA); + struct req_msg_field RMF_OBD_STATFS = DEFINE_MSGF("obd_statfs", 0, sizeof(struct obd_statfs), lustre_swab_obd_statfs, NULL); @@ -998,6 +1033,9 @@ struct req_msg_field RMF_EADATA = DEFINE_MSGF("eadata", 0, -1, NULL, NULL); EXPORT_SYMBOL(RMF_EADATA); +struct req_msg_field RMF_EAVALS = DEFINE_MSGF("eavals", 0, -1, NULL, NULL); +EXPORT_SYMBOL(RMF_EAVALS); + struct req_msg_field RMF_ACL = DEFINE_MSGF("acl", RMF_F_NO_SIZE_CHECK, LUSTRE_POSIX_ACL_MAX_SIZE, NULL, NULL); @@ -1049,6 +1087,11 @@ struct req_msg_field RMF_RCS = lustre_swab_generic_32s, dump_rcs); EXPORT_SYMBOL(RMF_RCS); +struct req_msg_field RMF_EAVALS_LENS = + DEFINE_MSGF("eavals_lens", RMF_F_STRUCT_ARRAY, sizeof(__u32), + lustre_swab_generic_32s, NULL); +EXPORT_SYMBOL(RMF_EAVALS_LENS); + struct req_msg_field RMF_OBD_ID = DEFINE_MSGF("obd_id", 0, sizeof(obd_id), lustre_swab_ost_last_id, NULL); @@ -1406,11 +1449,22 @@ struct req_format RQF_LDLM_INTENT_UNLINK = ldlm_intent_unlink_client, ldlm_intent_server); EXPORT_SYMBOL(RQF_LDLM_INTENT_UNLINK); +struct req_format RQF_LDLM_INTENT_GETXATTR = + DEFINE_REQ_FMT0("LDLM_INTENT_GETXATTR", + ldlm_intent_getxattr_client, + ldlm_intent_getxattr_server); +EXPORT_SYMBOL(RQF_LDLM_INTENT_GETXATTR); + struct req_format RQF_MDS_CLOSE = DEFINE_REQ_FMT0("MDS_CLOSE", mdt_close_client, mds_last_unlink_server); EXPORT_SYMBOL(RQF_MDS_CLOSE); +struct req_format RQF_MDS_RELEASE_CLOSE = + DEFINE_REQ_FMT0("MDS_CLOSE", + mdt_release_close_client, mds_last_unlink_server); +EXPORT_SYMBOL(RQF_MDS_RELEASE_CLOSE); + struct req_format RQF_MDS_PIN = DEFINE_REQ_FMT0("MDS_PIN", mdt_body_capa, mdt_body_only); @@ -1504,6 +1558,10 @@ struct req_format RQF_LLOG_ORIGIN_CONNECT = DEFINE_REQ_FMT0("LLOG_ORIGIN_CONNECT", llogd_conn_body_only, empty); EXPORT_SYMBOL(RQF_LLOG_ORIGIN_CONNECT); +struct req_format RQF_CONNECT = + DEFINE_REQ_FMT0("CONNECT", obd_connect_client, obd_connect_server); +EXPORT_SYMBOL(RQF_CONNECT); + struct req_format RQF_OST_CONNECT = DEFINE_REQ_FMT0("OST_CONNECT", obd_connect_client, obd_connect_server); @@ -1808,7 +1866,7 @@ swabber_dumper_helper(struct req_capsule *pill, const struct req_msg_field *field, enum req_location loc, int offset, - void *value, int len, int dump, void (*swabber)( void *)) + void *value, int len, int dump, void (*swabber)(void *)) { void *p; int i; @@ -1824,8 +1882,11 @@ swabber_dumper_helper(struct req_capsule *pill, else do_swab = 0; + if (!field->rmf_dumper) + dump = 0; + if (!(field->rmf_flags & RMF_F_STRUCT_ARRAY)) { - if (dump && field->rmf_dumper) { + if (dump) { CDEBUG(D_RPCTRACE, "Dump of %sfield %s follows\n", do_swab ? "unswabbed " : "", field->rmf_name); field->rmf_dumper(value); @@ -1851,7 +1912,7 @@ swabber_dumper_helper(struct req_capsule *pill, for (p = value, i = 0, n = len / field->rmf_size; i < n; i++, p += field->rmf_size) { - if (dump && field->rmf_dumper) { + if (dump) { CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, " "element %d follows\n", do_swab ? "unswabbed " : "", field->rmf_name, i); @@ -1860,7 +1921,7 @@ swabber_dumper_helper(struct req_capsule *pill, if (!do_swab) continue; swabber(p); - if (dump && field->rmf_dumper) { + if (dump) { CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, " "element %d follows\n", field->rmf_name, i); field->rmf_dumper(value); @@ -1883,7 +1944,7 @@ swabber_dumper_helper(struct req_capsule *pill, static void *__req_capsule_get(struct req_capsule *pill, const struct req_msg_field *field, enum req_location loc, - void (*swabber)( void *), + void (*swabber)(void *), int dump) { const struct req_format *fmt; diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c index 379e59477ea2..ab084541fddb 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c @@ -63,7 +63,7 @@ return (-EINVAL); \ } \ mutex_unlock(&ctxt->loc_mutex); \ -} while(0) +} while (0) #define LLOG_CLIENT_EXIT(ctxt, imp) do { \ mutex_lock(&ctxt->loc_mutex); \ @@ -72,7 +72,7 @@ ctxt->loc_imp, imp); \ class_import_put(imp); \ mutex_unlock(&ctxt->loc_mutex); \ -} while(0) +} while (0) /* This is a callback from the llog_* functions. * Assumes caller has already pushed us into the kernel context. */ @@ -302,7 +302,7 @@ static int llog_client_read_header(const struct lu_env *env, if (hdr == NULL) GOTO(out, rc =-EFAULT); - memcpy(handle->lgh_hdr, hdr, sizeof (*hdr)); + memcpy(handle->lgh_hdr, hdr, sizeof(*hdr)); handle->lgh_last_idx = handle->lgh_hdr->llh_tail.lrt_index; /* sanity checks */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/llog_server.c b/drivers/staging/lustre/lustre/ptlrpc/llog_server.c deleted file mode 100644 index af9d2ac391ef..000000000000 --- a/drivers/staging/lustre/lustre/ptlrpc/llog_server.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/ptlrpc/llog_server.c - * - * remote api for llog - server side - * - * Author: Andreas Dilger <adilger@clusterfs.com> - */ - -#define DEBUG_SUBSYSTEM S_LOG - - -#include <obd_class.h> -#include <lustre_log.h> -#include <lustre_net.h> -#include <lustre_fsfilt.h> - -#if defined(LUSTRE_LOG_SERVER) -static int llog_origin_close(const struct lu_env *env, struct llog_handle *lgh) -{ - if (lgh->lgh_hdr != NULL && lgh->lgh_hdr->llh_flags & LLOG_F_IS_CAT) - return llog_cat_close(env, lgh); - else - return llog_close(env, lgh); -} - -/* Only open is supported, no new llog can be created remotely */ -int llog_origin_handle_open(struct ptlrpc_request *req) -{ - struct obd_export *exp = req->rq_export; - struct obd_device *obd = exp->exp_obd; - struct obd_device *disk_obd; - struct lvfs_run_ctxt saved; - struct llog_handle *loghandle; - struct llogd_body *body; - struct llog_logid *logid = NULL; - struct llog_ctxt *ctxt; - char *name = NULL; - int rc; - - body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); - if (body == NULL) - return -EFAULT; - - if (ostid_id(&body->lgd_logid.lgl_oi) > 0) - logid = &body->lgd_logid; - - if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) { - name = req_capsule_client_get(&req->rq_pill, &RMF_NAME); - if (name == NULL) - return -EFAULT; - CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name); - } - - ctxt = llog_get_context(obd, body->lgd_ctxt_idx); - if (ctxt == NULL) { - CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n", - obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name); - return -ENODEV; - } - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid, - name, LLOG_OPEN_EXISTS); - if (rc) - GOTO(out_pop, rc); - - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - GOTO(out_close, rc = -ENOMEM); - - body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); - body->lgd_logid = loghandle->lgh_id; - -out_close: - llog_origin_close(req->rq_svc_thread->t_env, loghandle); -out_pop: - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_open); - -int llog_origin_handle_destroy(struct ptlrpc_request *req) -{ - struct obd_device *disk_obd; - struct lvfs_run_ctxt saved; - struct llogd_body *body; - struct llog_logid *logid = NULL; - struct llog_ctxt *ctxt; - int rc; - - body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); - if (body == NULL) - return -EFAULT; - - if (ostid_id(&body->lgd_logid.lgl_oi) > 0) - logid = &body->lgd_logid; - - if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN)) - CERROR("%s: wrong llog flags %x\n", - req->rq_export->exp_obd->obd_name, body->lgd_llh_flags); - - ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); - if (ctxt == NULL) - return -ENODEV; - - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - - rc = req_capsule_server_pack(&req->rq_pill); - /* erase only if no error and logid is valid */ - if (rc == 0) - rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL); - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_destroy); - -int llog_origin_handle_next_block(struct ptlrpc_request *req) -{ - struct obd_device *disk_obd; - struct llog_handle *loghandle; - struct llogd_body *body; - struct llogd_body *repbody; - struct lvfs_run_ctxt saved; - struct llog_ctxt *ctxt; - __u32 flags; - void *ptr; - int rc; - - body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); - if (body == NULL) - return -EFAULT; - - ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); - if (ctxt == NULL) - return -ENODEV; - - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, - &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); - if (rc) - GOTO(out_pop, rc); - - flags = body->lgd_llh_flags; - rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, - NULL); - if (rc) - GOTO(out_close, rc); - - req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER, - LLOG_CHUNK_SIZE); - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - GOTO(out_close, rc = -ENOMEM); - - repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); - *repbody = *body; - - ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA); - rc = llog_next_block(req->rq_svc_thread->t_env, loghandle, - &repbody->lgd_saved_index, repbody->lgd_index, - &repbody->lgd_cur_offset, ptr, LLOG_CHUNK_SIZE); - if (rc) - GOTO(out_close, rc); -out_close: - llog_origin_close(req->rq_svc_thread->t_env, loghandle); -out_pop: - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_next_block); - -int llog_origin_handle_prev_block(struct ptlrpc_request *req) -{ - struct llog_handle *loghandle; - struct llogd_body *body; - struct llogd_body *repbody; - struct obd_device *disk_obd; - struct lvfs_run_ctxt saved; - struct llog_ctxt *ctxt; - __u32 flags; - void *ptr; - int rc; - - body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); - if (body == NULL) - return -EFAULT; - - ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); - if (ctxt == NULL) - return -ENODEV; - - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, - &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); - if (rc) - GOTO(out_pop, rc); - - flags = body->lgd_llh_flags; - rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, - NULL); - if (rc) - GOTO(out_close, rc); - - req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER, - LLOG_CHUNK_SIZE); - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - GOTO(out_close, rc = -ENOMEM); - - repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); - *repbody = *body; - - ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA); - rc = llog_prev_block(req->rq_svc_thread->t_env, loghandle, - body->lgd_index, ptr, LLOG_CHUNK_SIZE); - if (rc) - GOTO(out_close, rc); - -out_close: - llog_origin_close(req->rq_svc_thread->t_env, loghandle); -out_pop: - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_prev_block); - -int llog_origin_handle_read_header(struct ptlrpc_request *req) -{ - struct obd_device *disk_obd; - struct llog_handle *loghandle; - struct llogd_body *body; - struct llog_log_hdr *hdr; - struct lvfs_run_ctxt saved; - struct llog_ctxt *ctxt; - __u32 flags; - int rc; - - body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); - if (body == NULL) - return -EFAULT; - - ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); - if (ctxt == NULL) - return -ENODEV; - - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - - rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, - &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); - if (rc) - GOTO(out_pop, rc); - - /* - * llog_init_handle() reads the llog header - */ - flags = body->lgd_llh_flags; - rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, - NULL); - if (rc) - GOTO(out_close, rc); - flags = loghandle->lgh_hdr->llh_flags; - - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - GOTO(out_close, rc = -ENOMEM); - - hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR); - *hdr = *loghandle->lgh_hdr; -out_close: - llog_origin_close(req->rq_svc_thread->t_env, loghandle); -out_pop: - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_read_header); - -int llog_origin_handle_close(struct ptlrpc_request *req) -{ - /* Nothing to do */ - return 0; -} -EXPORT_SYMBOL(llog_origin_handle_close); - -int llog_origin_handle_cancel(struct ptlrpc_request *req) -{ - int num_cookies, rc = 0, err, i, failed = 0; - struct obd_device *disk_obd; - struct llog_cookie *logcookies; - struct llog_ctxt *ctxt = NULL; - struct lvfs_run_ctxt saved; - struct llog_handle *cathandle; - struct inode *inode; - void *handle; - - logcookies = req_capsule_client_get(&req->rq_pill, &RMF_LOGCOOKIES); - num_cookies = req_capsule_get_size(&req->rq_pill, &RMF_LOGCOOKIES, - RCL_CLIENT) / sizeof(*logcookies); - if (logcookies == NULL || num_cookies == 0) { - DEBUG_REQ(D_HA, req, "No llog cookies sent"); - return -EFAULT; - } - - ctxt = llog_get_context(req->rq_export->exp_obd, - logcookies->lgc_subsys); - if (ctxt == NULL) - return -ENODEV; - - disk_obd = ctxt->loc_exp->exp_obd; - push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - for (i = 0; i < num_cookies; i++, logcookies++) { - cathandle = ctxt->loc_handle; - LASSERT(cathandle != NULL); - inode = cathandle->lgh_file->f_dentry->d_inode; - - handle = fsfilt_start_log(disk_obd, inode, - FSFILT_OP_CANCEL_UNLINK, NULL, 1); - if (IS_ERR(handle)) { - CERROR("fsfilt_start_log() failed: %ld\n", - PTR_ERR(handle)); - GOTO(pop_ctxt, rc = PTR_ERR(handle)); - } - - rc = llog_cat_cancel_records(req->rq_svc_thread->t_env, - cathandle, 1, logcookies); - - /* - * Do not raise -ENOENT errors for resent rpcs. This rec already - * might be killed. - */ - if (rc == -ENOENT && - (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT)) { - /* - * Do not change this message, reply-single.sh test_59b - * expects to find this in log. - */ - CDEBUG(D_RPCTRACE, "RESENT cancel req %p - ignored\n", - req); - rc = 0; - } else if (rc == 0) { - CDEBUG(D_RPCTRACE, "Canceled %d llog-records\n", - num_cookies); - } - - err = fsfilt_commit(disk_obd, inode, handle, 0); - if (err) { - CERROR("Error committing transaction: %d\n", err); - if (!rc) - rc = err; - failed++; - GOTO(pop_ctxt, rc); - } else if (rc) - failed++; - } - GOTO(pop_ctxt, rc); -pop_ctxt: - pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); - if (rc) - CERROR("Cancel %d of %d llog-records failed: %d\n", - failed, num_cookies, rc); - - llog_ctxt_put(ctxt); - return rc; -} -EXPORT_SYMBOL(llog_origin_handle_cancel); - -#else /* !__KERNEL__ */ -int llog_origin_handle_open(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} - -int llog_origin_handle_destroy(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} - -int llog_origin_handle_next_block(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} -int llog_origin_handle_prev_block(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} -int llog_origin_handle_read_header(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} -int llog_origin_handle_close(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} -int llog_origin_handle_cancel(struct ptlrpc_request *req) -{ - LBUG(); - return 0; -} -#endif diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c index bea44a3d4a2f..1be978609c59 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c +++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c @@ -46,8 +46,8 @@ struct ll_rpc_opcode { - __u32 opcode; - const char *opname; + __u32 opcode; + const char *opname; } ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = { { OST_REPLY, "ost_reply" }, { OST_GETATTR, "ost_getattr" }, @@ -114,10 +114,10 @@ struct ll_rpc_opcode { { MGS_SET_INFO, "mgs_set_info" }, { MGS_CONFIG_READ, "mgs_config_read" }, { OBD_PING, "obd_ping" }, - { OBD_LOG_CANCEL, "llog_origin_handle_cancel" }, + { OBD_LOG_CANCEL, "llog_cancel" }, { OBD_QC_CALLBACK, "obd_quota_callback" }, { OBD_IDX_READ, "dt_index_read" }, - { LLOG_ORIGIN_HANDLE_CREATE, "llog_origin_handle_create" }, + { LLOG_ORIGIN_HANDLE_CREATE, "llog_origin_handle_open" }, { LLOG_ORIGIN_HANDLE_NEXT_BLOCK, "llog_origin_handle_next_block" }, { LLOG_ORIGIN_HANDLE_READ_HEADER,"llog_origin_handle_read_header" }, { LLOG_ORIGIN_HANDLE_WRITE_REC, "llog_origin_handle_write_rec" }, @@ -137,8 +137,8 @@ struct ll_rpc_opcode { }; struct ll_eopcode { - __u32 opcode; - const char *opname; + __u32 opcode; + const char *opname; } ll_eopcode_table[EXTRA_LAST_OPC] = { { LDLM_GLIMPSE_ENQUEUE, "ldlm_glimpse_enqueue" }, { LDLM_PLAIN_ENQUEUE, "ldlm_plain_enqueue" }, @@ -221,7 +221,7 @@ void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir, for (i = 0; i < EXTRA_LAST_OPC; i++) { char *units; - switch(i) { + switch (i) { case BRW_WRITE_BYTES: case BRW_READ_BYTES: units = "bytes"; diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index a0e009717a5a..3c6bf23415f9 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -47,17 +47,17 @@ * over \a conn connection to portal \a portal. * Returns 0 on success or error code. */ -static int ptl_send_buf (lnet_handle_md_t *mdh, void *base, int len, - lnet_ack_req_t ack, struct ptlrpc_cb_id *cbid, - struct ptlrpc_connection *conn, int portal, __u64 xid, - unsigned int offset) +static int ptl_send_buf(lnet_handle_md_t *mdh, void *base, int len, + lnet_ack_req_t ack, struct ptlrpc_cb_id *cbid, + struct ptlrpc_connection *conn, int portal, __u64 xid, + unsigned int offset) { int rc; lnet_md_t md; - LASSERT (portal != 0); - LASSERT (conn != NULL); - CDEBUG (D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer)); + LASSERT(portal != 0); + LASSERT(conn != NULL); + CDEBUG(D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer)); md.start = base; md.length = len; md.threshold = (ack == LNET_ACK_REQ) ? 2 : 1; @@ -66,23 +66,24 @@ static int ptl_send_buf (lnet_handle_md_t *mdh, void *base, int len, md.eq_handle = ptlrpc_eq_h; if (unlikely(ack == LNET_ACK_REQ && - OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK, OBD_FAIL_ONCE))){ + OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK, + OBD_FAIL_ONCE))) { /* don't ask for the ack to simulate failing client */ ack = LNET_NOACK_REQ; } - rc = LNetMDBind (md, LNET_UNLINK, mdh); + rc = LNetMDBind(md, LNET_UNLINK, mdh); if (unlikely(rc != 0)) { - CERROR ("LNetMDBind failed: %d\n", rc); - LASSERT (rc == -ENOMEM); + CERROR("LNetMDBind failed: %d\n", rc); + LASSERT(rc == -ENOMEM); return -ENOMEM; } CDEBUG(D_NET, "Sending %d bytes to portal %d, xid "LPD64", offset %u\n", len, portal, xid, offset); - rc = LNetPut (conn->c_self, *mdh, ack, - conn->c_peer, portal, xid, offset, 0); + rc = LNetPut(conn->c_self, *mdh, ack, + conn->c_peer, portal, xid, offset, 0); if (unlikely(rc != 0)) { int rc2; /* We're going to get an UNLINK event when I unlink below, @@ -179,7 +180,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) LNET_UNLINK, LNET_INS_AFTER, &me_h); if (rc != 0) { CERROR("%s: LNetMEAttach failed x"LPU64"/%d: rc = %d\n", - desc->bd_export->exp_obd->obd_name, xid, + desc->bd_import->imp_obd->obd_name, xid, posted_md, rc); break; } @@ -189,7 +190,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) &desc->bd_mds[posted_md]); if (rc != 0) { CERROR("%s: LNetMDAttach failed x"LPU64"/%d: rc = %d\n", - desc->bd_export->exp_obd->obd_name, xid, + desc->bd_import->imp_obd->obd_name, xid, posted_md, rc); rc2 = LNetMEUnlink(me_h); LASSERT(rc2 == 0); @@ -219,7 +220,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req) /* Holler if peer manages to touch buffers before he knows the xid */ if (desc->bd_md_count != total_md) CWARN("%s: Peer %s touched %d buffers while I registered\n", - desc->bd_export->exp_obd->obd_name, libcfs_id2str(peer), + desc->bd_import->imp_obd->obd_name, libcfs_id2str(peer), total_md - desc->bd_md_count); spin_unlock(&desc->bd_lock); @@ -363,14 +364,14 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags) * request, or a saved copy if this is a req saved in * target_queue_final_reply(). */ - LASSERT (req->rq_no_reply == 0); - LASSERT (req->rq_reqbuf != NULL); - LASSERT (rs != NULL); - LASSERT ((flags & PTLRPC_REPLY_MAYBE_DIFFICULT) || !rs->rs_difficult); - LASSERT (req->rq_repmsg != NULL); - LASSERT (req->rq_repmsg == rs->rs_msg); - LASSERT (rs->rs_cb_id.cbid_fn == reply_out_callback); - LASSERT (rs->rs_cb_id.cbid_arg == rs); + LASSERT(req->rq_no_reply == 0); + LASSERT(req->rq_reqbuf != NULL); + LASSERT(rs != NULL); + LASSERT((flags & PTLRPC_REPLY_MAYBE_DIFFICULT) || !rs->rs_difficult); + LASSERT(req->rq_repmsg != NULL); + LASSERT(req->rq_repmsg == rs->rs_msg); + LASSERT(rs->rs_cb_id.cbid_fn == reply_out_callback); + LASSERT(rs->rs_cb_id.cbid_arg == rs); /* There may be no rq_export during failover */ @@ -423,12 +424,12 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags) req->rq_sent = cfs_time_current_sec(); - rc = ptl_send_buf (&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len, - (rs->rs_difficult && !rs->rs_no_ack) ? - LNET_ACK_REQ : LNET_NOACK_REQ, - &rs->rs_cb_id, conn, - ptlrpc_req2svc(req)->srv_rep_portal, - req->rq_xid, req->rq_reply_off); + rc = ptl_send_buf(&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len, + (rs->rs_difficult && !rs->rs_no_ack) ? + LNET_ACK_REQ : LNET_NOACK_REQ, + &rs->rs_cb_id, conn, + ptlrpc_req2svc(req)->srv_rep_portal, + req->rq_xid, req->rq_reply_off); out: if (unlikely(rc != 0)) ptlrpc_req_drop_rs(req); @@ -437,7 +438,7 @@ out: } EXPORT_SYMBOL(ptlrpc_send_reply); -int ptlrpc_reply (struct ptlrpc_request *req) +int ptlrpc_reply(struct ptlrpc_request *req) { if (req->rq_no_reply) return 0; @@ -537,13 +538,13 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) /* bulk register should be done after wrap_request() */ if (request->rq_bulk != NULL) { - rc = ptlrpc_register_bulk (request); + rc = ptlrpc_register_bulk(request); if (rc != 0) GOTO(out, rc); } if (!noreply) { - LASSERT (request->rq_replen != 0); + LASSERT(request->rq_replen != 0); if (request->rq_repbuf == NULL) { LASSERT(request->rq_repdata == NULL); LASSERT(request->rq_repmsg == NULL); @@ -566,7 +567,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) LNET_UNLINK, LNET_INS_AFTER, &reply_me_h); if (rc != 0) { CERROR("LNetMEAttach failed: %d\n", rc); - LASSERT (rc == -ENOMEM); + LASSERT(rc == -ENOMEM); GOTO(cleanup_bulk, rc = -ENOMEM); } } @@ -604,7 +605,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) &request->rq_reply_md_h); if (rc != 0) { CERROR("LNetMDAttach failed: %d\n", rc); - LASSERT (rc == -ENOMEM); + LASSERT(rc == -ENOMEM); spin_lock(&request->rq_lock); /* ...but the MD attach didn't succeed... */ request->rq_receiving_reply = 0; @@ -655,7 +656,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) * nobody apart from the PUT's target has the right nid+XID to * access the reply buffer. */ rc2 = LNetMEUnlink(reply_me_h); - LASSERT (rc2 == 0); + LASSERT(rc2 == 0); /* UNLINKED callback called synchronously */ LASSERT(!request->rq_receiving_reply); @@ -714,10 +715,10 @@ int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd) if (rc == 0) return (0); - CERROR("LNetMDAttach failed: %d; \n", rc); - LASSERT (rc == -ENOMEM); - rc = LNetMEUnlink (me_h); - LASSERT (rc == 0); + CERROR("LNetMDAttach failed: %d;\n", rc); + LASSERT(rc == -ENOMEM); + rc = LNetMEUnlink(me_h); + LASSERT(rc == 0); rqbd->rqbd_refcount = 0; return (-ENOMEM); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index cd2611a3b53d..464479c0f00b 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -274,8 +274,8 @@ do { \ spin_unlock(&ptlrpc_rs_debug_lock); \ } while (0) #else -# define PTLRPC_RS_DEBUG_LRU_ADD(rs) do {} while(0) -# define PTLRPC_RS_DEBUG_LRU_DEL(rs) do {} while(0) +# define PTLRPC_RS_DEBUG_LRU_ADD(rs) do {} while (0) +# define PTLRPC_RS_DEBUG_LRU_DEL(rs) do {} while (0) #endif struct ptlrpc_reply_state * @@ -507,14 +507,14 @@ void lustre_free_reply_state(struct ptlrpc_reply_state *rs) { PTLRPC_RS_DEBUG_LRU_DEL(rs); - LASSERT (atomic_read(&rs->rs_refcount) == 0); - LASSERT (!rs->rs_difficult || rs->rs_handled); - LASSERT (!rs->rs_on_net); - LASSERT (!rs->rs_scheduled); - LASSERT (rs->rs_export == NULL); - LASSERT (rs->rs_nlocks == 0); - LASSERT (list_empty(&rs->rs_exp_list)); - LASSERT (list_empty(&rs->rs_obd_list)); + LASSERT(atomic_read(&rs->rs_refcount) == 0); + LASSERT(!rs->rs_difficult || rs->rs_handled); + LASSERT(!rs->rs_on_net); + LASSERT(!rs->rs_scheduled); + LASSERT(rs->rs_export == NULL); + LASSERT(rs->rs_nlocks == 0); + LASSERT(list_empty(&rs->rs_exp_list)); + LASSERT(list_empty(&rs->rs_obd_list)); sptlrpc_svc_free_rs(rs); } @@ -548,8 +548,8 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len) required_len = lustre_msg_hdr_size_v2(m->lm_bufcount); if (len < required_len) { /* didn't receive all the buffer lengths */ - CERROR ("message length %d too small for %d buflens\n", - len, m->lm_bufcount); + CERROR("message length %d too small for %d buflens\n", + len, m->lm_bufcount); return -EINVAL; } @@ -636,8 +636,8 @@ static inline int lustre_unpack_ptlrpc_body_v2(struct ptlrpc_request *req, } if ((pb->pb_version & ~LUSTRE_VERSION_MASK) != PTLRPC_MSG_VERSION) { - CERROR("wrong lustre_msg version %08x\n", pb->pb_version); - return -EINVAL; + CERROR("wrong lustre_msg version %08x\n", pb->pb_version); + return -EINVAL; } if (!inout) @@ -749,7 +749,7 @@ char *lustre_msg_string(struct lustre_msg *m, int index, int max_len) } if (str == NULL) { - CERROR ("can't unpack string in msg %p buffer[%d]\n", m, index); + CERROR("can't unpack string in msg %p buffer[%d]\n", m, index); return NULL; } @@ -1653,25 +1653,25 @@ EXPORT_SYMBOL(do_set_info_async); */ void lustre_swab_ptlrpc_body(struct ptlrpc_body *b) { - __swab32s (&b->pb_type); - __swab32s (&b->pb_version); - __swab32s (&b->pb_opc); - __swab32s (&b->pb_status); - __swab64s (&b->pb_last_xid); - __swab64s (&b->pb_last_seen); - __swab64s (&b->pb_last_committed); - __swab64s (&b->pb_transno); - __swab32s (&b->pb_flags); - __swab32s (&b->pb_op_flags); - __swab32s (&b->pb_conn_cnt); - __swab32s (&b->pb_timeout); - __swab32s (&b->pb_service_time); - __swab32s (&b->pb_limit); - __swab64s (&b->pb_slv); - __swab64s (&b->pb_pre_versions[0]); - __swab64s (&b->pb_pre_versions[1]); - __swab64s (&b->pb_pre_versions[2]); - __swab64s (&b->pb_pre_versions[3]); + __swab32s(&b->pb_type); + __swab32s(&b->pb_version); + __swab32s(&b->pb_opc); + __swab32s(&b->pb_status); + __swab64s(&b->pb_last_xid); + __swab64s(&b->pb_last_seen); + __swab64s(&b->pb_last_committed); + __swab64s(&b->pb_transno); + __swab32s(&b->pb_flags); + __swab32s(&b->pb_op_flags); + __swab32s(&b->pb_conn_cnt); + __swab32s(&b->pb_timeout); + __swab32s(&b->pb_service_time); + __swab32s(&b->pb_limit); + __swab64s(&b->pb_slv); + __swab64s(&b->pb_pre_versions[0]); + __swab64s(&b->pb_pre_versions[1]); + __swab64s(&b->pb_pre_versions[2]); + __swab64s(&b->pb_pre_versions[3]); CLASSERT(offsetof(typeof(*b), pb_padding) != 0); /* While we need to maintain compatibility between * clients and servers without ptlrpc_body_v2 (< 2.3) @@ -1723,33 +1723,33 @@ void lustre_swab_connect(struct obd_connect_data *ocd) CLASSERT(offsetof(typeof(*ocd), paddingF) != 0); } -void lustre_swab_obdo (struct obdo *o) +void lustre_swab_obdo(struct obdo *o) { - __swab64s (&o->o_valid); + __swab64s(&o->o_valid); lustre_swab_ost_id(&o->o_oi); - __swab64s (&o->o_parent_seq); - __swab64s (&o->o_size); - __swab64s (&o->o_mtime); - __swab64s (&o->o_atime); - __swab64s (&o->o_ctime); - __swab64s (&o->o_blocks); - __swab64s (&o->o_grant); - __swab32s (&o->o_blksize); - __swab32s (&o->o_mode); - __swab32s (&o->o_uid); - __swab32s (&o->o_gid); - __swab32s (&o->o_flags); - __swab32s (&o->o_nlink); - __swab32s (&o->o_parent_oid); - __swab32s (&o->o_misc); - __swab64s (&o->o_ioepoch); - __swab32s (&o->o_stripe_idx); - __swab32s (&o->o_parent_ver); + __swab64s(&o->o_parent_seq); + __swab64s(&o->o_size); + __swab64s(&o->o_mtime); + __swab64s(&o->o_atime); + __swab64s(&o->o_ctime); + __swab64s(&o->o_blocks); + __swab64s(&o->o_grant); + __swab32s(&o->o_blksize); + __swab32s(&o->o_mode); + __swab32s(&o->o_uid); + __swab32s(&o->o_gid); + __swab32s(&o->o_flags); + __swab32s(&o->o_nlink); + __swab32s(&o->o_parent_oid); + __swab32s(&o->o_misc); + __swab64s(&o->o_ioepoch); + __swab32s(&o->o_stripe_idx); + __swab32s(&o->o_parent_ver); /* o_handle is opaque */ /* o_lcookie is swabbed elsewhere */ - __swab32s (&o->o_uid_h); - __swab32s (&o->o_gid_h); - __swab64s (&o->o_data_version); + __swab32s(&o->o_uid_h); + __swab32s(&o->o_gid_h); + __swab64s(&o->o_data_version); CLASSERT(offsetof(typeof(*o), o_padding_4) != 0); CLASSERT(offsetof(typeof(*o), o_padding_5) != 0); CLASSERT(offsetof(typeof(*o), o_padding_6) != 0); @@ -1757,19 +1757,19 @@ void lustre_swab_obdo (struct obdo *o) } EXPORT_SYMBOL(lustre_swab_obdo); -void lustre_swab_obd_statfs (struct obd_statfs *os) +void lustre_swab_obd_statfs(struct obd_statfs *os) { - __swab64s (&os->os_type); - __swab64s (&os->os_blocks); - __swab64s (&os->os_bfree); - __swab64s (&os->os_bavail); - __swab64s (&os->os_files); - __swab64s (&os->os_ffree); + __swab64s(&os->os_type); + __swab64s(&os->os_blocks); + __swab64s(&os->os_bfree); + __swab64s(&os->os_bavail); + __swab64s(&os->os_files); + __swab64s(&os->os_ffree); /* no need to swab os_fsid */ - __swab32s (&os->os_bsize); - __swab32s (&os->os_namelen); - __swab64s (&os->os_maxbytes); - __swab32s (&os->os_state); + __swab32s(&os->os_bsize); + __swab32s(&os->os_namelen); + __swab64s(&os->os_maxbytes); + __swab32s(&os->os_state); CLASSERT(offsetof(typeof(*os), os_fprecreated) != 0); CLASSERT(offsetof(typeof(*os), os_spare2) != 0); CLASSERT(offsetof(typeof(*os), os_spare3) != 0); @@ -1790,17 +1790,17 @@ void lustre_swab_obd_ioobj(struct obd_ioobj *ioo) } EXPORT_SYMBOL(lustre_swab_obd_ioobj); -void lustre_swab_niobuf_remote (struct niobuf_remote *nbr) +void lustre_swab_niobuf_remote(struct niobuf_remote *nbr) { - __swab64s (&nbr->offset); - __swab32s (&nbr->len); - __swab32s (&nbr->flags); + __swab64s(&nbr->offset); + __swab32s(&nbr->len); + __swab32s(&nbr->flags); } EXPORT_SYMBOL(lustre_swab_niobuf_remote); -void lustre_swab_ost_body (struct ost_body *b) +void lustre_swab_ost_body(struct ost_body *b) { - lustre_swab_obdo (&b->oa); + lustre_swab_obdo(&b->oa); } EXPORT_SYMBOL(lustre_swab_ost_body); @@ -1861,45 +1861,45 @@ void lustre_swab_lquota_lvb(struct lquota_lvb *lvb) } EXPORT_SYMBOL(lustre_swab_lquota_lvb); -void lustre_swab_mdt_body (struct mdt_body *b) +void lustre_swab_mdt_body(struct mdt_body *b) { - lustre_swab_lu_fid (&b->fid1); - lustre_swab_lu_fid (&b->fid2); + lustre_swab_lu_fid(&b->fid1); + lustre_swab_lu_fid(&b->fid2); /* handle is opaque */ - __swab64s (&b->valid); - __swab64s (&b->size); - __swab64s (&b->mtime); - __swab64s (&b->atime); - __swab64s (&b->ctime); - __swab64s (&b->blocks); - __swab64s (&b->ioepoch); - CLASSERT(offsetof(typeof(*b), unused1) != 0); - __swab32s (&b->fsuid); - __swab32s (&b->fsgid); - __swab32s (&b->capability); - __swab32s (&b->mode); - __swab32s (&b->uid); - __swab32s (&b->gid); - __swab32s (&b->flags); - __swab32s (&b->rdev); - __swab32s (&b->nlink); + __swab64s(&b->valid); + __swab64s(&b->size); + __swab64s(&b->mtime); + __swab64s(&b->atime); + __swab64s(&b->ctime); + __swab64s(&b->blocks); + __swab64s(&b->ioepoch); + __swab64s(&b->t_state); + __swab32s(&b->fsuid); + __swab32s(&b->fsgid); + __swab32s(&b->capability); + __swab32s(&b->mode); + __swab32s(&b->uid); + __swab32s(&b->gid); + __swab32s(&b->flags); + __swab32s(&b->rdev); + __swab32s(&b->nlink); CLASSERT(offsetof(typeof(*b), unused2) != 0); - __swab32s (&b->suppgid); - __swab32s (&b->eadatasize); - __swab32s (&b->aclsize); - __swab32s (&b->max_mdsize); - __swab32s (&b->max_cookiesize); - __swab32s (&b->uid_h); - __swab32s (&b->gid_h); + __swab32s(&b->suppgid); + __swab32s(&b->eadatasize); + __swab32s(&b->aclsize); + __swab32s(&b->max_mdsize); + __swab32s(&b->max_cookiesize); + __swab32s(&b->uid_h); + __swab32s(&b->gid_h); CLASSERT(offsetof(typeof(*b), padding_5) != 0); } EXPORT_SYMBOL(lustre_swab_mdt_body); -void lustre_swab_mdt_ioepoch (struct mdt_ioepoch *b) +void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b) { /* handle is opaque */ - __swab64s (&b->ioepoch); - __swab32s (&b->flags); + __swab64s(&b->ioepoch); + __swab32s(&b->flags); CLASSERT(offsetof(typeof(*b), padding) != 0); } EXPORT_SYMBOL(lustre_swab_mdt_ioepoch); @@ -1957,49 +1957,49 @@ void lustre_swab_mgs_config_res(struct mgs_config_res *body) } EXPORT_SYMBOL(lustre_swab_mgs_config_res); -static void lustre_swab_obd_dqinfo (struct obd_dqinfo *i) +static void lustre_swab_obd_dqinfo(struct obd_dqinfo *i) { - __swab64s (&i->dqi_bgrace); - __swab64s (&i->dqi_igrace); - __swab32s (&i->dqi_flags); - __swab32s (&i->dqi_valid); + __swab64s(&i->dqi_bgrace); + __swab64s(&i->dqi_igrace); + __swab32s(&i->dqi_flags); + __swab32s(&i->dqi_valid); } -static void lustre_swab_obd_dqblk (struct obd_dqblk *b) +static void lustre_swab_obd_dqblk(struct obd_dqblk *b) { - __swab64s (&b->dqb_ihardlimit); - __swab64s (&b->dqb_isoftlimit); - __swab64s (&b->dqb_curinodes); - __swab64s (&b->dqb_bhardlimit); - __swab64s (&b->dqb_bsoftlimit); - __swab64s (&b->dqb_curspace); - __swab64s (&b->dqb_btime); - __swab64s (&b->dqb_itime); - __swab32s (&b->dqb_valid); + __swab64s(&b->dqb_ihardlimit); + __swab64s(&b->dqb_isoftlimit); + __swab64s(&b->dqb_curinodes); + __swab64s(&b->dqb_bhardlimit); + __swab64s(&b->dqb_bsoftlimit); + __swab64s(&b->dqb_curspace); + __swab64s(&b->dqb_btime); + __swab64s(&b->dqb_itime); + __swab32s(&b->dqb_valid); CLASSERT(offsetof(typeof(*b), dqb_padding) != 0); } -void lustre_swab_obd_quotactl (struct obd_quotactl *q) +void lustre_swab_obd_quotactl(struct obd_quotactl *q) { - __swab32s (&q->qc_cmd); - __swab32s (&q->qc_type); - __swab32s (&q->qc_id); - __swab32s (&q->qc_stat); - lustre_swab_obd_dqinfo (&q->qc_dqinfo); - lustre_swab_obd_dqblk (&q->qc_dqblk); + __swab32s(&q->qc_cmd); + __swab32s(&q->qc_type); + __swab32s(&q->qc_id); + __swab32s(&q->qc_stat); + lustre_swab_obd_dqinfo(&q->qc_dqinfo); + lustre_swab_obd_dqblk(&q->qc_dqblk); } EXPORT_SYMBOL(lustre_swab_obd_quotactl); -void lustre_swab_mdt_remote_perm (struct mdt_remote_perm *p) +void lustre_swab_mdt_remote_perm(struct mdt_remote_perm *p) { - __swab32s (&p->rp_uid); - __swab32s (&p->rp_gid); - __swab32s (&p->rp_fsuid); - __swab32s (&p->rp_fsuid_h); - __swab32s (&p->rp_fsgid); - __swab32s (&p->rp_fsgid_h); - __swab32s (&p->rp_access_perm); - __swab32s (&p->rp_padding); + __swab32s(&p->rp_uid); + __swab32s(&p->rp_gid); + __swab32s(&p->rp_fsuid); + __swab32s(&p->rp_fsuid_h); + __swab32s(&p->rp_fsgid); + __swab32s(&p->rp_fsgid_h); + __swab32s(&p->rp_access_perm); + __swab32s(&p->rp_padding); }; EXPORT_SYMBOL(lustre_swab_mdt_remote_perm); @@ -2089,31 +2089,31 @@ void lustre_swab_mdt_rec_reint (struct mdt_rec_reint *rr) }; EXPORT_SYMBOL(lustre_swab_mdt_rec_reint); -void lustre_swab_lov_desc (struct lov_desc *ld) +void lustre_swab_lov_desc(struct lov_desc *ld) { - __swab32s (&ld->ld_tgt_count); - __swab32s (&ld->ld_active_tgt_count); - __swab32s (&ld->ld_default_stripe_count); - __swab32s (&ld->ld_pattern); - __swab64s (&ld->ld_default_stripe_size); - __swab64s (&ld->ld_default_stripe_offset); - __swab32s (&ld->ld_qos_maxage); + __swab32s(&ld->ld_tgt_count); + __swab32s(&ld->ld_active_tgt_count); + __swab32s(&ld->ld_default_stripe_count); + __swab32s(&ld->ld_pattern); + __swab64s(&ld->ld_default_stripe_size); + __swab64s(&ld->ld_default_stripe_offset); + __swab32s(&ld->ld_qos_maxage); /* uuid endian insensitive */ } EXPORT_SYMBOL(lustre_swab_lov_desc); -void lustre_swab_lmv_desc (struct lmv_desc *ld) +void lustre_swab_lmv_desc(struct lmv_desc *ld) { - __swab32s (&ld->ld_tgt_count); - __swab32s (&ld->ld_active_tgt_count); - __swab32s (&ld->ld_default_stripe_count); - __swab32s (&ld->ld_pattern); - __swab64s (&ld->ld_default_hash_size); - __swab32s (&ld->ld_qos_maxage); + __swab32s(&ld->ld_tgt_count); + __swab32s(&ld->ld_active_tgt_count); + __swab32s(&ld->ld_default_stripe_count); + __swab32s(&ld->ld_pattern); + __swab64s(&ld->ld_default_hash_size); + __swab32s(&ld->ld_qos_maxage); /* uuid endian insensitive */ } -void lustre_swab_lmv_stripe_md (struct lmv_stripe_md *mea) +void lustre_swab_lmv_stripe_md(struct lmv_stripe_md *mea) { __swab32s(&mea->mea_magic); __swab32s(&mea->mea_count); @@ -2142,7 +2142,7 @@ void lustre_swab_lmv_user_md(struct lmv_user_md *lum) } EXPORT_SYMBOL(lustre_swab_lmv_user_md); -static void print_lum (struct lov_user_md *lum) +static void print_lum(struct lov_user_md *lum) { CDEBUG(D_OTHER, "lov_user_md %p:\n", lum); CDEBUG(D_OTHER, "\tlmm_magic: %#x\n", lum->lmm_magic); @@ -2212,16 +2212,16 @@ void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod, } EXPORT_SYMBOL(lustre_swab_lov_user_md_objects); -void lustre_swab_ldlm_res_id (struct ldlm_res_id *id) +void lustre_swab_ldlm_res_id(struct ldlm_res_id *id) { int i; for (i = 0; i < RES_NAME_SIZE; i++) - __swab64s (&id->name[i]); + __swab64s(&id->name[i]); } EXPORT_SYMBOL(lustre_swab_ldlm_res_id); -void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d) +void lustre_swab_ldlm_policy_data(ldlm_wire_policy_data_t *d) { /* the lock data is a union and the first two fields are always an * extent so it's ok to process an LDLM_EXTENT and LDLM_FLOCK lock @@ -2234,46 +2234,46 @@ void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d) } EXPORT_SYMBOL(lustre_swab_ldlm_policy_data); -void lustre_swab_ldlm_intent (struct ldlm_intent *i) +void lustre_swab_ldlm_intent(struct ldlm_intent *i) { - __swab64s (&i->opc); + __swab64s(&i->opc); } EXPORT_SYMBOL(lustre_swab_ldlm_intent); -void lustre_swab_ldlm_resource_desc (struct ldlm_resource_desc *r) +void lustre_swab_ldlm_resource_desc(struct ldlm_resource_desc *r) { - __swab32s (&r->lr_type); + __swab32s(&r->lr_type); CLASSERT(offsetof(typeof(*r), lr_padding) != 0); - lustre_swab_ldlm_res_id (&r->lr_name); + lustre_swab_ldlm_res_id(&r->lr_name); } EXPORT_SYMBOL(lustre_swab_ldlm_resource_desc); -void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l) +void lustre_swab_ldlm_lock_desc(struct ldlm_lock_desc *l) { - lustre_swab_ldlm_resource_desc (&l->l_resource); - __swab32s (&l->l_req_mode); - __swab32s (&l->l_granted_mode); - lustre_swab_ldlm_policy_data (&l->l_policy_data); + lustre_swab_ldlm_resource_desc(&l->l_resource); + __swab32s(&l->l_req_mode); + __swab32s(&l->l_granted_mode); + lustre_swab_ldlm_policy_data(&l->l_policy_data); } EXPORT_SYMBOL(lustre_swab_ldlm_lock_desc); -void lustre_swab_ldlm_request (struct ldlm_request *rq) +void lustre_swab_ldlm_request(struct ldlm_request *rq) { - __swab32s (&rq->lock_flags); - lustre_swab_ldlm_lock_desc (&rq->lock_desc); - __swab32s (&rq->lock_count); + __swab32s(&rq->lock_flags); + lustre_swab_ldlm_lock_desc(&rq->lock_desc); + __swab32s(&rq->lock_count); /* lock_handle[] opaque */ } EXPORT_SYMBOL(lustre_swab_ldlm_request); -void lustre_swab_ldlm_reply (struct ldlm_reply *r) +void lustre_swab_ldlm_reply(struct ldlm_reply *r) { - __swab32s (&r->lock_flags); + __swab32s(&r->lock_flags); CLASSERT(offsetof(typeof(*r), lock_padding) != 0); - lustre_swab_ldlm_lock_desc (&r->lock_desc); + lustre_swab_ldlm_lock_desc(&r->lock_desc); /* lock_handle opaque */ - __swab64s (&r->lock_policy_res1); - __swab64s (&r->lock_policy_res2); + __swab64s(&r->lock_policy_res1); + __swab64s(&r->lock_policy_res2); } EXPORT_SYMBOL(lustre_swab_ldlm_reply); @@ -2409,7 +2409,7 @@ static inline int rep_ptlrpc_body_swabbed(struct ptlrpc_request *req) void _debug_req(struct ptlrpc_request *req, struct libcfs_debug_msg_data *msgdata, - const char *fmt, ... ) + const char *fmt, ...) { int req_ok = req->rq_reqmsg != NULL; int rep_ok = req->rq_repmsg != NULL; @@ -2457,20 +2457,20 @@ EXPORT_SYMBOL(_debug_req); void lustre_swab_lustre_capa(struct lustre_capa *c) { lustre_swab_lu_fid(&c->lc_fid); - __swab64s (&c->lc_opc); - __swab64s (&c->lc_uid); - __swab64s (&c->lc_gid); - __swab32s (&c->lc_flags); - __swab32s (&c->lc_keyid); - __swab32s (&c->lc_timeout); - __swab32s (&c->lc_expiry); + __swab64s(&c->lc_opc); + __swab64s(&c->lc_uid); + __swab64s(&c->lc_gid); + __swab32s(&c->lc_flags); + __swab32s(&c->lc_keyid); + __swab32s(&c->lc_timeout); + __swab32s(&c->lc_expiry); } EXPORT_SYMBOL(lustre_swab_lustre_capa); void lustre_swab_lustre_capa_key(struct lustre_capa_key *k) { - __swab64s (&k->lk_seq); - __swab32s (&k->lk_keyid); + __swab64s(&k->lk_seq); + __swab32s(&k->lk_keyid); CLASSERT(offsetof(typeof(*k), lk_padding) != 0); } EXPORT_SYMBOL(lustre_swab_lustre_capa_key); @@ -2565,3 +2565,10 @@ void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl) __swab64s(&msl->msl_flags); } EXPORT_SYMBOL(lustre_swab_swap_layouts); + +void lustre_swab_close_data(struct close_data *cd) +{ + lustre_swab_lu_fid(&cd->cd_fid); + __swab64s(&cd->cd_data_version); +} +EXPORT_SYMBOL(lustre_swab_close_data); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c index 4d340f4a2198..6dff502ce23e 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c @@ -45,7 +45,8 @@ #include "ptlrpc_internal.h" static int suppress_pings; -CFS_MODULE_PARM(suppress_pings, "i", int, 0644, "Suppress pings"); +module_param(suppress_pings, int, 0644); +MODULE_PARM_DESC(suppress_pings, "Suppress pings"); struct mutex pinger_mutex; static LIST_HEAD(pinger_imports); @@ -140,9 +141,6 @@ static inline int ptlrpc_next_reconnect(struct obd_import *imp) return cfs_time_shift(obd_timeout); } -static atomic_t suspend_timeouts = ATOMIC_INIT(0); -static cfs_time_t suspend_wakeup_time = 0; - cfs_duration_t pinger_check_timeout(cfs_time_t time) { struct timeout_item *item; @@ -162,67 +160,6 @@ cfs_duration_t pinger_check_timeout(cfs_time_t time) cfs_time_current()); } -static wait_queue_head_t suspend_timeouts_waitq; - -cfs_time_t ptlrpc_suspend_wakeup_time(void) -{ - return suspend_wakeup_time; -} - -void ptlrpc_deactivate_timeouts(struct obd_import *imp) -{ - /*XXX: disabled for now, will be replaced by adaptive timeouts */ -#if 0 - if (imp->imp_no_timeout) - return; - imp->imp_no_timeout = 1; - atomic_inc(&suspend_timeouts); - CDEBUG(D_HA|D_WARNING, "deactivate timeouts %u\n", - atomic_read(&suspend_timeouts)); -#endif -} - -void ptlrpc_activate_timeouts(struct obd_import *imp) -{ - /*XXX: disabled for now, will be replaced by adaptive timeouts */ -#if 0 - if (!imp->imp_no_timeout) - return; - imp->imp_no_timeout = 0; - LASSERT(atomic_read(&suspend_timeouts) > 0); - if (atomic_dec_and_test(&suspend_timeouts)) { - suspend_wakeup_time = cfs_time_current(); - wake_up(&suspend_timeouts_waitq); - } - CDEBUG(D_HA|D_WARNING, "activate timeouts %u\n", - atomic_read(&suspend_timeouts)); -#endif -} - -int ptlrpc_check_suspend(void) -{ - if (atomic_read(&suspend_timeouts)) - return 1; - return 0; -} - -int ptlrpc_check_and_wait_suspend(struct ptlrpc_request *req) -{ - struct l_wait_info lwi; - - if (atomic_read(&suspend_timeouts)) { - DEBUG_REQ(D_NET, req, "-- suspend %d regular timeout", - atomic_read(&suspend_timeouts)); - lwi = LWI_INTR(NULL, NULL); - l_wait_event(suspend_timeouts_waitq, - atomic_read(&suspend_timeouts) == 0, &lwi); - DEBUG_REQ(D_NET, req, "-- recharge regular timeout"); - return 1; - } - return 0; -} - - static bool ir_up; void ptlrpc_pinger_ir_up(void) @@ -377,7 +314,6 @@ int ptlrpc_start_pinger(void) return -EALREADY; init_waitqueue_head(&pinger_thread.t_ctl_waitq); - init_waitqueue_head(&suspend_timeouts_waitq); strcpy(pinger_thread.t_name, "ll_ping"); @@ -576,7 +512,7 @@ int ptlrpc_del_timeout_client(struct list_head *obd_list, break; } } - LASSERTF(ti != NULL, "ti is NULL ! \n"); + LASSERTF(ti != NULL, "ti is NULL !\n"); if (list_empty(&ti->ti_obd_list)) { list_del(&ti->ti_chain); OBD_FREE_PTR(ti); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index ab363477151d..e3b5a920bca2 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -77,13 +77,13 @@ void ptlrpc_lprocfs_register_service(struct proc_dir_entry *proc_entry, struct ptlrpc_service *svc); void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc); void ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount); -void ptlrpc_lprocfs_do_request_stat (struct ptlrpc_request *req, +void ptlrpc_lprocfs_do_request_stat(struct ptlrpc_request *req, long q_usec, long work_usec); #else -#define ptlrpc_lprocfs_register_service(params...) do{}while(0) -#define ptlrpc_lprocfs_unregister_service(params...) do{}while(0) -#define ptlrpc_lprocfs_rpc_sent(params...) do{}while(0) -#define ptlrpc_lprocfs_do_request_stat(params...) do{}while(0) +#define ptlrpc_lprocfs_register_service(params...) do {} while (0) +#define ptlrpc_lprocfs_unregister_service(params...) do {} while (0) +#define ptlrpc_lprocfs_rpc_sent(params...) do {} while (0) +#define ptlrpc_lprocfs_do_request_stat(params...) do {} while (0) #endif /* LPROCFS */ /* NRS */ @@ -259,8 +259,14 @@ void sptlrpc_enc_pool_fini(void); int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v); /* sec_lproc.c */ +#ifdef LPROCFS int sptlrpc_lproc_init(void); void sptlrpc_lproc_fini(void); +#else +static inline int sptlrpc_lproc_init(void) +{ return 0; } +static inline void sptlrpc_lproc_fini(void) {} +#endif /* sec_gc.c */ int sptlrpc_gc_init(void); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c index 419e634854df..0efd35887a15 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c @@ -112,7 +112,7 @@ __init int ptlrpc_init(void) return 0; cleanup: - switch(cleanup_phase) { + switch (cleanup_phase) { case 8: ptlrpc_nrs_fini(); case 7: diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 89c9be96f454..2d26fd543d46 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -77,12 +77,12 @@ struct ptlrpcd { }; static int max_ptlrpcds; -CFS_MODULE_PARM(max_ptlrpcds, "i", int, 0644, - "Max ptlrpcd thread count to be started."); +module_param(max_ptlrpcds, int, 0644); +MODULE_PARM_DESC(max_ptlrpcds, "Max ptlrpcd thread count to be started."); static int ptlrpcd_bind_policy = PDB_POLICY_PAIR; -CFS_MODULE_PARM(ptlrpcd_bind_policy, "i", int, 0644, - "Ptlrpcd threads binding mode."); +module_param(ptlrpcd_bind_policy, int, 0644); +MODULE_PARM_DESC(ptlrpcd_bind_policy, "Ptlrpcd threads binding mode."); static struct ptlrpcd *ptlrpcds; struct mutex ptlrpcd_mutex; @@ -600,7 +600,6 @@ static int ptlrpcd_bind(int index, int max) int ptlrpcd_start(int index, int max, const char *name, struct ptlrpcd_ctl *pc) { int rc; - int env = 0; /* * Do not allow start second thread for one pc. @@ -619,6 +618,7 @@ int ptlrpcd_start(int index, int max, const char *name, struct ptlrpcd_ctl *pc) pc->pc_set = ptlrpc_prep_set(); if (pc->pc_set == NULL) GOTO(out, rc = -ENOMEM); + /* * So far only "client" ptlrpcd uses an environment. In the future, * ptlrpcd thread (or a thread-set) has to be given an argument, @@ -626,40 +626,40 @@ int ptlrpcd_start(int index, int max, const char *name, struct ptlrpcd_ctl *pc) */ rc = lu_context_init(&pc->pc_env.le_ctx, LCT_CL_THREAD|LCT_REMEMBER); if (rc != 0) - GOTO(out, rc); + GOTO(out_set, rc); - env = 1; { struct task_struct *task; - if (index >= 0) { rc = ptlrpcd_bind(index, max); if (rc < 0) - GOTO(out, rc); + GOTO(out_env, rc); } task = kthread_run(ptlrpcd, pc, "%s", pc->pc_name); if (IS_ERR(task)) - GOTO(out, rc = PTR_ERR(task)); + GOTO(out_env, rc = PTR_ERR(task)); - rc = 0; wait_for_completion(&pc->pc_starting); } -out: - if (rc) { - if (pc->pc_set != NULL) { - struct ptlrpc_request_set *set = pc->pc_set; - - spin_lock(&pc->pc_lock); - pc->pc_set = NULL; - spin_unlock(&pc->pc_lock); - ptlrpc_set_destroy(set); - } - if (env != 0) - lu_context_fini(&pc->pc_env.le_ctx); - clear_bit(LIOD_BIND, &pc->pc_flags); - clear_bit(LIOD_START, &pc->pc_flags); + return 0; + +out_env: + lu_context_fini(&pc->pc_env.le_ctx); + +out_set: + if (pc->pc_set != NULL) { + struct ptlrpc_request_set *set = pc->pc_set; + + spin_lock(&pc->pc_lock); + pc->pc_set = NULL; + spin_unlock(&pc->pc_lock); + ptlrpc_set_destroy(set); } + clear_bit(LIOD_BIND, &pc->pc_flags); + +out: + clear_bit(LIOD_START, &pc->pc_flags); return rc; } diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 21de868da522..590fa8df8b7f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -44,19 +44,19 @@ /* The following are visible and mutable through /sys/module/ptlrpc */ int test_req_buffer_pressure = 0; -CFS_MODULE_PARM(test_req_buffer_pressure, "i", int, 0444, - "set non-zero to put pressure on request buffer pools"); -CFS_MODULE_PARM(at_min, "i", int, 0644, - "Adaptive timeout minimum (sec)"); -CFS_MODULE_PARM(at_max, "i", int, 0644, - "Adaptive timeout maximum (sec)"); -CFS_MODULE_PARM(at_history, "i", int, 0644, - "Adaptive timeouts remember the slowest event that took place " - "within this period (sec)"); -CFS_MODULE_PARM(at_early_margin, "i", int, 0644, - "How soon before an RPC deadline to send an early reply"); -CFS_MODULE_PARM(at_extra, "i", int, 0644, - "How much extra time to give with each early reply"); +module_param(test_req_buffer_pressure, int, 0444); +MODULE_PARM_DESC(test_req_buffer_pressure, "set non-zero to put pressure on request buffer pools"); +module_param(at_min, int, 0644); +MODULE_PARM_DESC(at_min, "Adaptive timeout minimum (sec)"); +module_param(at_max, int, 0644); +MODULE_PARM_DESC(at_max, "Adaptive timeout maximum (sec)"); +module_param(at_history, int, 0644); +MODULE_PARM_DESC(at_history, + "Adaptive timeouts remember the slowest event that took place within this period (sec)"); +module_param(at_early_margin, int, 0644); +MODULE_PARM_DESC(at_early_margin, "How soon before an RPC deadline to send an early reply"); +module_param(at_extra, int, 0644); +MODULE_PARM_DESC(at_extra, "How much extra time to give with each early reply"); /* forward ref */ @@ -386,7 +386,7 @@ ptlrpc_schedule_difficult_reply(struct ptlrpc_reply_state *rs) { LASSERT(spin_is_locked(&rs->rs_svcpt->scp_rep_lock)); LASSERT(spin_is_locked(&rs->rs_lock)); - LASSERT (rs->rs_difficult); + LASSERT(rs->rs_difficult); rs->rs_scheduled_ever = 1; /* flag any notification attempt */ if (rs->rs_scheduled) { /* being set up or already notified */ @@ -412,7 +412,7 @@ void ptlrpc_commit_replies(struct obd_export *exp) spin_lock(&exp->exp_uncommitted_replies_lock); list_for_each_entry_safe(rs, nxt, &exp->exp_uncommitted_replies, rs_obd_list) { - LASSERT (rs->rs_difficult); + LASSERT(rs->rs_difficult); /* VBR: per-export last_committed */ LASSERT(rs->rs_export); if (rs->rs_transno <= exp->exp_last_committed) { @@ -796,7 +796,7 @@ ptlrpc_register_service(struct ptlrpc_service_conf *conf, LASSERT(rc == 0); mutex_lock(&ptlrpc_all_services_mutex); - list_add (&service->srv_list, &ptlrpc_all_services); + list_add(&service->srv_list, &ptlrpc_all_services); mutex_unlock(&ptlrpc_all_services_mutex); if (proc_entry != NULL) @@ -1115,8 +1115,10 @@ static int ptlrpc_check_req(struct ptlrpc_request *req) } if (unlikely(req->rq_export->exp_obd && req->rq_export->exp_obd->obd_fail)) { - /* Failing over, don't handle any more reqs, send - error response instead. */ + /* + * Failing over, don't handle any more reqs, send + * error response instead. + */ CDEBUG(D_RPCTRACE, "Dropping req %p for failed obd %s\n", req, req->rq_export->exp_obd->obd_name); rc = -ENODEV; @@ -1268,7 +1270,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) return -ETIMEDOUT; } - if ((lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT) == 0){ + if (!(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, " "but no AT support"); return -ENOSYS; @@ -1777,9 +1779,9 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, rc = lustre_unpack_req_ptlrpc_body(req, MSG_PTLRPC_BODY_OFF); if (rc) { - CERROR ("error unpacking ptlrpc body: ptl %d from %s x" - LPU64"\n", svc->srv_req_portal, - libcfs_id2str(req->rq_peer), req->rq_xid); + CERROR("error unpacking ptlrpc body: ptl %d from %s x" + LPU64"\n", svc->srv_req_portal, + libcfs_id2str(req->rq_peer), req->rq_xid); goto err_req; } @@ -1798,7 +1800,7 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, goto err_req; } - switch(lustre_msg_get_opc(req->rq_reqmsg)) { + switch (lustre_msg_get_opc(req->rq_reqmsg)) { case MDS_WRITEPAGE: case OST_WRITE: req->rq_bulk_write = 1; @@ -1895,7 +1897,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt, ptlrpc_rqphase_move(request, RQ_PHASE_INTERPRET); - if(OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DUMP_LOG)) + if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DUMP_LOG)) libcfs_debug_dumplog(); do_gettimeofday(&work_start); @@ -1967,13 +1969,14 @@ put_conn: lu_context_fini(&request->rq_session); if (unlikely(cfs_time_current_sec() > request->rq_deadline)) { - DEBUG_REQ(D_WARNING, request, "Request took longer " - "than estimated ("CFS_DURATION_T":"CFS_DURATION_T"s);" - " client may timeout.", - cfs_time_sub(request->rq_deadline, - request->rq_arrival_time.tv_sec), - cfs_time_sub(cfs_time_current_sec(), - request->rq_deadline)); + DEBUG_REQ(D_WARNING, request, + "Request took longer than estimated (" + CFS_DURATION_T":"CFS_DURATION_T + "s); client may timeout.", + cfs_time_sub(request->rq_deadline, + request->rq_arrival_time.tv_sec), + cfs_time_sub(cfs_time_current_sec(), + request->rq_deadline)); } do_gettimeofday(&work_end); @@ -2037,13 +2040,13 @@ ptlrpc_handle_rs(struct ptlrpc_reply_state *rs) exp = rs->rs_export; - LASSERT (rs->rs_difficult); - LASSERT (rs->rs_scheduled); - LASSERT (list_empty(&rs->rs_list)); + LASSERT(rs->rs_difficult); + LASSERT(rs->rs_scheduled); + LASSERT(list_empty(&rs->rs_list)); spin_lock(&exp->exp_lock); /* Noop if removed already */ - list_del_init (&rs->rs_exp_list); + list_del_init(&rs->rs_exp_list); spin_unlock(&exp->exp_lock); /* The disk commit callback holds exp_uncommitted_replies_lock while it @@ -2113,9 +2116,9 @@ ptlrpc_handle_rs(struct ptlrpc_reply_state *rs) /* Off the net */ spin_unlock(&rs->rs_lock); - class_export_put (exp); + class_export_put(exp); rs->rs_export = NULL; - ptlrpc_rs_decref (rs); + ptlrpc_rs_decref(rs); if (atomic_dec_and_test(&svcpt->scp_nreps_difficult) && svc->srv_is_stopping) wake_up_all(&svcpt->scp_waitq); diff --git a/drivers/staging/lustre/lustre/ptlrpc/wirehdr.c b/drivers/staging/lustre/lustre/ptlrpc/wirehdr.c deleted file mode 100644 index 93bc40b422ee..000000000000 --- a/drivers/staging/lustre/lustre/ptlrpc/wirehdr.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_RPC - -# ifdef CONFIG_FS_POSIX_ACL -# include <linux/fs.h> -# include <linux/posix_acl_xattr.h> -# endif - -#include <obd_support.h> -#include <obd_class.h> -#include <lustre_net.h> -#include <lustre_disk.h> diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c index 9890bd9cfb93..3aa445952024 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c +++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c @@ -36,10 +36,8 @@ #define DEBUG_SUBSYSTEM S_RPC -# ifdef CONFIG_FS_POSIX_ACL -# include <linux/fs.h> -# include <linux/posix_acl_xattr.h> -# endif +#include <linux/fs.h> +#include <linux/posix_acl_xattr.h> #include <obd_support.h> #include <obd_class.h> @@ -49,9 +47,10 @@ void lustre_assert_wire_constants(void) { /* Wire protocol assertions generated by 'wirecheck' * (make -C lustre/utils newwiretest) - * running on Linux deva 2.6.32.279.lustre #5 SMP Tue Apr 9 22:52:17 CST 2013 x86_64 x86_64 x - * with gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) */ - + * running on Linux centos6-bis 2.6.32-358.0.1.el6-head + * #3 SMP Wed Apr 17 17:37:43 CEST 2013 + * with gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) + */ /* Constants... */ LASSERTF(PTL_RPC_MSG_REQUEST == 4711, "found %lld\n", @@ -432,6 +431,10 @@ void lustre_assert_wire_constants(void) (unsigned)LMAC_HSM); LASSERTF(LMAC_SOM == 0x00000002UL, "found 0x%.8xUL\n", (unsigned)LMAC_SOM); + LASSERTF(LMAC_NOT_IN_OI == 0x00000004UL, "found 0x%.8xUL\n", + (unsigned)LMAC_NOT_IN_OI); + LASSERTF(LMAC_FID_ON_OST == 0x00000008UL, "found 0x%.8xUL\n", + (unsigned)LMAC_FID_ON_OST); LASSERTF(OBJ_CREATE == 1, "found %lld\n", (long long)OBJ_CREATE); LASSERTF(OBJ_DESTROY == 2, "found %lld\n", @@ -1335,6 +1338,8 @@ void lustre_assert_wire_constants(void) OBD_MD_REINT); LASSERTF(OBD_MD_MEA == (0x0000000400000000ULL), "found 0x%.16llxULL\n", OBD_MD_MEA); + LASSERTF(OBD_MD_TSTATE == (0x0000000800000000ULL), + "found 0x%.16llxULL\n", OBD_MD_TSTATE); LASSERTF(OBD_MD_FLXATTR == (0x0000001000000000ULL), "found 0x%.16llxULL\n", OBD_MD_FLXATTR); LASSERTF(OBD_MD_FLXATTRLS == (0x0000002000000000ULL), "found 0x%.16llxULL\n", @@ -1918,10 +1923,11 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mdt_body, blocks)); LASSERTF((int)sizeof(((struct mdt_body *)0)->blocks) == 8, "found %lld\n", (long long)(int)sizeof(((struct mdt_body *)0)->blocks)); - LASSERTF((int)offsetof(struct mdt_body, unused1) == 96, "found %lld\n", - (long long)(int)offsetof(struct mdt_body, unused1)); - LASSERTF((int)sizeof(((struct mdt_body *)0)->unused1) == 8, "found %lld\n", - (long long)(int)sizeof(((struct mdt_body *)0)->unused1)); + LASSERTF((int)offsetof(struct mdt_body, t_state) == 96, "found %lld\n", + (long long)(int)offsetof(struct mdt_body, t_state)); + LASSERTF((int)sizeof(((struct mdt_body *)0)->t_state) == 8, + "found %lld\n", + (long long)(int)sizeof(((struct mdt_body *)0)->t_state)); LASSERTF((int)offsetof(struct mdt_body, fsuid) == 104, "found %lld\n", (long long)(int)offsetof(struct mdt_body, fsuid)); LASSERTF((int)sizeof(((struct mdt_body *)0)->fsuid) == 4, "found %lld\n", @@ -4416,6 +4422,64 @@ void lustre_assert_wire_constants(void) LASSERTF((int)sizeof(((struct hsm_user_request *)0)->hur_user_item) == 0, "found %lld\n", (long long)(int)sizeof(((struct hsm_user_request *)0)->hur_user_item)); + /* Checks for struct hsm_user_import */ + LASSERTF(sizeof(struct hsm_user_import) == 48, "found %lld\n", + (long long)sizeof(struct hsm_user_import)); + LASSERTF(offsetof(struct hsm_user_import, hui_size) == 0, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_size)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_size) == 8, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_size)); + LASSERTF(offsetof(struct hsm_user_import, hui_uid) == 32, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_uid)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_uid) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_uid)); + LASSERTF(offsetof(struct hsm_user_import, hui_gid) == 36, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_gid)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_gid) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_gid)); + LASSERTF(offsetof(struct hsm_user_import, hui_mode) == 40, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_mode)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_mode) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_mode)); + LASSERTF(offsetof(struct hsm_user_import, hui_atime) == 8, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_atime)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_atime) == 8, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_atime)); + LASSERTF(offsetof(struct hsm_user_import, hui_atime_ns) == 24, + "found %lld\n", + (long long)(int)offsetof(struct hsm_user_import, hui_atime_ns)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_atime_ns) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_atime_ns)); + LASSERTF(offsetof(struct hsm_user_import, hui_mtime) == 16, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_mtime)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_mtime) == 8, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_mtime)); + LASSERTF(offsetof(struct hsm_user_import, hui_mtime_ns) == 28, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_mtime_ns)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_mtime_ns) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_mtime_ns)); + LASSERTF(offsetof(struct hsm_user_import, hui_archive_id) == 44, + "found %lld\n", + (long long)offsetof(struct hsm_user_import, hui_archive_id)); + LASSERTF(sizeof(((struct hsm_user_import *)0)->hui_archive_id) == 4, + "found %lld\n", + (long long)sizeof(((struct hsm_user_import *)0)->hui_archive_id)); + /* Checks for struct update_buf */ LASSERTF((int)sizeof(struct update_buf) == 8, "found %lld\n", (long long)(int)sizeof(struct update_buf)); diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index 766a071b0a22..b7044a380fe3 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1009,7 +1009,7 @@ static int ipipe_validate_yee_params(struct vpfe_ipipe_yee *yee) yee->es_ofst_grad > YEE_THR_MASK) return -EINVAL; - for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT ; i++) + for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT; i++) if (yee->table[i] > YEE_ENTRY_MASK) return -EINVAL; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c index e027b92b54ef..2d36b60bdbf1 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c @@ -791,7 +791,7 @@ ipipe_set_3d_lut_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, /* valied table */ tbl = lut_3d->table; - for (i = 0 ; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) { + for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) { /* Each entry has 0-9 (B), 10-19 (G) and 20-29 R values */ val = tbl[i].b & D3_LUT_ENTRY_MASK; @@ -899,7 +899,7 @@ ipipe_set_gbce_regs(void *__iomem base_addr, void *__iomem isp5_base_addr, if (!gbce->table) return; - for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT ; count += 2) + for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; count += 2) w_ip_table(isp5_base_addr, ((gbce->table[count + 1] & mask) << GBCE_ENTRY_SHIFT) | (gbce->table[count] & mask), ((count/2) << 2) + GBCE_TB_START_ADDR); diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c index 081407be33ab..e729e52639c5 100644 --- a/drivers/staging/media/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c @@ -974,7 +974,7 @@ dt3155_remove(struct pci_dev *pdev) kfree(pd); } -static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { +static const struct pci_device_id pci_ids[] = { { PCI_DEVICE(DT3155_VENDOR_ID, DT3155_DEVICE_ID) }, { 0, /* zero marks the end */ }, }; diff --git a/drivers/staging/media/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c index c2d0e58afc34..479953b2d983 100644 --- a/drivers/staging/media/go7007/go7007-fw.c +++ b/drivers/staging/media/go7007/go7007-fw.c @@ -722,7 +722,8 @@ static int vti_bitlen(struct go7007 *go) { unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale; - for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i); + for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i) + ; return i + 1; } diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c index d80b235d72ee..6e2ca338cdd9 100644 --- a/drivers/staging/media/go7007/saa7134-go7007.c +++ b/drivers/staging/media/go7007/saa7134-go7007.c @@ -86,7 +86,7 @@ static const struct go7007_board_info board_voyager = { .audio_main_div = 2, .hpi_buffer_cap = 7, .num_inputs = 1, - .inputs = { + .inputs = { { .name = "SAA7134", }, diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c index 28c8b0bcf5b2..f2dcc4a292da 100644 --- a/drivers/staging/media/lirc/lirc_igorplugusb.c +++ b/drivers/staging/media/lirc/lirc_igorplugusb.c @@ -363,8 +363,8 @@ static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) /*dummy*/ir->buf_in, /*dummy*/ir->len_in, /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); if (ret < 0) - printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " - "error %d\n", ir->devnum, ret); + printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", + ir->devnum, ret); return 0; } else if (ret < 0) printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index ab2ae115b524..c7d6667e7d14 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -808,7 +808,8 @@ static int imon_probe(struct usb_interface *interface, /* Input endpoint is mandatory */ if (!ir_ep_found) { - dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__); + dev_err(dev, "%s: no valid input (IR) endpoint found.\n", + __func__); retval = -ENODEV; alloc_status = 2; goto alloc_status_switch; @@ -878,8 +879,8 @@ static int imon_probe(struct usb_interface *interface, alloc_status = 7; goto unlock; } else - dev_info(dev, "Registered iMON driver " - "(lirc minor: %d)\n", lirc_minor); + dev_info(dev, "Registered iMON driver (lirc minor: %d)\n", + lirc_minor); /* Needed while unregistering! */ driver->minor = lirc_minor; @@ -923,8 +924,8 @@ static int imon_probe(struct usb_interface *interface, if (usb_register_dev(interface, &imon_class)) { /* Not a fatal error, so ignore */ - dev_info(dev, "%s: could not get a minor number for " - "display\n", __func__); + dev_info(dev, "%s: could not get a minor number for display\n", + __func__); } } diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 2e3a98575d47..abe0d5caa20b 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -428,8 +428,8 @@ static int init_timing_params(unsigned int new_duty_cycle, period = 256 * 1000000L / freq; pulse_width = period * duty_cycle / 100; space_width = period - pulse_width; - dprintk("in init_timing_params, freq=%d pulse=%ld, " - "space=%ld\n", freq, pulse_width, space_width); + dprintk("in init_timing_params, freq=%d pulse=%ld, space=%ld\n", + freq, pulse_width, space_width); return 0; } #endif /* USE_RDTSC */ @@ -974,7 +974,7 @@ static void set_use_dec(void *data) spin_unlock_irqrestore(&hardware[type].lock, flags); } -static ssize_t lirc_write(struct file *file, const char *buf, +static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n, loff_t *ppos) { int i, count; diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 0feeaadf29dc..e1feb6164593 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -767,8 +767,8 @@ static int fw_load(struct IR_tx *tx) /* Request codeset data file */ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); if (ret != 0) { - zilog_error("firmware haup-ir-blaster.bin not available " - "(%d)\n", ret); + zilog_error("firmware haup-ir-blaster.bin not available (%d)\n", + ret); ret = ret < 0 ? ret : -EFAULT; goto out; } diff --git a/drivers/staging/media/solo6x10/solo6x10-core.c b/drivers/staging/media/solo6x10/solo6x10-core.c index 36750205d23f..480b7c4064cc 100644 --- a/drivers/staging/media/solo6x10/solo6x10-core.c +++ b/drivers/staging/media/solo6x10/solo6x10-core.c @@ -669,7 +669,7 @@ static void solo_pci_remove(struct pci_dev *pdev) free_solo_dev(solo_dev); } -static DEFINE_PCI_DEVICE_TABLE(solo_id_table) = { +static const struct pci_device_id solo_id_table[] = { /* 6010 based cards */ { PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010), .driver_data = SOLO_DEV_6010 }, diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 49ea76b3435d..bb152201e93d 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -83,7 +83,7 @@ enum nvec_sleep_subcmds { static struct nvec_chip *nvec_power_handle; -static struct mfd_cell nvec_devices[] = { +static const struct mfd_cell nvec_devices[] = { { .name = "nvec-kbd", .id = 1, diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 92b02891704d..26b4ec56fd30 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -255,17 +255,19 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) { int err; + console_lock(); if (!lock_fb_info(dcon->fbinfo)) { + console_unlock(); dev_err(&dcon->client->dev, "unable to lock framebuffer\n"); return false; } - console_lock(); + dcon->ignore_fb_events = true; err = fb_blank(dcon->fbinfo, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); dcon->ignore_fb_events = false; - console_unlock(); unlock_fb_info(dcon->fbinfo); + console_unlock(); if (err) { dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n", diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c index 9b86486c6b11..02d541247819 100644 --- a/drivers/staging/ozwpan/ozeltbuf.c +++ b/drivers/staging/ozwpan/ozeltbuf.c @@ -138,7 +138,7 @@ int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count) oz_dbg(ON, "%s: (0x%x)\n", __func__, id); - st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC | __GFP_ZERO); + st = kzalloc(sizeof(struct oz_elt_stream), GFP_ATOMIC); if (st == NULL) return -ENOMEM; atomic_set(&st->ref_count, 1); diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 88714ec85705..9f2dffe6e131 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -337,7 +337,7 @@ static void oz_rx_frame(struct sk_buff *skb) oz_dbg(RX_FRAMES, "RX frame PN=0x%x LPN=0x%x control=0x%x\n", oz_hdr->pkt_num, oz_hdr->last_pkt_num, oz_hdr->control); mac_hdr = skb_mac_header(skb); - src_addr = &mac_hdr[ETH_ALEN] ; + src_addr = &mac_hdr[ETH_ALEN]; length = skb->len; /* Check the version field */ diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index 919cb95236fc..57fc27958797 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -69,7 +69,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static DEFINE_PCI_DEVICE_TABLE(phison_pci_tbl) = { +static const struct pci_device_id phison_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000), PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 }, { 0, }, diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c index 9d2d5c58add2..4483c2c0307c 100644 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.c +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c @@ -1,16 +1,6 @@ -//----------------------------------------------------------------------------- -// File: -// Dot11d.c -// -// Description: -// Implement 802.11d. -// -//----------------------------------------------------------------------------- - #include "dot11d.h" -void -Dot11d_Init(struct ieee80211_device *ieee) +void Dot11d_Init(struct ieee80211_device *ieee) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); @@ -22,23 +12,19 @@ Dot11d_Init(struct ieee80211_device *ieee) memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); RESET_CIE_WATCHDOG(ieee); - printk("Dot11d_Init()\n"); + netdev_info(ieee->dev, "Dot11d_Init()\n"); } -// -// Description: -// Reset to the state as we are just entering a regulatory domain. -// -void -Dot11d_Reset(struct ieee80211_device *ieee) +/* Reset to the state as we are just entering a regulatory domain. */ +void Dot11d_Reset(struct ieee80211_device *ieee) { u32 i; PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); - // Clear old channel map + /* Clear old channel map */ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - // Set new channel map + /* Set new channel map */ for (i = 1; i <= 11; i++) (pDot11dInfo->channel_map)[i] = 1; @@ -48,36 +34,30 @@ Dot11d_Reset(struct ieee80211_device *ieee) pDot11dInfo->State = DOT11D_STATE_NONE; pDot11dInfo->CountryIeLen = 0; RESET_CIE_WATCHDOG(ieee); - - //printk("Dot11d_Reset()\n"); } -// -// Description: -// Update country IE from Beacon or Probe Response -// and configure PHY for operation in the regulatory domain. -// -// TODO: -// Configure Tx power. -// -// Assumption: -// 1. IS_DOT11D_ENABLE() is TRUE. -// 2. Input IE is an valid one. -// -void -Dot11d_UpdateCountryIe( - struct ieee80211_device *dev, - u8 *pTaddr, - u16 CoutryIeLen, - u8 *pCoutryIe - ) +/* + * Description: + * Update country IE from Beacon or Probe Response and configure PHY for + * operation in the regulatory domain. + * + * TODO: + * Configure Tx power. + * + * Assumption: + * 1. IS_DOT11D_ENABLE() is TRUE. + * 2. Input IE is an valid one. + */ +void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, + u16 CoutryIeLen, u8 *pCoutryIe) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); u8 i, j, NumTriples, MaxChnlNum; + u8 index, MaxTxPowerInDbm; PCHNL_TXPOWER_TRIPLE pTriple; if ((CoutryIeLen - 3)%3 != 0) { - printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); + netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); Dot11d_Reset(dev); return; } @@ -85,37 +65,47 @@ Dot11d_UpdateCountryIe( memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string. + NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */ pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3); for (i = 0; i < NumTriples; i++) { if (MaxChnlNum >= pTriple->FirstChnl) { - // It is not in a monotonically increasing order, so stop processing. - printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); + /* + * It is not in a monotonically increasing order, + * so stop processing. + */ + netdev_info(dev->dev, + "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); Dot11d_Reset(dev); return; } - if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls)) { - // It is not a valid set of channel id, so stop processing. - printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); + if (MAX_CHANNEL_NUMBER < + (pTriple->FirstChnl + pTriple->NumChnls)) { + /* + * It is not a valid set of channel id, + * so stop processing + */ + netdev_info(dev->dev, + "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); Dot11d_Reset(dev); return; } - for (j = 0 ; j < pTriple->NumChnls; j++) { - pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; - pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm; + for (j = 0; j < pTriple->NumChnls; j++) { + index = pTriple->FirstChnl + j; + pDot11dInfo->channel_map[index] = 1; + MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm; + pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm; MaxChnlNum = pTriple->FirstChnl + j; } pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3); } #if 1 - //printk("Dot11d_UpdateCountryIe(): Channel List:\n"); - printk("Channel List:"); + netdev_info(dev->dev, "Channel List:"); for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) if (pDot11dInfo->channel_map[i] > 0) - printk(" %d", i); - printk("\n"); + netdev_info(dev->dev, " %d", i); + netdev_info(dev->dev, "\n"); #endif UPDATE_CIE_SRC(dev, pTaddr); @@ -125,31 +115,23 @@ Dot11d_UpdateCountryIe( pDot11dInfo->State = DOT11D_STATE_LEARNED; } -u8 -DOT11D_GetMaxTxPwrInDbm( - struct ieee80211_device *dev, - u8 Channel - ) +u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); u8 MaxTxPwrInDbm = 255; if (MAX_CHANNEL_NUMBER < Channel) { - printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); + netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); return MaxTxPwrInDbm; } - if (pDot11dInfo->channel_map[Channel]) { + if (pDot11dInfo->channel_map[Channel]) MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; - } return MaxTxPwrInDbm; } -void -DOT11D_ScanComplete( - struct ieee80211_device *dev - ) +void DOT11D_ScanComplete(struct ieee80211_device *dev) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); @@ -160,7 +142,7 @@ DOT11D_ScanComplete( case DOT11D_STATE_DONE: if (GET_CIE_WATCHDOG(dev) == 0) { - // Reset country IE if previous one is gone. + /* Reset country IE if previous one is gone. */ Dot11d_Reset(dev); } break; @@ -169,15 +151,12 @@ DOT11D_ScanComplete( } } -int IsLegalChannel( - struct ieee80211_device *dev, - u8 channel -) +int IsLegalChannel(struct ieee80211_device *dev, u8 channel) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); if (MAX_CHANNEL_NUMBER < channel) { - printk("IsLegalChannel(): Invalid Channel\n"); + netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n"); return 0; } if (pDot11dInfo->channel_map[channel] > 0) @@ -185,10 +164,7 @@ int IsLegalChannel( return 0; } -int ToLegalChannel( - struct ieee80211_device *dev, - u8 channel -) +int ToLegalChannel(struct ieee80211_device *dev, u8 channel) { PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); u8 default_chn = 0; @@ -202,7 +178,7 @@ int ToLegalChannel( } if (MAX_CHANNEL_NUMBER < channel) { - printk("IsLegalChannel(): Invalid Channel\n"); + netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n"); return default_chn; } diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h index 029c2cab1e00..63f4f3c72f10 100644 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.h +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h @@ -3,9 +3,9 @@ #include "ieee80211.h" -//#define ENABLE_DOT11D +/* #define ENABLE_DOT11D */ -//#define DOT11D_MAX_CHNL_NUM 83 +/* #define DOT11D_MAX_CHNL_NUM 83 */ typedef struct _CHNL_TXPOWER_TRIPLE { u8 FirstChnl; @@ -20,18 +20,18 @@ typedef enum _DOT11D_STATE { }DOT11D_STATE; typedef struct _RT_DOT11D_INFO { - //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + /* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */ - bool bEnabled; // dot11MultiDomainCapabilityEnabled + bool bEnabled; /* dot11MultiDomainCapabilityEnabled */ - u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */ u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */ u8 CountryIeWatchdog; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) - //u8 ChnlListLen; // #Bytes valid in ChnlList[]. - //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */ + /* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */ + /* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; DOT11D_STATE State; @@ -58,43 +58,13 @@ typedef struct _RT_DOT11D_INFO { #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) +void Dot11d_Init(struct ieee80211_device *dev); +void Dot11d_Reset(struct ieee80211_device *dev); +void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, + u16 CoutryIeLen, u8 *pCoutryIe); +u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel); +void DOT11D_ScanComplete(struct ieee80211_device *dev); +int IsLegalChannel(struct ieee80211_device *dev, u8 channel); +int ToLegalChannel(struct ieee80211_device *dev, u8 channel); -void -Dot11d_Init( - struct ieee80211_device *dev - ); - -void -Dot11d_Reset( - struct ieee80211_device *dev - ); - -void -Dot11d_UpdateCountryIe( - struct ieee80211_device *dev, - u8 * pTaddr, - u16 CoutryIeLen, - u8 * pCoutryIe - ); - -u8 -DOT11D_GetMaxTxPwrInDbm( - struct ieee80211_device *dev, - u8 Channel - ); - -void -DOT11D_ScanComplete( - struct ieee80211_device * dev - ); - -int IsLegalChannel( - struct ieee80211_device * dev, - u8 channel -); - -int ToLegalChannel( - struct ieee80211_device * dev, - u8 channel -); -#endif // #ifndef __INC_DOT11D_H +#endif /* #ifndef __INC_DOT11D_H */ diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 7f015499cfae..09ffd9bc8991 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -90,6 +90,9 @@ #define IEEE_CRYPT_ALG_NAME_LEN 16 +extern int ieee80211_crypto_tkip_init(void); +extern void ieee80211_crypto_tkip_exit(void); + //by amy for ps typedef struct ieee_param { u32 cmd; @@ -1237,7 +1240,8 @@ static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) return 1; } -static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, + int mode) { /* * It is possible for both access points and our device to support @@ -1300,19 +1304,16 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee); /* ieee80211_tx.c */ -extern int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len); +extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, + struct sk_buff *frag, int hdr_len); -extern int ieee80211_rtl_xmit(struct sk_buff *skb, - struct net_device *dev); +extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats); + struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); @@ -1328,25 +1329,28 @@ extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *key); extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); + struct iw_request_info *info, + struct iw_param *data, char *extra); int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); /* ieee80211_softmac.c */ extern short ieee80211_is_54g(const struct ieee80211_network *net); extern short ieee80211_is_shortslot(const struct ieee80211_network *net); -extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype); -extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); - -extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, + struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, + u16 type, u16 stype); +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, + struct ieee80211_network *net); + +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, + struct ieee80211_device *ieee); extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); extern void ieee80211_start_bss(struct ieee80211_device *ieee); extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); @@ -1368,16 +1372,17 @@ extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, + struct iw_point *p); extern void notify_wx_assoc_event(struct ieee80211_device *ieee); extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); -extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn); +extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, + u8 asRsn); extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee); //Add for RF power on power off by lizhaoming 080512 -extern void SendDisassociation(struct ieee80211_device *ieee, - u8* asSta, - u8 asRsn); +extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, + u8 asRsn); /* ieee80211_crypt_ccmp&tkip&wep.c */ extern void ieee80211_tkip_null(void); @@ -1386,64 +1391,72 @@ extern void ieee80211_ccmp_null(void); /* ieee80211_softmac_wx.c */ extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); + struct iw_request_info *info, + union iwreq_data *wrqu, char *ext); extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra); + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra); -extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee); -extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr); +extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, + short pwr); extern const long ieee80211_wlan_frequencies[]; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 694eae3d4fda..a0340ee9d8b7 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -39,8 +39,7 @@ struct ieee80211_crypto { static struct ieee80211_crypto *hcrypt; -void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, - int force) +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) { struct list_head *ptr, *n; struct ieee80211_crypt_data *entry; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index f5949e89e5c2..0e8392acdeac 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -11,7 +11,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -//#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -61,7 +60,7 @@ struct ieee80211_ccmp_data { }; void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) + const u8 pt[16], u8 ct[16]) { crypto_cipher_encrypt_one((void *)tfm, ct, pt); } @@ -130,7 +129,6 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x08)); */ - // fixed by David :2006.9.6 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x80)); aad_len = 22; @@ -212,7 +210,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; -// mic = skb_put(skb, CCMP_MIC_LEN); i = CCMP_PN_LEN - 1; while (i >= 0) { @@ -232,7 +229,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = key->tx_pn[0]; hdr = (struct ieee80211_hdr_4addr *)skb->data; - //mic is moved to here by john mic = skb_put(skb, CCMP_MIC_LEN); ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); @@ -416,9 +412,8 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) static char *ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%pm rx_pn=%pm " - "format_errors=%d replays=%d decrypt_errors=%d\n", + p += sprintf(p, + "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->key_idx, ccmp->key_set, ccmp->tx_pn, ccmp->rx_pn, ccmp->dot11RSNAStatsCCMPFormatErrors, @@ -430,7 +425,6 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv) void ieee80211_ccmp_null(void) { -// printk("============>%s()\n", __func__); return; } static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c index da24e430ca13..34a10d1868b4 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c @@ -9,7 +9,6 @@ * more details. */ -//#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -65,7 +64,7 @@ struct ieee80211_tkip_data { u8 rx_hdr[16], tx_hdr[16]; }; -static void * ieee80211_tkip_init(int key_idx) +static void *ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; @@ -304,8 +303,8 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_tkip_data *tkey = priv; - struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; + struct ieee80211_tkip_data *tkey = priv; + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; int len; u8 *pos; struct ieee80211_hdr_4addr *hdr; @@ -467,27 +466,27 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return keyidx; } -static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, - u8 * data, size_t data_len, u8 * mic) +static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr, + u8 *data, size_t data_len, u8 *mic) { - struct hash_desc desc; - struct scatterlist sg[2]; + struct hash_desc desc; + struct scatterlist sg[2]; - if (tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); - return -1; - } + if (tfm_michael == NULL) { + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } sg_init_table(sg, 2); sg_set_buf(&sg[0], hdr, 16); sg_set_buf(&sg[1], data, data_len); - if (crypto_hash_setkey(tfm_michael, key, 8)) - return -1; + if (crypto_hash_setkey(tfm_michael, key, 8)) + return -1; - desc.tfm = tfm_michael; - desc.flags = 0; - return crypto_hash_digest(&desc, sg, data_len + 16, mic); + desc.tfm = tfm_michael; + desc.flags = 0; + return crypto_hash_digest(&desc, sg, data_len + 16, mic); } static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) @@ -521,7 +520,8 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) } -static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, + void *priv) { struct ieee80211_tkip_data *tkey = priv; u8 *pos; @@ -538,12 +538,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri michael_mic_hdr(skb, tkey->tx_hdr); - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; } - // } pos = skb_put(skb, 8); if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, @@ -554,8 +551,8 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri } static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr_4addr *hdr, - int keyidx) + struct ieee80211_hdr_4addr *hdr, + int keyidx) { union iwreq_data wrqu; struct iw_michaelmicfailure ev; @@ -575,7 +572,7 @@ static void ieee80211_michael_mic_failure(struct net_device *dev, } static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) + int hdr_len, void *priv) { struct ieee80211_tkip_data *tkey = priv; u8 mic[8]; @@ -587,12 +584,9 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, return -1; michael_mic_hdr(skb, tkey->rx_hdr); - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; } - // } if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) @@ -688,7 +682,7 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) } -static char * ieee80211_tkip_print_stats(char *p, void *priv) +static char *ieee80211_tkip_print_stats(char *p, void *priv) { struct ieee80211_tkip_data *tkip = priv; p += sprintf(p, "key[%d] alg=TKIP key_set=%d " @@ -746,6 +740,4 @@ void ieee80211_crypto_tkip_exit(void) void ieee80211_tkip_null(void) { -// printk("============>%s()\n", __func__); - return; } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c index 304579096562..b522b57a2691 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c @@ -337,8 +337,9 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, /* Called only as a tasklet (software IRQ), by ieee80211_rx */ static inline int -ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *skb, - int keyidx, struct ieee80211_crypt_data *crypt) +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, + struct sk_buff *skb, int keyidx, + struct ieee80211_crypt_data *crypt) { struct ieee80211_hdr_4addr *hdr; int res, hdrlen; @@ -366,7 +367,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, struct sk_buff *s /* this function is stolen from ipw2200 driver*/ #define IEEE_PACKET_RETRY_TIME (5*HZ) static int is_duplicate_packet(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header) + struct ieee80211_hdr_4addr *header) { u16 fc = le16_to_cpu(header->frame_ctl); u16 sc = le16_to_cpu(header->seq_ctl); @@ -467,7 +468,7 @@ drop: * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) + struct ieee80211_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -794,9 +795,7 @@ static inline int ieee80211_is_ofdm_rate(u8 rate) return 0; } -static inline int ieee80211_SignalStrengthTranslate( - int CurrSS - ) +static inline int ieee80211_SignalStrengthTranslate(int CurrSS) { int RetSS; @@ -831,12 +830,10 @@ static inline int ieee80211_SignalStrengthTranslate( return RetSS; } -static inline void ieee80211_extract_country_ie( - struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - struct ieee80211_network *network, - u8 *addr2 -) +static inline void +ieee80211_extract_country_ie(struct ieee80211_device *ieee, + struct ieee80211_info_element *info_element, + struct ieee80211_network *network, u8 *addr2) { if (IS_DOT11D_ENABLE(ieee)) { if (info_element->len != 0) { @@ -858,10 +855,8 @@ static inline void ieee80211_extract_country_ie( } -static int -ieee80211_TranslateToDbm( - unsigned char SignalStrengthIndex // 0-100 index. - ) +/* SignalStrengthIndex is 0-100 */ +static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex) { unsigned char SignalPower; // in dBm. @@ -1197,7 +1192,7 @@ static inline int is_same_network(struct ieee80211_network *src, } inline void update_network(struct ieee80211_network *dst, - struct ieee80211_network *src) + struct ieee80211_network *src) { unsigned char quality = src->stats.signalstrength; unsigned char signal = 0; @@ -1281,10 +1276,10 @@ inline void update_network(struct ieee80211_network *dst, } -inline void ieee80211_process_probe_response( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_rx_stats *stats) +inline void +ieee80211_process_probe_response(struct ieee80211_device *ieee, + struct ieee80211_probe_response *beacon, + struct ieee80211_rx_stats *stats) { struct ieee80211_network network; struct ieee80211_network *target; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 029070603f66..3af1bf965981 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -20,17 +20,17 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/interrupt.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <linux/etherdevice.h> #include "dot11d.h" u8 rsn_authen_cipher_suite[16][4] = { - {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved - {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default - {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default} - {0x00,0x0F,0xAC,0x03}, //WRAP-historical - {0x00,0x0F,0xAC,0x04}, //CCMP - {0x00,0x0F,0xAC,0x05}, //WEP-104 + {0x00, 0x0F, 0xAC, 0x00}, //Use group key, //Reserved + {0x00, 0x0F, 0xAC, 0x01}, //WEP-40 //RSNA default + {0x00, 0x0F, 0xAC, 0x02}, //TKIP //NONE //{used just as default} + {0x00, 0x0F, 0xAC, 0x03}, //WRAP-historical + {0x00, 0x0F, 0xAC, 0x04}, //CCMP + {0x00, 0x0F, 0xAC, 0x05}, //WEP-104 }; short ieee80211_is_54g(const struct ieee80211_network *net) @@ -106,7 +106,8 @@ void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) } -void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) +{ u8 *tag = *tag_p; *tag++ = MFIE_TYPE_GENERIC; //0 @@ -118,30 +119,28 @@ void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { *tag++ = 0x00; *tag++ = 0x01; #ifdef SUPPORT_USPD - if(ieee->current_network.wmm_info & 0x80) { + if (ieee->current_network.wmm_info & 0x80) *tag++ = 0x0f|MAX_SP_Len; - } else { + else *tag++ = MAX_SP_Len; - } #else *tag++ = MAX_SP_Len; #endif *tag_p = tag; } -void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) { +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) +{ u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; //0 - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0xe0; - *tag++ = 0x4c; - *tag++ = 0x01;//5 - *tag++ = 0x02; - *tag++ = 0x11; + *tag++ = MFIE_TYPE_GENERIC; /* 0 */ + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0xe0; + *tag++ = 0x4c; + *tag++ = 0x01; /* 5 */ + *tag++ = 0x02; + *tag++ = 0x11; *tag++ = 0x00; - *tag_p = tag; printk(KERN_ALERT "This is enable turbo mode IE process\n"); } @@ -187,7 +186,8 @@ void init_mgmt_queue(struct ieee80211_device *ieee) void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); -inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +inline void softmac_mgmt_xmit(struct sk_buff *skb, + struct ieee80211_device *ieee) { unsigned long flags; short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; @@ -238,7 +238,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee } -inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, + struct ieee80211_device *ieee) { short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; @@ -276,10 +277,9 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i // dev_kfree_skb_any(skb);//edit by thomas } //by amy for power save -inline struct sk_buff *ieee80211_disassociate_skb( - struct ieee80211_network *beacon, - struct ieee80211_device *ieee, - u8 asRsn) +inline struct sk_buff * +ieee80211_disassociate_skb(struct ieee80211_network *beacon, + struct ieee80211_device *ieee, u8 asRsn) { struct sk_buff *skb; struct ieee80211_disassoc_frame *disass; @@ -299,12 +299,7 @@ inline struct sk_buff *ieee80211_disassociate_skb( disass->reasoncode = asRsn; return skb; } -void -SendDisassociation( - struct ieee80211_device *ieee, - u8* asSta, - u8 asRsn -) +void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn) { struct ieee80211_network *beacon = &ieee->current_network; struct sk_buff *skb; @@ -735,8 +730,9 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) } -inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, int challengelen) +inline struct sk_buff * +ieee80211_authentication_req(struct ieee80211_network *beacon, + struct ieee80211_device *ieee, int challengelen) { struct sk_buff *skb; struct ieee80211_authentication *auth; @@ -768,7 +764,8 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be } -static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) +static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, + u8 *dest) { u8 *tag; int beacon_size; @@ -969,7 +966,7 @@ static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee, } -struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) +struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr) { struct sk_buff *skb; struct ieee80211_hdr_3addr* hdr; @@ -995,7 +992,7 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) } -void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest) { struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); @@ -1006,7 +1003,7 @@ void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) } -void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest) +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest) { struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); @@ -1029,7 +1026,9 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) } -inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) +inline struct sk_buff * +ieee80211_association_req(struct ieee80211_network *beacon, + struct ieee80211_device *ieee) { struct sk_buff *skb; //unsigned long flags; @@ -1200,7 +1199,8 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) } } -void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) +void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, + int chlen) { u8 *c; struct sk_buff *skb; @@ -1310,7 +1310,8 @@ void ieee80211_associate_procedure_wq(struct work_struct *work) up(&ieee->wx_sem); } -inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, + struct ieee80211_network *net) { u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; int tmp_ssid_len = 0; @@ -1423,7 +1424,7 @@ void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) } -static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) +static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) { struct ieee80211_authentication *a; u8 *t; @@ -1449,7 +1450,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) } -int auth_rq_parse(struct sk_buff *skb,u8* dest) +int auth_rq_parse(struct sk_buff *skb, u8 *dest) { struct ieee80211_authentication *a; @@ -1467,7 +1468,8 @@ int auth_rq_parse(struct sk_buff *skb,u8* dest) return WLAN_STATUS_SUCCESS; } -static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, + u8 *src) { u8 *tag; u8 *skbend; @@ -1505,7 +1507,7 @@ static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, } -int assoc_rq_parse(struct sk_buff *skb,u8* dest) +int assoc_rq_parse(struct sk_buff *skb, u8 *dest) { struct ieee80211_assoc_request_frame *a; @@ -1536,8 +1538,8 @@ static inline u16 assoc_parse(struct sk_buff *skb, int *aid) return le16_to_cpu(a->status); } -static inline void -ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee, + struct sk_buff *skb) { u8 dest[ETH_ALEN]; @@ -1551,8 +1553,8 @@ ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) } } -inline void -ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) +inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, + struct sk_buff *skb) { u8 dest[ETH_ALEN]; int status; @@ -1595,7 +1597,8 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) } -short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, + u32 *time_l) { int timeout = 0; @@ -1770,10 +1773,10 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) spin_unlock_irqrestore(&ieee->lock, flags); } -inline int -ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) +inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, + struct sk_buff *skb, + struct ieee80211_rx_stats *rx_stats, + u16 type, u16 stype) { struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; u16 errcode; @@ -1976,7 +1979,8 @@ associate_complete: * to the driver later, when it wakes the queue. */ -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, + struct ieee80211_device *ieee) { @@ -2619,7 +2623,8 @@ static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) } -void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len) +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, + int wpa_ie_len) { /* make sure WPA is enabled */ ieee80211_wpa_enable(ieee, 1); @@ -2628,7 +2633,8 @@ void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int } -static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, + int reason) { int ret = 0; @@ -2652,7 +2658,7 @@ static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int re static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, - struct ieee_param *param, int plen) + struct ieee_param *param, int plen) { u8 *buf; @@ -2706,7 +2712,8 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) return ret; } -static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, + u32 value) { int ret=0; unsigned long flags; @@ -2784,7 +2791,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v /* implementation borrowed from hostap driver */ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, - struct ieee_param *param, int param_len) + struct ieee_param *param, int param_len) { int ret = 0; @@ -2931,7 +2938,8 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, return ret; } -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, + struct iw_point *p) { struct ieee_param *param; int ret=0; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index e5282068e3de..46f35644126c 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -28,8 +28,9 @@ const long ieee80211_wlan_frequencies[] = { }; -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { int ret; struct iw_freq *fwrq = &wrqu->freq; @@ -82,8 +83,8 @@ out: int ieee80211_wx_get_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { struct iw_freq *fwrq = &wrqu->freq; @@ -97,8 +98,8 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee, } int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { unsigned long flags; @@ -126,8 +127,7 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee, int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, + struct iw_request_info *info, union iwreq_data *awrq, char *extra) { @@ -174,8 +174,9 @@ out: return ret; } -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int ieee80211_wx_get_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { int len, ret = 0; unsigned long flags; @@ -211,8 +212,8 @@ out: } int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { u32 target_rate = wrqu->bitrate.value; @@ -230,8 +231,8 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee, int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { wrqu->bitrate.value = ieee->rate * 100000; @@ -239,8 +240,9 @@ int ieee80211_wx_get_rate(struct ieee80211_device *ieee, return 0; } -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { ieee->sync_scan_hurryup = 1; @@ -305,8 +307,9 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) } -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { int ret = 0; @@ -333,8 +336,8 @@ out: } int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *a, union iwreq_data *wrqu, + char *extra) { int ret = 0, len; @@ -395,8 +398,9 @@ out: return ret; } -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int ieee80211_wx_get_mode(struct ieee80211_device *ieee, + struct iw_request_info *a, union iwreq_data *wrqu, + char *b) { wrqu->mode = ieee->iw_mode; @@ -404,8 +408,8 @@ int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info } int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { int *parms = (int *)extra; @@ -440,8 +444,8 @@ int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, } int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { strlcpy(wrqu->name, "802.11", IFNAMSIZ); if (ieee->modulation & IEEE80211_CCK_MODULATION) { @@ -464,8 +468,8 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, /* this is mostly stolen from hostap */ int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { int ret = 0; @@ -525,8 +529,8 @@ exit: /* this is stolen from hostap */ int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, union iwreq_data *wrqu, + char *extra) { int ret = 0; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index f5a5219fe14d..0dc5ae414270 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -177,10 +177,8 @@ static inline int ieee80211_put_snap(u8 *data, u16 h_proto) return SNAP_SIZE + sizeof(u16); } -int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len) +int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, + struct sk_buff *frag, int hdr_len) { struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx]; int res; @@ -279,8 +277,8 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, * Classify the to-be send data packet * Need to acquire the sent queue index. */ -static int -ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) +static int ieee80211_classify(struct sk_buff *skb, + struct ieee80211_network *network) { struct ether_header *eh = (struct ether_header *)skb->data; unsigned int wme_UP = 0; @@ -310,8 +308,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) } /* SKBs are added to the ieee->tx_queue. */ -int ieee80211_rtl_xmit(struct sk_buff *skb, - struct net_device *dev) +int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee80211_device *ieee = netdev_priv(dev); struct ieee80211_txb *txb = NULL; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index 24d39ccc1337..3b7955f0ff98 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -633,8 +633,8 @@ done: return ret; } int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct iw_mlme *mlme = (struct iw_mlme *) extra; // printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __func__, mlme->cmd); @@ -653,8 +653,8 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, } int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra) + struct iw_request_info *info, + struct iw_param *data, char *extra) { /* struct ieee80211_security sec = { diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index d052f4a9a839..e9602f67cac8 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -639,20 +639,20 @@ typedef struct r8180_priv ((_ac) == WME_AC_BK) ? BK_PRIORITY : \ BE_PRIORITY) -short rtl8180_tx(struct net_device *dev,u8* skbuf, int len,int priority, - short morefrag,short fragdesc,int rate); +short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority, + short morefrag, short fragdesc, int rate); u8 read_nic_byte(struct net_device *dev, int x); u32 read_nic_dword(struct net_device *dev, int x); u16 read_nic_word(struct net_device *dev, int x) ; -void write_nic_byte(struct net_device *dev, int x,u8 y); -void write_nic_word(struct net_device *dev, int x,u16 y); -void write_nic_dword(struct net_device *dev, int x,u32 y); +void write_nic_byte(struct net_device *dev, int x, u8 y); +void write_nic_word(struct net_device *dev, int x, u16 y); +void write_nic_dword(struct net_device *dev, int x, u32 y); void force_pci_posting(struct net_device *dev); void rtl8180_rtx_disable(struct net_device *); -void rtl8180_set_anaparam(struct net_device *dev,u32 a); -void rtl8185_set_anaparam2(struct net_device *dev,u32 a); +void rtl8180_set_anaparam(struct net_device *dev, u32 a); +void rtl8185_set_anaparam2(struct net_device *dev, u32 a); void rtl8180_set_hw_wep(struct net_device *dev); void rtl8180_no_hw_wep(struct net_device *dev); void rtl8180_update_msr(struct net_device *dev); @@ -661,7 +661,7 @@ void rtl8180_beacon_rx_disable(struct net_device *dev); int rtl8180_down(struct net_device *dev); int rtl8180_up(struct net_device *dev); void rtl8180_commit(struct net_device *dev); -void rtl8180_set_chan(struct net_device *dev,short ch); +void rtl8180_set_chan(struct net_device *dev, short ch); void write_phy(struct net_device *dev, u8 adr, u8 data); void write_phy_cck(struct net_device *dev, u8 adr, u32 data); void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); @@ -671,7 +671,8 @@ void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); int get_curr_tx_free_desc(struct net_device *dev, int priority); void UpdateInitialGain(struct net_device *dev); -bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, bool bAntDiversity); +bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, + bool bAntDiversity); //#ifdef CONFIG_RTL8185B void rtl8185b_adapter_start(struct net_device *dev); @@ -684,6 +685,17 @@ void fix_tx_fifo(struct net_device *dev); void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch); void rtl8180_rate_adapter(struct work_struct * work); //#endif -bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource); +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, + u32 ChangeSource); #endif + +/* fun with the built-in ieee80211 stack... */ +extern int ieee80211_crypto_init(void); +extern void ieee80211_crypto_deinit(void); +extern int ieee80211_crypto_tkip_init(void); +extern void ieee80211_crypto_tkip_exit(void); +extern int ieee80211_crypto_ccmp_init(void); +extern void ieee80211_crypto_ccmp_exit(void); +extern int ieee80211_crypto_wep_init(void); +extern void ieee80211_crypto_wep_exit(void); diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 76a67386b927..297136b3c57d 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -79,7 +79,7 @@ module_param(hwwep, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards"); static int rtl8180_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); + const struct pci_device_id *id); static void rtl8180_pci_remove(struct pci_dev *pdev); @@ -387,7 +387,8 @@ static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, return 0; } -void buffer_free(struct net_device *dev, struct buffer **buffer, int len, short consistent) +void buffer_free(struct net_device *dev, struct buffer **buffer, int len, + short consistent) { struct buffer *tmp, *next; @@ -1855,7 +1856,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority, if (remain == len && !descfrag) { ownbit_flag = false; - *tail = *tail | (1<<29) ; /* fist segment of the packet */ + *tail = *tail | (1<<29); /* fist segment of the packet */ *tail = *tail | (len); } else { ownbit_flag = true; @@ -2238,7 +2239,8 @@ static CHANNEL_LIST ChannelPlan[] = { {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} /* world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826 */ }; -static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee) +static void rtl8180_set_channel_map(u8 channel_plan, + struct ieee80211_device *ieee) { int i; @@ -2830,11 +2832,8 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev) /* * Change current and default preamble mode. */ -bool -MgntActSet_802_11_PowerSaveMode( - struct r8180_priv *priv, - RT_PS_MODE rtPsMode -) +bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv, + RT_PS_MODE rtPsMode) { /* Currently, we do not change power save mode on IBSS mode. */ if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) @@ -3161,7 +3160,7 @@ static const struct net_device_ops rtl8180_netdev_ops = { }; static int rtl8180_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) + const struct pci_device_id *id) { unsigned long ioaddr = 0; struct net_device *dev = NULL; @@ -3310,16 +3309,6 @@ static void rtl8180_pci_remove(struct pci_dev *pdev) DMESG("wlan driver removed\n"); } -/* fun with the built-in ieee80211 stack... */ -extern int ieee80211_crypto_init(void); -extern void ieee80211_crypto_deinit(void); -extern int ieee80211_crypto_tkip_init(void); -extern void ieee80211_crypto_tkip_exit(void); -extern int ieee80211_crypto_ccmp_init(void); -extern void ieee80211_crypto_ccmp_exit(void); -extern int ieee80211_crypto_wep_init(void); -extern void ieee80211_crypto_wep_exit(void); - static int __init rtl8180_pci_module_init(void) { int ret; diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h index 732c06ac1026..cb4046f346ef 100644 --- a/drivers/staging/rtl8187se/r8180_dm.h +++ b/drivers/staging/rtl8187se/r8180_dm.h @@ -5,7 +5,7 @@ /* #include "r8180_hw.h" */ /* #include "r8180_93cx6.h" */ void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength); -bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex); +bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex); bool SwitchAntenna(struct net_device *dev); void SwAntennaDiversity(struct net_device *dev); void SwAntennaDiversityTimerCallback(struct net_device *dev); diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h index c94ca0794a5d..de084f07a071 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225.h +++ b/drivers/staging/rtl8187se/r8180_rtl8225.h @@ -28,7 +28,8 @@ u16 RF_ReadReg(struct net_device *dev, u8 offset); void rtl8180_set_mode(struct net_device *dev, int mode); void rtl8180_set_mode(struct net_device *dev, int mode); -bool SetZebraRFPowerState8185(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState); +bool SetZebraRFPowerState8185(struct net_device *dev, + RT_RF_POWER_STATE eRFPowerState); void rtl8225z4_rf_sleep(struct net_device *dev); void rtl8225z4_rf_wakeup(struct net_device *dev); diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 4e01653e098a..bae68759bd6a 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -21,6 +21,7 @@ #include "r8180.h" #include "r8180_hw.h" +#include <net/iw_handler.h> #include "ieee80211/dot11d.h" u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, @@ -74,8 +75,9 @@ static int r8180_wx_set_key(struct net_device *dev, } -static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa, - union iwreq_data *wrqu, char *b) +static int r8180_wx_set_beaconinterval(struct net_device *dev, + struct iw_request_info *aa, + union iwreq_data *wrqu, char *b) { int *parms = (int *)b; int bi = parms[0]; @@ -473,9 +475,8 @@ static int r8180_wx_get_frag(struct net_device *dev, static int r8180_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) + struct iw_request_info *info, + union iwreq_data *awrq, char *extra) { int ret; struct r8180_priv *priv = ieee80211_priv(dev); @@ -537,8 +538,10 @@ static int r8180_wx_get_enc(struct net_device *dev, } -static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union - iwreq_data *wrqu, char *p) { +static int r8180_wx_set_scan_type(struct net_device *dev, + struct iw_request_info *aa, + union iwreq_data *wrqu, char *p) +{ struct r8180_priv *priv = ieee80211_priv(dev); int *parms = (int*)p; @@ -553,8 +556,8 @@ static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info } static int r8180_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int err = 0; @@ -601,8 +604,8 @@ exit: } static int r8180_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -625,8 +628,8 @@ static int r8180_wx_get_retry(struct net_device *dev, } static int r8180_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); if (priv->rf_set_sens == NULL) @@ -637,8 +640,8 @@ static int r8180_wx_get_sens(struct net_device *dev, static int r8180_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -666,8 +669,8 @@ exit: static int r8180_wx_set_rawtx(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int ret; @@ -686,8 +689,8 @@ static int r8180_wx_set_rawtx(struct net_device *dev, } static int r8180_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { int ret; struct r8180_priv *priv = ieee80211_priv(dev); @@ -702,8 +705,8 @@ static int r8180_wx_get_power(struct net_device *dev, } static int r8180_wx_set_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { int ret; struct r8180_priv *priv = ieee80211_priv(dev); @@ -728,8 +731,8 @@ static int r8180_wx_set_power(struct net_device *dev, } static int r8180_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -750,8 +753,8 @@ static int r8180_wx_set_rts(struct net_device *dev, return 0; } static int r8180_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -841,8 +844,8 @@ static int r8180_wx_set_iwmode(struct net_device *dev, return ret; } static int r8180_wx_get_preamble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -858,8 +861,8 @@ static int r8180_wx_get_preamble(struct net_device *dev, return 0; } static int r8180_wx_set_preamble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int ret = 0; @@ -881,8 +884,8 @@ static int r8180_wx_set_preamble(struct net_device *dev, return ret; } static int r8180_wx_get_siglevel(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int ret = 0; @@ -900,8 +903,8 @@ static int r8180_wx_get_siglevel(struct net_device *dev, return ret; } static int r8180_wx_get_sigqual(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int ret = 0; @@ -959,8 +962,8 @@ static int r8180_wx_reset_stats(struct net_device *dev, } static int r8180_wx_radio_on(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -978,8 +981,8 @@ static int r8180_wx_radio_on(struct net_device *dev, } static int r8180_wx_radio_off(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -996,8 +999,8 @@ static int r8180_wx_radio_off(struct net_device *dev, } static int r8180_wx_get_channelplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -1013,8 +1016,8 @@ static int r8180_wx_get_channelplan(struct net_device *dev, return 0; } static int r8180_wx_set_channelplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); int *val = (int *)extra; @@ -1043,8 +1046,8 @@ static int r8180_wx_set_channelplan(struct net_device *dev, } static int r8180_wx_get_version(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); /* struct ieee80211_device *ieee; */ @@ -1059,8 +1062,8 @@ static int r8180_wx_get_version(struct net_device *dev, /* added by amy 080818 */ /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */ static int r8180_wx_set_forcerate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); u8 forcerate = *extra; @@ -1084,8 +1087,8 @@ static int r8180_wx_set_forcerate(struct net_device *dev, } static int r8180_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -1118,8 +1121,8 @@ static int r8180_wx_set_auth(struct net_device *dev, } static int r8180_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { int ret = 0; struct r8180_priv *priv = ieee80211_priv(dev); @@ -1156,65 +1159,48 @@ static int r8180_wx_set_gen_ie(struct net_device *dev, } -static iw_handler r8180_wx_handlers[] = { - NULL, /* SIOCSIWCOMMIT */ - r8180_wx_get_name, /* SIOCGIWNAME */ - dummy, /* SIOCSIWNWID */ - dummy, /* SIOCGIWNWID */ - r8180_wx_set_freq, /* SIOCSIWFREQ */ - r8180_wx_get_freq, /* SIOCGIWFREQ */ - r8180_wx_set_mode, /* SIOCSIWMODE */ - r8180_wx_get_mode, /* SIOCGIWMODE */ - r8180_wx_set_sens, /* SIOCSIWSENS */ - r8180_wx_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - rtl8180_wx_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - dummy, /* SIOCSIWSPY */ - dummy, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - r8180_wx_set_wap, /* SIOCSIWAP */ - r8180_wx_get_wap, /* SIOCGIWAP */ - r8180_wx_set_mlme, /* SIOCSIWMLME*/ - dummy, /* SIOCGIWAPLIST -- deprecated */ - r8180_wx_set_scan, /* SIOCSIWSCAN */ - r8180_wx_get_scan, /* SIOCGIWSCAN */ - r8180_wx_set_essid, /* SIOCSIWESSID */ - r8180_wx_get_essid, /* SIOCGIWESSID */ - dummy, /* SIOCSIWNICKN */ - dummy, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - r8180_wx_set_rate, /* SIOCSIWRATE */ - r8180_wx_get_rate, /* SIOCGIWRATE */ - r8180_wx_set_rts, /* SIOCSIWRTS */ - r8180_wx_get_rts, /* SIOCGIWRTS */ - r8180_wx_set_frag, /* SIOCSIWFRAG */ - r8180_wx_get_frag, /* SIOCGIWFRAG */ - dummy, /* SIOCSIWTXPOW */ - dummy, /* SIOCGIWTXPOW */ - r8180_wx_set_retry, /* SIOCSIWRETRY */ - r8180_wx_get_retry, /* SIOCGIWRETRY */ - r8180_wx_set_enc, /* SIOCSIWENCODE */ - r8180_wx_get_enc, /* SIOCGIWENCODE */ - r8180_wx_set_power, /* SIOCSIWPOWER */ - r8180_wx_get_power, /* SIOCGIWPOWER */ - NULL, /*---hole---*/ - NULL, /*---hole---*/ - r8180_wx_set_gen_ie, /* SIOCSIWGENIE */ - NULL, /* SIOCSIWGENIE */ - r8180_wx_set_auth, /* SIOCSIWAUTH */ - NULL, /* SIOCSIWAUTH */ - r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCSIWPMKSA */ - NULL, /*---hole---*/ -}; +static const iw_handler r8180_wx_handlers[] = { + IW_HANDLER(SIOCGIWNAME, r8180_wx_get_name), + IW_HANDLER(SIOCSIWNWID, dummy), + IW_HANDLER(SIOCGIWNWID, dummy), + IW_HANDLER(SIOCSIWFREQ, r8180_wx_set_freq), + IW_HANDLER(SIOCGIWFREQ, r8180_wx_get_freq), + IW_HANDLER(SIOCSIWMODE, r8180_wx_set_mode), + IW_HANDLER(SIOCGIWMODE, r8180_wx_get_mode), + IW_HANDLER(SIOCSIWSENS, r8180_wx_set_sens), + IW_HANDLER(SIOCGIWSENS, r8180_wx_get_sens), + IW_HANDLER(SIOCGIWRANGE, rtl8180_wx_get_range), + IW_HANDLER(SIOCSIWSPY, dummy), + IW_HANDLER(SIOCGIWSPY, dummy), + IW_HANDLER(SIOCSIWAP, r8180_wx_set_wap), + IW_HANDLER(SIOCGIWAP, r8180_wx_get_wap), + IW_HANDLER(SIOCSIWMLME, r8180_wx_set_mlme), + IW_HANDLER(SIOCGIWAPLIST, dummy), /* deprecated */ + IW_HANDLER(SIOCSIWSCAN, r8180_wx_set_scan), + IW_HANDLER(SIOCGIWSCAN, r8180_wx_get_scan), + IW_HANDLER(SIOCSIWESSID, r8180_wx_set_essid), + IW_HANDLER(SIOCGIWESSID, r8180_wx_get_essid), + IW_HANDLER(SIOCSIWNICKN, dummy), + IW_HANDLER(SIOCGIWNICKN, dummy), + IW_HANDLER(SIOCSIWRATE, r8180_wx_set_rate), + IW_HANDLER(SIOCGIWRATE, r8180_wx_get_rate), + IW_HANDLER(SIOCSIWRTS, r8180_wx_set_rts), + IW_HANDLER(SIOCGIWRTS, r8180_wx_get_rts), + IW_HANDLER(SIOCSIWFRAG, r8180_wx_set_frag), + IW_HANDLER(SIOCGIWFRAG, r8180_wx_get_frag), + IW_HANDLER(SIOCSIWTXPOW, dummy), + IW_HANDLER(SIOCGIWTXPOW, dummy), + IW_HANDLER(SIOCSIWRETRY, r8180_wx_set_retry), + IW_HANDLER(SIOCGIWRETRY, r8180_wx_get_retry), + IW_HANDLER(SIOCSIWENCODE, r8180_wx_set_enc), + IW_HANDLER(SIOCGIWENCODE, r8180_wx_get_enc), + IW_HANDLER(SIOCSIWPOWER, r8180_wx_set_power), + IW_HANDLER(SIOCGIWPOWER, r8180_wx_get_power), + IW_HANDLER(SIOCSIWGENIE, r8180_wx_set_gen_ie), + IW_HANDLER(SIOCSIWAUTH, r8180_wx_set_auth), + IW_HANDLER(SIOCSIWENCODEEXT, r8180_wx_set_enc_ext), +}; static const struct iw_priv_args r8180_private_args[] = { { @@ -1350,7 +1336,7 @@ static iw_handler r8180_private_handler[] = { }; static inline int is_same_network(struct ieee80211_network *src, - struct ieee80211_network *dst, + struct ieee80211_network *dst, struct ieee80211_device *ieee) { /* A network is only a duplicate if the channel, BSSID, ESSID diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index dc52a3e584d8..c8b9baff1dbc 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -497,7 +497,7 @@ static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) */ RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); - printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", + netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); } else { @@ -870,9 +870,10 @@ static u8 GetSupportedWirelessMode8185(struct net_device *dev) return WIRELESS_MODE_B | WIRELESS_MODE_G; } -static void ActUpdateChannelAccessSetting(struct net_device *dev, - WIRELESS_MODE WirelessMode, - PCHANNEL_ACCESS_SETTING ChnlAccessSetting) +static void +ActUpdateChannelAccessSetting(struct net_device *dev, + WIRELESS_MODE WirelessMode, + PCHANNEL_ACCESS_SETTING ChnlAccessSetting) { AC_CODING eACI; @@ -1084,7 +1085,7 @@ static bool MgntDisconnect(struct net_device *dev, u8 asRsn) * PASSIVE LEVEL. */ static bool SetRFPowerState(struct net_device *dev, - RT_RF_POWER_STATE eRFPowerState) + RT_RF_POWER_STATE eRFPowerState) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bResult = false; @@ -1097,8 +1098,8 @@ static bool SetRFPowerState(struct net_device *dev, return bResult; } -bool MgntActSet_RF_State(struct net_device *dev, - RT_RF_POWER_STATE StateToSet, u32 ChangeSource) +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, + u32 ChangeSource) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bActionAllowed = false; @@ -1125,7 +1126,7 @@ bool MgntActSet_RF_State(struct net_device *dev, * to be stuck here. */ if (RFWaitCounter > 1000) { /* 1sec */ - printk("MgntActSet_RF_State(): Wait too long to set RF\n"); + netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n"); /* TODO: Reset RF state? */ return false; } diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c6560b20..c47990a62b7c 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -296,7 +296,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pme if (ret == _SUCCESS) ret = rtw_sctx_wait(&sctx); - return ret; + return ret; } void _rtw_write_port_cancel(struct adapter *adapter) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 7ab5ff039c88..6519a7b3f833 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -4419,7 +4419,7 @@ s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntfr if (ret == _SUCCESS) ret = rtw_sctx_wait(&sctx); - return ret; + return ret; } s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c index a594e51d2e1c..01662f78e53d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_xmit.c +++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c @@ -685,7 +685,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr _func_enter_; - hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);; + hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ); if (pattrib->encrypt == _TKIP_) {/* if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_PRIVACY_) */ /* encode mic code */ diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 52b3fba0fae1..a291d7ae6f42 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -2304,7 +2304,7 @@ void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */ pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x18)>>3; if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) - pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;; + pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3; } else { pHalData->AntDivCfg = registry_par->antdiv_cfg; /* 0:OFF , 1:ON, 2:By EFUSE */ } diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c index 05e2475cfd61..511f61cbb9e0 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c @@ -86,7 +86,7 @@ void update_recvframe_attrib_88e(union recv_frame *precvframe, struct recv_stat pattrib = &precvframe->u.hdr.attrib; _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); - pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);;/* u8)prxreport->crc32; */ + pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */ /* update rx report to recv_frame attribute */ pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */ diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index ae5458770234..a002d2e75e9f 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -7228,25 +7228,25 @@ static int rtw_mp_thermal(struct net_device *dev, if (copy_from_user(extra, wrqu->pointer, wrqu->length)) return -EFAULT; - bwrite = strncmp(extra, "write", 6); /* strncmp true is 0 */ + bwrite = strncmp(extra, "write", 6); /* strncmp true is 0 */ - Hal_GetThermalMeter(padapter, &val); + Hal_GetThermalMeter(padapter, &val); - if (bwrite == 0) { - EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); - if (2 > max_available_size) { - DBG_88E("no available efuse!\n"); - return -EFAULT; - } - if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) { - DBG_88E("rtw_efuse_map_write error\n"); - return -EFAULT; - } else { - sprintf(extra, " efuse write ok :%d", val); - } - } else { - sprintf(extra, "%d", val); - } + if (bwrite == 0) { + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); + if (2 > max_available_size) { + DBG_88E("no available efuse!\n"); + return -EFAULT; + } + if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) { + DBG_88E("rtw_efuse_map_write error\n"); + return -EFAULT; + } else { + sprintf(extra, " efuse write ok :%d", val); + } + } else { + sprintf(extra, "%d", val); + } wrqu->length = strlen(extra); return 0; diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c index a1ae72772c5f..2ffb4184fd08 100644 --- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c +++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c @@ -52,7 +52,7 @@ u32 rtw_atoi(u8 *s) } if (flag == 1) num = num * -1; - return num; + return num; } inline u8 *_rtw_vmalloc(u32 sz) diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 7d14779310d3..b21b1566424b 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -71,7 +71,7 @@ struct rtw_usb_drv { }; static struct rtw_usb_drv rtl8188e_usb_drv = { - .usbdrv.name = (char *)"r8188eu", + .usbdrv.name = "r8188eu", .usbdrv.probe = rtw_drv_init, .usbdrv.disconnect = rtw_dev_remove, .usbdrv.id_table = rtw_usb_id_tbl, diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c index 1260f10944ef..eb33c517fcc8 100644 --- a/drivers/staging/rtl8192e/dot11d.c +++ b/drivers/staging/rtl8192e/dot11d.c @@ -144,7 +144,7 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, return; } - for (j = 0 ; j < pTriple->NumChnls; j++) { + for (j = 0; j < pTriple->NumChnls; j++) { pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm; diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index fb7683fa5ffd..eeea50260f1d 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -87,7 +87,10 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src) #define CIE_WATCHDOG_TH 1 #define GET_CIE_WATCHDOG(__pIeeeDev) \ (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) -#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 +static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__pIeeeDev) +{ + GET_CIE_WATCHDOG(__pIeeeDev) = 0; +} #define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) #define IS_DOT11D_STATE_DONE(__pIeeeDev) \ diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index 2cace9a4525a..4a35f9b5602d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -30,7 +30,7 @@ #include "rtl_dm.h" #include "rtl_wx.h" -extern int WDCAPARA_ADD[]; +static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; void rtl8192e_start_beacon(struct net_device *dev) { @@ -193,11 +193,12 @@ void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val) dm_init_edca_turbo(dev); - u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[pAcParam])) << + u4bAcParam = (((le16_to_cpu( + qos_parameters->tx_op_limit[pAcParam])) << AC_PARAM_TXOP_LIMIT_OFFSET) | - (((u32)(qos_parameters->cw_max[pAcParam])) << + ((le16_to_cpu(qos_parameters->cw_max[pAcParam])) << AC_PARAM_ECW_MAX_OFFSET) | - (((u32)(qos_parameters->cw_min[pAcParam])) << + ((le16_to_cpu(qos_parameters->cw_min[pAcParam])) << AC_PARAM_ECW_MIN_OFFSET) | (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); @@ -1271,7 +1272,7 @@ void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, pdesc->LastSeg = 1; pdesc->TxBufferSize = skb->len; - pdesc->TxBuffAddr = cpu_to_le32(mapping); + pdesc->TxBuffAddr = mapping; } void rtl8192_tx_fill_cmd_desc(struct net_device *dev, @@ -1301,7 +1302,7 @@ void rtl8192_tx_fill_cmd_desc(struct net_device *dev, entry_tmp->RATid = (u8)DESC_PACKET_TYPE_INIT; } entry->TxBufferSize = skb->len; - entry->TxBuffAddr = cpu_to_le32(mapping); + entry->TxBuffAddr = mapping; entry->OWN = 1; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c index fa5603a562c3..c46c65c5542f 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c @@ -28,7 +28,6 @@ #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ #include "r8192E_cmdpkt.h" -extern int hwwep; void CamResetAllEntry(struct net_device *dev) { u32 ulcommand = 0; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index d93caca9657d..c01abc23213e 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -562,8 +562,8 @@ void rtl8192_update_cap(struct net_device *dev, u16 cap) } static struct rtllib_qos_parameters def_qos_parameters = { - {3, 3, 3, 3}, - {7, 7, 7, 7}, + {cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3), cpu_to_le16(3)}, + {cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7), cpu_to_le16(7)}, {2, 2, 2, 2}, {0, 0, 0, 0}, {0, 0, 0, 0} @@ -585,8 +585,6 @@ static void rtl8192_update_beacon(void *data) rtl8192_update_cap(dev, net->capability); } -int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; - static void rtl8192_qos_activate(void *data) { struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, @@ -1845,7 +1843,7 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) struct tx_desc *entry = &ring->desc[ring->idx]; struct sk_buff *skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + pci_unmap_single(priv->pdev, entry->TxBuffAddr, skb->len, PCI_DMA_TODEVICE); kfree_skb(skb); ring->idx = (ring->idx + 1) % ring->entries; @@ -1950,7 +1948,7 @@ static void rtl8192_tx_isr(struct net_device *dev, int prio) } skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + pci_unmap_single(priv->pdev, entry->TxBuffAddr, skb->len, PCI_DMA_TODEVICE); kfree_skb(skb); @@ -2011,7 +2009,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) fwinfo_size = sizeof(struct tx_fwinfo_8190pci); header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); - fc = header->frame_ctl; + fc = le16_to_cpu(header->frame_ctl); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); pda_addr = header->addr1; @@ -2101,7 +2099,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) dev_kfree_skb_any(skb); return -1; } - entry->BufferAddress = cpu_to_le32(*mapping); + entry->BufferAddress = *mapping; entry->Length = priv->rxbuffersize; entry->OWN = 1; @@ -2137,8 +2135,8 @@ static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, for (i = 0; i < entries; i++) ring[i].NextDescAddress = - cpu_to_le32((u32)dma + ((i + 1) % entries) * - sizeof(*ring)); + (u32)dma + ((i + 1) % entries) * + sizeof(*ring); return 0; } @@ -2198,7 +2196,7 @@ void rtl8192_pci_resetdescring(struct net_device *dev) __skb_dequeue(&ring->queue); pci_unmap_single(priv->pdev, - le32_to_cpu(entry->TxBuffAddr), + entry->TxBuffAddr, skb->len, PCI_DMA_TODEVICE); kfree_skb(skb); ring->idx = (ring->idx + 1) % ring->entries; @@ -2400,7 +2398,7 @@ static void rtl8192_rx_normal(struct net_device *dev) } } done: - pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); + pdesc->BufferAddress = *((dma_addr_t *)skb->cb); pdesc->OWN = 1; pdesc->Length = priv->rxbuffersize; if (priv->rx_idx[rx_queue_idx] == priv->rxringcount-1) @@ -2692,7 +2690,7 @@ out: } -irqreturn_t rtl8192_interrupt(int irq, void *netdev) +static irqreturn_t rtl8192_interrupt(int irq, void *netdev) { struct net_device *dev = (struct net_device *) netdev; struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index b015bf61cf05..ce239be8f2f6 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -188,6 +188,8 @@ #define MAX_RX_COUNT 64 #define MAX_TX_QUEUE_COUNT 9 +extern int hwwep; + enum RTL819x_PHY_PARAM { RTL819X_PHY_MACPHY_REG = 0, RTL819X_PHY_MACPHY_REG_PG = 1, diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c index 32fbbc9d0d92..adc6cc7ca3d6 100644 --- a/drivers/staging/rtl8192e/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -115,14 +115,14 @@ static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, if (ACT_ADDBARSP == type) { RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); - tmp = cpu_to_le16(StatusCode); + tmp = StatusCode; memcpy(tag, (u8 *)&tmp, 2); tag += 2; } - tmp = cpu_to_le16(pBA->BaParamSet.shortData); + tmp = pBA->BaParamSet.shortData; memcpy(tag, (u8 *)&tmp, 2); tag += 2; - tmp = cpu_to_le16(pBA->BaTimeoutValue); + tmp = pBA->BaTimeoutValue; memcpy(tag, (u8 *)&tmp, 2); tag += 2; @@ -178,10 +178,10 @@ static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, *tag ++= ACT_CAT_BA; *tag ++= ACT_DELBA; - tmp = cpu_to_le16(DelbaParamSet.shortData); + tmp = DelbaParamSet.shortData; memcpy(tag, (u8 *)&tmp, 2); tag += 2; - tmp = cpu_to_le16(ReasonCode); + tmp = ReasonCode; memcpy(tag, (u8 *)&tmp, 2); tag += 2; diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index e51cb49ce10e..5e5c76bcdbd0 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -443,13 +443,13 @@ static struct lib80211_crypto_ops rtllib_crypt_ccmp = { }; -int __init rtllib_crypto_ccmp_init(void) +static int __init rtllib_crypto_ccmp_init(void) { return lib80211_register_crypto_ops(&rtllib_crypt_ccmp); } -void __exit rtllib_crypto_ccmp_exit(void) +static void __exit rtllib_crypto_ccmp_exit(void) { lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp); } diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index 5cfd73baf1cc..d2768986c53e 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -173,7 +173,7 @@ static inline u16 Mk16(u8 hi, u8 lo) static inline u16 Mk16_le(u16 *v) { - return le16_to_cpu(*v); + return *v; } @@ -752,13 +752,13 @@ static struct lib80211_crypto_ops rtllib_crypt_tkip = { }; -int __init rtllib_crypto_tkip_init(void) +static int __init rtllib_crypto_tkip_init(void) { return lib80211_register_crypto_ops(&rtllib_crypt_tkip); } -void __exit rtllib_crypto_tkip_exit(void) +static void __exit rtllib_crypto_tkip_exit(void) { lib80211_unregister_crypto_ops(&rtllib_crypt_tkip); } diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c index c4df6e01ef74..b0e5f1ff07ee 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c @@ -270,13 +270,13 @@ static struct lib80211_crypto_ops rtllib_crypt_wep = { }; -int __init rtllib_crypto_wep_init(void) +static int __init rtllib_crypto_wep_init(void) { return lib80211_register_crypto_ops(&rtllib_crypt_wep); } -void __exit rtllib_crypto_wep_exit(void) +static void __exit rtllib_crypto_wep_exit(void) { lib80211_unregister_crypto_ops(&rtllib_crypt_wep); } diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c index 51d46e04d3f5..136909eff6d5 100644 --- a/drivers/staging/rtl8192e/rtllib_module.c +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -237,7 +237,7 @@ static const struct file_operations fops = { .release = single_release, }; -int __init rtllib_init(void) +static int __init rtllib_init(void) { struct proc_dir_entry *e; @@ -257,7 +257,7 @@ int __init rtllib_init(void) return 0; } -void __exit rtllib_exit(void) +static void __exit rtllib_exit(void) { if (rtllib_proc) { remove_proc_entry("debug_level", rtllib_proc); diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 1a011b9b9da6..1fab69d313ba 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -490,7 +490,7 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx } else { u16 len; /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); + len = sub_skb->len; memcpy(skb_push(sub_skb, 2), &len, 2); memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); @@ -1224,7 +1224,7 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, } else { u16 len; /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); + len = sub_skb->len; memcpy(skb_push(sub_skb, 2), &len, 2); memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); @@ -1632,13 +1632,13 @@ static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci]; - qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F; + qos_param->cw_min[aci] = cpu_to_le16(ac_params->ecw_min_max & 0x0F); - qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4; + qos_param->cw_max[aci] = cpu_to_le16((ac_params->ecw_min_max & 0xF0) >> 4); qos_param->flag[aci] = (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; - qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit); + qos_param->tx_op_limit[aci] = ac_params->tx_op_limit; } return rc; } @@ -2260,9 +2260,9 @@ static inline int rtllib_network_init( memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); network->capability = le16_to_cpu(beacon->capability); network->last_scanned = jiffies; - network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); - network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); - network->beacon_interval = le32_to_cpu(beacon->beacon_interval); + network->time_stamp[0] = beacon->time_stamp[0]; + network->time_stamp[1] = beacon->time_stamp[1]; + network->beacon_interval = le16_to_cpu(beacon->beacon_interval); /* Where to pull this? beacon->listen_interval;*/ network->listen_interval = 0x0A; network->rates_len = network->rates_ex_len = 0; @@ -2528,29 +2528,30 @@ static inline void rtllib_process_probe_response( "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), beacon->header.addr3, - (beacon->capability & (1<<0xf)) ? '1' : '0', - (beacon->capability & (1<<0xe)) ? '1' : '0', - (beacon->capability & (1<<0xd)) ? '1' : '0', - (beacon->capability & (1<<0xc)) ? '1' : '0', - (beacon->capability & (1<<0xb)) ? '1' : '0', - (beacon->capability & (1<<0xa)) ? '1' : '0', - (beacon->capability & (1<<0x9)) ? '1' : '0', - (beacon->capability & (1<<0x8)) ? '1' : '0', - (beacon->capability & (1<<0x7)) ? '1' : '0', - (beacon->capability & (1<<0x6)) ? '1' : '0', - (beacon->capability & (1<<0x5)) ? '1' : '0', - (beacon->capability & (1<<0x4)) ? '1' : '0', - (beacon->capability & (1<<0x3)) ? '1' : '0', - (beacon->capability & (1<<0x2)) ? '1' : '0', - (beacon->capability & (1<<0x1)) ? '1' : '0', - (beacon->capability & (1<<0x0)) ? '1' : '0'); + (le16_to_cpu(beacon->capability) & (1<<0xf)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xe)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xd)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xc)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xb)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0xa)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x9)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x8)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x7)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x6)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x5)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x4)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x3)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x2)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x1)) ? '1' : '0', + (le16_to_cpu(beacon->capability) & (1<<0x0)) ? '1' : '0'); if (rtllib_network_init(ieee, beacon, network, stats)) { RTLLIB_DEBUG_SCAN("Dropped '%s' ( %pM) via %s.\n", escape_essid(info_element->data, info_element->len), beacon->header.addr3, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + WLAN_FC_GET_STYPE( + le16_to_cpu(beacon->header.frame_ctl)) == RTLLIB_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); goto free_network; @@ -2560,7 +2561,7 @@ static inline void rtllib_process_probe_response( if (!rtllib_legal_channel(ieee, network->channel)) goto free_network; - if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) == RTLLIB_STYPE_PROBE_RESP) { if (IsPassiveChannel(ieee, network->channel)) { printk(KERN_INFO "GetScanInfo(): For Global Domain, " @@ -2629,7 +2630,8 @@ static inline void rtllib_process_probe_response( RTLLIB_DEBUG_SCAN("Adding '%s' ( %pM) via %s.\n", escape_essid(network->ssid, network->ssid_len), network->bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + WLAN_FC_GET_STYPE( + le16_to_cpu(beacon->header.frame_ctl)) == RTLLIB_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); memcpy(target, network, sizeof(*target)); @@ -2640,7 +2642,8 @@ static inline void rtllib_process_probe_response( RTLLIB_DEBUG_SCAN("Updating '%s' ( %pM) via %s.\n", escape_essid(target->ssid, target->ssid_len), target->bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + WLAN_FC_GET_STYPE( + le16_to_cpu(beacon->header.frame_ctl)) == RTLLIB_STYPE_PROBE_RESP ? "PROBE RESPONSE" : "BEACON"); @@ -2682,15 +2685,17 @@ void rtllib_rx_mgt(struct rtllib_device *ieee, { struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ; - if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP && - WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON) + if ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) != + RTLLIB_STYPE_PROBE_RESP) && + (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) != + RTLLIB_STYPE_BEACON)) ieee->last_rx_ps_time = jiffies; - switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) { case RTLLIB_STYPE_BEACON: RTLLIB_DEBUG_MGMT("received BEACON (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); + WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); RTLLIB_DEBUG_SCAN("Beacon\n"); rtllib_process_probe_response( ieee, (struct rtllib_probe_response *)header, @@ -2705,14 +2710,15 @@ void rtllib_rx_mgt(struct rtllib_device *ieee, case RTLLIB_STYPE_PROBE_RESP: RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); + WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))); RTLLIB_DEBUG_SCAN("Probe response\n"); rtllib_process_probe_response(ieee, (struct rtllib_probe_response *)header, stats); break; case RTLLIB_STYPE_PROBE_REQ: RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); + WLAN_FC_GET_STYPE( + le16_to_cpu(header->frame_ctl))); RTLLIB_DEBUG_SCAN("Probe request\n"); if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && ((ieee->iw_mode == IW_MODE_ADHOC || diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 933bd6deaca1..eeec19cde229 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -227,7 +227,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) /* called with 2nd param 0, no mgmt lock required */ rtllib_sta_wakeup(ieee, 0); - if (header->frame_ctl == RTLLIB_STYPE_BEACON) + if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON) tcb_desc->queue_index = BEACON_QUEUE; else tcb_desc->queue_index = MGNT_QUEUE; @@ -295,7 +295,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, u16 fc, type, stype; struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); - fc = header->frame_ctl; + fc = le16_to_cpu(header->frame_ctl); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); @@ -807,18 +807,18 @@ inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon, auth = (struct rtllib_authentication *) skb_put(skb, sizeof(struct rtllib_authentication)); - auth->header.frame_ctl = RTLLIB_STYPE_AUTH; + auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH); if (challengelen) - auth->header.frame_ctl |= RTLLIB_FCTL_WEP; + auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP); - auth->header.duration_id = 0x013a; + auth->header.duration_id = cpu_to_le16(0x013a); memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); if (ieee->auth_mode == 0) auth->algorithm = WLAN_AUTH_OPEN; else if (ieee->auth_mode == 1) - auth->algorithm = WLAN_AUTH_SHARED_KEY; + auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY); else if (ieee->auth_mode == 2) auth->algorithm = WLAN_AUTH_OPEN; auth->transaction = cpu_to_le16(ieee->associate_seq); @@ -921,8 +921,8 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest) if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) - cpu_to_le16((beacon_buf->capability |= - WLAN_CAPABILITY_SHORT_SLOT_TIME)); + beacon_buf->capability |= + cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; if (encrypt) @@ -952,7 +952,7 @@ static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest) u16 val16; *(tag++) = MFIE_TYPE_IBSS_SET; *(tag++) = 2; - val16 = cpu_to_le16(ieee->current_network.atim_window); + val16 = ieee->current_network.atim_window; memcpy((u8 *)tag, (u8 *)&val16, 2); tag += 2; } @@ -1260,7 +1260,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, hdr->header.frame_ctl = RTLLIB_STYPE_ASSOC_REQ; - hdr->header.duration_id = 37; + hdr->header.duration_id = cpu_to_le16(37); memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); @@ -1279,7 +1279,7 @@ inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); - hdr->listen_interval = beacon->listen_interval; + hdr->listen_interval = cpu_to_le16(beacon->listen_interval); hdr->info_element[0].id = MFIE_TYPE_SSID; @@ -3633,7 +3633,7 @@ out: } EXPORT_SYMBOL(rtllib_wpa_supplicant_ioctl); -void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) +static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) { u8 OpMode; u8 i; @@ -3658,7 +3658,7 @@ void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) } -void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, +static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, u8 asRsn) { u8 i; @@ -3684,7 +3684,7 @@ void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, } -void +static void rtllib_MgntDisconnectAP( struct rtllib_device *rtllib, u8 asRsn diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 3183627823fb..77964885b3f2 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto) snap->oui[1] = oui[1]; snap->oui[2] = oui[2]; - *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + *(u16 *)(data + SNAP_SIZE) = h_proto; return SNAP_SIZE + sizeof(u16); } @@ -231,7 +231,7 @@ static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size, memset(txb, 0, sizeof(struct rtllib_txb)); txb->nr_frags = nr_frags; - txb->frag_size = txb_size; + txb->frag_size = cpu_to_le16(txb_size); for (i = 0; i < nr_frags; i++) { txb->fragments[i] = dev_alloc_skb(txb_size); @@ -610,7 +610,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } txb->encrypted = 0; - txb->payload_size = skb->len; + txb->payload_size = cpu_to_le16(skb->len); memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len); @@ -764,7 +764,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) goto failed; } txb->encrypted = encrypt; - txb->payload_size = bytes; + txb->payload_size = cpu_to_le16(bytes); if (qos_actived) txb->queue_index = UP2AC(skb->priority); @@ -812,10 +812,10 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } if ((qos_actived) && (!bIsMulticast)) { frag_hdr->seq_ctl = - rtllib_query_seqnum(ieee, skb_frag, - header.addr1); + cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, + header.addr1)); frag_hdr->seq_ctl = - cpu_to_le16(frag_hdr->seq_ctl<<4 | i); + cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i); } else { frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); @@ -870,7 +870,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } txb->encrypted = 0; - txb->payload_size = skb->len; + txb->payload_size = cpu_to_le16(skb->len); memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len); } diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 8fa0f9d49a8a..3ea99aea4385 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -1043,9 +1043,6 @@ void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) struct sta_priv *pstapriv = &adapter->stapriv; struct recv_reorder_ctrl *precvreorder_ctrl = NULL; - netdev_info(adapter->pnetdev, "%s: mac = %pM, seq = %d, tid = %d\n", - __func__, pAddbareq_pram->MacAddress, - pAddbareq_pram->StartSeqNum, pAddbareq_pram->tid); psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress); if (psta) { precvreorder_ctrl = diff --git a/drivers/staging/rts5208/Kconfig b/drivers/staging/rts5208/Kconfig new file mode 100644 index 000000000000..055655cecaf7 --- /dev/null +++ b/drivers/staging/rts5208/Kconfig @@ -0,0 +1,15 @@ +config RTS5208 + tristate "Realtek PCI-E Card Reader RTS5208/5288 support" + depends on PCI && SCSI + help + Say Y here to include driver code to support the Realtek + PCI-E card reader rts5208/rts5288. + + If this driver is compiled as a module, it will be named rts5208. + +config RTS5208_DEBUG + bool "Realtek PCI-E Card Reader RTS5208/5288 verbose debug" + depends on RTS5208 + help + Say Y here in order to have the rts5208 code generate + verbose debugging messages. diff --git a/drivers/staging/rts5208/Makefile b/drivers/staging/rts5208/Makefile new file mode 100644 index 000000000000..17b4471c4d6d --- /dev/null +++ b/drivers/staging/rts5208/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_RTS5208) := rts5208.o + +ccflags-y := -Idrivers/scsi + +rts5208-y := rtsx.o rtsx_chip.o rtsx_transport.o rtsx_scsi.o \ + rtsx_card.o general.o sd.o xd.o ms.o spi.o diff --git a/drivers/staging/rts5208/TODO b/drivers/staging/rts5208/TODO new file mode 100644 index 000000000000..57bcf5834c0c --- /dev/null +++ b/drivers/staging/rts5208/TODO @@ -0,0 +1,7 @@ +TODO: +- use kernel coding style +- checkpatch.pl fixes +- We will use the stack in drivers/mmc to implement + rts5208/5288 in the future + +Micky Ching <micky_ching@realsil.com.cn>
\ No newline at end of file diff --git a/drivers/staging/rts5208/debug.h b/drivers/staging/rts5208/debug.h new file mode 100644 index 000000000000..5ba8a3a0fbdc --- /dev/null +++ b/drivers/staging/rts5208/debug.h @@ -0,0 +1,43 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_DEBUG_H +#define __REALTEK_RTSX_DEBUG_H + +#include <linux/kernel.h> + +#define RTSX_STOR "rts5208: " + +#ifdef CONFIG_RTS5208_DEBUG +#define RTSX_DEBUGP(x...) pr_debug(RTSX_STOR x) +#define RTSX_DEBUGPN(x...) pr_debug(x) +#define RTSX_DEBUGPX(x...) printk(x) +#define RTSX_DEBUG(x) x +#else +#define RTSX_DEBUGP(x...) +#define RTSX_DEBUGPN(x...) +#define RTSX_DEBUGPX(x...) +#define RTSX_DEBUG(x) +#endif + +#endif /* __REALTEK_RTSX_DEBUG_H */ diff --git a/drivers/staging/rts5208/general.c b/drivers/staging/rts5208/general.c new file mode 100644 index 000000000000..eada934288b2 --- /dev/null +++ b/drivers/staging/rts5208/general.c @@ -0,0 +1,35 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include "general.h" + +int bit1cnt_long(u32 data) +{ + int i, cnt = 0; + for (i = 0; i < 32; i++) { + if (data & 0x01) + cnt++; + data >>= 1; + } + return cnt; +} + diff --git a/drivers/staging/rts5208/general.h b/drivers/staging/rts5208/general.h new file mode 100644 index 000000000000..90a1f9297f5e --- /dev/null +++ b/drivers/staging/rts5208/general.h @@ -0,0 +1,31 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __RTSX_GENERAL_H +#define __RTSX_GENERAL_H + +#include "rtsx.h" + +int bit1cnt_long(u32 data); + +#endif /* __RTSX_GENERAL_H */ diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c new file mode 100644 index 000000000000..edf979f18a6c --- /dev/null +++ b/drivers/staging/rts5208/ms.c @@ -0,0 +1,4208 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/vmalloc.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "ms.h" + +static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + ms_card->err_code = err_code; +} + +static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + return (ms_card->err_code == err_code); +} + +static int ms_parse_err_code(struct rtsx_chip *chip) +{ + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, + u8 tpc, u8 cnt, u8 cfg) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 *ptr; + + RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, + 0xFF, MS_TRANSFER_START | trans_mode); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + rtsx_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + if (!(tpc & 0x08)) { /* Read Packet */ + if (*ptr & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { /* Write Packet */ + if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) { + if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } + } + + if (*ptr & MS_RDY_TIMEOUT) { + rtsx_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, + u8 tpc, u16 sec_cnt, u8 cfg, int mode_2k, + int use_sg, void *buf, int buf_len) +{ + int retval; + u8 val, err_code = 0; + enum dma_data_direction dir; + + if (!buf || !buf_len) + TRACE_RET(chip, STATUS_FAIL); + + if (trans_mode == MS_TM_AUTO_READ) { + dir = DMA_FROM_DEVICE; + err_code = MS_FLASH_READ_ERROR; + } else if (trans_mode == MS_TM_AUTO_WRITE) { + dir = DMA_TO_DEVICE; + err_code = MS_FLASH_WRITE_ERROR; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + + if (mode_2k) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); + } + + trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); + rtsx_add_cmd(chip, CHECK_REG_CMD, + MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len, + use_sg, dir, chip->mspro_timeout); + if (retval < 0) { + ms_set_err_code(chip, err_code); + if (retval == -ETIMEDOUT) + retval = STATUS_TIMEDOUT; + else + retval = STATUS_FAIL; + + TRACE_RET(chip, retval); + } + + RTSX_READ_REG(chip, MS_TRANS_CFG, &val); + if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_write_bytes(struct rtsx_chip *chip, + u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + if (!data || (data_len < cnt)) + TRACE_RET(chip, STATUS_ERROR); + + rtsx_init_cmd(chip); + + for (i = 0; i < cnt; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, data[i]); + } + if (cnt % 2) + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); + rtsx_add_cmd(chip, CHECK_REG_CMD, + MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + u8 val = 0; + + rtsx_read_register(chip, MS_TRANS_CFG, &val); + RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); + + rtsx_clear_ms_error(chip); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, + ms_parse_err_code(chip)); + } + } + } + + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +static int ms_read_bytes(struct rtsx_chip *chip, + u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 *ptr; + + if (!data) + TRACE_RET(chip, STATUS_ERROR); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_READ_BYTES); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + for (i = 0; i < data_len - 1; i++) + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); + + if (data_len % 2) + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); + else + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, + 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + u8 val = 0; + + rtsx_read_register(chip, MS_TRANS_CFG, &val); + rtsx_clear_ms_error(chip); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, + ms_parse_err_code(chip)); + } + } + } + + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + for (i = 0; i < data_len; i++) + data[i] = ptr[i]; + + if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) { + RTSX_DEBUGP("Read format progress:\n"); + RTSX_DUMP(ptr, cnt); + } + + return STATUS_SUCCESS; +} + +static int ms_set_rw_reg_addr(struct rtsx_chip *chip, + u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt) +{ + int retval, i; + u8 data[4]; + + data[0] = read_start; + data[1] = read_cnt; + data[2] = write_start; + data[3] = write_cnt; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4, + NO_WAIT_INT, data, 4); + if (retval == STATUS_SUCCESS) + return STATUS_SUCCESS; + rtsx_clear_ms_error(chip); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg) +{ + u8 data[2]; + + data[0] = cmd; + data[1] = 0; + + return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); +} + +static int ms_set_init_para(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_HG8BIT(ms_card)) { + if (chip->asic_code) + ms_card->ms_clock = chip->asic_ms_hg_clk; + else + ms_card->ms_clock = chip->fpga_ms_hg_clk; + + } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { + if (chip->asic_code) + ms_card->ms_clock = chip->asic_ms_4bit_clk; + else + ms_card->ms_clock = chip->fpga_ms_4bit_clk; + + } else { + if (chip->asic_code) + ms_card->ms_clock = chip->asic_ms_1bit_clk; + else + ms_card->ms_clock = chip->fpga_ms_1bit_clk; + } + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_switch_clock(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + MS_D1_PD | MS_D2_PD | MS_CLK_PD | MS_D6_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + MS_D3_PD | MS_D0_PD | MS_BS_PD | XD_D4_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +static int ms_pull_ctl_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL2, 0xFF, 0x45); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL3, 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL4, 0xFF, 0x29); + } + } + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_prepare_reset(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 oc_mask = 0; + + ms_card->ms_type = 0; + ms_card->check_ms_flow = 0; + ms_card->switch_8bit_fail = 0; + ms_card->delay_write.delay_write_flag = 0; + + ms_card->pro_under_formatting = 0; + + retval = ms_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->ft2_fast_mode) + wait_timeout(250); + + retval = enable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->asic_code) { + retval = ms_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_MS_PULL_CTL_BIT | 0x20, 0); + } + + if (!chip->ft2_fast_mode) { + retval = card_power_on(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(150); + +#ifdef SUPPORT_OCP + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + oc_mask = MS_OC_NOW | MS_OC_EVER; + else + oc_mask = SD_OC_NOW | SD_OC_EVER; + + if (chip->ocp_stat & oc_mask) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN); + + if (chip->asic_code) { + RTSX_WRITE_REG(chip, MS_CFG, 0xFF, + SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + } else { + RTSX_WRITE_REG(chip, MS_CFG, 0xFF, + SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + } + RTSX_WRITE_REG(chip, MS_TRANS_CFG, + 0xFF, NO_WAIT_INT | NO_AUTO_READ_INT_REG); + RTSX_WRITE_REG(chip, CARD_STOP, + MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val; + + retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, + 6, NO_WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val); + RTSX_DEBUGP("Type register: 0x%x\n", val); + if (val != 0x01) { + if (val != 0x02) + ms_card->check_ms_flow = 1; + + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val); + RTSX_DEBUGP("Category register: 0x%x\n", val); + if (val != 0) { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val); + RTSX_DEBUGP("Class register: 0x%x\n", val); + if (val == 0) { + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) + chip->card_wp |= MS_CARD; + else + chip->card_wp &= ~MS_CARD; + + } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { + chip->card_wp |= MS_CARD; + } else { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->ms_type |= TYPE_MSPRO; + + RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val); + RTSX_DEBUGP("IF Mode register: 0x%x\n", val); + if (val == 0) { + ms_card->ms_type &= 0x0F; + } else if (val == 7) { + if (switch_8bit_bus) + ms_card->ms_type |= MS_HG; + else + ms_card->ms_type &= 0x0F; + + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_confirm_cpu_startup(struct rtsx_chip *chip) +{ + int retval, i, k; + u8 val; + + /* Confirm CPU StartUp */ + k = 0; + do { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_read_bytes(chip, GET_INT, 1, + NO_WAIT_INT, &val, 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (k > 100) + TRACE_RET(chip, STATUS_FAIL); + + k++; + wait_timeout(100); + } while (!(val & INT_REG_CED)); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_ERR) { + if (val & INT_REG_CMDNK) + chip->card_wp |= (MS_CARD); + else + TRACE_RET(chip, STATUS_FAIL); + } + /* -- end confirm CPU startup */ + + return STATUS_SUCCESS; +} + +static int ms_switch_parallel_bus(struct rtsx_chip *chip) +{ + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_4BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, + data, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_switch_8bit_bus(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_8BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 1, + NO_WAIT_INT, data, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, MS_CFG, 0x98, + MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); + ms_card->ms_type |= MS_8BIT; + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, + 1, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + for (i = 0; i < 3; i++) { + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_identify_media_type(chip, switch_8bit_bus); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_confirm_cpu_startup(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_switch_parallel_bus(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + continue; + } else { + break; + } + } + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* Switch MS-PRO into Parallel mode */ + RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); + RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* If MSPro HG Card, We shall try to switch to 8-bit bus */ + if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { + retval = ms_switch_8bit_bus(chip); + if (retval != STATUS_SUCCESS) { + ms_card->switch_8bit_fail = 1; + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +#ifdef XC_POWERCLASS +static int msxc_change_power(struct rtsx_chip *chip, u8 mode) +{ + int retval; + u8 buf[6]; + + ms_cleanup_work(chip); + + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf[0] = 0; + buf[1] = mode; + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = 0; + + retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, MS_TRANS_CFG, buf); + if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} +#endif + +static int ms_read_attribute_info(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, *buf, class_code, device_type, sub_class, data[16]; + u16 total_blk = 0, blk_size = 0; +#ifdef SUPPORT_MSXC + u32 xc_total_blk = 0, xc_blk_size = 0; +#endif + u32 sys_info_addr = 0, sys_info_size; +#ifdef SUPPORT_PCGL_1P18 + u32 model_name_addr = 0, model_name_size; + int found_sys_info = 0, found_model_name = 0; +#endif + + retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS8BIT(ms_card)) + data[0] = PARALLEL_8BIT_IF; + else + data[0] = PARALLEL_4BIT_IF; + + data[1] = 0; + + data[2] = 0x40; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, + data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf = kmalloc(64 * 512, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, STATUS_ERROR); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); + if (retval != STATUS_SUCCESS) + continue; + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & MS_INT_BREQ)) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, + PRO_READ_LONG_DATA, 0x40, WAIT_INT, + 0, 0, buf, 64 * 512); + if (retval == STATUS_SUCCESS) + break; + else + rtsx_clear_ms_error(chip); + } + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + i = 0; + do { + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) + break; + + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, + PRO_READ_LONG_DATA, 0, WAIT_INT); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + i++; + } while (i < 1024); + + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { + /* Signature code is wrong */ + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[4] < 1) || (buf[4] > 12)) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < buf[4]; i++) { + int cur_addr_off = 16 + i * 12; + +#ifdef SUPPORT_MSXC + if ((buf[cur_addr_off + 8] == 0x10) || + (buf[cur_addr_off + 8] == 0x13)) +#else + if (buf[cur_addr_off + 8] == 0x10) +#endif + { + sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) | + ((u32)buf[cur_addr_off + 1] << 16) | + ((u32)buf[cur_addr_off + 2] << 8) | + buf[cur_addr_off + 3]; + sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) | + ((u32)buf[cur_addr_off + 5] << 16) | + ((u32)buf[cur_addr_off + 6] << 8) | + buf[cur_addr_off + 7]; + RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n", + sys_info_addr, sys_info_size); + if (sys_info_size != 96) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (sys_info_addr < 0x1A0) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((sys_info_size + sys_info_addr) > 0x8000) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_MSXC + if (buf[cur_addr_off + 8] == 0x13) + ms_card->ms_type |= MS_XC; +#endif +#ifdef SUPPORT_PCGL_1P18 + found_sys_info = 1; +#else + break; +#endif + } +#ifdef SUPPORT_PCGL_1P18 + if (buf[cur_addr_off + 8] == 0x15) { + model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) | + ((u32)buf[cur_addr_off + 1] << 16) | + ((u32)buf[cur_addr_off + 2] << 8) | + buf[cur_addr_off + 3]; + model_name_size = ((u32)buf[cur_addr_off + 4] << 24) | + ((u32)buf[cur_addr_off + 5] << 16) | + ((u32)buf[cur_addr_off + 6] << 8) | + buf[cur_addr_off + 7]; + RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n", + model_name_addr, model_name_size); + if (model_name_size != 48) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (model_name_addr < 0x1A0) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((model_name_size + model_name_addr) > 0x8000) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + found_model_name = 1; + } + + if (found_sys_info && found_model_name) + break; +#endif + } + + if (i == buf[4]) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + class_code = buf[sys_info_addr + 0]; + device_type = buf[sys_info_addr + 56]; + sub_class = buf[sys_info_addr + 46]; +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) | + ((u32)buf[sys_info_addr + 7] << 16) | + ((u32)buf[sys_info_addr + 8] << 8) | + buf[sys_info_addr + 9]; + xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) | + ((u32)buf[sys_info_addr + 33] << 16) | + ((u32)buf[sys_info_addr + 34] << 8) | + buf[sys_info_addr + 35]; + RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", + xc_total_blk, xc_blk_size); + } else { + total_blk = ((u16)buf[sys_info_addr + 6] << 8) | + buf[sys_info_addr + 7]; + blk_size = ((u16)buf[sys_info_addr + 2] << 8) | + buf[sys_info_addr + 3]; + RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", + total_blk, blk_size); + } +#else + total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; + blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; + RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size); +#endif + + RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n", + class_code, device_type, sub_class); + + memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); +#ifdef SUPPORT_PCGL_1P18 + memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); +#endif + + kfree(buf); + +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + if (class_code != 0x03) + TRACE_RET(chip, STATUS_FAIL); + } else { + if (class_code != 0x02) + TRACE_RET(chip, STATUS_FAIL); + } +#else + if (class_code != 0x02) + TRACE_RET(chip, STATUS_FAIL); +#endif + + if (device_type != 0x00) { + if ((device_type == 0x01) || (device_type == 0x02) || + (device_type == 0x03)) { + chip->card_wp |= MS_CARD; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (sub_class & 0xC0) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", + class_code, device_type, sub_class); + +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + chip->capacity[chip->card2lun[MS_CARD]] = + ms_card->capacity = xc_total_blk * xc_blk_size; + } else { + chip->capacity[chip->card2lun[MS_CARD]] = + ms_card->capacity = total_blk * blk_size; + } +#else + ms_card->capacity = total_blk * blk_size; + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; +#endif + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_MAGIC_GATE +static int mg_set_tpc_para_sub(struct rtsx_chip *chip, + int type, u8 mg_entry_num); +#endif + +static int reset_ms_pro(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; +#ifdef XC_POWERCLASS + u8 change_power_class; + + if (chip->ms_power_class_en & 0x02) + change_power_class = 2; + else if (chip->ms_power_class_en & 0x01) + change_power_class = 1; + else + change_power_class = 0; +#endif + +#ifdef XC_POWERCLASS +Retry: +#endif + retval = ms_pro_reset_flow(chip, 1); + if (retval != STATUS_SUCCESS) { + if (ms_card->switch_8bit_fail) { + retval = ms_pro_reset_flow(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_attribute_info(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + +#ifdef XC_POWERCLASS + if (CHK_HG8BIT(ms_card)) + change_power_class = 0; + + if (change_power_class && CHK_MSXC(ms_card)) { + u8 power_class_en = chip->ms_power_class_en; + + RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en); + RTSX_DEBUGP("change_power_class = %d\n", change_power_class); + + if (change_power_class) + power_class_en &= (1 << (change_power_class - 1)); + else + power_class_en = 0; + + if (power_class_en) { + u8 power_class_mode = + (ms_card->raw_sys_info[46] & 0x18) >> 3; + RTSX_DEBUGP("power_class_mode = 0x%x", + power_class_mode); + if (change_power_class > power_class_mode) + change_power_class = power_class_mode; + if (change_power_class) { + retval = msxc_change_power(chip, + change_power_class); + if (retval != STATUS_SUCCESS) { + change_power_class--; + goto Retry; + } + } + } + } +#endif + +#ifdef SUPPORT_MAGIC_GATE + retval = mg_set_tpc_para_sub(chip, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); +#endif + + if (CHK_HG8BIT(ms_card)) + chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; + else + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + + return STATUS_SUCCESS; +} + +static int ms_read_status_reg(struct rtsx_chip *chip) +{ + int retval; + u8 val[2]; + + retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +static int ms_read_extra_data(struct rtsx_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, data[10]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x40; + data[5] = page_num; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, + data, 6); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, + data, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (buf && buf_len) { + if (buf_len > MS_EXTRA_SIZE) + buf_len = MS_EXTRA_SIZE; + memcpy(buf, data, buf_len); + } + + return STATUS_SUCCESS; +} + +static int ms_write_extra_data(struct rtsx_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, data[16]; + + if (!buf || (buf_len < MS_EXTRA_SIZE)) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6 + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x40; + data[5] = page_num; + + for (i = 6; i < MS_EXTRA_SIZE + 6; i++) + data[i] = buf[i - 6]; + + retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), + NO_WAIT_INT, data, 16); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val, data[6]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x20; + data[5] = page_num; + + retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, + 0, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + + +static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val, data[8], extra[MS_EXTRA_SIZE]; + + retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = extra[0] & 0x7F; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i = 0; + u8 val, data[6]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0; + data[5] = 0; + + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + +ERASE_RTY: + retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + if (i < 3) { + i++; + goto ERASE_RTY; + } + + ms_set_err_code(chip, MS_CMD_NK); + ms_set_bad_block(chip, phy_blk); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) +{ + if (!extra || (extra_len < MS_EXTRA_SIZE)) + return; + + memset(extra, 0xFF, MS_EXTRA_SIZE); + + if (type == setPS_NG) { + /* set page status as 1:NG,and block status keep 1:OK */ + extra[0] = 0xB8; + } else { + /* set page status as 0:Data Error,and block status keep 1:OK */ + extra[0] = 0x98; + } + + extra[2] = (u8)(log_blk >> 8); + extra[3] = (u8)log_blk; +} + +static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, + u8 start_page, u8 end_page) +{ + int retval; + u8 extra[MS_EXTRA_SIZE], i; + + memset(extra, 0xff, MS_EXTRA_SIZE); + + extra[0] = 0xf8; /* Block, page OK, data erased */ + extra[1] = 0xff; + extra[2] = (u8)(log_blk >> 8); + extra[3] = (u8)log_blk; + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_write_extra_data(chip, phy_blk, i, + extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page, u8 end_page) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, rty_cnt, uncorrect_flag = 0; + u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; + + RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n", + old_blk, new_blk, log_blk); + RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page); + + retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + + if (val & BUF_FULL) { + retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x20; + data[5] = i; + + retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, + data, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + uncorrect_flag = 1; + RTSX_DEBUGP("Uncorrectable error\n"); + } else { + uncorrect_flag = 0; + } + + retval = ms_transfer_tpc(chip, + MS_TM_NORMAL_READ, + READ_PAGE_DATA, + 0, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (uncorrect_flag) { + ms_set_page_status(log_blk, setPS_NG, + extra, MS_EXTRA_SIZE); + if (i == 0) + extra[0] &= 0xEF; + + ms_write_extra_data(chip, old_blk, i, + extra, MS_EXTRA_SIZE); + RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]); + MS_SET_BAD_BLOCK_FLG(ms_card); + + ms_set_page_status(log_blk, setPS_Error, + extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, new_blk, i, + extra, MS_EXTRA_SIZE); + continue; + } + + for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; + rty_cnt++) { + retval = ms_transfer_tpc( + chip, + MS_TM_NORMAL_WRITE, + WRITE_PAGE_DATA, + 0, NO_WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (rty_cnt == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE)); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(new_blk >> 8); + data[3] = (u8)new_blk; + data[4] = 0x20; + data[5] = i; + + if ((extra[0] & 0x60) != 0x60) + data[6] = extra[0]; + else + data[6] = 0xF8; + + data[6 + 1] = 0xFF; + data[6 + 2] = (u8)(log_blk >> 8); + data[6 + 3] = (u8)log_blk; + + for (j = 4; j <= MS_EXTRA_SIZE; j++) + data[6 + j] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), + NO_WAIT_INT, data, 16); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (i == 0) { + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, 7, + NO_WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, + NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, + MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + return STATUS_SUCCESS; +} + + +static int reset_ms(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u16 i, reg_addr, block_size; + u8 val, extra[MS_EXTRA_SIZE], j, *ptr; +#ifndef SUPPORT_MAGIC_GATE + u16 eblock_cnt; +#endif + + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_card->ms_type |= TYPE_MS; + + retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) + chip->card_wp |= MS_CARD; + else + chip->card_wp &= ~MS_CARD; + + i = 0; + +RE_SEARCH: + /* Search Boot Block */ + while (i < (MAX_DEFECTIVE_BLOCK + 2)) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + i++; + continue; + } + + if (extra[0] & BLOCK_OK) { + if (!(extra[1] & NOT_BOOT_BLOCK)) { + ms_card->boot_block = i; + break; + } + } + i++; + } + + if (i == (MAX_DEFECTIVE_BLOCK + 2)) { + RTSX_DEBUGP("No boot block found!"); + TRACE_RET(chip, STATUS_FAIL); + } + + for (j = 0; j < 3; j++) { + retval = ms_read_page(chip, ms_card->boot_block, j); + if (retval != STATUS_SUCCESS) { + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { + i = ms_card->boot_block + 1; + ms_set_err_code(chip, MS_NO_ERROR); + goto RE_SEARCH; + } + } + } + + retval = ms_read_page(chip, ms_card->boot_block, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* Read MS system information as sys_info */ + rtsx_init_cmd(chip); + + for (i = 0; i < 96; i++) + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + ptr = rtsx_get_cmd_data(chip); + memcpy(ms_card->raw_sys_info, ptr, 96); + + /* Read useful block contents */ + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); + + for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + ptr = rtsx_get_cmd_data(chip); + + RTSX_DEBUGP("Boot block data:\n"); + RTSX_DUMP(ptr, 16); + + /* Block ID error + * HEADER_ID0, HEADER_ID1 + */ + if (ptr[0] != 0x00 || ptr[1] != 0x01) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + + /* Page size error + * PAGE_SIZE_0, PAGE_SIZE_1 + */ + if (ptr[12] != 0x02 || ptr[13] != 0x00) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + + if ((ptr[14] == 1) || (ptr[14] == 3)) + chip->card_wp |= MS_CARD; + + /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ + block_size = ((u16)ptr[6] << 8) | ptr[7]; + if (block_size == 0x0010) { + /* Block size 16KB */ + ms_card->block_shift = 5; + ms_card->page_off = 0x1F; + } else if (block_size == 0x0008) { + /* Block size 8KB */ + ms_card->block_shift = 4; + ms_card->page_off = 0x0F; + } + + /* BLOCK_COUNT_0, BLOCK_COUNT_1 */ + ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9]; + +#ifdef SUPPORT_MAGIC_GATE + j = ptr[10]; + + if (ms_card->block_shift == 4) { /* 4MB or 8MB */ + if (j < 2) { /* Effective block for 4MB: 0x1F0 */ + ms_card->capacity = 0x1EE0; + } else { /* Effective block for 8MB: 0x3E0 */ + ms_card->capacity = 0x3DE0; + } + } else { /* 16MB, 32MB, 64MB or 128MB */ + if (j < 5) { /* Effective block for 16MB: 0x3E0 */ + ms_card->capacity = 0x7BC0; + } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */ + ms_card->capacity = 0xF7C0; + } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */ + ms_card->capacity = 0x1EF80; + } else { /* Effective block for 128MB: 0x1F00 */ + ms_card->capacity = 0x3DF00; + } + } +#else + /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */ + eblock_cnt = ((u16)ptr[10] << 8) | ptr[11]; + + ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift; +#endif + + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; + + /* Switch I/F Mode */ + if (ptr[15]) { + retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); + RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); + + retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, + MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT); + + ms_card->ms_type |= MS_4BIT; + } + + if (CHK_MS4BIT(ms_card)) + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + else + chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; + + return STATUS_SUCCESS; +} + +static int ms_init_l2p_tbl(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int size, i, seg_no, retval; + u16 defect_block, reg_addr; + u8 val1, val2; + + ms_card->segment_cnt = ms_card->total_block >> 9; + RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); + + size = ms_card->segment_cnt * sizeof(struct zone_entry); + ms_card->segment = vzalloc(size); + if (ms_card->segment == NULL) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_page(chip, ms_card->boot_block, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + + reg_addr = PPBUF_BASE2; + for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { + retval = rtsx_read_register(chip, reg_addr++, &val1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + + retval = rtsx_read_register(chip, reg_addr++, &val2); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + + defect_block = ((u16)val1 << 8) | val2; + if (defect_block == 0xFFFF) + break; + + seg_no = defect_block / 512; + ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block; + } + + for (i = 0; i < ms_card->segment_cnt; i++) { + ms_card->segment[i].build_flag = 0; + ms_card->segment[i].l2p_table = NULL; + ms_card->segment[i].free_table = NULL; + ms_card->segment[i].get_index = 0; + ms_card->segment[i].set_index = 0; + ms_card->segment[i].unused_blk_cnt = 0; + + RTSX_DEBUGP("defective block count of segment %d is %d\n", + i, ms_card->segment[i].disable_count); + } + + return STATUS_SUCCESS; + +INIT_FAIL: + if (ms_card->segment) { + vfree(ms_card->segment); + ms_card->segment = NULL; + } + + return STATUS_FAIL; +} + +static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return 0xFFFF; + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table) + return segment->l2p_table[log_off]; + + return 0xFFFF; +} + +static void ms_set_l2p_tbl(struct rtsx_chip *chip, + int seg_no, u16 log_off, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return; + + segment = &(ms_card->segment[seg_no]); + if (segment->l2p_table) + segment->l2p_table[log_off] = phy_blk; +} + +static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + + segment->free_table[segment->set_index++] = phy_blk; + if (segment->set_index >= MS_FREE_TABLE_CNT) + segment->set_index = 0; + + segment->unused_blk_cnt++; +} + +static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + u16 phy_blk; + + segment = &(ms_card->segment[seg_no]); + + if (segment->unused_blk_cnt <= 0) + return 0xFFFF; + + phy_blk = segment->free_table[segment->get_index]; + segment->free_table[segment->get_index++] = 0xFFFF; + if (segment->get_index >= MS_FREE_TABLE_CNT) + segment->get_index = 0; + + segment->unused_blk_cnt--; + + return phy_blk; +} + +static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, + 2974, 3470, 3966, 4462, 4958, + 5454, 5950, 6446, 6942, 7438, + 7934}; + +static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, + u16 log_off, u8 us1, u8 us2) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + u16 tmp_blk; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + tmp_blk = segment->l2p_table[log_off]; + + if (us1 != us2) { + if (us1 == 0) { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, tmp_blk); + + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } else { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, phy_blk); + + ms_set_unused_block(chip, phy_blk); + } + } else { + if (phy_blk < tmp_blk) { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, phy_blk); + + ms_set_unused_block(chip, phy_blk); + } else { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, tmp_blk); + + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } + } + + return STATUS_SUCCESS; +} + +static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int retval, table_size, disable_cnt, defect_flag, i; + u16 start, end, phy_blk, log_blk, tmp_blk; + u8 extra[MS_EXTRA_SIZE], us1, us2; + + RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no); + + if (ms_card->segment == NULL) { + retval = ms_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + if (ms_card->segment[seg_no].build_flag) { + RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no); + return STATUS_SUCCESS; + } + + if (seg_no == 0) + table_size = 494; + else + table_size = 496; + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table == NULL) { + segment->l2p_table = vmalloc(table_size * 2); + if (segment->l2p_table == NULL) + TRACE_GOTO(chip, BUILD_FAIL); + } + memset((u8 *)(segment->l2p_table), 0xff, table_size * 2); + + if (segment->free_table == NULL) { + segment->free_table = vmalloc(MS_FREE_TABLE_CNT * 2); + if (segment->free_table == NULL) + TRACE_GOTO(chip, BUILD_FAIL); + } + memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); + + start = (u16)seg_no << 9; + end = (u16)(seg_no + 1) << 9; + + disable_cnt = segment->disable_count; + + segment->get_index = segment->set_index = 0; + segment->unused_blk_cnt = 0; + + for (phy_blk = start; phy_blk < end; phy_blk++) { + if (disable_cnt) { + defect_flag = 0; + for (i = 0; i < segment->disable_count; i++) { + if (phy_blk == segment->defect_list[i]) { + defect_flag = 1; + break; + } + } + if (defect_flag) { + disable_cnt--; + continue; + } + } + + retval = ms_read_extra_data(chip, phy_blk, 0, + extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("read extra data fail\n"); + ms_set_bad_block(chip, phy_blk); + continue; + } + + if (seg_no == ms_card->segment_cnt - 1) { + if (!(extra[1] & NOT_TRANSLATION_TABLE)) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + extra[2] = 0xff; + extra[3] = 0xff; + } + } + } + + if (!(extra[0] & BLOCK_OK)) + continue; + if (!(extra[1] & NOT_BOOT_BLOCK)) + continue; + if ((extra[0] & PAGE_OK) != PAGE_OK) + continue; + + log_blk = ((u16)extra[2] << 8) | extra[3]; + + if (log_blk == 0xFFFF) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if ((log_blk < ms_start_idx[seg_no]) || + (log_blk >= ms_start_idx[seg_no+1])) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == 0xFFFF) { + segment->l2p_table[log_blk - ms_start_idx[seg_no]] = phy_blk; + continue; + } + + us1 = extra[0] & 0x10; + tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]]; + retval = ms_read_extra_data(chip, tmp_blk, 0, + extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + continue; + us2 = extra[0] & 0x10; + + (void)ms_arbitrate_l2p(chip, phy_blk, + log_blk-ms_start_idx[seg_no], us1, us2); + continue; + } + + segment->build_flag = 1; + + RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt); + + /* Logical Address Confirmation Process */ + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) + chip->card_wp |= MS_CARD; + } else { + if (segment->unused_blk_cnt < 1) + chip->card_wp |= MS_CARD; + } + + if (chip->card_wp & MS_CARD) + return STATUS_SUCCESS; + + for (log_blk = ms_start_idx[seg_no]; + log_blk < ms_start_idx[seg_no + 1]; log_blk++) { + if (segment->l2p_table[log_blk-ms_start_idx[seg_no]] == 0xFFFF) { + phy_blk = ms_get_unused_block(chip, seg_no); + if (phy_blk == 0xFFFF) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, BUILD_FAIL); + + segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk; + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } else { + if (segment->unused_blk_cnt < 1) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } + } + } + + /* Make boot block be the first normal block */ + if (seg_no == 0) { + for (log_blk = 0; log_blk < 494; log_blk++) { + tmp_blk = segment->l2p_table[log_blk]; + if (tmp_blk < ms_card->boot_block) { + RTSX_DEBUGP("Boot block is not the first normal block.\n"); + + if (chip->card_wp & MS_CARD) + break; + + phy_blk = ms_get_unused_block(chip, 0); + retval = ms_copy_page(chip, tmp_blk, phy_blk, + log_blk, 0, ms_card->page_off + 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + segment->l2p_table[log_blk] = phy_blk; + + retval = ms_set_bad_block(chip, tmp_blk); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + return STATUS_SUCCESS; + +BUILD_FAIL: + segment->build_flag = 0; + if (segment->l2p_table) { + vfree(segment->l2p_table); + segment->l2p_table = NULL; + } + if (segment->free_table) { + vfree(segment->free_table); + segment->free_table = NULL; + } + + return STATUS_FAIL; +} + + +int reset_ms_card(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + memset(ms_card, 0, sizeof(struct ms_info)); + + retval = enable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_card->ms_type = 0; + + retval = reset_ms_pro(chip); + if (retval != STATUS_SUCCESS) { + if (ms_card->check_ms_flow) { + retval = reset_ms(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!CHK_MSPRO(ms_card)) { + /* Build table for the last segment, + * to check if L2P table block exists, erasing it + */ + retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); + + return STATUS_SUCCESS; +} + +static int mspro_set_rw_cmd(struct rtsx_chip *chip, + u32 start_sec, u16 sec_cnt, u8 cmd) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = (u8)(sec_cnt >> 8); + data[2] = (u8)sec_cnt; + data[3] = (u8)(start_sec >> 24); + data[4] = (u8)(start_sec >> 16); + data[5] = (u8)(start_sec >> 8); + data[6] = (u8)start_sec; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, + WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + + +void mspro_stop_seq_mode(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (ms_card->seq_mode) { + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + return; + + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } +} + +static inline int ms_auto_tune_clock(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (chip->asic_code) { + if (ms_card->ms_clock > 30) + ms_card->ms_clock -= 20; + } else { + if (ms_card->ms_clock == CLK_80) + ms_card->ms_clock = CLK_60; + else if (ms_card->ms_clock == CLK_60) + ms_card->ms_clock = CLK_40; + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int mspro_rw_multi_sector(struct scsi_cmnd *srb, + struct rtsx_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, mode_2k = 0; + u16 count; + u8 val, trans_mode, rw_tpc, rw_cmd; + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->cleanup_counter = 0; + + if (CHK_MSHG(ms_card)) { + if ((start_sector % 4) || (sector_cnt % 4)) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_QUAD_DATA; + rw_cmd = PRO_READ_2K_DATA; + } else { + rw_tpc = PRO_WRITE_QUAD_DATA; + rw_cmd = PRO_WRITE_2K_DATA; + } + mode_2k = 1; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) + trans_mode = MS_TM_AUTO_READ; + else + trans_mode = MS_TM_AUTO_WRITE; + + RTSX_READ_REG(chip, MS_TRANS_CFG, &val); + + if (ms_card->seq_mode) { + if ((ms_card->pre_dir != srb->sc_data_direction) + || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != start_sector) + || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) + || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) + || !(val & MS_INT_BREQ) + || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + if (val & MS_INT_BREQ) { + retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } + } + } + + if (!ms_card->seq_mode) { + ms_card->total_sec_cnt = 0; + if (sector_cnt >= SEQ_START_CRITERIA) { + if ((ms_card->capacity - start_sector) > 0xFE00) + count = 0xFE00; + else + count = (u16)(ms_card->capacity - start_sector); + + if (count > sector_cnt) { + if (mode_2k) + ms_card->seq_mode |= MODE_2K_SEQ; + else + ms_card->seq_mode |= MODE_512_SEQ; + } + } else { + count = sector_cnt; + } + retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, + WAIT_INT, mode_2k, scsi_sg_count(srb), + scsi_sglist(srb), scsi_bufflen(srb)); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + rtsx_read_register(chip, MS_TRANS_CFG, &val); + rtsx_clear_ms_error(chip); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & MS_INT_BREQ) + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + RTSX_DEBUGP("MSPro CRC error, tune clock!\n"); + chip->rw_need_retry = 1; + ms_auto_tune_clock(chip); + } + + TRACE_RET(chip, retval); + } + + if (ms_card->seq_mode) { + ms_card->pre_sec_addr = start_sector; + ms_card->pre_sec_cnt = sector_cnt; + ms_card->pre_dir = srb->sc_data_direction; + ms_card->total_sec_cnt += sector_cnt; + } + + return STATUS_SUCCESS; +} + +static int mspro_read_format_progress(struct rtsx_chip *chip, + const int short_data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u32 total_progress, cur_progress; + u8 cnt, tmp; + u8 data[8]; + + RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n", + short_data_len); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(tmp & MS_INT_BREQ)) { + if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + return STATUS_SUCCESS; + } + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (short_data_len >= 256) + cnt = 0; + else + cnt = (u8)short_data_len; + + retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, + MS_NO_CHECK_INT); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, + data, 8); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + total_progress = (data[0] << 24) | (data[1] << 16) | + (data[2] << 8) | data[3]; + cur_progress = (data[4] << 24) | (data[5] << 16) | + (data[6] << 8) | data[7]; + + RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n", + total_progress, cur_progress); + + if (total_progress == 0) { + ms_card->progress = 0; + } else { + u64 ulltmp = (u64)cur_progress * (u64)65535; + do_div(ulltmp, total_progress); + ms_card->progress = (u16)ulltmp; + } + RTSX_DEBUGP("progress = %d\n", ms_card->progress); + + for (i = 0; i < 5000; i++) { + retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + if (tmp & (MS_INT_CED | MS_INT_CMDNK | + MS_INT_BREQ | MS_INT_ERR)) + break; + + wait_timeout(1); + } + + retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (i == 5000) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (tmp & MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + ms_card->pro_under_formatting = 0; + } else if (tmp & MS_INT_BREQ) { + ms_card->format_status = FORMAT_IN_PROGRESS; + } else { + ms_card->format_status = FORMAT_FAIL; + ms_card->pro_under_formatting = 0; + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +void mspro_polling_format_status(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i; + + if (ms_card->pro_under_formatting && + (rtsx_get_stat(chip) != RTSX_STAT_SS)) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + + for (i = 0; i < 65535; i++) { + mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); + if (ms_card->format_status != FORMAT_IN_PROGRESS) + break; + } + } + + return; +} + +int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, + int short_data_len, int quick_format) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 buf[8], tmp; + u16 para; + + RTSX_DEBUGP("--%s--\n", __func__); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + memset(buf, 0, 2); + switch (short_data_len) { + case 32: + buf[0] = 0; + break; + case 64: + buf[0] = 1; + break; + case 128: + buf[0] = 2; + break; + case 256: + default: + buf[0] = 3; + break; + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, + NO_WAIT_INT, buf, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (quick_format) + para = 0x0000; + else + para = 0x0001; + + retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp); + + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) + TRACE_RET(chip, STATUS_FAIL); + + if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { + ms_card->pro_under_formatting = 1; + ms_card->progress = 0; + ms_card->format_status = FORMAT_IN_PROGRESS; + return STATUS_SUCCESS; + } + + if (tmp & MS_INT_CED) { + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + ms_card->format_status = FORMAT_SUCCESS; + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); + return STATUS_SUCCESS; + } + + TRACE_RET(chip, STATUS_FAIL); +} + + +static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, + u16 log_blk, u8 start_page, u8 end_page, + u8 *buf, unsigned int *index, + unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; + u8 *ptr; + + retval = ms_read_extra_data(chip, phy_blk, start_page, + extra, MS_EXTRA_SIZE); + if (retval == STATUS_SUCCESS) { + if ((extra[1] & 0x30) != 0x30) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0; + data[5] = start_page; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, + data, 6); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ptr = buf; + + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + if (val & INT_REG_BREQ) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + if (!(chip->card_wp & MS_CARD)) { + reset_ms(chip); + ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, phy_blk, + page_addr, extra, MS_EXTRA_SIZE); + } + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, + &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + trans_cfg = NO_WAIT_INT; + } else { + trans_cfg = WAIT_INT; + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, + 0xFF, trans_cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, RING_BUFFER); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_READ); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, + 512, scsi_sg_count(chip->srb), + index, offset, DMA_FROM_DEVICE, + chip->ms_timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_TIMEDOUT); + } + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_TIMEDOUT); + } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + ms_set_err_code(chip, MS_CRC16_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (scsi_sg_count(chip->srb) == 0) + ptr += 512; + } + + return STATUS_SUCCESS; +} + +static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, + u16 new_blk, u16 log_blk, u8 start_page, + u8 end_page, u8 *buf, unsigned int *index, + unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 page_addr, val, data[16]; + u8 *ptr; + + if (!start_page) { + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, + data, 8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, (6 + MS_EXTRA_SIZE)); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) + data[0] = 0x88; + else + data[0] = 0x80; + + data[1] = 0; + data[2] = (u8)(new_blk >> 8); + data[3] = (u8)new_blk; + if ((end_page - start_page) == 1) + data[4] = 0x20; + else + data[4] = 0; + + data[5] = start_page; + data[6] = 0xF8; + data[7] = 0xFF; + data[8] = (u8)(log_blk >> 8); + data[9] = (u8)log_blk; + + for (i = 0x0A; i < 0x10; i++) + data[i] = 0xFF; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, + NO_WAIT_INT, data, 16); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + ptr = buf; + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + udelay(30); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, + 0xFF, WRITE_PAGE_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, + 0xFF, WAIT_INT); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, RING_BUFFER); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, + 512, scsi_sg_count(chip->srb), + index, offset, DMA_TO_DEVICE, + chip->ms_timeout); + if (retval < 0) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + + if (retval == -ETIMEDOUT) + TRACE_RET(chip, STATUS_TIMEDOUT); + else + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if ((end_page - start_page) == 1) { + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = ms_send_cmd(chip, BLOCK_END, + WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, + NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + if ((page_addr == (end_page - 1)) || + (page_addr == ms_card->page_off)) { + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, + MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if (scsi_sg_count(chip->srb) == 0) + ptr += 512; + } + + return STATUS_SUCCESS; +} + + +static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 page_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, seg_no; + + retval = ms_copy_page(chip, old_blk, new_blk, log_blk, + page_off, ms_card->page_off + 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + seg_no = old_blk >> 9; + + if (MS_TST_BAD_BLOCK_FLG(ms_card)) { + MS_CLR_BAD_BLOCK_FLG(ms_card); + ms_set_bad_block(chip, old_blk); + } else { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) + ms_set_unused_block(chip, old_blk); + } + + ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); + + return STATUS_SUCCESS; +} + +static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page) +{ + int retval; + + if (start_page) { + retval = ms_copy_page(chip, old_blk, new_blk, log_blk, + 0, start_page); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +#ifdef MS_DELAY_WRITE +int ms_delay_write(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + delay_write->delay_write_flag = 0; + retval = ms_finish_write(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->logblock, + delay_write->pageoff); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); +} + +static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, seg_no; + unsigned int index = 0, offset = 0; + u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *ptr; +#ifdef MS_DELAY_WRITE + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); +#endif + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->cleanup_counter = 0; + + ptr = (u8 *)scsi_sglist(srb); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + log_blk = (u16)(start_sector >> ms_card->block_shift); + start_page = (u8)(start_sector & ms_card->page_off); + + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { + if (log_blk < ms_start_idx[seg_no+1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { +#ifdef MS_DELAY_WRITE + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + retval = ms_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, log_blk, + delay_write->pageoff, start_page); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + new_blk = ms_get_unused_block(chip, seg_no); + if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_prepare_write(chip, old_blk, new_blk, + log_blk, start_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef MS_DELAY_WRITE + } +#endif + } else { +#ifdef MS_DELAY_WRITE + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", + seg_no, old_blk, new_blk); + + while (total_sec_cnt) { + if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) + end_page = ms_card->page_off + 1; + else + end_page = start_page + (u8)total_sec_cnt; + + page_cnt = end_page - start_page; + + RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n", + start_page, end_page, page_cnt); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + retval = ms_read_multiple_pages(chip, + old_blk, log_blk, start_page, end_page, + ptr, &index, &offset); + } else { + retval = ms_write_multiple_pages(chip, old_blk, + new_blk, log_blk, start_page, end_page, + ptr, &index, &offset); + } + + if (retval != STATUS_SUCCESS) { + toggle_gpio(chip, 1); + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page == (ms_card->page_off + 1)) { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) + ms_set_unused_block(chip, old_blk); + + ms_set_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no], + new_blk); + } + } + + total_sec_cnt -= page_cnt; + if (scsi_sg_count(srb) == 0) + ptr += page_cnt * 512; + + if (total_sec_cnt == 0) + break; + + log_blk++; + + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; + seg_no++) { + if (log_blk < ms_start_idx[seg_no+1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + old_blk = ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = ms_get_unused_block(chip, seg_no); + if (new_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", + seg_no, old_blk, new_blk); + + start_page = 0; + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page < (ms_card->page_off + 1)) { +#ifdef MS_DELAY_WRITE + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; +#else + retval = ms_finish_write(chip, old_blk, new_blk, + log_blk, end_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_MSPRO(ms_card)) + retval = mspro_rw_multi_sector(srb, chip, start_sector, + sector_cnt); + else + retval = ms_rw_multi_sector(srb, chip, start_sector, + sector_cnt); + + return retval; +} + + +void ms_free_l2p_tbl(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i = 0; + + if (ms_card->segment != NULL) { + for (i = 0; i < ms_card->segment_cnt; i++) { + if (ms_card->segment[i].l2p_table != NULL) { + vfree(ms_card->segment[i].l2p_table); + ms_card->segment[i].l2p_table = NULL; + } + if (ms_card->segment[i].free_table != NULL) { + vfree(ms_card->segment[i].free_table); + ms_card->segment[i].free_table = NULL; + } + } + vfree(ms_card->segment); + ms_card->segment = NULL; + } +} + +#ifdef SUPPORT_MAGIC_GATE + +#ifdef READ_BYTES_WAIT_INT +static int ms_poll_int(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + val = *rtsx_get_cmd_data(chip); + if (val & MS_INT_ERR) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} +#endif + +#ifdef MS_SAMPLE_INT_ERR +static int check_ms_err(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + retval = rtsx_read_register(chip, MS_TRANSFER, &val); + if (retval != STATUS_SUCCESS) + return 1; + if (val & MS_TRANSFER_ERR) + return 1; + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) + return 1; + + if (val & (MS_INT_ERR | MS_INT_CMDNK)) + return 1; + + return 0; +} +#else +static int check_ms_err(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + retval = rtsx_read_register(chip, MS_TRANSFER, &val); + if (retval != STATUS_SUCCESS) + return 1; + if (val & MS_TRANSFER_ERR) + return 1; + + return 0; +} +#endif + +static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = entry_num; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, + data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (check_ms_err(chip)) { + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, + u8 mg_entry_num) +{ + int retval; + u8 buf[6]; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (type == 0) + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); + else + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf[0] = 0; + buf[1] = 0; + if (type == 1) { + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = mg_entry_num; + } + retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, + NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[12]; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (scsi_bufflen(srb) < 12) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, STATUS_FAIL); + } + + memset(buf1, 0, 32); + rtsx_stor_get_xfer_buf(buf2, min_t(int, 12, scsi_bufflen(srb)), srb); + for (i = 0; i < 8; i++) + buf1[8+i] = buf2[4+i]; + + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, + buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = STATUS_FAIL; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf = kmalloc(1540, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + buf[0] = 0x04; + buf[1] = 0x1A; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_GOTO(chip, GetEKBFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 3, WAIT_INT, 0, 0, buf + 4, 1536); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_GOTO(chip, GetEKBFinish); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min_t(int, 1052, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, bufflen, srb); + +GetEKBFinish: + kfree(buf); + return retval; +} + +int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, + buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(ms_card->magic_gate_id, buf, 16); + +#ifdef READ_BYTES_WAIT_INT + retval = ms_poll_int(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min_t(int, 12, scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) + buf[i] = buf[4+i]; + + for (i = 0; i < 24; i++) + buf[8+i] = 0; + + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, + 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->mg_auth = 0; + + return STATUS_SUCCESS; +} + +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[36]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, + buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + buf2[0] = 0x00; + buf2[1] = 0x22; + buf2[2] = 0x00; + buf2[3] = 0x00; + + memcpy(buf2 + 4, ms_card->magic_gate_id, 16); + memcpy(buf2 + 20, buf1, 16); + + bufflen = min_t(int, 36, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf2, bufflen, srb); + +#ifdef READ_BYTES_WAIT_INT + retval = ms_poll_int(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + return STATUS_SUCCESS; +} + +int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int i; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min_t(int, 12, scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) + buf[i] = buf[4+i]; + + for (i = 0; i < 24; i++) + buf[8+i] = 0; + + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, + buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->mg_auth = 1; + + return STATUS_SUCCESS; +} + +int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf = kmalloc(1028, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + buf[0] = 0x04; + buf[1] = 0x02; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_GOTO(chip, GetICVFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rtsx_clear_ms_error(chip); + TRACE_GOTO(chip, GetICVFinish); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min_t(int, 1028, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, bufflen, srb); + +GetICVFinish: + kfree(buf); + return retval; +} + +int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; +#ifdef MG_SET_ICV_SLOW + int i; +#endif + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf = kmalloc(1028, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + bufflen = min_t(int, 1028, scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } + +#ifdef MG_SET_ICV_SLOW + for (i = 0; i < 2; i++) { + udelay(50); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, + 0xFF, PRO_WRITE_LONG_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, RING_BUFFER); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512, + 512, 0, DMA_TO_DEVICE, 3000); + if ((retval < 0) || check_ms_err(chip)) { + rtsx_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } + retval = STATUS_FAIL; + TRACE_GOTO(chip, SetICVFinish); + } + } +#else + retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) { + rtsx_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } +#endif + +SetICVFinish: + kfree(buf); + return retval; +} + +#endif /* SUPPORT_MAGIC_GATE */ + +void ms_cleanup_work(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + RTSX_DEBUGP("MS Pro: stop transmission\n"); + mspro_stop_seq_mode(chip); + ms_card->cleanup_counter = 0; + } + if (CHK_MSHG(ms_card)) { + rtsx_write_register(chip, MS_CFG, + MS_2K_SECTOR_MODE, 0x00); + } + } +#ifdef MS_DELAY_WRITE + else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) { + RTSX_DEBUGP("MS: delay write\n"); + ms_delay_write(chip); + ms_card->cleanup_counter = 0; + } +#endif +} + +int ms_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->asic_code) { + retval = ms_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT); + } + RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int release_ms_card(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("release_ms_card\n"); + +#ifdef MS_DELAY_WRITE + ms_card->delay_write.delay_write_flag = 0; +#endif + ms_card->pro_under_formatting = 0; + + chip->card_ready &= ~MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->card_wp &= ~MS_CARD; + + ms_free_l2p_tbl(chip); + + memset(ms_card->raw_sys_info, 0, 96); +#ifdef SUPPORT_PCGL_1P18 + memset(ms_card->raw_model_name, 0, 48); +#endif + + retval = ms_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h new file mode 100644 index 000000000000..26c5b03d535e --- /dev/null +++ b/drivers/staging/rts5208/ms.h @@ -0,0 +1,227 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_MS_H +#define __REALTEK_RTSX_MS_H + +#define MS_DELAY_WRITE + +#define MS_MAX_RETRY_COUNT 3 + +#define MS_EXTRA_SIZE 0x9 + +#define WRT_PRTCT 0x01 + +/* Error Code */ +#define MS_NO_ERROR 0x00 +#define MS_CRC16_ERROR 0x80 +#define MS_TO_ERROR 0x40 +#define MS_NO_CARD 0x20 +#define MS_NO_MEMORY 0x10 +#define MS_CMD_NK 0x08 +#define MS_FLASH_READ_ERROR 0x04 +#define MS_FLASH_WRITE_ERROR 0x02 +#define MS_BREQ_ERROR 0x01 +#define MS_NOT_FOUND 0x03 + +/* Transfer Protocol Command */ +#define READ_PAGE_DATA 0x02 +#define READ_REG 0x04 +#define GET_INT 0x07 +#define WRITE_PAGE_DATA 0x0D +#define WRITE_REG 0x0B +#define SET_RW_REG_ADRS 0x08 +#define SET_CMD 0x0E + +#define PRO_READ_LONG_DATA 0x02 +#define PRO_READ_SHORT_DATA 0x03 +#define PRO_READ_REG 0x04 +#define PRO_READ_QUAD_DATA 0x05 +#define PRO_GET_INT 0x07 +#define PRO_WRITE_LONG_DATA 0x0D +#define PRO_WRITE_SHORT_DATA 0x0C +#define PRO_WRITE_QUAD_DATA 0x0A +#define PRO_WRITE_REG 0x0B +#define PRO_SET_RW_REG_ADRS 0x08 +#define PRO_SET_CMD 0x0E +#define PRO_EX_SET_CMD 0x09 + +#ifdef SUPPORT_MAGIC_GATE + +#define MG_GET_ID 0x40 +#define MG_SET_LID 0x41 +#define MG_GET_LEKB 0x42 +#define MG_SET_RD 0x43 +#define MG_MAKE_RMS 0x44 +#define MG_MAKE_KSE 0x45 +#define MG_SET_IBD 0x46 +#define MG_GET_IBD 0x47 + +#endif + +#ifdef XC_POWERCLASS +#define XC_CHG_POWER 0x16 +#endif + +#define BLOCK_READ 0xAA +#define BLOCK_WRITE 0x55 +#define BLOCK_END 0x33 +#define BLOCK_ERASE 0x99 +#define FLASH_STOP 0xCC + +#define SLEEP 0x5A +#define CLEAR_BUF 0xC3 +#define MS_RESET 0x3C + +#define PRO_READ_DATA 0x20 +#define PRO_WRITE_DATA 0x21 +#define PRO_READ_ATRB 0x24 +#define PRO_STOP 0x25 +#define PRO_ERASE 0x26 +#define PRO_READ_2K_DATA 0x27 +#define PRO_WRITE_2K_DATA 0x28 + +#define PRO_FORMAT 0x10 +#define PRO_SLEEP 0x11 + +#define IntReg 0x01 +#define StatusReg0 0x02 +#define StatusReg1 0x03 + +#define SystemParm 0x10 +#define BlockAdrs 0x11 +#define CMDParm 0x14 +#define PageAdrs 0x15 + +#define OverwriteFlag 0x16 +#define ManagemenFlag 0x17 +#define LogicalAdrs 0x18 +#define ReserveArea 0x1A + +#define Pro_IntReg 0x01 +#define Pro_StatusReg 0x02 +#define Pro_TypeReg 0x04 +#define Pro_IFModeReg 0x05 +#define Pro_CatagoryReg 0x06 +#define Pro_ClassReg 0x07 + + +#define Pro_SystemParm 0x10 +#define Pro_DataCount1 0x11 +#define Pro_DataCount0 0x12 +#define Pro_DataAddr3 0x13 +#define Pro_DataAddr2 0x14 +#define Pro_DataAddr1 0x15 +#define Pro_DataAddr0 0x16 + +#define Pro_TPCParm 0x17 +#define Pro_CMDParm 0x18 + +#define INT_REG_CED 0x80 +#define INT_REG_ERR 0x40 +#define INT_REG_BREQ 0x20 +#define INT_REG_CMDNK 0x01 + +#define BLOCK_BOOT 0xC0 +#define BLOCK_OK 0x80 +#define PAGE_OK 0x60 +#define DATA_COMPL 0x10 + +#define NOT_BOOT_BLOCK 0x4 +#define NOT_TRANSLATION_TABLE 0x8 + +#define HEADER_ID0 PPBUF_BASE2 +#define HEADER_ID1 (PPBUF_BASE2 + 1) +#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) +#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) +#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) +#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) +#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) +#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) +#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) +#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) +#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) +#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) +#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) +#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) + +#define MS_Device_Type (PPBUF_BASE2 + 0x1D8) + +#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3) + +#define setPS_NG 1 +#define setPS_Error 0 + +#define PARALLEL_8BIT_IF 0x40 +#define PARALLEL_4BIT_IF 0x00 +#define SERIAL_IF 0x80 + +#define BUF_FULL 0x10 +#define BUF_EMPTY 0x20 + +#define MEDIA_BUSY 0x80 +#define FLASH_BUSY 0x40 +#define DATA_ERROR 0x20 +#define STS_UCDT 0x10 +#define EXTRA_ERROR 0x08 +#define STS_UCEX 0x04 +#define FLAG_ERROR 0x02 +#define STS_UCFG 0x01 + +#define MS_SHORT_DATA_LEN 32 + +#define FORMAT_SUCCESS 0 +#define FORMAT_FAIL 1 +#define FORMAT_IN_PROGRESS 2 + +#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) +#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) +#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) + +void mspro_polling_format_status(struct rtsx_chip *chip); + +void mspro_stop_seq_mode(struct rtsx_chip *chip); +int reset_ms_card(struct rtsx_chip *chip); +int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt); +int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, + int short_data_len, int quick_format); +void ms_free_l2p_tbl(struct rtsx_chip *chip); +void ms_cleanup_work(struct rtsx_chip *chip); +int ms_power_off_card3v3(struct rtsx_chip *chip); +int release_ms_card(struct rtsx_chip *chip); +#ifdef MS_DELAY_WRITE +int ms_delay_write(struct rtsx_chip *chip); +#endif + +#ifdef SUPPORT_MAGIC_GATE +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_MS_H */ diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c new file mode 100644 index 000000000000..8586ac5d2144 --- /dev/null +++ b/drivers/staging/rts5208/rtsx.c @@ -0,0 +1,1071 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> + +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "general.h" + +#include "ms.h" +#include "sd.h" +#include "xd.h" + +MODULE_DESCRIPTION("Realtek PCI-Express card reader rts5208/rts5288 driver"); +MODULE_LICENSE("GPL"); + +static unsigned int delay_use = 1; +module_param(delay_use, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); + +static int ss_en; +module_param(ss_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_en, "enable selective suspend"); + +static int ss_interval = 50; +module_param(ss_interval, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds"); + +static int auto_delink_en; +module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); + +static unsigned char aspm_l0s_l1_en; +module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm"); + +static int msi_en; +module_param(msi_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(msi_en, "enable msi"); + +static irqreturn_t rtsx_interrupt(int irq, void *dev_id); + +/*********************************************************************** + * Host functions + ***********************************************************************/ + +static const char *host_info(struct Scsi_Host *host) +{ + return "SCSI emulation for PCI-Express Mass Storage devices"; +} + +static int slave_alloc(struct scsi_device *sdev) +{ + /* + * Set the INQUIRY transfer length to 36. We don't use any of + * the extra data and many devices choke if asked for more or + * less than 36 bytes. + */ + sdev->inquiry_len = 36; + return 0; +} + +static int slave_configure(struct scsi_device *sdev) +{ + /* Scatter-gather buffers (all but the last) must have a length + * divisible by the bulk maxpacket size. Otherwise a data packet + * would end up being short, causing a premature end to the data + * transfer. Since high-speed bulk pipes have a maxpacket size + * of 512, we'll use that as the scsi device queue's DMA alignment + * mask. Guaranteeing proper alignment of the first buffer will + * have the desired effect because, except at the beginning and + * the end, scatter-gather buffers follow page boundaries. */ + blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); + + /* Set the SCSI level to at least 2. We'll leave it at 3 if that's + * what is originally reported. We need this to avoid confusing + * the SCSI layer with devices that report 0 or 1, but need 10-byte + * commands (ala ATAPI devices behind certain bridges, or devices + * which simply have broken INQUIRY data). + * + * NOTE: This means /dev/sg programs (ala cdrecord) will get the + * actual information. This seems to be the preference for + * programs like that. + * + * NOTE: This also means that /proc/scsi/scsi and sysfs may report + * the actual value or the modified one, depending on where the + * data comes from. + */ + if (sdev->scsi_level < SCSI_2) + sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; + + return 0; +} + + +/*********************************************************************** + * /proc/scsi/ functions + ***********************************************************************/ + +/* we use this macro to help us write into the buffer */ +#undef SPRINTF +#define SPRINTF(args...) \ + do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) + +/* queue a command */ +/* This is always called with scsi_lock(host) held */ +static int queuecommand_lck(struct scsi_cmnd *srb, + void (*done)(struct scsi_cmnd *)) +{ + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); + struct rtsx_chip *chip = dev->chip; + + /* check for state-transition errors */ + if (chip->srb != NULL) { + dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n", + __func__, chip->srb); + return SCSI_MLQUEUE_HOST_BUSY; + } + + /* fail the command if we are disconnecting */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + dev_info(&dev->pci->dev, "Fail command during disconnect\n"); + srb->result = DID_NO_CONNECT << 16; + done(srb); + return 0; + } + + /* enqueue the command and wake up the control thread */ + srb->scsi_done = done; + chip->srb = srb; + complete(&dev->cmnd_ready); + + return 0; +} + +static DEF_SCSI_QCMD(queuecommand) + +/*********************************************************************** + * Error handling functions + ***********************************************************************/ + +/* Command timeout and abort */ +static int command_abort(struct scsi_cmnd *srb) +{ + struct Scsi_Host *host = srb->device->host; + struct rtsx_dev *dev = host_to_rtsx(host); + struct rtsx_chip *chip = dev->chip; + + dev_info(&dev->pci->dev, "%s called\n", __func__); + + scsi_lock(host); + + /* Is this command still active? */ + if (chip->srb != srb) { + scsi_unlock(host); + dev_info(&dev->pci->dev, "-- nothing to abort\n"); + return FAILED; + } + + rtsx_set_stat(chip, RTSX_STAT_ABORT); + + scsi_unlock(host); + + /* Wait for the aborted command to finish */ + wait_for_completion(&dev->notify); + + return SUCCESS; +} + +/* This invokes the transport reset mechanism to reset the state of the + * device */ +static int device_reset(struct scsi_cmnd *srb) +{ + int result = 0; + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); + + dev_info(&dev->pci->dev, "%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + +/* Simulate a SCSI bus reset by resetting the device's USB port. */ +static int bus_reset(struct scsi_cmnd *srb) +{ + int result = 0; + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); + + dev_info(&dev->pci->dev, "%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + + +/* + * this defines our host template, with which we'll allocate hosts + */ + +static struct scsi_host_template rtsx_host_template = { + /* basic userland interface stuff */ + .name = CR_DRIVER_NAME, + .proc_name = CR_DRIVER_NAME, + .info = host_info, + + /* command interface -- queued only */ + .queuecommand = queuecommand, + + /* error and abort handlers */ + .eh_abort_handler = command_abort, + .eh_device_reset_handler = device_reset, + .eh_bus_reset_handler = bus_reset, + + /* queue commands only, only one command per LUN */ + .can_queue = 1, + .cmd_per_lun = 1, + + /* unknown initiator id */ + .this_id = -1, + + .slave_alloc = slave_alloc, + .slave_configure = slave_configure, + + /* lots of sg segments can be handled */ + .sg_tablesize = SG_ALL, + + /* limit the total size of a transfer to 120 KB */ + .max_sectors = 240, + + /* merge commands... this seems to help performance, but + * periodically someone should test to see which setting is more + * optimal. + */ + .use_clustering = 1, + + /* emulated HBA */ + .emulated = 1, + + /* we do our own delay after a device or bus reset */ + .skip_settle_delay = 1, + + /* module management */ + .module = THIS_MODULE +}; + + +static int rtsx_acquire_irq(struct rtsx_dev *dev) +{ + struct rtsx_chip *chip = dev->chip; + + dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n", + __func__, chip->msi_en, dev->pci->irq); + + if (request_irq(dev->pci->irq, rtsx_interrupt, + chip->msi_en ? 0 : IRQF_SHARED, + CR_DRIVER_NAME, dev)) { + dev_err(&dev->pci->dev, + "rtsx: unable to grab IRQ %d, disabling device\n", + dev->pci->irq); + return -1; + } + + dev->irq = dev->pci->irq; + pci_intx(dev->pci, !chip->msi_en); + + return 0; +} + + +int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val) +{ + struct pci_dev *pdev; + u8 data; + u8 devfn = (dev << 3) | func; + + pdev = pci_get_bus_and_slot(bus, devfn); + if (!pdev) + return -1; + + pci_read_config_byte(pdev, offset, &data); + if (val) + *val = data; + + return 0; +} + +#ifdef CONFIG_PM +/* + * power management + */ +static int rtsx_suspend(struct pci_dev *pci, pm_message_t state) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + if (!dev) + return 0; + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + chip = dev->chip; + + rtsx_do_before_power_down(chip, PM_S3); + + if (dev->irq >= 0) { + synchronize_irq(dev->irq); + free_irq(dev->irq, (void *)dev); + dev->irq = -1; + } + + if (chip->msi_en) + pci_disable_msi(pci); + + pci_save_state(pci); + pci_enable_wake(pci, pci_choose_state(pci, state), 1); + pci_disable_device(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + + return 0; +} + +static int rtsx_resume(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + if (!dev) + return 0; + + chip = dev->chip; + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); + if (pci_enable_device(pci) < 0) { + dev_err(&dev->pci->dev, + "%s: pci_enable_device failed, disabling device\n", + CR_DRIVER_NAME); + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + return -EIO; + } + pci_set_master(pci); + + if (chip->msi_en) { + if (pci_enable_msi(pci) < 0) + chip->msi_en = 0; + } + + if (rtsx_acquire_irq(dev) < 0) { + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + return -EIO; + } + + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); + rtsx_init_chip(chip); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + + return 0; +} +#endif /* CONFIG_PM */ + +static void rtsx_shutdown(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + if (!dev) + return; + + chip = dev->chip; + + rtsx_do_before_power_down(chip, PM_S1); + + if (dev->irq >= 0) { + synchronize_irq(dev->irq); + free_irq(dev->irq, (void *)dev); + dev->irq = -1; + } + + if (chip->msi_en) + pci_disable_msi(pci); + + pci_disable_device(pci); + + return; +} + +static int rtsx_control_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + struct Scsi_Host *host = rtsx_to_host(dev); + + for (;;) { + if (wait_for_completion_interruptible(&dev->cmnd_ready)) + break; + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + /* if the device has disconnected, we are free to exit */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + dev_info(&dev->pci->dev, "-- rtsx-control exiting\n"); + mutex_unlock(&dev->dev_mutex); + break; + } + + /* lock access to the state */ + scsi_lock(host); + + /* has the command aborted ? */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + chip->srb->result = DID_ABORT << 16; + goto SkipForAbort; + } + + scsi_unlock(host); + + /* reject the command if the direction indicator + * is UNKNOWN + */ + if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { + dev_err(&dev->pci->dev, "UNKNOWN data direction\n"); + chip->srb->result = DID_ERROR << 16; + } + + /* reject if target != 0 or if LUN is higher than + * the maximum known LUN + */ + else if (chip->srb->device->id) { + dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n", + chip->srb->device->id, + chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + else if (chip->srb->device->lun > chip->max_lun) { + dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n", + chip->srb->device->id, + chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + /* we've got a command, let's do it! */ + else { + RTSX_DEBUG(scsi_show_command(chip->srb)); + rtsx_invoke_transport(chip->srb, chip); + } + + /* lock access to the state */ + scsi_lock(host); + + /* did the command already complete because of a disconnect? */ + if (!chip->srb) + ; /* nothing to do */ + + /* indicate that the command is done */ + else if (chip->srb->result != DID_ABORT << 16) { + chip->srb->scsi_done(chip->srb); + } else { +SkipForAbort: + dev_err(&dev->pci->dev, "scsi command aborted\n"); + } + + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + complete(&(dev->notify)); + + rtsx_set_stat(chip, RTSX_STAT_IDLE); + } + + /* finished working on this command */ + chip->srb = NULL; + scsi_unlock(host); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + } /* for (;;) */ + + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + complete_and_exit(&dev->control_exit, 0); +} + + +static int rtsx_polling_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + struct sd_info *sd_card = &(chip->sd_card); + struct xd_info *xd_card = &(chip->xd_card); + struct ms_info *ms_card = &(chip->ms_card); + + sd_card->cleanup_counter = 0; + xd_card->cleanup_counter = 0; + ms_card->cleanup_counter = 0; + + /* Wait until SCSI scan finished */ + wait_timeout((delay_use + 5) * 1000); + + for (;;) { + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(POLLING_INTERVAL); + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + /* if the device has disconnected, we are free to exit */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n"); + mutex_unlock(&dev->dev_mutex); + break; + } + + mutex_unlock(&dev->dev_mutex); + + mspro_polling_format_status(chip); + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + rtsx_polling_func(chip); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + } + + complete_and_exit(&dev->polling_exit, 0); +} + +/* + * interrupt handler + */ +static irqreturn_t rtsx_interrupt(int irq, void *dev_id) +{ + struct rtsx_dev *dev = dev_id; + struct rtsx_chip *chip; + int retval; + u32 status; + + if (dev) + chip = dev->chip; + else + return IRQ_NONE; + + if (!chip) + return IRQ_NONE; + + spin_lock(&dev->reg_lock); + + retval = rtsx_pre_handle_interrupt(chip); + if (retval == STATUS_FAIL) { + spin_unlock(&dev->reg_lock); + if (chip->int_reg == 0xFFFFFFFF) + return IRQ_HANDLED; + else + return IRQ_NONE; + } + + status = chip->int_reg; + + if (dev->check_card_cd) { + if (!(dev->check_card_cd & status)) { + /* card not exist, return TRANS_RESULT_FAIL */ + dev->trans_result = TRANS_RESULT_FAIL; + if (dev->done) + complete(dev->done); + goto Exit; + } + } + + if (status & (NEED_COMPLETE_INT | DELINK_INT)) { + if (status & (TRANS_FAIL_INT | DELINK_INT)) { + if (status & DELINK_INT) + RTSX_SET_DELINK(chip); + dev->trans_result = TRANS_RESULT_FAIL; + if (dev->done) + complete(dev->done); + } else if (status & TRANS_OK_INT) { + dev->trans_result = TRANS_RESULT_OK; + if (dev->done) + complete(dev->done); + } else if (status & DATA_DONE_INT) { + dev->trans_result = TRANS_NOT_READY; + if (dev->done && (dev->trans_state == STATE_TRANS_SG)) + complete(dev->done); + } + } + +Exit: + spin_unlock(&dev->reg_lock); + return IRQ_HANDLED; +} + + +/* Release all our dynamic resources */ +static void rtsx_release_resources(struct rtsx_dev *dev) +{ + dev_info(&dev->pci->dev, "-- %s\n", __func__); + + /* Tell the control thread to exit. The SCSI host must + * already have been removed so it won't try to queue + * any more commands. + */ + dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); + complete(&dev->cmnd_ready); + if (dev->ctl_thread) + wait_for_completion(&dev->control_exit); + if (dev->polling_thread) + wait_for_completion(&dev->polling_exit); + + wait_timeout(200); + + if (dev->rtsx_resv_buf) { + dma_free_coherent(&(dev->pci->dev), RTSX_RESV_BUF_LEN, + dev->rtsx_resv_buf, dev->rtsx_resv_buf_addr); + dev->chip->host_cmds_ptr = NULL; + dev->chip->host_sg_tbl_ptr = NULL; + } + + if (dev->irq > 0) + free_irq(dev->irq, (void *)dev); + if (dev->chip->msi_en) + pci_disable_msi(dev->pci); + if (dev->remap_addr) + iounmap(dev->remap_addr); + + pci_disable_device(dev->pci); + pci_release_regions(dev->pci); + + rtsx_release_chip(dev->chip); + kfree(dev->chip); +} + +/* First stage of disconnect processing: stop all commands and remove + * the host */ +static void quiesce_and_remove_host(struct rtsx_dev *dev) +{ + struct Scsi_Host *host = rtsx_to_host(dev); + struct rtsx_chip *chip = dev->chip; + + /* Prevent new transfers, stop the current command, and + * interrupt a SCSI-scan or device-reset delay */ + mutex_lock(&dev->dev_mutex); + scsi_lock(host); + rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); + scsi_unlock(host); + mutex_unlock(&dev->dev_mutex); + wake_up(&dev->delay_wait); + wait_for_completion(&dev->scanning_done); + + /* Wait some time to let other threads exist */ + wait_timeout(100); + + /* queuecommand won't accept any new commands and the control + * thread won't execute a previously-queued command. If there + * is such a command pending, complete it with an error. */ + mutex_lock(&dev->dev_mutex); + if (chip->srb) { + chip->srb->result = DID_NO_CONNECT << 16; + scsi_lock(host); + chip->srb->scsi_done(dev->chip->srb); + chip->srb = NULL; + scsi_unlock(host); + } + mutex_unlock(&dev->dev_mutex); + + /* Now we own no commands so it's safe to remove the SCSI host */ + scsi_remove_host(host); +} + +/* Second stage of disconnect processing: deallocate all resources */ +static void release_everything(struct rtsx_dev *dev) +{ + rtsx_release_resources(dev); + + /* Drop our reference to the host; the SCSI core will free it + * when the refcount becomes 0. */ + scsi_host_put(rtsx_to_host(dev)); +} + +/* Thread to carry out delayed SCSI-device scanning */ +static int rtsx_scan_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + + /* Wait for the timeout to expire or for a disconnect */ + if (delay_use > 0) { + dev_info(&dev->pci->dev, + "%s: waiting for device to settle before scanning\n", + CR_DRIVER_NAME); + wait_event_interruptible_timeout(dev->delay_wait, + rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), + delay_use * HZ); + } + + /* If the device is still connected, perform the scanning */ + if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + scsi_scan_host(rtsx_to_host(dev)); + dev_info(&dev->pci->dev, "%s: device scan complete\n", + CR_DRIVER_NAME); + + /* Should we unbind if no devices were detected? */ + } + + complete_and_exit(&dev->scanning_done, 0); +} + +static void rtsx_init_options(struct rtsx_chip *chip) +{ + chip->vendor_id = chip->rtsx->pci->vendor; + chip->product_id = chip->rtsx->pci->device; + chip->adma_mode = 1; + chip->lun_mc = 0; + chip->driver_first_load = 1; +#ifdef HW_AUTO_SWITCH_SD_BUS + chip->sdio_in_charge = 0; +#endif + + chip->mspro_formatter_enable = 1; + chip->ignore_sd = 0; + chip->use_hw_setting = 0; + chip->lun_mode = DEFAULT_SINGLE; + chip->auto_delink_en = auto_delink_en; + chip->ss_en = ss_en; + chip->ss_idle_period = ss_interval * 1000; + chip->remote_wakeup_en = 0; + chip->aspm_l0s_l1_en = aspm_l0s_l1_en; + chip->dynamic_aspm = 1; + chip->fpga_sd_sdr104_clk = CLK_200; + chip->fpga_sd_ddr50_clk = CLK_100; + chip->fpga_sd_sdr50_clk = CLK_100; + chip->fpga_sd_hs_clk = CLK_100; + chip->fpga_mmc_52m_clk = CLK_80; + chip->fpga_ms_hg_clk = CLK_80; + chip->fpga_ms_4bit_clk = CLK_80; + chip->fpga_ms_1bit_clk = CLK_40; + chip->asic_sd_sdr104_clk = 203; + chip->asic_sd_sdr50_clk = 98; + chip->asic_sd_ddr50_clk = 98; + chip->asic_sd_hs_clk = 98; + chip->asic_mmc_52m_clk = 98; + chip->asic_ms_hg_clk = 117; + chip->asic_ms_4bit_clk = 78; + chip->asic_ms_1bit_clk = 39; + chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M; + chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M; + chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M; + chip->ssc_depth_sd_hs = SSC_DEPTH_1M; + chip->ssc_depth_mmc_52m = SSC_DEPTH_1M; + chip->ssc_depth_ms_hg = SSC_DEPTH_1M; + chip->ssc_depth_ms_4bit = SSC_DEPTH_512K; + chip->ssc_depth_low_speed = SSC_DEPTH_512K; + chip->ssc_en = 1; + chip->sd_speed_prior = 0x01040203; + chip->sd_current_prior = 0x00010203; + chip->sd_ctl = SD_PUSH_POINT_AUTO | + SD_SAMPLE_POINT_AUTO | + SUPPORT_MMC_DDR_MODE; + chip->sd_ddr_tx_phase = 0; + chip->mmc_ddr_tx_phase = 1; + chip->sd_default_tx_phase = 15; + chip->sd_default_rx_phase = 15; + chip->pmos_pwr_on_interval = 200; + chip->sd_voltage_switch_delay = 1000; + chip->ms_power_class_en = 3; + + chip->sd_400mA_ocp_thd = 1; + chip->sd_800mA_ocp_thd = 5; + chip->ms_ocp_thd = 2; + + chip->card_drive_sel = 0x55; + chip->sd30_drive_sel_1v8 = 0x03; + chip->sd30_drive_sel_3v3 = 0x01; + + chip->do_delink_before_power_down = 1; + chip->auto_power_down = 1; + chip->polling_config = 0; + + chip->force_clkreq_0 = 1; + chip->ft2_fast_mode = 0; + + chip->sdio_retry_cnt = 1; + + chip->xd_timeout = 2000; + chip->sd_timeout = 10000; + chip->ms_timeout = 2000; + chip->mspro_timeout = 15000; + + chip->power_down_in_ss = 1; + + chip->sdr104_en = 1; + chip->sdr50_en = 1; + chip->ddr50_en = 1; + + chip->delink_stage1_step = 100; + chip->delink_stage2_step = 40; + chip->delink_stage3_step = 20; + + chip->auto_delink_in_L1 = 1; + chip->blink_led = 1; + chip->msi_en = msi_en; + chip->hp_watch_bios_hotplug = 0; + chip->max_payload = 0; + chip->phy_voltage = 0; + + chip->support_ms_8bit = 1; + chip->s3_pwr_off_delay = 1000; +} + +static int rtsx_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + struct Scsi_Host *host; + struct rtsx_dev *dev; + int err = 0; + struct task_struct *th; + + RTSX_DEBUGP("Realtek PCI-E card reader detected\n"); + + err = pci_enable_device(pci); + if (err < 0) { + dev_err(&pci->dev, "PCI enable device failed!\n"); + return err; + } + + err = pci_request_regions(pci, CR_DRIVER_NAME); + if (err < 0) { + dev_err(&pci->dev, "PCI request regions for %s failed!\n", + CR_DRIVER_NAME); + pci_disable_device(pci); + return err; + } + + /* + * Ask the SCSI layer to allocate a host structure, with extra + * space at the end for our private rtsx_dev structure. + */ + host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); + if (!host) { + dev_err(&pci->dev, "Unable to allocate the scsi host\n"); + pci_release_regions(pci); + pci_disable_device(pci); + return -ENOMEM; + } + + dev = host_to_rtsx(host); + memset(dev, 0, sizeof(struct rtsx_dev)); + + dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL); + if (dev->chip == NULL) { + err = -ENOMEM; + goto errout; + } + + spin_lock_init(&dev->reg_lock); + mutex_init(&(dev->dev_mutex)); + init_completion(&dev->cmnd_ready); + init_completion(&dev->control_exit); + init_completion(&dev->polling_exit); + init_completion(&(dev->notify)); + init_completion(&dev->scanning_done); + init_waitqueue_head(&dev->delay_wait); + + dev->pci = pci; + dev->irq = -1; + + dev_info(&pci->dev, "Resource length: 0x%x\n", + (unsigned int)pci_resource_len(pci, 0)); + dev->addr = pci_resource_start(pci, 0); + dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); + if (dev->remap_addr == NULL) { + dev_err(&pci->dev, "ioremap error\n"); + err = -ENXIO; + goto errout; + } + + /* + * Using "unsigned long" cast here to eliminate gcc warning in + * 64-bit system + */ + dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", + (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); + + dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, + &(dev->rtsx_resv_buf_addr), GFP_KERNEL); + if (dev->rtsx_resv_buf == NULL) { + dev_err(&pci->dev, "alloc dma buffer fail\n"); + err = -ENXIO; + goto errout; + } + dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; + dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; + dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; + dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + + HOST_CMDS_BUF_LEN; + + dev->chip->rtsx = dev; + + rtsx_init_options(dev->chip); + + dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); + + if (dev->chip->msi_en) { + if (pci_enable_msi(pci) < 0) + dev->chip->msi_en = 0; + } + + if (rtsx_acquire_irq(dev) < 0) { + err = -EBUSY; + goto errout; + } + + pci_set_master(pci); + synchronize_irq(dev->irq); + + rtsx_init_chip(dev->chip); + + /* set the supported max_lun and max_id for the scsi host + * NOTE: the minimal value of max_id is 1 */ + host->max_id = 1; + host->max_lun = dev->chip->max_lun; + + /* Start up our control thread */ + th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); + if (IS_ERR(th)) { + dev_err(&pci->dev, "Unable to start control thread\n"); + err = PTR_ERR(th); + goto errout; + } + dev->ctl_thread = th; + + err = scsi_add_host(host, &pci->dev); + if (err) { + dev_err(&pci->dev, "Unable to add the scsi host\n"); + goto errout; + } + + /* Start up the thread for delayed SCSI-device scanning */ + th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); + if (IS_ERR(th)) { + dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); + complete(&dev->scanning_done); + quiesce_and_remove_host(dev); + err = PTR_ERR(th); + goto errout; + } + + /* Start up the thread for polling thread */ + th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); + if (IS_ERR(th)) { + dev_err(&pci->dev, "Unable to start the device-polling thread\n"); + quiesce_and_remove_host(dev); + err = PTR_ERR(th); + goto errout; + } + dev->polling_thread = th; + + pci_set_drvdata(pci, dev); + + return 0; + + /* We come here if there are any problems */ +errout: + dev_err(&pci->dev, "rtsx_probe() failed\n"); + release_everything(dev); + + return err; +} + + +static void rtsx_remove(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + + dev_info(&pci->dev, "rtsx_remove() called\n"); + + quiesce_and_remove_host(dev); + release_everything(dev); + + pci_set_drvdata(pci, NULL); +} + +/* PCI IDs */ +static DEFINE_PCI_DEVICE_TABLE(rtsx_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, rtsx_ids); + +/* pci_driver definition */ +static struct pci_driver driver = { + .name = CR_DRIVER_NAME, + .id_table = rtsx_ids, + .probe = rtsx_probe, + .remove = rtsx_remove, +#ifdef CONFIG_PM + .suspend = rtsx_suspend, + .resume = rtsx_resume, +#endif + .shutdown = rtsx_shutdown, +}; + +static int __init rtsx_init(void) +{ + pr_info("Initializing Realtek PCIE storage driver...\n"); + + return pci_register_driver(&driver); +} + +static void __exit rtsx_exit(void) +{ + pr_info("rtsx_exit() called\n"); + + pci_unregister_driver(&driver); + + pr_info("%s module exit\n", CR_DRIVER_NAME); +} + +module_init(rtsx_init) +module_exit(rtsx_exit) diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h new file mode 100644 index 000000000000..3f048e061231 --- /dev/null +++ b/drivers/staging/rts5208/rtsx.h @@ -0,0 +1,186 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_H +#define __REALTEK_RTSX_H + +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <linux/mutex.h> +#include <linux/cdrom.h> +#include <linux/workqueue.h> +#include <linux/timer.h> +#include <linux/time.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_devinfo.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_host.h> + +#include "debug.h" +#include "trace.h" +#include "general.h" + +#define CR_DRIVER_NAME "rts5208" + +#define pci_get_bus_and_slot(bus, devfn) \ + pci_get_domain_bus_and_slot(0, (bus), (devfn)) + +/* + * macros for easy use + */ +#define rtsx_writel(chip, reg, value) \ + iowrite32(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readl(chip, reg) \ + ioread32((chip)->rtsx->remap_addr + reg) +#define rtsx_writew(chip, reg, value) \ + iowrite16(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readw(chip, reg) \ + ioread16((chip)->rtsx->remap_addr + reg) +#define rtsx_writeb(chip, reg, value) \ + iowrite8(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readb(chip, reg) \ + ioread8((chip)->rtsx->remap_addr + reg) + +#define rtsx_read_config_byte(chip, where, val) \ + pci_read_config_byte((chip)->rtsx->pci, where, val) + +#define rtsx_write_config_byte(chip, where, val) \ + pci_write_config_byte((chip)->rtsx->pci, where, val) + +#define wait_timeout_x(task_state, msecs) \ +do { \ + set_current_state((task_state)); \ + schedule_timeout((msecs) * HZ / 1000); \ +} while (0) +#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) + + +#define STATE_TRANS_NONE 0 +#define STATE_TRANS_CMD 1 +#define STATE_TRANS_BUF 2 +#define STATE_TRANS_SG 3 + +#define TRANS_NOT_READY 0 +#define TRANS_RESULT_OK 1 +#define TRANS_RESULT_FAIL 2 + +#define SCSI_LUN(srb) ((srb)->device->lun) + +typedef unsigned long DELAY_PARA_T; + +struct rtsx_chip; + +struct rtsx_dev { + struct pci_dev *pci; + + /* pci resources */ + unsigned long addr; + void __iomem *remap_addr; + int irq; + + /* locks */ + spinlock_t reg_lock; + + struct task_struct *ctl_thread; /* the control thread */ + struct task_struct *polling_thread; /* the polling thread */ + + /* mutual exclusion and synchronization structures */ + struct completion cmnd_ready; /* to sleep thread on */ + struct completion control_exit; /* control thread exit */ + struct completion polling_exit; /* polling thread exit */ + struct completion notify; /* thread begin/end */ + struct completion scanning_done; /* wait for scan thread */ + + wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct mutex dev_mutex; + + /* host reserved buffer */ + void *rtsx_resv_buf; + dma_addr_t rtsx_resv_buf_addr; + + char trans_result; + char trans_state; + + struct completion *done; + /* Whether interrupt handler should care card cd info */ + u32 check_card_cd; + + struct rtsx_chip *chip; +}; + +typedef struct rtsx_dev rtsx_dev_t; + +/* Convert between rtsx_dev and the corresponding Scsi_Host */ +static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev) +{ + return container_of((void *) dev, struct Scsi_Host, hostdata); +} +static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) +{ + return (struct rtsx_dev *) host->hostdata; +} + +static inline void get_current_time(u8 *timeval_buf, int buf_len) +{ + struct timeval tv; + + if (!timeval_buf || (buf_len < 8)) + return; + + do_gettimeofday(&tv); + + timeval_buf[0] = (u8)(tv.tv_sec >> 24); + timeval_buf[1] = (u8)(tv.tv_sec >> 16); + timeval_buf[2] = (u8)(tv.tv_sec >> 8); + timeval_buf[3] = (u8)(tv.tv_sec); + timeval_buf[4] = (u8)(tv.tv_usec >> 24); + timeval_buf[5] = (u8)(tv.tv_usec >> 16); + timeval_buf[6] = (u8)(tv.tv_usec >> 8); + timeval_buf[7] = (u8)(tv.tv_usec); +} + +/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the + * single queue element srb for write access */ +#define scsi_unlock(host) spin_unlock_irq(host->host_lock) +#define scsi_lock(host) spin_lock_irq(host->host_lock) + +#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) +#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) + +/* struct scsi_cmnd transfer buffer access utilities */ +enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; + +int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val); + +#endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c new file mode 100644 index 000000000000..3055eb10c076 --- /dev/null +++ b/drivers/staging/rts5208/rtsx_card.c @@ -0,0 +1,1126 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> +#include <linux/kernel.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" + +#include "rtsx_sys.h" +#include "general.h" + +#include "sd.h" +#include "xd.h" +#include "ms.h" + +void do_remaining_work(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); +#ifdef XD_DELAY_WRITE + struct xd_info *xd_card = &(chip->xd_card); +#endif + struct ms_info *ms_card = &(chip->ms_card); + + if (chip->card_ready & SD_CARD) { + if (sd_card->seq_mode) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + sd_card->cleanup_counter++; + } else { + sd_card->cleanup_counter = 0; + } + } + +#ifdef XD_DELAY_WRITE + if (chip->card_ready & XD_CARD) { + if (xd_card->delay_write.delay_write_flag) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + xd_card->cleanup_counter++; + } else { + xd_card->cleanup_counter = 0; + } + } +#endif + + if (chip->card_ready & MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + ms_card->cleanup_counter++; + } else { + ms_card->cleanup_counter = 0; + } + } else { +#ifdef MS_DELAY_WRITE + if (ms_card->delay_write.delay_write_flag) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + ms_card->cleanup_counter++; + } else { + ms_card->cleanup_counter = 0; + } +#endif + } + } + + if (sd_card->cleanup_counter > POLLING_WAIT_CNT) + sd_cleanup_work(chip); + + if (xd_card->cleanup_counter > POLLING_WAIT_CNT) + xd_cleanup_work(chip); + + if (ms_card->cleanup_counter > POLLING_WAIT_CNT) + ms_cleanup_work(chip); +} + +void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) +{ + u8 reg1 = 0, reg2 = 0; + + rtsx_read_register(chip, 0xFF34, ®1); + rtsx_read_register(chip, 0xFF38, ®2); + RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2); + if ((reg1 & 0xC0) && (reg2 & 0xC0)) { + chip->sd_int = 1; + rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); + rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + } +} + +#ifdef SUPPORT_SDIO_ASPM +void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) +{ + u8 buf[12], reg; + int i; + + for (i = 0; i < 12; i++) + rtsx_read_register(chip, 0xFF08 + i, &buf[i]); + rtsx_read_register(chip, 0xFF25, ®); + if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { + chip->sdio_counter = 0; + chip->sdio_idle = 0; + } else { + if (!chip->sdio_idle) { + chip->sdio_counter++; + if (chip->sdio_counter >= SDIO_IDLE_COUNT) { + chip->sdio_counter = 0; + chip->sdio_idle = 1; + } + } + } + memcpy(chip->sdio_raw_data, buf, 12); + + if (chip->sdio_idle) { + if (!chip->sdio_aspm) { + RTSX_DEBUGP("SDIO enter ASPM!\n"); + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, + 0x30 | (chip->aspm_level[1] << 2)); + chip->sdio_aspm = 1; + } + } else { + if (chip->sdio_aspm) { + RTSX_DEBUGP("SDIO exit ASPM!\n"); + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); + chip->sdio_aspm = 0; + } + } +} +#endif + +void do_reset_sd_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->sd_reset_counter, chip->card2lun[SD_CARD]); + + if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_sd_card(chip); + if (chip->need_release & SD_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + chip->card_ready |= SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; + } else { + if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + } else { + chip->sd_reset_counter++; + } + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->rw_card[chip->card2lun[SD_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, SD_CARD); + if (chip->sd_io) { + chip->sd_int = 0; + try_to_switch_sdio_ctrl(chip); + } else { + disable_card_clock(chip, SD_CARD); + } + } +} + +void do_reset_xd_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->xd_reset_counter, chip->card2lun[XD_CARD]); + + if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_xd_card(chip); + if (chip->need_release & XD_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->card_ready |= XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; + } else { + if (chip->xd_reset_counter >= MAX_RESET_CNT) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + } else { + chip->xd_reset_counter++; + } + chip->card_ready &= ~XD_CARD; + chip->card_fail |= XD_CARD; + chip->capacity[chip->card2lun[XD_CARD]] = 0; + chip->rw_card[chip->card2lun[XD_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, XD_CARD); + disable_card_clock(chip, XD_CARD); + } +} + +void do_reset_ms_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->ms_reset_counter, chip->card2lun[MS_CARD]); + + if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_ms_card(chip); + if (chip->need_release & MS_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->card_ready |= MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; + } else { + if (chip->ms_reset_counter >= MAX_RESET_CNT) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + } else { + chip->ms_reset_counter++; + } + chip->card_ready &= ~MS_CARD; + chip->card_fail |= MS_CARD; + chip->capacity[chip->card2lun[MS_CARD]] = 0; + chip->rw_card[chip->card2lun[MS_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, MS_CARD); + disable_card_clock(chip, MS_CARD); + } +} + +static void release_sdio(struct rtsx_chip *chip) +{ + if (chip->sd_io) { + rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + + if (chip->chip_insert_with_sdio) { + chip->chip_insert_with_sdio = 0; + + if (CHECK_PID(chip, 0x5288)) + rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); + else + rtsx_write_register(chip, 0xFE70, 0x80, 0x00); + } + + rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); + chip->sd_io = 0; + } +} + +void rtsx_power_off_card(struct rtsx_chip *chip) +{ + if ((chip->card_ready & SD_CARD) || chip->sd_io) { + sd_cleanup_work(chip); + sd_power_off_card3v3(chip); + } + + if (chip->card_ready & XD_CARD) { + xd_cleanup_work(chip); + xd_power_off_card3v3(chip); + } + + if (chip->card_ready & MS_CARD) { + ms_cleanup_work(chip); + ms_power_off_card3v3(chip); + } +} + +void rtsx_release_cards(struct rtsx_chip *chip) +{ + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if ((chip->card_ready & SD_CARD) || chip->sd_io) { + if (chip->int_reg & SD_EXIST) + sd_cleanup_work(chip); + release_sd_card(chip); + } + + if (chip->card_ready & XD_CARD) { + if (chip->int_reg & XD_EXIST) + xd_cleanup_work(chip); + release_xd_card(chip); + } + + if (chip->card_ready & MS_CARD) { + if (chip->int_reg & MS_EXIST) + ms_cleanup_work(chip); + release_ms_card(chip); + } +} + +void rtsx_reset_cards(struct rtsx_chip *chip) +{ + if (!chip->need_reset) + return; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + + rtsx_disable_aspm(chip); + + if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) + clear_bit(SD_NR, &(chip->need_reset)); + + if (chip->need_reset & XD_CARD) { + chip->card_exist |= XD_CARD; + + if (chip->xd_show_cnt >= MAX_SHOW_CNT) + do_reset_xd_card(chip); + else + chip->xd_show_cnt++; + } + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { + if (chip->card_exist & XD_CARD) { + clear_bit(SD_NR, &(chip->need_reset)); + clear_bit(MS_NR, &(chip->need_reset)); + } + } + if (chip->need_reset & SD_CARD) { + chip->card_exist |= SD_CARD; + + if (chip->sd_show_cnt >= MAX_SHOW_CNT) { + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + do_reset_sd_card(chip); + } else { + chip->sd_show_cnt++; + } + } + if (chip->need_reset & MS_CARD) { + chip->card_exist |= MS_CARD; + + if (chip->ms_show_cnt >= MAX_SHOW_CNT) + do_reset_ms_card(chip); + else + chip->ms_show_cnt++; + } +} + +void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) +{ + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + + if (reset_chip) + rtsx_reset_chip(chip); + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { + release_sdio(chip); + release_sd_card(chip); + + wait_timeout(100); + + chip->card_exist |= SD_CARD; + do_reset_sd_card(chip); + } + + if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { + release_xd_card(chip); + + wait_timeout(100); + + chip->card_exist |= XD_CARD; + do_reset_xd_card(chip); + } + + if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { + release_ms_card(chip); + + wait_timeout(100); + + chip->card_exist |= MS_CARD; + do_reset_ms_card(chip); + } + + chip->need_reinit = 0; +} + +#ifdef DISABLE_CARD_INT +void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release) +{ + u8 release_map = 0, reset_map = 0; + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (chip->card_exist) { + if (chip->card_exist & XD_CARD) { + if (!(chip->int_reg & XD_EXIST)) + release_map |= XD_CARD; + } else if (chip->card_exist & SD_CARD) { + if (!(chip->int_reg & SD_EXIST)) + release_map |= SD_CARD; + } else if (chip->card_exist & MS_CARD) { + if (!(chip->int_reg & MS_EXIST)) + release_map |= MS_CARD; + } + } else { + if (chip->int_reg & XD_EXIST) + reset_map |= XD_CARD; + else if (chip->int_reg & SD_EXIST) + reset_map |= SD_CARD; + else if (chip->int_reg & MS_EXIST) + reset_map |= MS_CARD; + } + + if (reset_map) { + int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; + int i; + + for (i = 0; i < (DEBOUNCE_CNT); i++) { + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (chip->int_reg & XD_EXIST) + xd_cnt++; + else + xd_cnt = 0; + + if (chip->int_reg & SD_EXIST) + sd_cnt++; + else + sd_cnt = 0; + + if (chip->int_reg & MS_EXIST) + ms_cnt++; + else + ms_cnt = 0; + + wait_timeout(30); + } + + reset_map = 0; + if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1))) + reset_map |= XD_CARD; + if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1))) + reset_map |= SD_CARD; + if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1))) + reset_map |= MS_CARD; + } + + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); + + if (need_reset) + *need_reset = reset_map; + if (need_release) + *need_release = release_map; +} +#endif + +void rtsx_init_cards(struct rtsx_chip *chip) +{ + if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { + RTSX_DEBUGP("Reset chip in polling thread!\n"); + rtsx_reset_chip(chip); + RTSX_CLR_DELINK(chip); + } + +#ifdef DISABLE_CARD_INT + card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release)); +#endif + + if (chip->need_release) { + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { + if (chip->int_reg & XD_EXIST) { + clear_bit(SD_NR, &(chip->need_release)); + clear_bit(MS_NR, &(chip->need_release)); + } + } + + if (!(chip->card_exist & SD_CARD) && !chip->sd_io) + clear_bit(SD_NR, &(chip->need_release)); + if (!(chip->card_exist & XD_CARD)) + clear_bit(XD_NR, &(chip->need_release)); + if (!(chip->card_exist & MS_CARD)) + clear_bit(MS_NR, &(chip->need_release)); + + RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release)); + +#ifdef SUPPORT_OCP + if (chip->need_release) { + if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) + rtsx_write_register(chip, OCPCLR, + CARD_OC_INT_CLR | CARD_OC_CLR, + CARD_OC_INT_CLR | CARD_OC_CLR); + chip->ocp_stat = 0; + } +#endif + if (chip->need_release) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + } + + if (chip->need_release & SD_CARD) { + clear_bit(SD_NR, &(chip->need_release)); + chip->card_exist &= ~SD_CARD; + chip->card_ejected &= ~SD_CARD; + chip->card_fail &= ~SD_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); + chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + + release_sdio(chip); + release_sd_card(chip); + } + + if (chip->need_release & XD_CARD) { + clear_bit(XD_NR, &(chip->need_release)); + chip->card_exist &= ~XD_CARD; + chip->card_ejected &= ~XD_CARD; + chip->card_fail &= ~XD_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); + chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; + + release_xd_card(chip); + + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0); + } + + if (chip->need_release & MS_CARD) { + clear_bit(MS_NR, &(chip->need_release)); + chip->card_exist &= ~MS_CARD; + chip->card_ejected &= ~MS_CARD; + chip->card_fail &= ~MS_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); + chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; + + release_ms_card(chip); + } + + RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist); + + if (!chip->card_exist) + turn_off_led(chip, LED_GPIO); + } + + if (chip->need_reset) { + RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); + + rtsx_reset_cards(chip); + } + + if (chip->need_reinit) { + RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit)); + + rtsx_reinit_cards(chip, 0); + } +} + +static inline u8 double_depth(u8 depth) +{ + return ((depth > 1) ? (depth - 1) : depth); +} + +int switch_ssc_clock(struct rtsx_chip *chip, int clk) +{ + int retval; + u8 N = (u8)(clk - 2), min_N, max_N; + u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + min_N = 60; + max_N = 120; + max_div = CLK_DIV_4; + + RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); + + if ((clk <= 2) || (N > max_N)) + TRACE_RET(chip, STATUS_FAIL); + + mcu_cnt = (u8)(125/clk + 3); + if (mcu_cnt > 7) + mcu_cnt = 7; + + div = CLK_DIV_1; + while ((N < min_N) && (div < max_div)) { + N = (N + 2) * 2 - 2; + div++; + } + RTSX_DEBUGP("N = %d, div = %d\n", N, div); + + if (chip->ssc_en) { + ssc_depth = 0x01; + N -= 2; + } else { + ssc_depth = 0; + } + + ssc_depth_mask = 0x03; + + RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); + if (sd_vpclk_phase_reset) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + } + + retval = rtsx_send_cmd(chip, 0, WAIT_TIME); + if (retval < 0) + TRACE_RET(chip, STATUS_ERROR); + + udelay(10); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +int switch_normal_clock(struct rtsx_chip *chip, int clk) +{ + u8 sel, div, mcu_cnt; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + switch (clk) { + case CLK_20: + RTSX_DEBUGP("Switch clock to 20MHz\n"); + sel = SSC_80; + div = CLK_DIV_4; + mcu_cnt = 7; + break; + + case CLK_30: + RTSX_DEBUGP("Switch clock to 30MHz\n"); + sel = SSC_120; + div = CLK_DIV_4; + mcu_cnt = 7; + break; + + case CLK_40: + RTSX_DEBUGP("Switch clock to 40MHz\n"); + sel = SSC_80; + div = CLK_DIV_2; + mcu_cnt = 7; + break; + + case CLK_50: + RTSX_DEBUGP("Switch clock to 50MHz\n"); + sel = SSC_100; + div = CLK_DIV_2; + mcu_cnt = 6; + break; + + case CLK_60: + RTSX_DEBUGP("Switch clock to 60MHz\n"); + sel = SSC_120; + div = CLK_DIV_2; + mcu_cnt = 6; + break; + + case CLK_80: + RTSX_DEBUGP("Switch clock to 80MHz\n"); + sel = SSC_80; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_100: + RTSX_DEBUGP("Switch clock to 100MHz\n"); + sel = SSC_100; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_120: + RTSX_DEBUGP("Switch clock to 120MHz\n"); + sel = SSC_120; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_150: + RTSX_DEBUGP("Switch clock to 150MHz\n"); + sel = SSC_150; + div = CLK_DIV_1; + mcu_cnt = 4; + break; + + case CLK_200: + RTSX_DEBUGP("Switch clock to 200MHz\n"); + sel = SSC_200; + div = CLK_DIV_1; + mcu_cnt = 4; + break; + + default: + RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); + if (sd_vpclk_phase_reset) { + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0); + } + RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); + RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel); + + if (sd_vpclk_phase_reset) { + udelay(200); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + udelay(200); + } + RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0); + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size) +{ + if (pack_size > DMA_1024) + pack_size = DMA_512; + + rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); + + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); + + if (dir == DMA_FROM_DEVICE) { + rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_FROM_CARD | DMA_EN | pack_size); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_TO_CARD | DMA_EN | pack_size); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); +} + +int enable_card_clock(struct rtsx_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en); + + return STATUS_SUCCESS; +} + +int disable_card_clock(struct rtsx_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); + + return STATUS_SUCCESS; +} + +int card_power_on(struct rtsx_chip *chip, u8 card) +{ + int retval; + u8 mask, val1, val2; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { + mask = MS_POWER_MASK; + val1 = MS_PARTIAL_POWER_ON; + val2 = MS_POWER_ON; + } else { + mask = SD_POWER_MASK; + val1 = SD_PARTIAL_POWER_ON; + val2 = SD_POWER_ON; + } + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + udelay(chip->pmos_pwr_on_interval); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int card_power_off(struct rtsx_chip *chip, u8 card) +{ + u8 mask, val; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { + mask = MS_POWER_MASK; + val = MS_POWER_OFF; + } else { + mask = SD_POWER_MASK; + val = SD_POWER_OFF; + } + + RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); + + return STATUS_SUCCESS; +} + +int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt) +{ + int retval; + unsigned int lun = SCSI_LUN(srb); + int i; + + if (chip->rw_card[lun] == NULL) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < 3; i++) { + chip->rw_need_retry = 0; + + retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); + if (retval != STATUS_SUCCESS) { + if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { + rtsx_release_chip(chip); + TRACE_RET(chip, STATUS_FAIL); + } + if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->rw_need_retry) { + RTSX_DEBUGP("RW fail, but no need to retry\n"); + break; + } + } else { + chip->rw_need_retry = 0; + break; + } + + RTSX_DEBUGP("Retry RW, (i = %d)\n", i); + } + + return retval; +} + +int card_share_mode(struct rtsx_chip *chip, int card) +{ + u8 mask, value; + + if (CHECK_PID(chip, 0x5208)) { + mask = CARD_SHARE_MASK; + if (card == SD_CARD) + value = CARD_SHARE_48_SD; + else if (card == MS_CARD) + value = CARD_SHARE_48_MS; + else if (card == XD_CARD) + value = CARD_SHARE_48_XD; + else + TRACE_RET(chip, STATUS_FAIL); + + } else if (CHECK_PID(chip, 0x5288)) { + mask = 0x03; + if (card == SD_CARD) + value = CARD_SHARE_BAROSSA_SD; + else if (card == MS_CARD) + value = CARD_SHARE_BAROSSA_MS; + else if (card == XD_CARD) + value = CARD_SHARE_BAROSSA_XD; + else + TRACE_RET(chip, STATUS_FAIL); + + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value); + + return STATUS_SUCCESS; +} + + +int select_card(struct rtsx_chip *chip, int card) +{ + int retval; + + if (chip->cur_card != card) { + u8 mod; + + if (card == SD_CARD) + mod = SD_MOD_SEL; + else if (card == MS_CARD) + mod = MS_MOD_SEL; + else if (card == XD_CARD) + mod = XD_MOD_SEL; + else if (card == SPI_CARD) + mod = SPI_MOD_SEL; + else + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod); + chip->cur_card = card; + + retval = card_share_mode(chip, card); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +void toggle_gpio(struct rtsx_chip *chip, u8 gpio) +{ + u8 temp_reg; + + rtsx_read_register(chip, CARD_GPIO, &temp_reg); + temp_reg ^= (0x01 << gpio); + rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); +} + +void turn_on_led(struct rtsx_chip *chip, u8 gpio) +{ + if (CHECK_PID(chip, 0x5288)) + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); + else + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); +} + +void turn_off_led(struct rtsx_chip *chip, u8 gpio) +{ + if (CHECK_PID(chip, 0x5288)) + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); + else + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); +} + +int detect_card_cd(struct rtsx_chip *chip, int card) +{ + u32 card_cd, status; + + if (card == SD_CARD) { + card_cd = SD_EXIST; + } else if (card == MS_CARD) { + card_cd = MS_EXIST; + } else if (card == XD_CARD) { + card_cd = XD_EXIST; + } else { + RTSX_DEBUGP("Wrong card type: 0x%x\n", card); + TRACE_RET(chip, STATUS_FAIL); + } + + status = rtsx_readl(chip, RTSX_BIPR); + if (!(status & card_cd)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int check_card_exist(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_exist & chip->lun2card[lun]) + return 1; + + return 0; +} + +int check_card_ready(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_ready & chip->lun2card[lun]) + return 1; + + return 0; +} + +int check_card_wp(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_wp & chip->lun2card[lun]) + return 1; + + return 0; +} + +int check_card_fail(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_fail & chip->lun2card[lun]) + return 1; + + return 0; +} + +int check_card_ejected(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_ejected & chip->lun2card[lun]) + return 1; + + return 0; +} + +u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) +{ + if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) + return (u8)XD_CARD; + else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) + return (u8)SD_CARD; + else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) + return (u8)MS_CARD; + + return 0; +} + +void eject_card(struct rtsx_chip *chip, unsigned int lun) +{ + do_remaining_work(chip); + + if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { + release_sd_card(chip); + chip->card_ejected |= SD_CARD; + chip->card_ready &= ~SD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { + release_xd_card(chip); + chip->card_ejected |= XD_CARD; + chip->card_ready &= ~XD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { + release_ms_card(chip); + chip->card_ejected |= MS_CARD; + chip->card_ready &= ~MS_CARD; + chip->capacity[lun] = 0; + } +} diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h new file mode 100644 index 000000000000..4528b619f6b3 --- /dev/null +++ b/drivers/staging/rts5208/rtsx_card.h @@ -0,0 +1,1098 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_CARD_H +#define __REALTEK_RTSX_CARD_H + +#include "debug.h" +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_transport.h" +#include "sd.h" + +#define SSC_POWER_DOWN 0x01 +#define SD_OC_POWER_DOWN 0x02 +#define MS_OC_POWER_DOWN 0x04 +#define ALL_POWER_DOWN 0x07 +#define OC_POWER_DOWN 0x06 + +#define PMOS_STRG_MASK 0x10 +#define PMOS_STRG_800mA 0x10 +#define PMOS_STRG_400mA 0x00 + +#define POWER_OFF 0x03 +#define PARTIAL_POWER_ON 0x01 +#define POWER_ON 0x00 + +#define MS_POWER_OFF 0x0C +#define MS_PARTIAL_POWER_ON 0x04 +#define MS_POWER_ON 0x00 +#define MS_POWER_MASK 0x0C + +#define SD_POWER_OFF 0x03 +#define SD_PARTIAL_POWER_ON 0x01 +#define SD_POWER_ON 0x00 +#define SD_POWER_MASK 0x03 + +#define XD_OUTPUT_EN 0x02 +#define SD_OUTPUT_EN 0x04 +#define MS_OUTPUT_EN 0x08 +#define SPI_OUTPUT_EN 0x10 + +#define CLK_LOW_FREQ 0x01 + +#define CLK_DIV_1 0x01 +#define CLK_DIV_2 0x02 +#define CLK_DIV_4 0x03 +#define CLK_DIV_8 0x04 + +#define SSC_80 0 +#define SSC_100 1 +#define SSC_120 2 +#define SSC_150 3 +#define SSC_200 4 + +#define XD_CLK_EN 0x02 +#define SD_CLK_EN 0x04 +#define MS_CLK_EN 0x08 +#define SPI_CLK_EN 0x10 + +#define XD_MOD_SEL 1 +#define SD_MOD_SEL 2 +#define MS_MOD_SEL 3 +#define SPI_MOD_SEL 4 + +#define CHANGE_CLK 0x01 + +#define SD_CRC7_ERR 0x80 +#define SD_CRC16_ERR 0x40 +#define SD_CRC_WRITE_ERR 0x20 +#define SD_CRC_WRITE_ERR_MASK 0x1C +#define GET_CRC_TIME_OUT 0x02 +#define SD_TUNING_COMPARE_ERR 0x01 + +#define SD_RSP_80CLK_TIMEOUT 0x01 + +#define SD_CLK_TOGGLE_EN 0x80 +#define SD_CLK_FORCE_STOP 0x40 +#define SD_DAT3_STATUS 0x10 +#define SD_DAT2_STATUS 0x08 +#define SD_DAT1_STATUS 0x04 +#define SD_DAT0_STATUS 0x02 +#define SD_CMD_STATUS 0x01 + +#define SD_IO_USING_1V8 0x80 +#define SD_IO_USING_3V3 0x7F +#define TYPE_A_DRIVING 0x00 +#define TYPE_B_DRIVING 0x01 +#define TYPE_C_DRIVING 0x02 +#define TYPE_D_DRIVING 0x03 + +#define DDR_FIX_RX_DAT 0x00 +#define DDR_VAR_RX_DAT 0x80 +#define DDR_FIX_RX_DAT_EDGE 0x00 +#define DDR_FIX_RX_DAT_14_DELAY 0x40 +#define DDR_FIX_RX_CMD 0x00 +#define DDR_VAR_RX_CMD 0x20 +#define DDR_FIX_RX_CMD_POS_EDGE 0x00 +#define DDR_FIX_RX_CMD_14_DELAY 0x10 +#define SD20_RX_POS_EDGE 0x00 +#define SD20_RX_14_DELAY 0x08 +#define SD20_RX_SEL_MASK 0x08 + +#define DDR_FIX_TX_CMD_DAT 0x00 +#define DDR_VAR_TX_CMD_DAT 0x80 +#define DDR_FIX_TX_DAT_14_TSU 0x00 +#define DDR_FIX_TX_DAT_12_TSU 0x40 +#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 +#define DDR_FIX_TX_CMD_14_AHEAD 0x20 +#define SD20_TX_NEG_EDGE 0x00 +#define SD20_TX_14_AHEAD 0x10 +#define SD20_TX_SEL_MASK 0x10 +#define DDR_VAR_SDCLK_POL_SWAP 0x01 + +#define SD_TRANSFER_START 0x80 +#define SD_TRANSFER_END 0x40 +#define SD_STAT_IDLE 0x20 +#define SD_TRANSFER_ERR 0x10 +#define SD_TM_NORMAL_WRITE 0x00 +#define SD_TM_AUTO_WRITE_3 0x01 +#define SD_TM_AUTO_WRITE_4 0x02 +#define SD_TM_AUTO_READ_3 0x05 +#define SD_TM_AUTO_READ_4 0x06 +#define SD_TM_CMD_RSP 0x08 +#define SD_TM_AUTO_WRITE_1 0x09 +#define SD_TM_AUTO_WRITE_2 0x0A +#define SD_TM_NORMAL_READ 0x0C +#define SD_TM_AUTO_READ_1 0x0D +#define SD_TM_AUTO_READ_2 0x0E +#define SD_TM_AUTO_TUNING 0x0F + +#define PHASE_CHANGE 0x80 +#define PHASE_NOT_RESET 0x40 + +#define DCMPS_CHANGE 0x80 +#define DCMPS_CHANGE_DONE 0x40 +#define DCMPS_ERROR 0x20 +#define DCMPS_CURRENT_PHASE 0x1F + +#define SD_CLK_DIVIDE_0 0x00 +#define SD_CLK_DIVIDE_256 0xC0 +#define SD_CLK_DIVIDE_128 0x80 +#define SD_BUS_WIDTH_1 0x00 +#define SD_BUS_WIDTH_4 0x01 +#define SD_BUS_WIDTH_8 0x02 +#define SD_ASYNC_FIFO_NOT_RST 0x10 +#define SD_20_MODE 0x00 +#define SD_DDR_MODE 0x04 +#define SD_30_MODE 0x08 + +#define SD_CLK_DIVIDE_MASK 0xC0 + +#define SD_CMD_IDLE 0x80 + +#define SD_DATA_IDLE 0x80 + +#define DCM_RESET 0x08 +#define DCM_LOCKED 0x04 +#define DCM_208M 0x00 +#define DCM_TX 0x01 +#define DCM_RX 0x02 + +#define DRP_START 0x80 +#define DRP_DONE 0x40 + +#define DRP_WRITE 0x80 +#define DRP_READ 0x00 +#define DCM_WRITE_ADDRESS_50 0x50 +#define DCM_WRITE_ADDRESS_51 0x51 +#define DCM_READ_ADDRESS_00 0x00 +#define DCM_READ_ADDRESS_51 0x51 + +#define SD_CALCULATE_CRC7 0x00 +#define SD_NO_CALCULATE_CRC7 0x80 +#define SD_CHECK_CRC16 0x00 +#define SD_NO_CHECK_CRC16 0x40 +#define SD_NO_CHECK_WAIT_CRC_TO 0x20 +#define SD_WAIT_BUSY_END 0x08 +#define SD_NO_WAIT_BUSY_END 0x00 +#define SD_CHECK_CRC7 0x00 +#define SD_NO_CHECK_CRC7 0x04 +#define SD_RSP_LEN_0 0x00 +#define SD_RSP_LEN_6 0x01 +#define SD_RSP_LEN_17 0x02 +#define SD_RSP_TYPE_R0 0x04 +#define SD_RSP_TYPE_R1 0x01 +#define SD_RSP_TYPE_R1b 0x09 +#define SD_RSP_TYPE_R2 0x02 +#define SD_RSP_TYPE_R3 0x05 +#define SD_RSP_TYPE_R4 0x05 +#define SD_RSP_TYPE_R5 0x01 +#define SD_RSP_TYPE_R6 0x01 +#define SD_RSP_TYPE_R7 0x01 + +#define SD_RSP_80CLK_TIMEOUT_EN 0x01 + +#define SAMPLE_TIME_RISING 0x00 +#define SAMPLE_TIME_FALLING 0x80 +#define PUSH_TIME_DEFAULT 0x00 +#define PUSH_TIME_ODD 0x40 +#define NO_EXTEND_TOGGLE 0x00 +#define EXTEND_TOGGLE_CHK 0x20 +#define MS_BUS_WIDTH_1 0x00 +#define MS_BUS_WIDTH_4 0x10 +#define MS_BUS_WIDTH_8 0x18 +#define MS_2K_SECTOR_MODE 0x04 +#define MS_512_SECTOR_MODE 0x00 +#define MS_TOGGLE_TIMEOUT_EN 0x00 +#define MS_TOGGLE_TIMEOUT_DISEN 0x01 +#define MS_NO_CHECK_INT 0x02 + +#define WAIT_INT 0x80 +#define NO_WAIT_INT 0x00 +#define NO_AUTO_READ_INT_REG 0x00 +#define AUTO_READ_INT_REG 0x40 +#define MS_CRC16_ERR 0x20 +#define MS_RDY_TIMEOUT 0x10 +#define MS_INT_CMDNK 0x08 +#define MS_INT_BREQ 0x04 +#define MS_INT_ERR 0x02 +#define MS_INT_CED 0x01 + +#define MS_TRANSFER_START 0x80 +#define MS_TRANSFER_END 0x40 +#define MS_TRANSFER_ERR 0x20 +#define MS_BS_STATE 0x10 +#define MS_TM_READ_BYTES 0x00 +#define MS_TM_NORMAL_READ 0x01 +#define MS_TM_WRITE_BYTES 0x04 +#define MS_TM_NORMAL_WRITE 0x05 +#define MS_TM_AUTO_READ 0x08 +#define MS_TM_AUTO_WRITE 0x0C + +#define CARD_SHARE_MASK 0x0F +#define CARD_SHARE_MULTI_LUN 0x00 +#define CARD_SHARE_NORMAL 0x00 +#define CARD_SHARE_48_XD 0x02 +#define CARD_SHARE_48_SD 0x04 +#define CARD_SHARE_48_MS 0x08 +#define CARD_SHARE_BAROSSA_XD 0x00 +#define CARD_SHARE_BAROSSA_SD 0x01 +#define CARD_SHARE_BAROSSA_MS 0x02 + +#define MS_DRIVE_8 0x00 +#define MS_DRIVE_4 0x40 +#define MS_DRIVE_12 0x80 +#define SD_DRIVE_8 0x00 +#define SD_DRIVE_4 0x10 +#define SD_DRIVE_12 0x20 +#define XD_DRIVE_8 0x00 +#define XD_DRIVE_4 0x04 +#define XD_DRIVE_12 0x08 + +#define SPI_STOP 0x01 +#define XD_STOP 0x02 +#define SD_STOP 0x04 +#define MS_STOP 0x08 +#define SPI_CLR_ERR 0x10 +#define XD_CLR_ERR 0x20 +#define SD_CLR_ERR 0x40 +#define MS_CLR_ERR 0x80 + +#define CRC_FIX_CLK (0x00 << 0) +#define CRC_VAR_CLK0 (0x01 << 0) +#define CRC_VAR_CLK1 (0x02 << 0) +#define SD30_FIX_CLK (0x00 << 2) +#define SD30_VAR_CLK0 (0x01 << 2) +#define SD30_VAR_CLK1 (0x02 << 2) +#define SAMPLE_FIX_CLK (0x00 << 4) +#define SAMPLE_VAR_CLK0 (0x01 << 4) +#define SAMPLE_VAR_CLK1 (0x02 << 4) + +#define SDIO_VER_20 0x80 +#define SDIO_VER_10 0x00 +#define SDIO_VER_CHG 0x40 +#define SDIO_BUS_AUTO_SWITCH 0x10 + +#define PINGPONG_BUFFER 0x01 +#define RING_BUFFER 0x00 + +#define RB_FLUSH 0x80 + +#define DMA_DONE_INT_EN 0x80 +#define SUSPEND_INT_EN 0x40 +#define LINK_RDY_INT_EN 0x20 +#define LINK_DOWN_INT_EN 0x10 + +#define DMA_DONE_INT 0x80 +#define SUSPEND_INT 0x40 +#define LINK_RDY_INT 0x20 +#define LINK_DOWN_INT 0x10 + +#define MRD_ERR_INT_EN 0x40 +#define MWR_ERR_INT_EN 0x20 +#define SCSI_CMD_INT_EN 0x10 +#define TLP_RCV_INT_EN 0x08 +#define TLP_TRSMT_INT_EN 0x04 +#define MRD_COMPLETE_INT_EN 0x02 +#define MWR_COMPLETE_INT_EN 0x01 + +#define MRD_ERR_INT 0x40 +#define MWR_ERR_INT 0x20 +#define SCSI_CMD_INT 0x10 +#define TLP_RX_INT 0x08 +#define TLP_TX_INT 0x04 +#define MRD_COMPLETE_INT 0x02 +#define MWR_COMPLETE_INT 0x01 + +#define MSG_RX_INT_EN 0x08 +#define MRD_RX_INT_EN 0x04 +#define MWR_RX_INT_EN 0x02 +#define CPLD_RX_INT_EN 0x01 + +#define MSG_RX_INT 0x08 +#define MRD_RX_INT 0x04 +#define MWR_RX_INT 0x02 +#define CPLD_RX_INT 0x01 + +#define MSG_TX_INT_EN 0x08 +#define MRD_TX_INT_EN 0x04 +#define MWR_TX_INT_EN 0x02 +#define CPLD_TX_INT_EN 0x01 + +#define MSG_TX_INT 0x08 +#define MRD_TX_INT 0x04 +#define MWR_TX_INT 0x02 +#define CPLD_TX_INT 0x01 + +#define DMA_RST 0x80 +#define DMA_BUSY 0x04 +#define DMA_DIR_TO_CARD 0x00 +#define DMA_DIR_FROM_CARD 0x02 +#define DMA_EN 0x01 +#define DMA_128 (0 << 4) +#define DMA_256 (1 << 4) +#define DMA_512 (2 << 4) +#define DMA_1024 (3 << 4) +#define DMA_PACK_SIZE_MASK 0x30 + +#define XD_PWR_OFF_DELAY0 0x00 +#define XD_PWR_OFF_DELAY1 0x02 +#define XD_PWR_OFF_DELAY2 0x04 +#define XD_PWR_OFF_DELAY3 0x06 +#define XD_AUTO_PWR_OFF_EN 0xF7 +#define XD_NO_AUTO_PWR_OFF 0x08 + +#define XD_TIME_RWN_1 0x00 +#define XD_TIME_RWN_STEP 0x20 +#define XD_TIME_RW_1 0x00 +#define XD_TIME_RW_STEP 0x04 +#define XD_TIME_SETUP_1 0x00 +#define XD_TIME_SETUP_STEP 0x01 + +#define XD_ECC2_UNCORRECTABLE 0x80 +#define XD_ECC2_ERROR 0x40 +#define XD_ECC1_UNCORRECTABLE 0x20 +#define XD_ECC1_ERROR 0x10 +#define XD_RDY 0x04 +#define XD_CE_EN 0xFD +#define XD_CE_DISEN 0x02 +#define XD_WP_EN 0xFE +#define XD_WP_DISEN 0x01 + +#define XD_TRANSFER_START 0x80 +#define XD_TRANSFER_END 0x40 +#define XD_PPB_EMPTY 0x20 +#define XD_RESET 0x00 +#define XD_ERASE 0x01 +#define XD_READ_STATUS 0x02 +#define XD_READ_ID 0x03 +#define XD_READ_REDUNDANT 0x04 +#define XD_READ_PAGES 0x05 +#define XD_SET_CMD 0x06 +#define XD_NORMAL_READ 0x07 +#define XD_WRITE_PAGES 0x08 +#define XD_NORMAL_WRITE 0x09 +#define XD_WRITE_REDUNDANT 0x0A +#define XD_SET_ADDR 0x0B + +#define XD_PPB_TO_SIE 0x80 +#define XD_TO_PPB_ONLY 0x00 +#define XD_BA_TRANSFORM 0x40 +#define XD_BA_NO_TRANSFORM 0x00 +#define XD_NO_CALC_ECC 0x20 +#define XD_CALC_ECC 0x00 +#define XD_IGNORE_ECC 0x10 +#define XD_CHECK_ECC 0x00 +#define XD_DIRECT_TO_RB 0x08 +#define XD_ADDR_LENGTH_0 0x00 +#define XD_ADDR_LENGTH_1 0x01 +#define XD_ADDR_LENGTH_2 0x02 +#define XD_ADDR_LENGTH_3 0x03 +#define XD_ADDR_LENGTH_4 0x04 + +#define XD_GPG 0xFF +#define XD_BPG 0x00 + +#define XD_GBLK 0xFF +#define XD_LATER_BBLK 0xF0 + +#define XD_ECC2_ALL1 0x80 +#define XD_ECC1_ALL1 0x40 +#define XD_BA2_ALL0 0x20 +#define XD_BA1_ALL0 0x10 +#define XD_BA1_BA2_EQL 0x04 +#define XD_BA2_VALID 0x02 +#define XD_BA1_VALID 0x01 + +#define XD_PGSTS_ZEROBIT_OVER4 0x00 +#define XD_PGSTS_NOT_FF 0x02 +#define XD_AUTO_CHK_DATA_STATUS 0x01 + +#define RSTB_MODE_DETECT 0x80 +#define MODE_OUT_VLD 0x40 +#define MODE_OUT_0_NONE 0x00 +#define MODE_OUT_10_NONE 0x04 +#define MODE_OUT_10_47 0x05 +#define MODE_OUT_10_180 0x06 +#define MODE_OUT_10_680 0x07 +#define MODE_OUT_16_NONE 0x08 +#define MODE_OUT_16_47 0x09 +#define MODE_OUT_16_180 0x0A +#define MODE_OUT_16_680 0x0B +#define MODE_OUT_NONE_NONE 0x0C +#define MODE_OUT_NONE_47 0x0D +#define MODE_OUT_NONE_180 0x0E +#define MODE_OUT_NONE_680 0x0F + +#define CARD_OC_INT_EN 0x20 +#define CARD_DETECT_EN 0x08 + +#define MS_DETECT_EN 0x80 +#define MS_OCP_INT_EN 0x40 +#define MS_OCP_INT_CLR 0x20 +#define MS_OC_CLR 0x10 +#define SD_DETECT_EN 0x08 +#define SD_OCP_INT_EN 0x04 +#define SD_OCP_INT_CLR 0x02 +#define SD_OC_CLR 0x01 + +#define CARD_OCP_DETECT 0x80 +#define CARD_OC_NOW 0x08 +#define CARD_OC_EVER 0x04 + +#define MS_OCP_DETECT 0x80 +#define MS_OC_NOW 0x40 +#define MS_OC_EVER 0x20 +#define SD_OCP_DETECT 0x08 +#define SD_OC_NOW 0x04 +#define SD_OC_EVER 0x02 + +#define CARD_OC_INT_CLR 0x08 +#define CARD_OC_CLR 0x02 + +#define SD_OCP_GLITCH_MASK 0x07 +#define SD_OCP_GLITCH_6_4 0x00 +#define SD_OCP_GLITCH_64 0x01 +#define SD_OCP_GLITCH_640 0x02 +#define SD_OCP_GLITCH_1000 0x03 +#define SD_OCP_GLITCH_2000 0x04 +#define SD_OCP_GLITCH_4000 0x05 +#define SD_OCP_GLITCH_8000 0x06 +#define SD_OCP_GLITCH_10000 0x07 + +#define MS_OCP_GLITCH_MASK 0x70 +#define MS_OCP_GLITCH_6_4 (0x00 << 4) +#define MS_OCP_GLITCH_64 (0x01 << 4) +#define MS_OCP_GLITCH_640 (0x02 << 4) +#define MS_OCP_GLITCH_1000 (0x03 << 4) +#define MS_OCP_GLITCH_2000 (0x04 << 4) +#define MS_OCP_GLITCH_4000 (0x05 << 4) +#define MS_OCP_GLITCH_8000 (0x06 << 4) +#define MS_OCP_GLITCH_10000 (0x07 << 4) + +#define OCP_TIME_60 0x00 +#define OCP_TIME_100 (0x01 << 3) +#define OCP_TIME_200 (0x02 << 3) +#define OCP_TIME_400 (0x03 << 3) +#define OCP_TIME_600 (0x04 << 3) +#define OCP_TIME_800 (0x05 << 3) +#define OCP_TIME_1100 (0x06 << 3) +#define OCP_TIME_MASK 0x38 + +#define MS_OCP_TIME_60 0x00 +#define MS_OCP_TIME_100 (0x01 << 4) +#define MS_OCP_TIME_200 (0x02 << 4) +#define MS_OCP_TIME_400 (0x03 << 4) +#define MS_OCP_TIME_600 (0x04 << 4) +#define MS_OCP_TIME_800 (0x05 << 4) +#define MS_OCP_TIME_1100 (0x06 << 4) +#define MS_OCP_TIME_MASK 0x70 + +#define SD_OCP_TIME_60 0x00 +#define SD_OCP_TIME_100 0x01 +#define SD_OCP_TIME_200 0x02 +#define SD_OCP_TIME_400 0x03 +#define SD_OCP_TIME_600 0x04 +#define SD_OCP_TIME_800 0x05 +#define SD_OCP_TIME_1100 0x06 +#define SD_OCP_TIME_MASK 0x07 + +#define OCP_THD_315_417 0x00 +#define OCP_THD_283_783 (0x01 << 6) +#define OCP_THD_244_946 (0x02 << 6) +#define OCP_THD_191_1080 (0x03 << 6) +#define OCP_THD_MASK 0xC0 + +#define MS_OCP_THD_450 0x00 +#define MS_OCP_THD_550 (0x01 << 4) +#define MS_OCP_THD_650 (0x02 << 4) +#define MS_OCP_THD_750 (0x03 << 4) +#define MS_OCP_THD_850 (0x04 << 4) +#define MS_OCP_THD_950 (0x05 << 4) +#define MS_OCP_THD_1050 (0x06 << 4) +#define MS_OCP_THD_1150 (0x07 << 4) +#define MS_OCP_THD_MASK 0x70 + +#define SD_OCP_THD_450 0x00 +#define SD_OCP_THD_550 0x01 +#define SD_OCP_THD_650 0x02 +#define SD_OCP_THD_750 0x03 +#define SD_OCP_THD_850 0x04 +#define SD_OCP_THD_950 0x05 +#define SD_OCP_THD_1050 0x06 +#define SD_OCP_THD_1150 0x07 +#define SD_OCP_THD_MASK 0x07 + +#define FPGA_MS_PULL_CTL_EN 0xEF +#define FPGA_SD_PULL_CTL_EN 0xF7 +#define FPGA_XD_PULL_CTL_EN1 0xFE +#define FPGA_XD_PULL_CTL_EN2 0xFD +#define FPGA_XD_PULL_CTL_EN3 0xFB + +#define FPGA_MS_PULL_CTL_BIT 0x10 +#define FPGA_SD_PULL_CTL_BIT 0x08 + +#define BLINK_EN 0x08 +#define LED_GPIO0 (0 << 4) +#define LED_GPIO1 (1 << 4) +#define LED_GPIO2 (2 << 4) + +#define SDIO_BUS_CTRL 0x01 +#define SDIO_CD_CTRL 0x02 + +#define SSC_RSTB 0x80 +#define SSC_8X_EN 0x40 +#define SSC_FIX_FRAC 0x20 +#define SSC_SEL_1M 0x00 +#define SSC_SEL_2M 0x08 +#define SSC_SEL_4M 0x10 +#define SSC_SEL_8M 0x18 + +#define SSC_DEPTH_MASK 0x07 +#define SSC_DEPTH_DISALBE 0x00 +#define SSC_DEPTH_4M 0x01 +#define SSC_DEPTH_2M 0x02 +#define SSC_DEPTH_1M 0x03 +#define SSC_DEPTH_512K 0x04 +#define SSC_DEPTH_256K 0x05 +#define SSC_DEPTH_128K 0x06 +#define SSC_DEPTH_64K 0x07 + +#define XD_D3_NP 0x00 +#define XD_D3_PD (0x01 << 6) +#define XD_D3_PU (0x02 << 6) +#define XD_D2_NP 0x00 +#define XD_D2_PD (0x01 << 4) +#define XD_D2_PU (0x02 << 4) +#define XD_D1_NP 0x00 +#define XD_D1_PD (0x01 << 2) +#define XD_D1_PU (0x02 << 2) +#define XD_D0_NP 0x00 +#define XD_D0_PD 0x01 +#define XD_D0_PU 0x02 + +#define SD_D7_NP 0x00 +#define SD_D7_PD (0x01 << 4) +#define SD_DAT7_PU (0x02 << 4) +#define SD_CLK_NP 0x00 +#define SD_CLK_PD (0x01 << 2) +#define SD_CLK_PU (0x02 << 2) +#define SD_D5_NP 0x00 +#define SD_D5_PD 0x01 +#define SD_D5_PU 0x02 + +#define MS_D1_NP 0x00 +#define MS_D1_PD (0x01 << 6) +#define MS_D1_PU (0x02 << 6) +#define MS_D2_NP 0x00 +#define MS_D2_PD (0x01 << 4) +#define MS_D2_PU (0x02 << 4) +#define MS_CLK_NP 0x00 +#define MS_CLK_PD (0x01 << 2) +#define MS_CLK_PU (0x02 << 2) +#define MS_D6_NP 0x00 +#define MS_D6_PD 0x01 +#define MS_D6_PU 0x02 + +#define XD_D7_NP 0x00 +#define XD_D7_PD (0x01 << 6) +#define XD_D7_PU (0x02 << 6) +#define XD_D6_NP 0x00 +#define XD_D6_PD (0x01 << 4) +#define XD_D6_PU (0x02 << 4) +#define XD_D5_NP 0x00 +#define XD_D5_PD (0x01 << 2) +#define XD_D5_PU (0x02 << 2) +#define XD_D4_NP 0x00 +#define XD_D4_PD 0x01 +#define XD_D4_PU 0x02 + +#define SD_D6_NP 0x00 +#define SD_D6_PD (0x01 << 6) +#define SD_D6_PU (0x02 << 6) +#define SD_D0_NP 0x00 +#define SD_D0_PD (0x01 << 4) +#define SD_D0_PU (0x02 << 4) +#define SD_D1_NP 0x00 +#define SD_D1_PD 0x01 +#define SD_D1_PU 0x02 + +#define MS_D3_NP 0x00 +#define MS_D3_PD (0x01 << 6) +#define MS_D3_PU (0x02 << 6) +#define MS_D0_NP 0x00 +#define MS_D0_PD (0x01 << 4) +#define MS_D0_PU (0x02 << 4) +#define MS_BS_NP 0x00 +#define MS_BS_PD (0x01 << 2) +#define MS_BS_PU (0x02 << 2) + +#define XD_WP_NP 0x00 +#define XD_WP_PD (0x01 << 6) +#define XD_WP_PU (0x02 << 6) +#define XD_CE_NP 0x00 +#define XD_CE_PD (0x01 << 3) +#define XD_CE_PU (0x02 << 3) +#define XD_CLE_NP 0x00 +#define XD_CLE_PD (0x01 << 1) +#define XD_CLE_PU (0x02 << 1) +#define XD_CD_PD 0x00 +#define XD_CD_PU 0x01 + +#define SD_D4_NP 0x00 +#define SD_D4_PD (0x01 << 6) +#define SD_D4_PU (0x02 << 6) + +#define MS_D7_NP 0x00 +#define MS_D7_PD (0x01 << 6) +#define MS_D7_PU (0x02 << 6) + +#define XD_RDY_NP 0x00 +#define XD_RDY_PD (0x01 << 6) +#define XD_RDY_PU (0x02 << 6) +#define XD_WE_NP 0x00 +#define XD_WE_PD (0x01 << 4) +#define XD_WE_PU (0x02 << 4) +#define XD_RE_NP 0x00 +#define XD_RE_PD (0x01 << 2) +#define XD_RE_PU (0x02 << 2) +#define XD_ALE_NP 0x00 +#define XD_ALE_PD 0x01 +#define XD_ALE_PU 0x02 + +#define SD_D3_NP 0x00 +#define SD_D3_PD (0x01 << 4) +#define SD_D3_PU (0x02 << 4) +#define SD_D2_NP 0x00 +#define SD_D2_PD (0x01 << 2) +#define SD_D2_PU (0x02 << 2) + +#define MS_INS_PD 0x00 +#define MS_INS_PU (0x01 << 7) +#define SD_WP_NP 0x00 +#define SD_WP_PD (0x01 << 5) +#define SD_WP_PU (0x02 << 5) +#define SD_CD_PD 0x00 +#define SD_CD_PU (0x01 << 4) +#define SD_CMD_NP 0x00 +#define SD_CMD_PD (0x01 << 2) +#define SD_CMD_PU (0x02 << 2) + +#define MS_D5_NP 0x00 +#define MS_D5_PD (0x01 << 2) +#define MS_D5_PU (0x02 << 2) +#define MS_D4_NP 0x00 +#define MS_D4_PD 0x01 +#define MS_D4_PU 0x02 + +#define FORCE_PM_CLOCK 0x10 +#define EN_CLOCK_PM 0x01 + +#define HOST_ENTER_S3 0x02 +#define HOST_ENTER_S1 0x01 + +#define AUX_PWR_DETECTED 0x01 + +#define PHY_DEBUG_MODE 0x01 + +#define SPI_COMMAND_BIT_8 0xE0 +#define SPI_ADDRESS_BIT_24 0x17 +#define SPI_ADDRESS_BIT_32 0x1F + +#define SPI_TRANSFER0_START 0x80 +#define SPI_TRANSFER0_END 0x40 +#define SPI_C_MODE0 0x00 +#define SPI_CA_MODE0 0x01 +#define SPI_CDO_MODE0 0x02 +#define SPI_CDI_MODE0 0x03 +#define SPI_CADO_MODE0 0x04 +#define SPI_CADI_MODE0 0x05 +#define SPI_POLLING_MODE0 0x06 + +#define SPI_TRANSFER1_START 0x80 +#define SPI_TRANSFER1_END 0x40 +#define SPI_DO_MODE1 0x00 +#define SPI_DI_MODE1 0x01 + +#define CS_POLARITY_HIGH 0x40 +#define CS_POLARITY_LOW 0x00 +#define DTO_MSB_FIRST 0x00 +#define DTO_LSB_FIRST 0x20 +#define SPI_MASTER 0x00 +#define SPI_SLAVE 0x10 +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x04 +#define SPI_MODE2 0x08 +#define SPI_MODE3 0x0C +#define SPI_MANUAL 0x00 +#define SPI_HALF_AUTO 0x01 +#define SPI_AUTO 0x02 +#define SPI_EEPROM_AUTO 0x03 + +#define EDO_TIMING_MASK 0x03 +#define SAMPLE_RISING 0x00 +#define SAMPLE_DELAY_HALF 0x01 +#define SAMPLE_DELAY_ONE 0x02 +#define SAPMLE_DELAY_ONE_HALF 0x03 +#define TCS_MASK 0x0C + +#define NOT_BYPASS_SD 0x02 +#define DISABLE_SDIO_FUNC 0x04 +#define SELECT_1LUN 0x08 + +#define PWR_GATE_EN 0x01 +#define LDO3318_PWR_MASK 0x06 +#define LDO_ON 0x00 +#define LDO_SUSPEND 0x04 +#define LDO_OFF 0x06 + +#define SD_CFG1 0xFDA0 +#define SD_CFG2 0xFDA1 +#define SD_CFG3 0xFDA2 +#define SD_STAT1 0xFDA3 +#define SD_STAT2 0xFDA4 +#define SD_BUS_STAT 0xFDA5 +#define SD_PAD_CTL 0xFDA6 +#define SD_SAMPLE_POINT_CTL 0xFDA7 +#define SD_PUSH_POINT_CTL 0xFDA8 +#define SD_CMD0 0xFDA9 +#define SD_CMD1 0xFDAA +#define SD_CMD2 0xFDAB +#define SD_CMD3 0xFDAC +#define SD_CMD4 0xFDAD +#define SD_CMD5 0xFDAE +#define SD_BYTE_CNT_L 0xFDAF +#define SD_BYTE_CNT_H 0xFDB0 +#define SD_BLOCK_CNT_L 0xFDB1 +#define SD_BLOCK_CNT_H 0xFDB2 +#define SD_TRANSFER 0xFDB3 +#define SD_CMD_STATE 0xFDB5 +#define SD_DATA_STATE 0xFDB6 + +#define DCM_DRP_CTL 0xFC23 +#define DCM_DRP_TRIG 0xFC24 +#define DCM_DRP_CFG 0xFC25 +#define DCM_DRP_WR_DATA_L 0xFC26 +#define DCM_DRP_WR_DATA_H 0xFC27 +#define DCM_DRP_RD_DATA_L 0xFC28 +#define DCM_DRP_RD_DATA_H 0xFC29 +#define SD_VPCLK0_CTL 0xFC2A +#define SD_VPCLK1_CTL 0xFC2B +#define SD_DCMPS0_CTL 0xFC2C +#define SD_DCMPS1_CTL 0xFC2D +#define SD_VPTX_CTL SD_VPCLK0_CTL +#define SD_VPRX_CTL SD_VPCLK1_CTL +#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL +#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL + +#define CARD_CLK_SOURCE 0xFC2E + +#define CARD_PWR_CTL 0xFD50 +#define CARD_CLK_SWITCH 0xFD51 +#define CARD_SHARE_MODE 0xFD52 +#define CARD_DRIVE_SEL 0xFD53 +#define CARD_STOP 0xFD54 +#define CARD_OE 0xFD55 +#define CARD_AUTO_BLINK 0xFD56 +#define CARD_GPIO_DIR 0xFD57 +#define CARD_GPIO 0xFD58 + +#define CARD_DATA_SOURCE 0xFD5B +#define CARD_SELECT 0xFD5C +#define SD30_DRIVE_SEL 0xFD5E + +#define CARD_CLK_EN 0xFD69 + +#define SDIO_CTRL 0xFD6B + +#define FPDCTL 0xFC00 +#define PDINFO 0xFC01 + +#define CLK_CTL 0xFC02 +#define CLK_DIV 0xFC03 +#define CLK_SEL 0xFC04 + +#define SSC_DIV_N_0 0xFC0F +#define SSC_DIV_N_1 0xFC10 + +#define RCCTL 0xFC14 + +#define FPGA_PULL_CTL 0xFC1D + +#define CARD_PULL_CTL1 0xFD60 +#define CARD_PULL_CTL2 0xFD61 +#define CARD_PULL_CTL3 0xFD62 +#define CARD_PULL_CTL4 0xFD63 +#define CARD_PULL_CTL5 0xFD64 +#define CARD_PULL_CTL6 0xFD65 + +#define IRQEN0 0xFE20 +#define IRQSTAT0 0xFE21 +#define IRQEN1 0xFE22 +#define IRQSTAT1 0xFE23 +#define TLPRIEN 0xFE24 +#define TLPRISTAT 0xFE25 +#define TLPTIEN 0xFE26 +#define TLPTISTAT 0xFE27 +#define DMATC0 0xFE28 +#define DMATC1 0xFE29 +#define DMATC2 0xFE2A +#define DMATC3 0xFE2B +#define DMACTL 0xFE2C +#define BCTL 0xFE2D +#define RBBC0 0xFE2E +#define RBBC1 0xFE2F +#define RBDAT 0xFE30 +#define RBCTL 0xFE34 +#define CFGADDR0 0xFE35 +#define CFGADDR1 0xFE36 +#define CFGDATA0 0xFE37 +#define CFGDATA1 0xFE38 +#define CFGDATA2 0xFE39 +#define CFGDATA3 0xFE3A +#define CFGRWCTL 0xFE3B +#define PHYRWCTL 0xFE3C +#define PHYDATA0 0xFE3D +#define PHYDATA1 0xFE3E +#define PHYADDR 0xFE3F +#define MSGRXDATA0 0xFE40 +#define MSGRXDATA1 0xFE41 +#define MSGRXDATA2 0xFE42 +#define MSGRXDATA3 0xFE43 +#define MSGTXDATA0 0xFE44 +#define MSGTXDATA1 0xFE45 +#define MSGTXDATA2 0xFE46 +#define MSGTXDATA3 0xFE47 +#define MSGTXCTL 0xFE48 +#define PETXCFG 0xFE49 + +#define CDRESUMECTL 0xFE52 +#define WAKE_SEL_CTL 0xFE54 +#define PME_FORCE_CTL 0xFE56 +#define ASPM_FORCE_CTL 0xFE57 +#define PM_CLK_FORCE_CTL 0xFE58 +#define PERST_GLITCH_WIDTH 0xFE5C +#define CHANGE_LINK_STATE 0xFE5B +#define RESET_LOAD_REG 0xFE5E +#define HOST_SLEEP_STATE 0xFE60 +#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */ + +#define NFTS_TX_CTRL 0xFE72 + +#define PWR_GATE_CTRL 0xFE75 +#define PWD_SUSPEND_EN 0xFE76 + +#define EFUSE_CONTENT 0xFE5F + +#define XD_INIT 0xFD10 +#define XD_DTCTL 0xFD11 +#define XD_CTL 0xFD12 +#define XD_TRANSFER 0xFD13 +#define XD_CFG 0xFD14 +#define XD_ADDRESS0 0xFD15 +#define XD_ADDRESS1 0xFD16 +#define XD_ADDRESS2 0xFD17 +#define XD_ADDRESS3 0xFD18 +#define XD_ADDRESS4 0xFD19 +#define XD_DAT 0xFD1A +#define XD_PAGE_CNT 0xFD1B +#define XD_PAGE_STATUS 0xFD1C +#define XD_BLOCK_STATUS 0xFD1D +#define XD_BLOCK_ADDR1_L 0xFD1E +#define XD_BLOCK_ADDR1_H 0xFD1F +#define XD_BLOCK_ADDR2_L 0xFD20 +#define XD_BLOCK_ADDR2_H 0xFD21 +#define XD_BYTE_CNT_L 0xFD22 +#define XD_BYTE_CNT_H 0xFD23 +#define XD_PARITY 0xFD24 +#define XD_ECC_BIT1 0xFD25 +#define XD_ECC_BYTE1 0xFD26 +#define XD_ECC_BIT2 0xFD27 +#define XD_ECC_BYTE2 0xFD28 +#define XD_RESERVED0 0xFD29 +#define XD_RESERVED1 0xFD2A +#define XD_RESERVED2 0xFD2B +#define XD_RESERVED3 0xFD2C +#define XD_CHK_DATA_STATUS 0xFD2D +#define XD_CATCTL 0xFD2E + +#define MS_CFG 0xFD40 +#define MS_TPC 0xFD41 +#define MS_TRANS_CFG 0xFD42 +#define MS_TRANSFER 0xFD43 +#define MS_INT_REG 0xFD44 +#define MS_BYTE_CNT 0xFD45 +#define MS_SECTOR_CNT_L 0xFD46 +#define MS_SECTOR_CNT_H 0xFD47 +#define MS_DBUS_H 0xFD48 + +#define SSC_CTL1 0xFC11 +#define SSC_CTL2 0xFC12 + +#define OCPCTL 0xFC15 +#define OCPSTAT 0xFC16 +#define OCPCLR 0xFC17 /* 5208 */ +#define OCPPARA1 0xFC18 +#define OCPPARA2 0xFC19 + +#define EFUSE_OP 0xFC20 +#define EFUSE_CTRL 0xFC21 +#define EFUSE_DATA 0xFC22 + +#define SPI_COMMAND 0xFD80 +#define SPI_ADDR0 0xFD81 +#define SPI_ADDR1 0xFD82 +#define SPI_ADDR2 0xFD83 +#define SPI_ADDR3 0xFD84 +#define SPI_CA_NUMBER 0xFD85 +#define SPI_LENGTH0 0xFD86 +#define SPI_LENGTH1 0xFD87 +#define SPI_DATA 0xFD88 +#define SPI_DATA_NUMBER 0xFD89 +#define SPI_TRANSFER0 0xFD90 +#define SPI_TRANSFER1 0xFD91 +#define SPI_CONTROL 0xFD92 +#define SPI_SIG 0xFD93 +#define SPI_TCTL 0xFD94 +#define SPI_SLAVE_NUM 0xFD95 +#define SPI_CLK_DIVIDER0 0xFD96 +#define SPI_CLK_DIVIDER1 0xFD97 + +#define SRAM_BASE 0xE600 +#define RBUF_BASE 0xF400 +#define PPBUF_BASE1 0xF800 +#define PPBUF_BASE2 0xFA00 +#define IMAGE_FLAG_ADDR0 0xCE80 +#define IMAGE_FLAG_ADDR1 0xCE81 + +#define READ_OP 1 +#define WRITE_OP 2 + +#define LCTLR 0x80 + +#define POLLING_WAIT_CNT 1 +#define IDLE_MAX_COUNT 10 +#define SDIO_IDLE_COUNT 10 + +#define DEBOUNCE_CNT 5 + +void do_remaining_work(struct rtsx_chip *chip); +void try_to_switch_sdio_ctrl(struct rtsx_chip *chip); +void do_reset_sd_card(struct rtsx_chip *chip); +void do_reset_xd_card(struct rtsx_chip *chip); +void do_reset_ms_card(struct rtsx_chip *chip); +void rtsx_power_off_card(struct rtsx_chip *chip); +void rtsx_release_cards(struct rtsx_chip *chip); +void rtsx_reset_cards(struct rtsx_chip *chip); +void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip); +void rtsx_init_cards(struct rtsx_chip *chip); +int switch_ssc_clock(struct rtsx_chip *chip, int clk); +int switch_normal_clock(struct rtsx_chip *chip, int clk); +int enable_card_clock(struct rtsx_chip *chip, u8 card); +int disable_card_clock(struct rtsx_chip *chip, u8 card); +int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 sec_addr, u16 sec_cnt); +void trans_dma_enable(enum dma_data_direction dir, + struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size); +void toggle_gpio(struct rtsx_chip *chip, u8 gpio); +void turn_on_led(struct rtsx_chip *chip, u8 gpio); +void turn_off_led(struct rtsx_chip *chip, u8 gpio); + +int card_share_mode(struct rtsx_chip *chip, int card); +int select_card(struct rtsx_chip *chip, int card); +int detect_card_cd(struct rtsx_chip *chip, int card); +int check_card_exist(struct rtsx_chip *chip, unsigned int lun); +int check_card_ready(struct rtsx_chip *chip, unsigned int lun); +int check_card_wp(struct rtsx_chip *chip, unsigned int lun); +int check_card_fail(struct rtsx_chip *chip, unsigned int lun); +int check_card_ejected(struct rtsx_chip *chip, unsigned int lun); +void eject_card(struct rtsx_chip *chip, unsigned int lun); +u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); + +static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); + + if ((get_lun_card(chip, lun) == SD_CARD) && + (sd_card->sd_lock_status & SD_LOCKED)) + return 0; + else + return chip->capacity[lun]; +#else + return chip->capacity[lun]; +#endif +} + +static inline int switch_clock(struct rtsx_chip *chip, int clk) +{ + int retval = 0; + + if (chip->asic_code) + retval = switch_ssc_clock(chip, clk); + else + retval = switch_normal_clock(chip, clk); + + return retval; +} + +int card_power_on(struct rtsx_chip *chip, u8 card); +int card_power_off(struct rtsx_chip *chip, u8 card); + +static inline int card_power_off_all(struct rtsx_chip *chip) +{ + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0x0F, 0x0F); + + return STATUS_SUCCESS; +} + +static inline void rtsx_clear_xd_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, + XD_STOP | XD_CLR_ERR); +} + +static inline void rtsx_clear_sd_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); +} + +static inline void rtsx_clear_ms_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, + MS_STOP | MS_CLR_ERR); +} + +static inline void rtsx_clear_spi_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, + SPI_STOP | SPI_CLR_ERR); +} + +#ifdef SUPPORT_SDIO_ASPM +void dynamic_configure_sdio_aspm(struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_CARD_H */ diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c new file mode 100644 index 000000000000..6426807a906f --- /dev/null +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -0,0 +1,1979 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> +#include <linux/vmalloc.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "rtsx_chip.h" +#include "rtsx_sys.h" +#include "general.h" + +#include "sd.h" +#include "xd.h" +#include "ms.h" + +static void rtsx_calibration(struct rtsx_chip *chip) +{ + rtsx_write_phy_register(chip, 0x1B, 0x135E); + wait_timeout(10); + rtsx_write_phy_register(chip, 0x00, 0x0280); + rtsx_write_phy_register(chip, 0x01, 0x7112); + rtsx_write_phy_register(chip, 0x01, 0x7110); + rtsx_write_phy_register(chip, 0x01, 0x7112); + rtsx_write_phy_register(chip, 0x01, 0x7113); + rtsx_write_phy_register(chip, 0x00, 0x0288); +} + +void rtsx_disable_card_int(struct rtsx_chip *chip) +{ + u32 reg = rtsx_readl(chip, RTSX_BIER); + + reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN); + rtsx_writel(chip, RTSX_BIER, reg); +} + +void rtsx_enable_card_int(struct rtsx_chip *chip) +{ + u32 reg = rtsx_readl(chip, RTSX_BIER); + int i; + + for (i = 0; i <= chip->max_lun; i++) { + if (chip->lun2card[i] & XD_CARD) + reg |= XD_INT_EN; + if (chip->lun2card[i] & SD_CARD) + reg |= SD_INT_EN; + if (chip->lun2card[i] & MS_CARD) + reg |= MS_INT_EN; + } + if (chip->hw_bypass_sd) + reg &= ~((u32)SD_INT_EN); + + rtsx_writel(chip, RTSX_BIER, reg); +} + +void rtsx_enable_bus_int(struct rtsx_chip *chip) +{ + u32 reg = 0; +#ifndef DISABLE_CARD_INT + int i; +#endif + + reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; + +#ifndef DISABLE_CARD_INT + for (i = 0; i <= chip->max_lun; i++) { + RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]); + + if (chip->lun2card[i] & XD_CARD) + reg |= XD_INT_EN; + if (chip->lun2card[i] & SD_CARD) + reg |= SD_INT_EN; + if (chip->lun2card[i] & MS_CARD) + reg |= MS_INT_EN; + } + if (chip->hw_bypass_sd) + reg &= ~((u32)SD_INT_EN); +#endif + + if (chip->ic_version >= IC_VER_C) + reg |= DELINK_INT_EN; +#ifdef SUPPORT_OCP + reg |= OC_INT_EN; +#endif + if (!chip->adma_mode) + reg |= DATA_DONE_INT_EN; + + /* Enable Bus Interrupt */ + rtsx_writel(chip, RTSX_BIER, reg); + + RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg); +} + +void rtsx_disable_bus_int(struct rtsx_chip *chip) +{ + rtsx_writel(chip, RTSX_BIER, 0); +} + +static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) +{ + if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { + if (chip->asic_code) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, + FPGA_SD_PULL_CTL_EN); + } + RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD); + + /* Enable SDIO internal clock */ + RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01); + + RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, + SDIO_BUS_CTRL | SDIO_CD_CTRL); + + chip->sd_int = 1; + chip->sd_io = 1; + } else { + chip->need_reset |= SD_CARD; + } + + return STATUS_SUCCESS; +} + +#ifdef HW_AUTO_SWITCH_SD_BUS +static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) +{ + u8 tmp; + int sw_bypass_sd = 0; + int retval; + + if (chip->driver_first_load) { + if (CHECK_PID(chip, 0x5288)) { + RTSX_READ_REG(chip, 0xFE5A, &tmp); + if (tmp & 0x08) + sw_bypass_sd = 1; + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_READ_REG(chip, 0xFE70, &tmp); + if (tmp & 0x80) + sw_bypass_sd = 1; + } + } else { + if (chip->sdio_in_charge) + sw_bypass_sd = 1; + } + RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge); + RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load); + RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd); + + if (sw_bypass_sd) { + u8 cd_toggle_mask = 0; + + RTSX_READ_REG(chip, TLPTISTAT, &tmp); + cd_toggle_mask = 0x08; + + if (tmp & cd_toggle_mask) { + /* Disable sdio_bus_auto_switch */ + if (CHECK_PID(chip, 0x5288)) + RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00); + else if (CHECK_PID(chip, 0x5208)) + RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00); + + RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp); + + chip->need_reset |= SD_CARD; + } else { + RTSX_DEBUGP("Chip inserted with SDIO!\n"); + + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, 0); + } + retval = card_share_mode(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* Enable sdio_bus_auto_switch */ + if (CHECK_PID(chip, 0x5288)) + RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08); + else if (CHECK_PID(chip, 0x5208)) + RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80); + + chip->chip_insert_with_sdio = 1; + chip->sd_io = 1; + } + } else { + RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08); + + chip->need_reset |= SD_CARD; + } + + return STATUS_SUCCESS; +} +#endif + +int rtsx_reset_chip(struct rtsx_chip *chip) +{ + int retval; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + rtsx_disable_aspm(chip); + + RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00); + + /* Disable card clock */ + RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0); + +#ifdef SUPPORT_OCP + /* SSC power on, OCD power on */ + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0); + else + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN); + + RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800); + RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946); + RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN); +#else + /* OC power down */ + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN); +#endif + + if (!CHECK_PID(chip, 0x5288)) + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03); + + /* Turn off LED */ + RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03); + + /* Reset delink mode */ + RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0); + + /* Card driving select */ + RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel); + +#ifdef LED_AUTO_BLINK + RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, + LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); +#endif + + if (chip->asic_code) { + /* Enable SSC Clock */ + RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M); + RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12); + } + + /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) + 0xFE5B + bit[1] u_cd_rst_core_en rst_value = 0 + bit[2] u_force_rst_core_en rst_value = 0 + bit[5] u_mac_phy_rst_n_dbg rst_value = 1 + bit[4] u_non_sticky_rst_n_dbg rst_value = 0 + */ + RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10); + + /* Enable ASPM */ + if (chip->aspm_l0s_l1_en) { + if (chip->dynamic_aspm) { + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5288)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + } + } else { + if (CHECK_PID(chip, 0x5208)) + RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, + 0xFF, 0x3F); + + retval = rtsx_write_config_byte(chip, LCTLR, + chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->aspm_level[0] = chip->aspm_l0s_l1_en; + if (CHK_SDIO_EXIST(chip)) { + chip->aspm_level[1] = chip->aspm_l0s_l1_en; + if (CHECK_PID(chip, 0x5288)) + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + else + retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } + + chip->aspm_enabled = 1; + } + } else { + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + retval = rtsx_write_phy_register(chip, 0x07, 0x0129); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_config_byte(chip, LCTLR, + chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rtsx_write_config_byte(chip, 0x81, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5288)) + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, + 0xFF00, 0x0100); + else + retval = rtsx_write_cfg_dw(chip, 1, 0xC0, + 0xFF00, 0x0100); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } + + if (CHECK_PID(chip, 0x5288)) { + if (!CHK_SDIO_EXIST(chip)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, + 0x0103); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } + } + + RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + + RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); + + /* Enable PCIE interrupt */ + if (chip->asic_code) { + if (CHECK_PID(chip, 0x5208)) { + if (chip->phy_debug_mode) { + RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); + rtsx_disable_bus_int(chip); + } else { + rtsx_enable_bus_int(chip); + } + + if (chip->ic_version >= IC_VER_D) { + u16 reg; + retval = rtsx_read_phy_register(chip, 0x00, + ®); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFE7F; + reg |= 0x80; + retval = rtsx_write_phy_register(chip, 0x00, + reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = rtsx_read_phy_register(chip, 0x1C, + ®); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + reg &= 0xFFF7; + retval = rtsx_write_phy_register(chip, 0x1C, + reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } + + if (chip->driver_first_load && + (chip->ic_version < IC_VER_C)) + rtsx_calibration(chip); + + } else { + rtsx_enable_bus_int(chip); + } + } else { + rtsx_enable_bus_int(chip); + } + + chip->need_reset = 0; + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (chip->hw_bypass_sd) + goto NextCard; + RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", + chip->int_reg); + if (chip->int_reg & SD_EXIST) { +#ifdef HW_AUTO_SWITCH_SD_BUS + if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) + retval = rtsx_pre_handle_sdio_old(chip); + else + retval = rtsx_pre_handle_sdio_new(chip); + + RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", + (unsigned int)(chip->need_reset)); +#else /* HW_AUTO_SWITCH_SD_BUS */ + retval = rtsx_pre_handle_sdio_old(chip); +#endif /* HW_AUTO_SWITCH_SD_BUS */ + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } else { + chip->sd_io = 0; + RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, + 0); + } + +NextCard: + if (chip->int_reg & XD_EXIST) + chip->need_reset |= XD_CARD; + if (chip->int_reg & MS_EXIST) + chip->need_reset |= MS_CARD; + if (chip->int_reg & CARD_EXIST) + RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB); + + RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", + (unsigned int)(chip->need_reset)); + + RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00); + + if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { + /* Turn off main power when entering S3/S4 state */ + RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03); + } + + if (chip->remote_wakeup_en && !chip->auto_delink_en) { + RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07); + if (chip->aux_pwr_exist) + RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33); + } else { + RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04); + RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30); + } + + if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) + RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14); + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->ft2_fast_mode) { + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, + MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); + udelay(chip->pmos_pwr_on_interval); + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, + MS_POWER_ON | SD_POWER_ON); + + wait_timeout(200); + } + + /* Reset card */ + rtsx_reset_detected_cards(chip, 0); + + chip->driver_first_load = 0; + + return STATUS_SUCCESS; +} + +static inline int check_sd_speed_prior(u32 sd_speed_prior) +{ + int i, fake_para = 0; + + for (i = 0; i < 4; i++) { + u8 tmp = (u8)(sd_speed_prior >> (i*8)); + if ((tmp < 0x01) || (tmp > 0x04)) { + fake_para = 1; + break; + } + } + + return !fake_para; +} + +static inline int check_sd_current_prior(u32 sd_current_prior) +{ + int i, fake_para = 0; + + for (i = 0; i < 4; i++) { + u8 tmp = (u8)(sd_current_prior >> (i*8)); + if (tmp > 0x03) { + fake_para = 1; + break; + } + } + + return !fake_para; +} + +static int rts5208_init(struct rtsx_chip *chip) +{ + int retval; + u16 reg = 0; + u8 val = 0; + + RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); + RTSX_READ_REG(chip, CLK_SEL, &val); + if (val == 0) + chip->asic_code = 1; + else + chip->asic_code = 0; + + if (chip->asic_code) { + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg); + chip->ic_version = (reg >> 4) & 0x07; + if (reg & PHY_DEBUG_MODE) + chip->phy_debug_mode = 1; + else + chip->phy_debug_mode = 0; + + } else { + RTSX_READ_REG(chip, 0xFE80, &val); + chip->ic_version = val; + chip->phy_debug_mode = 0; + } + + RTSX_READ_REG(chip, PDINFO, &val); + RTSX_DEBUGP("PDINFO: 0x%x\n", val); + if (val & AUX_PWR_DETECTED) + chip->aux_pwr_exist = 1; + else + chip->aux_pwr_exist = 0; + + RTSX_READ_REG(chip, 0xFE50, &val); + if (val & 0x01) + chip->hw_bypass_sd = 1; + else + chip->hw_bypass_sd = 0; + + rtsx_read_config_byte(chip, 0x0E, &val); + if (val & 0x80) + SET_SDIO_EXIST(chip); + else + CLR_SDIO_EXIST(chip); + + if (chip->use_hw_setting) { + RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); + if (val & 0x80) + chip->auto_delink_en = 1; + else + chip->auto_delink_en = 0; + } + + return STATUS_SUCCESS; +} + +static int rts5288_init(struct rtsx_chip *chip) +{ + int retval; + u8 val = 0, max_func; + u32 lval = 0; + + RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); + RTSX_READ_REG(chip, CLK_SEL, &val); + if (val == 0) + chip->asic_code = 1; + else + chip->asic_code = 0; + + chip->ic_version = 0; + chip->phy_debug_mode = 0; + + RTSX_READ_REG(chip, PDINFO, &val); + RTSX_DEBUGP("PDINFO: 0x%x\n", val); + if (val & AUX_PWR_DETECTED) + chip->aux_pwr_exist = 1; + else + chip->aux_pwr_exist = 0; + + RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); + RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val); + if (val & 0x04) + chip->baro_pkg = QFN; + else + chip->baro_pkg = LQFP; + + RTSX_READ_REG(chip, 0xFE5A, &val); + if (val & 0x10) + chip->hw_bypass_sd = 1; + else + chip->hw_bypass_sd = 0; + + retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + max_func = (u8)((lval >> 29) & 0x07); + RTSX_DEBUGP("Max function number: %d\n", max_func); + if (max_func == 0x02) + SET_SDIO_EXIST(chip); + else + CLR_SDIO_EXIST(chip); + + if (chip->use_hw_setting) { + RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); + if (val & 0x80) + chip->auto_delink_en = 1; + else + chip->auto_delink_en = 0; + + if (CHECK_BARO_PKG(chip, LQFP)) + chip->lun_mode = SD_MS_1LUN; + else + chip->lun_mode = DEFAULT_SINGLE; + + } + + return STATUS_SUCCESS; +} + +int rtsx_init_chip(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct xd_info *xd_card = &(chip->xd_card); + struct ms_info *ms_card = &(chip->ms_card); + int retval; + unsigned int i; + + RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n", + chip->vendor_id, chip->product_id); + + chip->ic_version = 0; + +#ifdef _MSG_TRACE + chip->msg_idx = 0; +#endif + + memset(xd_card, 0, sizeof(struct xd_info)); + memset(sd_card, 0, sizeof(struct sd_info)); + memset(ms_card, 0, sizeof(struct ms_info)); + + chip->xd_reset_counter = 0; + chip->sd_reset_counter = 0; + chip->ms_reset_counter = 0; + + chip->xd_show_cnt = MAX_SHOW_CNT; + chip->sd_show_cnt = MAX_SHOW_CNT; + chip->ms_show_cnt = MAX_SHOW_CNT; + + chip->sd_io = 0; + chip->auto_delink_cnt = 0; + chip->auto_delink_allowed = 1; + rtsx_set_stat(chip, RTSX_STAT_INIT); + + chip->aspm_enabled = 0; + chip->chip_insert_with_sdio = 0; + chip->sdio_aspm = 0; + chip->sdio_idle = 0; + chip->sdio_counter = 0; + chip->cur_card = 0; + chip->phy_debug_mode = 0; + chip->sdio_func_exist = 0; + memset(chip->sdio_raw_data, 0, 12); + + for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) { + set_sense_type(chip, i, SENSE_TYPE_NO_SENSE); + chip->rw_fail_cnt[i] = 0; + } + + if (!check_sd_speed_prior(chip->sd_speed_prior)) + chip->sd_speed_prior = 0x01040203; + + RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior); + + if (!check_sd_current_prior(chip->sd_current_prior)) + chip->sd_current_prior = 0x00010203; + + RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior); + + if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0)) + chip->sd_ddr_tx_phase = 0; + + if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0)) + chip->mmc_ddr_tx_phase = 0; + + RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0); + wait_timeout(200); + RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07); + RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting); + + if (CHECK_PID(chip, 0x5208)) { + retval = rts5208_init(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } else if (CHECK_PID(chip, 0x5288)) { + retval = rts5288_init(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + } + + if (chip->ss_en == 2) + chip->ss_en = 0; + + RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code); + RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version); + RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode); + RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist); + RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist); + RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd); + RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en); + RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode); + RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en); + RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en); + RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg); + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 1; + chip->card2lun[XD_CARD] = 0xFF; + chip->lun2card[0] = SD_CARD; + chip->lun2card[1] = MS_CARD; + chip->max_lun = 1; + SET_SDIO_IGNORED(chip); + } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 0; + chip->card2lun[XD_CARD] = 0xFF; + chip->lun2card[0] = SD_CARD | MS_CARD; + chip->max_lun = 0; + } else { + chip->card2lun[XD_CARD] = 0; + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 0; + chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; + chip->max_lun = 0; + } + + retval = rtsx_reset_chip(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +void rtsx_release_chip(struct rtsx_chip *chip) +{ + xd_free_l2p_tbl(chip); + ms_free_l2p_tbl(chip); + chip->card_exist = 0; + chip->card_ready = 0; +} + +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) +static inline void rtsx_blink_led(struct rtsx_chip *chip) +{ + if (chip->card_exist && chip->blink_led) { + if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) { + chip->led_toggle_counter++; + } else { + chip->led_toggle_counter = 0; + toggle_gpio(chip, LED_GPIO); + } + } +} +#endif + +static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) +{ + int maybe_support_aspm, reg_changed; + u32 tmp = 0; + u8 reg0 = 0, reg1 = 0; + + maybe_support_aspm = 0; + reg_changed = 0; + rtsx_read_config_byte(chip, LCTLR, ®0); + if (chip->aspm_level[0] != reg0) { + reg_changed = 1; + chip->aspm_level[0] = reg0; + } + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); + reg1 = (u8)tmp; + if (chip->aspm_level[1] != reg1) { + reg_changed = 1; + chip->aspm_level[1] = reg1; + } + + if ((reg0 & 0x03) && (reg1 & 0x03)) + maybe_support_aspm = 1; + + } else { + if (reg0 & 0x03) + maybe_support_aspm = 1; + + } + + if (reg_changed) { + if (maybe_support_aspm) + chip->aspm_l0s_l1_en = 0x03; + + RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", + chip->aspm_level[0], chip->aspm_level[1]); + + if (chip->aspm_l0s_l1_en) { + chip->aspm_enabled = 1; + } else { + chip->aspm_enabled = 0; + chip->sdio_aspm = 0; + } + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, + 0x30 | chip->aspm_level[0] | + (chip->aspm_level[1] << 2)); + } +} + +void rtsx_polling_func(struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + int ss_allowed; + + if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) + return; + + if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) + goto Delink_Stage; + + if (chip->polling_config) { + u8 val; + rtsx_read_config_byte(chip, 0, &val); + } + + if (rtsx_chk_stat(chip, RTSX_STAT_SS)) + return; + +#ifdef SUPPORT_OCP + if (chip->ocp_int) { + rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat)); + + if (chip->card_exist & SD_CARD) + sd_power_off_card3v3(chip); + else if (chip->card_exist & MS_CARD) + ms_power_off_card3v3(chip); + else if (chip->card_exist & XD_CARD) + xd_power_off_card3v3(chip); + + chip->ocp_int = 0; + } +#endif + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + if (chip->card_exist & SD_CARD) { + u8 val; + rtsx_read_register(chip, 0xFD30, &val); + if (val & 0x02) { + sd_card->sd_erase_status = SD_NOT_ERASE; + sd_card->sd_lock_notify = 1; + chip->need_reinit |= SD_CARD; + } + } else { + sd_card->sd_erase_status = SD_NOT_ERASE; + } + } +#endif + + rtsx_init_cards(chip); + + if (chip->ss_en) { + ss_allowed = 1; + + if (CHECK_PID(chip, 0x5288)) { + ss_allowed = 0; + } else { + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + u32 val; + rtsx_read_cfg_dw(chip, 1, 0x04, &val); + if (val & 0x07) + ss_allowed = 0; + + } + } + } else { + ss_allowed = 0; + } + + if (ss_allowed && !chip->sd_io) { + if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { + chip->ss_counter = 0; + } else { + if (chip->ss_counter < + (chip->ss_idle_period / POLLING_INTERVAL)) { + chip->ss_counter++; + } else { + rtsx_exclusive_enter_ss(chip); + return; + } + } + } + + if (CHECK_PID(chip, 0x5208)) { + rtsx_monitor_aspm_config(chip); + +#ifdef SUPPORT_SDIO_ASPM + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && + chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (chip->sd_io) { + dynamic_configure_sdio_aspm(chip); + } else { + if (!chip->sdio_aspm) { + RTSX_DEBUGP("SDIO enter ASPM!\n"); + rtsx_write_register(chip, + ASPM_FORCE_CTL, 0xFC, + 0x30 | (chip->aspm_level[1] << 2)); + chip->sdio_aspm = 1; + } + } + } +#endif + } + + if (chip->idle_counter < IDLE_MAX_COUNT) { + chip->idle_counter++; + } else { + if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { + RTSX_DEBUGP("Idle state!\n"); + rtsx_set_stat(chip, RTSX_STAT_IDLE); + +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) + chip->led_toggle_counter = 0; +#endif + rtsx_force_power_on(chip, SSC_PDCTL); + + turn_off_led(chip, LED_GPIO); + + if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + + } + } + + switch (rtsx_get_stat(chip)) { + case RTSX_STAT_RUN: +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) + rtsx_blink_led(chip); +#endif + do_remaining_work(chip); + break; + + case RTSX_STAT_IDLE: + if (chip->sd_io && !chip->sd_int) + try_to_switch_sdio_ctrl(chip); + + rtsx_enable_aspm(chip); + break; + + default: + break; + } + + +#ifdef SUPPORT_OCP + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { +#ifdef CONFIG_RTS5208_DEBUG + if (chip->ocp_stat & + (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); +#endif + + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + if (chip->card_exist & SD_CARD) { + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, + 0); + card_power_off(chip, SD_CARD); + chip->card_fail |= SD_CARD; + } + } + if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { + if (chip->card_exist & MS_CARD) { + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, + 0); + card_power_off(chip, MS_CARD); + chip->card_fail |= MS_CARD; + } + } + } else { + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + if (chip->card_exist & SD_CARD) { + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, + 0); + chip->card_fail |= SD_CARD; + } else if (chip->card_exist & MS_CARD) { + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, + 0); + chip->card_fail |= MS_CARD; + } else if (chip->card_exist & XD_CARD) { + rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, + 0); + chip->card_fail |= XD_CARD; + } + card_power_off(chip, SD_CARD); + } + } +#endif + +Delink_Stage: + if (chip->auto_delink_en && chip->auto_delink_allowed && + !chip->card_ready && !chip->card_ejected && !chip->sd_io) { + int enter_L1 = chip->auto_delink_in_L1 && ( + chip->aspm_l0s_l1_en || chip->ss_en); + int delink_stage1_cnt = chip->delink_stage1_step; + int delink_stage2_cnt = delink_stage1_cnt + + chip->delink_stage2_step; + int delink_stage3_cnt = delink_stage2_cnt + + chip->delink_stage3_step; + + if (chip->auto_delink_cnt <= delink_stage3_cnt) { + if (chip->auto_delink_cnt == delink_stage1_cnt) { + rtsx_set_stat(chip, RTSX_STAT_DELINK); + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_set_phy_reg_bit(chip, 0x1C, 2); + + if (chip->card_exist) { + RTSX_DEBUGP("False card inserted, do force delink\n"); + + if (enter_L1) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + + rtsx_write_register(chip, + CHANGE_LINK_STATE, 0x0A, + 0x0A); + + if (enter_L1) + rtsx_enter_L1(chip); + + chip->auto_delink_cnt = delink_stage3_cnt + 1; + } else { + RTSX_DEBUGP("No card inserted, do delink\n"); + + if (enter_L1) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); + + if (enter_L1) + rtsx_enter_L1(chip); + + } + } + + if (chip->auto_delink_cnt == delink_stage2_cnt) { + RTSX_DEBUGP("Try to do force delink\n"); + + if (enter_L1) + rtsx_exit_L1(chip); + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_set_phy_reg_bit(chip, 0x1C, 2); + + rtsx_write_register(chip, CHANGE_LINK_STATE, + 0x0A, 0x0A); + } + + chip->auto_delink_cnt++; + } + } else { + chip->auto_delink_cnt = 0; + } +} + +void rtsx_undo_delink(struct rtsx_chip *chip) +{ + chip->auto_delink_allowed = 0; + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00); +} + +/** + * rtsx_stop_cmd - stop command transfer and DMA transfer + * @chip: Realtek's card reader chip + * @card: flash card type + * + * Stop command transfer and DMA transfer. + * This function is called in error handler. + */ +void rtsx_stop_cmd(struct rtsx_chip *chip, int card) +{ + int i; + + for (i = 0; i <= 8; i++) { + int addr = RTSX_HCBAR + i * 4; + u32 reg; + reg = rtsx_readl(chip, addr); + RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg); + } + rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD); + rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA); + + for (i = 0; i < 16; i++) { + u16 addr = 0xFE20 + (u16)i; + u8 val; + rtsx_read_register(chip, addr, &val); + RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val); + } + + rtsx_write_register(chip, DMACTL, 0x80, 0x80); + rtsx_write_register(chip, RBCTL, 0x80, 0x80); +} + +#define MAX_RW_REG_CNT 1024 + +int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) +{ + int i; + u32 val = 3 << 30; + + val |= (u32)(addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + rtsx_writel(chip, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_readl(chip, RTSX_HAIMR); + if ((val & (1 << 31)) == 0) { + if (data != (u8)val) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; + } + } + + TRACE_RET(chip, STATUS_TIMEDOUT); +} + +int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) +{ + u32 val = 2 << 30; + int i; + + if (data) + *data = 0; + + val |= (u32)(addr & 0x3FFF) << 16; + + rtsx_writel(chip, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_readl(chip, RTSX_HAIMR); + if ((val & (1 << 31)) == 0) + break; + } + + if (i >= MAX_RW_REG_CNT) + TRACE_RET(chip, STATUS_TIMEDOUT); + + if (data) + *data = (u8)(val & 0xFF); + + return STATUS_SUCCESS; +} + +int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, + u32 val) +{ + u8 mode = 0, tmp; + int i; + + for (i = 0; i < 4; i++) { + if (mask & 0xFF) { + RTSX_WRITE_REG(chip, CFGDATA0 + i, + 0xFF, (u8)(val & mask & 0xFF)); + mode |= (1 << i); + } + mask >>= 8; + val >>= 8; + } + + if (mode) { + RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); + RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); + + RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, + 0x80 | mode | ((func_no & 0x03) << 4)); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + RTSX_READ_REG(chip, CFGRWCTL, &tmp); + if ((tmp & 0x80) == 0) + break; + } + } + + return STATUS_SUCCESS; +} + +int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) +{ + int i; + u8 tmp; + u32 data = 0; + + RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); + RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); + RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, 0x80 | ((func_no & 0x03) << 4)); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + RTSX_READ_REG(chip, CFGRWCTL, &tmp); + if ((tmp & 0x80) == 0) + break; + } + + for (i = 0; i < 4; i++) { + RTSX_READ_REG(chip, CFGDATA0 + i, &tmp); + data |= (u32)tmp << (i * 8); + } + + if (val) + *val = data; + + return STATUS_SUCCESS; +} + +int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, + int len) +{ + u32 *data, *mask; + u16 offset = addr % 4; + u16 aligned_addr = addr - offset; + int dw_len, i, j; + int retval; + + RTSX_DEBUGP("%s\n", __func__); + + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + if ((len + offset) % 4) + dw_len = (len + offset) / 4 + 1; + else + dw_len = (len + offset) / 4; + + RTSX_DEBUGP("dw_len = %d\n", dw_len); + + data = vzalloc(dw_len * 4); + if (!data) + TRACE_RET(chip, STATUS_NOMEM); + + mask = vzalloc(dw_len * 4); + if (!mask) { + vfree(data); + TRACE_RET(chip, STATUS_NOMEM); + } + + j = 0; + for (i = 0; i < len; i++) { + mask[j] |= 0xFF << (offset * 8); + data[j] |= buf[i] << (offset * 8); + if (++offset == 4) { + j++; + offset = 0; + } + } + + RTSX_DUMP(mask, dw_len * 4); + RTSX_DUMP(data, dw_len * 4); + + for (i = 0; i < dw_len; i++) { + retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, + mask[i], data[i]); + if (retval != STATUS_SUCCESS) { + vfree(data); + vfree(mask); + TRACE_RET(chip, STATUS_FAIL); + } + } + + vfree(data); + vfree(mask); + + return STATUS_SUCCESS; +} + +int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, + int len) +{ + u32 *data; + u16 offset = addr % 4; + u16 aligned_addr = addr - offset; + int dw_len, i, j; + int retval; + + RTSX_DEBUGP("%s\n", __func__); + + if ((len + offset) % 4) + dw_len = (len + offset) / 4 + 1; + else + dw_len = (len + offset) / 4; + + RTSX_DEBUGP("dw_len = %d\n", dw_len); + + data = vmalloc(dw_len * 4); + if (!data) + TRACE_RET(chip, STATUS_NOMEM); + + for (i = 0; i < dw_len; i++) { + retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, + data + i); + if (retval != STATUS_SUCCESS) { + vfree(data); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (buf) { + j = 0; + + for (i = 0; i < len; i++) { + buf[i] = (u8)(data[j] >> (offset * 8)); + if (++offset == 4) { + j++; + offset = 0; + } + } + } + + vfree(data); + + return STATUS_SUCCESS; +} + +int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) +{ + int i, finished = 0; + u8 tmp; + + RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val); + RTSX_WRITE_REG(chip, PHYDATA1, 0xFF, (u8)(val >> 8)); + RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); + RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x81); + + for (i = 0; i < 100000; i++) { + RTSX_READ_REG(chip, PHYRWCTL, &tmp); + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) +{ + int i, finished = 0; + u16 data = 0; + u8 tmp; + + RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); + RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x80); + + for (i = 0; i < 100000; i++) { + RTSX_READ_REG(chip, PHYRWCTL, &tmp); + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_READ_REG(chip, PHYDATA0, &tmp); + data = tmp; + RTSX_READ_REG(chip, PHYDATA1, &tmp); + data |= (u16)tmp << 8; + + if (val) + *val = data; + + return STATUS_SUCCESS; +} + +int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) +{ + int i; + u8 data = 0; + + RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0x80|addr); + + for (i = 0; i < 100; i++) { + RTSX_READ_REG(chip, EFUSE_CTRL, &data); + if (!(data & 0x80)) + break; + udelay(1); + } + + if (data & 0x80) + TRACE_RET(chip, STATUS_TIMEDOUT); + + RTSX_READ_REG(chip, EFUSE_DATA, &data); + if (val) + *val = data; + + return STATUS_SUCCESS; +} + +int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) +{ + int i, j; + u8 data = 0, tmp = 0xFF; + + for (i = 0; i < 8; i++) { + if (val & (u8)(1 << i)) + continue; + + tmp &= (~(u8)(1 << i)); + RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr); + + RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp); + RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr); + + for (j = 0; j < 100; j++) { + RTSX_READ_REG(chip, EFUSE_CTRL, &data); + if (!(data & 0x80)) + break; + wait_timeout(3); + } + + if (data & 0x80) + TRACE_RET(chip, STATUS_TIMEDOUT); + + wait_timeout(5); + } + + return STATUS_SUCCESS; +} + +int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) +{ + int retval; + u16 value; + + retval = rtsx_read_phy_register(chip, reg, &value); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (value & (1 << bit)) { + value &= ~(1 << bit); + retval = rtsx_write_phy_register(chip, reg, value); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) +{ + int retval; + u16 value; + + retval = rtsx_read_phy_register(chip, reg, &value); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (0 == (value & (1 << bit))) { + value |= (1 << bit); + retval = rtsx_write_phy_register(chip, reg, value); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int rtsx_check_link_ready(struct rtsx_chip *chip) +{ + u8 val; + + RTSX_READ_REG(chip, IRQSTAT0, &val); + + RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val); + if (val & LINK_RDY_INT) { + RTSX_DEBUGP("Delinked!\n"); + rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + return STATUS_FAIL; + } + + return STATUS_SUCCESS; +} + +static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) +{ + u32 ultmp; + + RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate); + + if (CHK_SDIO_EXIST(chip)) { + u8 func_no; + + if (CHECK_PID(chip, 0x5288)) + func_no = 2; + else + func_no = 1; + + rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); + RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no, + ultmp); + rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); + } + + rtsx_write_config_byte(chip, 0x44, dstate); + rtsx_write_config_byte(chip, 0x45, 0); +} + +void rtsx_enter_L1(struct rtsx_chip *chip) +{ + rtsx_handle_pm_dstate(chip, 2); +} + +void rtsx_exit_L1(struct rtsx_chip *chip) +{ + rtsx_write_config_byte(chip, 0x44, 0); + rtsx_write_config_byte(chip, 0x45, 0); +} + +void rtsx_enter_ss(struct rtsx_chip *chip) +{ + RTSX_DEBUGP("Enter Selective Suspend State!\n"); + + rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + + if (chip->power_down_in_ss) { + rtsx_power_off_card(chip); + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + } + + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5288)) + rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); + else + rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); + } + + if (chip->auto_delink_en) { + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); + } else { + if (!chip->phy_debug_mode) { + u32 tmp; + tmp = rtsx_readl(chip, RTSX_BIER); + tmp |= CARD_INT; + rtsx_writel(chip, RTSX_BIER, tmp); + } + + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0); + } + + rtsx_enter_L1(chip); + + RTSX_CLR_DELINK(chip); + rtsx_set_stat(chip, RTSX_STAT_SS); +} + +void rtsx_exit_ss(struct rtsx_chip *chip) +{ + RTSX_DEBUGP("Exit Selective Suspend State!\n"); + + rtsx_exit_L1(chip); + + if (chip->power_down_in_ss) { + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + udelay(1000); + } + + if (RTSX_TST_DELINK(chip)) { + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + RTSX_CLR_DELINK(chip); + } else if (chip->power_down_in_ss) { + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 0); + } +} + +int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) +{ + u32 status, int_enable; + int exit_ss = 0; +#ifdef SUPPORT_OCP + u32 ocp_int = 0; + + ocp_int = OC_INT; +#endif + + if (chip->ss_en) { + chip->ss_counter = 0; + if (rtsx_get_stat(chip) == RTSX_STAT_SS) { + exit_ss = 1; + rtsx_exit_L1(chip); + rtsx_set_stat(chip, RTSX_STAT_RUN); + } + } + + int_enable = rtsx_readl(chip, RTSX_BIER); + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (((chip->int_reg & int_enable) == 0) || + (chip->int_reg == 0xFFFFFFFF)) + return STATUS_FAIL; + + status = chip->int_reg &= (int_enable | 0x7FFFFF); + + if (status & CARD_INT) { + chip->auto_delink_cnt = 0; + + if (status & SD_INT) { + if (status & SD_EXIST) { + set_bit(SD_NR, &(chip->need_reset)); + } else { + set_bit(SD_NR, &(chip->need_release)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + clear_bit(SD_NR, &(chip->need_reset)); + } + } else { + /* If multi-luns, it's possible that + when plugging/unplugging one card + there is another card which still + exists in the slot. In this case, + all existed cards should be reset. + */ + if (exit_ss && (status & SD_EXIST)) + set_bit(SD_NR, &(chip->need_reinit)); + } + if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { + if (status & XD_INT) { + if (status & XD_EXIST) { + set_bit(XD_NR, &(chip->need_reset)); + } else { + set_bit(XD_NR, &(chip->need_release)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + clear_bit(XD_NR, &(chip->need_reset)); + } + } else { + if (exit_ss && (status & XD_EXIST)) + set_bit(XD_NR, &(chip->need_reinit)); + } + } + if (status & MS_INT) { + if (status & MS_EXIST) { + set_bit(MS_NR, &(chip->need_reset)); + } else { + set_bit(MS_NR, &(chip->need_release)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + clear_bit(MS_NR, &(chip->need_reset)); + } + } else { + if (exit_ss && (status & MS_EXIST)) + set_bit(MS_NR, &(chip->need_reinit)); + } + } + +#ifdef SUPPORT_OCP + chip->ocp_int = ocp_int & status; +#endif + + if (chip->sd_io) { + if (chip->int_reg & DATA_DONE_INT) + chip->int_reg &= ~(u32)DATA_DONE_INT; + } + + return STATUS_SUCCESS; +} + +void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) +{ + int retval; + + RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat); + + rtsx_set_stat(chip, RTSX_STAT_SUSPEND); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) + return; + + rtsx_release_cards(chip); + rtsx_disable_bus_int(chip); + turn_off_led(chip, LED_GPIO); + +#ifdef HW_AUTO_SWITCH_SD_BUS + if (chip->sd_io) { + chip->sdio_in_charge = 1; + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); + /* Enable sdio_bus_auto_switch */ + rtsx_write_register(chip, 0xFE70, 0x80, 0x80); + } else if (CHECK_PID(chip, 0x5288)) { + rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); + /* Enable sdio_bus_auto_switch */ + rtsx_write_register(chip, 0xFE5A, 0x08, 0x08); + } + } +#endif + + if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { + /* u_force_clkreq_0 */ + rtsx_write_register(chip, PETXCFG, 0x08, 0x08); + } + + if (pm_stat == PM_S1) { + RTSX_DEBUGP("Host enter S1\n"); + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, + HOST_ENTER_S1); + } else if (pm_stat == PM_S3) { + if (chip->s3_pwr_off_delay > 0) + wait_timeout(chip->s3_pwr_off_delay); + + RTSX_DEBUGP("Host enter S3\n"); + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, + HOST_ENTER_S3); + } + + if (chip->do_delink_before_power_down && chip->auto_delink_en) + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); + + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + + chip->cur_clk = 0; + chip->cur_card = 0; + chip->card_exist = 0; +} + +void rtsx_enable_aspm(struct rtsx_chip *chip) +{ + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (!chip->aspm_enabled) { + RTSX_DEBUGP("Try to enable ASPM\n"); + chip->aspm_enabled = 1; + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0); + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, + 0x30 | chip->aspm_level[0]); + } else { + rtsx_write_config_byte(chip, LCTLR, + chip->aspm_l0s_l1_en); + } + + if (CHK_SDIO_EXIST(chip)) { + u16 val = chip->aspm_l0s_l1_en | 0x0100; + if (CHECK_PID(chip, 0x5288)) + rtsx_write_cfg_dw(chip, 2, 0xC0, + 0xFFFF, val); + else + rtsx_write_cfg_dw(chip, 1, 0xC0, + 0xFFFF, val); + } + } + } + + return; +} + +void rtsx_disable_aspm(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) + rtsx_monitor_aspm_config(chip); + + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (chip->aspm_enabled) { + RTSX_DEBUGP("Try to disable ASPM\n"); + chip->aspm_enabled = 0; + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0x0129); + if (CHECK_PID(chip, 0x5208)) + rtsx_write_register(chip, ASPM_FORCE_CTL, + 0xF3, 0x30); + else + rtsx_write_config_byte(chip, LCTLR, 0x00); + + wait_timeout(1); + } + } + + return; +} + +int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) +{ + int retval; + int i, j; + u16 reg_addr; + u8 *ptr; + + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + ptr = buf; + reg_addr = PPBUF_BASE2; + for (i = 0; i < buf_len/256; i++) { + rtsx_init_cmd(chip); + + for (j = 0; j < 256; j++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + memcpy(ptr, rtsx_get_cmd_data(chip), 256); + ptr += 256; + } + + if (buf_len%256) { + rtsx_init_cmd(chip); + + for (j = 0; j < buf_len%256; j++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256); + + return STATUS_SUCCESS; +} + +int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) +{ + int retval; + int i, j; + u16 reg_addr; + u8 *ptr; + + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + ptr = buf; + reg_addr = PPBUF_BASE2; + for (i = 0; i < buf_len/256; i++) { + rtsx_init_cmd(chip); + + for (j = 0; j < 256; j++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, + *ptr); + ptr++; + } + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf_len%256) { + rtsx_init_cmd(chip); + + for (j = 0; j < buf_len%256; j++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, + *ptr); + ptr++; + } + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int rtsx_check_chip_exist(struct rtsx_chip *chip) +{ + if (rtsx_readl(chip, 0) == 0xFFFFFFFF) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) +{ + int retval; + u8 mask = 0; + + if (ctl & SSC_PDCTL) + mask |= SSC_POWER_DOWN; + +#ifdef SUPPORT_OCP + if (ctl & OC_PDCTL) { + mask |= SD_OC_POWER_DOWN; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + mask |= MS_OC_POWER_DOWN; + } +#endif + + if (mask) { + retval = rtsx_write_register(chip, FPDCTL, mask, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHECK_PID(chip, 0x5288)) + wait_timeout(200); + } + + return STATUS_SUCCESS; +} + +int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) +{ + int retval; + u8 mask = 0, val = 0; + + if (ctl & SSC_PDCTL) + mask |= SSC_POWER_DOWN; + +#ifdef SUPPORT_OCP + if (ctl & OC_PDCTL) { + mask |= SD_OC_POWER_DOWN; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + mask |= MS_OC_POWER_DOWN; + } +#endif + + if (mask) { + val = mask; + retval = rtsx_write_register(chip, FPDCTL, mask, val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h new file mode 100644 index 000000000000..c25efcc3f3aa --- /dev/null +++ b/drivers/staging/rts5208/rtsx_chip.h @@ -0,0 +1,1002 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_CHIP_H +#define __REALTEK_RTSX_CHIP_H + +#include "rtsx.h" + +#define SUPPORT_CPRM +#define SUPPORT_OCP +#define SUPPORT_SDIO_ASPM +#define SUPPORT_MAGIC_GATE +#define SUPPORT_MSXC +#define SUPPORT_SD_LOCK +/* Hardware switch bus_ctl and cd_ctl automatically */ +#define HW_AUTO_SWITCH_SD_BUS +/* Enable hardware interrupt write clear */ +#define HW_INT_WRITE_CLR +/* #define LED_AUTO_BLINK */ +/* #define DISABLE_CARD_INT */ + +#ifdef SUPPORT_MAGIC_GATE + /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */ + #define MG_SET_ICV_SLOW + /* HW may miss ERR/CMDNK signal when sampling INT status. */ + #define MS_SAMPLE_INT_ERR + /* HW DO NOT support Wait_INT function during READ_BYTES + * transfer mode */ + #define READ_BYTES_WAIT_INT +#endif + +#ifdef SUPPORT_MSXC +#define XC_POWERCLASS +#define SUPPORT_PCGL_1P18 +#endif + +#ifndef LED_AUTO_BLINK +#define REGULAR_BLINK +#endif + +#define LED_BLINK_SPEED 5 +#define LED_TOGGLE_INTERVAL 6 +#define GPIO_TOGGLE_THRESHOLD 1024 +#define LED_GPIO 0 + +#define POLLING_INTERVAL 30 + +#define TRACE_ITEM_CNT 64 + +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS 0 +#endif +#ifndef STATUS_FAIL +#define STATUS_FAIL 1 +#endif +#ifndef STATUS_TIMEDOUT +#define STATUS_TIMEDOUT 2 +#endif +#ifndef STATUS_NOMEM +#define STATUS_NOMEM 3 +#endif +#ifndef STATUS_READ_FAIL +#define STATUS_READ_FAIL 4 +#endif +#ifndef STATUS_WRITE_FAIL +#define STATUS_WRITE_FAIL 5 +#endif +#ifndef STATUS_ERROR +#define STATUS_ERROR 10 +#endif + +#define PM_S1 1 +#define PM_S3 3 + +/* + * Transport return codes + */ + +#define TRANSPORT_GOOD 0 /* Transport good, command good */ +#define TRANSPORT_FAILED 1 /* Transport good, command failed */ +#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ +#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ + + +/*----------------------------------- + Start-Stop-Unit +-----------------------------------*/ +#define STOP_MEDIUM 0x00 /* access disable */ +#define MAKE_MEDIUM_READY 0x01 /* access enable */ +#define UNLOAD_MEDIUM 0x02 /* unload */ +#define LOAD_MEDIUM 0x03 /* load */ + +/*----------------------------------- + STANDARD_INQUIRY +-----------------------------------*/ +#define QULIFIRE 0x00 +#define AENC_FNC 0x00 +#define TRML_IOP 0x00 +#define REL_ADR 0x00 +#define WBUS_32 0x00 +#define WBUS_16 0x00 +#define SYNC 0x00 +#define LINKED 0x00 +#define CMD_QUE 0x00 +#define SFT_RE 0x00 + +#define VEN_ID_LEN 8 /* Vendor ID Length */ +#define PRDCT_ID_LEN 16 /* Product ID Length */ +#define PRDCT_REV_LEN 4 /* Product LOT Length */ + +/* Dynamic flag definitions: used in set_bit() etc. */ +#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */ +#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in + * progress */ +#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect + * in progress */ +#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ + (1UL << US_FLIDX_DISCONNECTING)) +#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset + * in progress */ +#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI + * midlayer timed out */ + +#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ +#define RMB_DISC 0x80 /* The Device is Removable */ +#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ + +#define SCSI 0x00 /* Interface ID */ + +#define WRITE_PROTECTED_MEDIA 0x07 + +/*---- sense key ----*/ +#define ILI 0x20 /* ILI bit is on */ + +#define NO_SENSE 0x00 /* not exist sense key */ +#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ +#define NOT_READY 0x02 /* Logical unit is not ready */ +#define MEDIA_ERR 0x03 /* medium/data error */ +#define HARDWARE_ERR 0x04 /* hardware error */ +#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ +#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ +#define DAT_PRTCT 0x07 /* read/write is desable */ +#define BLNC_CHK 0x08 /* find blank/DOF in read */ + /* write to unblank area */ +#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ +#define ABRT_CMD 0x0b /* Target make the command in error */ +#define EQUAL 0x0c /* Search Data end with Equal */ +#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ +#define MISCMP 0x0e /* find inequality */ + +#define READ_ERR -1 +#define WRITE_ERR -2 + +#define FIRST_RESET 0x01 +#define USED_EXIST 0x02 + +/*----------------------------------- + SENSE_DATA +-----------------------------------*/ +/*---- valid ----*/ +#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ +#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ + +/*---- error code ----*/ +#define CUR_ERR 0x70 /* current error */ +#define DEF_ERR 0x71 /* specific command error */ + +/*---- sense key Information ----*/ +#define SNSKEYINFO_LEN 3 /* length of sense key information */ + +#define SKSV 0x80 +#define CDB_ILLEGAL 0x40 +#define DAT_ILLEGAL 0x00 +#define BPV 0x08 +#define BIT_ILLEGAL0 0 /* bit0 is illegal */ +#define BIT_ILLEGAL1 1 /* bit1 is illegal */ +#define BIT_ILLEGAL2 2 /* bit2 is illegal */ +#define BIT_ILLEGAL3 3 /* bit3 is illegal */ +#define BIT_ILLEGAL4 4 /* bit4 is illegal */ +#define BIT_ILLEGAL5 5 /* bit5 is illegal */ +#define BIT_ILLEGAL6 6 /* bit6 is illegal */ +#define BIT_ILLEGAL7 7 /* bit7 is illegal */ + +/*---- ASC ----*/ +#define ASC_NO_INFO 0x00 +#define ASC_MISCMP 0x1d +#define ASC_INVLD_CDB 0x24 +#define ASC_INVLD_PARA 0x26 +#define ASC_LU_NOT_READY 0x04 +#define ASC_WRITE_ERR 0x0c +#define ASC_READ_ERR 0x11 +#define ASC_LOAD_EJCT_ERR 0x53 +#define ASC_MEDIA_NOT_PRESENT 0x3A +#define ASC_MEDIA_CHANGED 0x28 +#define ASC_MEDIA_IN_PROCESS 0x04 +#define ASC_WRITE_PROTECT 0x27 +#define ASC_LUN_NOT_SUPPORTED 0x25 + +/*---- ASQC ----*/ +#define ASCQ_NO_INFO 0x00 +#define ASCQ_MEDIA_IN_PROCESS 0x01 +#define ASCQ_MISCMP 0x00 +#define ASCQ_INVLD_CDB 0x00 +#define ASCQ_INVLD_PARA 0x02 +#define ASCQ_LU_NOT_READY 0x02 +#define ASCQ_WRITE_ERR 0x02 +#define ASCQ_READ_ERR 0x00 +#define ASCQ_LOAD_EJCT_ERR 0x00 +#define ASCQ_WRITE_PROTECT 0x00 + + +struct sense_data_t { + unsigned char err_code; /* error code */ + /* bit7 : valid */ + /* (1 : SCSI2) */ + /* (0 : Vendor * specific) */ + /* bit6-0 : error * code */ + /* (0x70 : current * error) */ + /* (0x71 : specific command error) */ + unsigned char seg_no; /* segment No. */ + unsigned char sense_key; /* byte5 : ILI */ + /* bit3-0 : sense key */ + unsigned char info[4]; /* information */ + unsigned char ad_sense_len; /* additional sense data length */ + unsigned char cmd_info[4]; /* command specific information */ + unsigned char asc; /* ASC */ + unsigned char ascq; /* ASCQ */ + unsigned char rfu; /* FRU */ + unsigned char sns_key_info[3];/* sense key specific information */ +}; + +/* PCI Operation Register Address */ +#define RTSX_HCBAR 0x00 +#define RTSX_HCBCTLR 0x04 +#define RTSX_HDBAR 0x08 +#define RTSX_HDBCTLR 0x0C +#define RTSX_HAIMR 0x10 +#define RTSX_BIPR 0x14 +#define RTSX_BIER 0x18 + +/* Host command buffer control register */ +#define STOP_CMD (0x01 << 28) + +/* Host data buffer control register */ +#define SDMA_MODE 0x00 +#define ADMA_MODE (0x02 << 26) +#define STOP_DMA (0x01 << 28) +#define TRIG_DMA (0x01 << 31) + +/* Bus interrupt pending register */ +#define CMD_DONE_INT (1 << 31) +#define DATA_DONE_INT (1 << 30) +#define TRANS_OK_INT (1 << 29) +#define TRANS_FAIL_INT (1 << 28) +#define XD_INT (1 << 27) +#define MS_INT (1 << 26) +#define SD_INT (1 << 25) +#define GPIO0_INT (1 << 24) +#define OC_INT (1 << 23) +#define SD_WRITE_PROTECT (1 << 19) +#define XD_EXIST (1 << 18) +#define MS_EXIST (1 << 17) +#define SD_EXIST (1 << 16) +#define DELINK_INT GPIO0_INT +#define MS_OC_INT (1 << 23) +#define SD_OC_INT (1 << 22) + +#define CARD_INT (XD_INT | MS_INT | SD_INT) +#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) +#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | GPIO0_INT | OC_INT) + +#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) + +/* Bus interrupt enable register */ +#define CMD_DONE_INT_EN (1 << 31) +#define DATA_DONE_INT_EN (1 << 30) +#define TRANS_OK_INT_EN (1 << 29) +#define TRANS_FAIL_INT_EN (1 << 28) +#define XD_INT_EN (1 << 27) +#define MS_INT_EN (1 << 26) +#define SD_INT_EN (1 << 25) +#define GPIO0_INT_EN (1 << 24) +#define OC_INT_EN (1 << 23) +#define DELINK_INT_EN GPIO0_INT_EN +#define MS_OC_INT_EN (1 << 23) +#define SD_OC_INT_EN (1 << 22) + + +#define READ_REG_CMD 0 +#define WRITE_REG_CMD 1 +#define CHECK_REG_CMD 2 + +#define HOST_TO_DEVICE 0 +#define DEVICE_TO_HOST 1 + + +#define RTSX_RESV_BUF_LEN 4096 +#define HOST_CMDS_BUF_LEN 1024 +#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) + +#define SD_NR 2 +#define MS_NR 3 +#define XD_NR 4 +#define SPI_NR 7 +#define SD_CARD (1 << SD_NR) +#define MS_CARD (1 << MS_NR) +#define XD_CARD (1 << XD_NR) +#define SPI_CARD (1 << SPI_NR) + +#define MAX_ALLOWED_LUN_CNT 8 + +#define XD_FREE_TABLE_CNT 1200 +#define MS_FREE_TABLE_CNT 512 + + +/* Bit Operation */ +#define SET_BIT(data, idx) ((data) |= 1 << (idx)) +#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) +#define CHK_BIT(data, idx) ((data) & (1 << (idx))) + +/* SG descriptor */ +#define SG_INT 0x04 +#define SG_END 0x02 +#define SG_VALID 0x01 + +#define SG_NO_OP 0x00 +#define SG_TRANS_DATA (0x02 << 4) +#define SG_LINK_DESC (0x03 << 4) + +struct rtsx_chip; + +typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 sec_addr, u16 sec_cnt); + +/* Supported Clock */ +enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, + CLK_80, CLK_100, CLK_120, CLK_150, CLK_200}; + +enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS, + RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, + RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT}; +enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3}; + +#define MAX_RESET_CNT 3 + +/* For MS Card */ +#define MAX_DEFECTIVE_BLOCK 10 + +struct zone_entry { + u16 *l2p_table; + u16 *free_table; + u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ + int set_index; + int get_index; + int unused_blk_cnt; + int disable_count; + /* To indicate whether the L2P table of this zone has been built. */ + int build_flag; +}; + +#define TYPE_SD 0x0000 +#define TYPE_MMC 0x0001 + +/* TYPE_SD */ +#define SD_HS 0x0100 +#define SD_SDR50 0x0200 +#define SD_DDR50 0x0400 +#define SD_SDR104 0x0800 +#define SD_HCXC 0x1000 + +/* TYPE_MMC */ +#define MMC_26M 0x0100 +#define MMC_52M 0x0200 +#define MMC_4BIT 0x0400 +#define MMC_8BIT 0x0800 +#define MMC_SECTOR_MODE 0x1000 +#define MMC_DDR52 0x2000 + +/* SD card */ +#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) +#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS)) +#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50)) +#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50)) +#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104)) +#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC)) +#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity <= 0x4000000)) +#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity > 0x4000000)) +#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) || CHK_SD_SDR104(sd_card)) + +#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) +#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) +#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) +#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) +#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) +#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) + +#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) +#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) +#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) +#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) +#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) + +/* MMC card */ +#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_MMC) +#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M)) +#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M)) +#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT)) +#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT)) +#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE)) +#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52)) + +#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) +#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) +#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) +#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) +#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) +#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) +#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) + +#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) +#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) +#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) +#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) +#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) +#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) + +#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card)) +#define CLR_MMC_HS(sd_card) \ +do { \ + CLR_MMC_DDR52(sd_card); \ + CLR_MMC_52M(sd_card); \ + CLR_MMC_26M(sd_card); \ +} while (0) + +#define SD_SUPPORT_CLASS_TEN 0x01 +#define SD_SUPPORT_1V8 0x02 + +#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN) +#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN) +#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN) +#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_1V8) +#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_1V8) +#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8) + +struct sd_info { + u16 sd_type; + u8 err_code; + u8 sd_data_buf_ready; + u32 sd_addr; + u32 capacity; + + u8 raw_csd[16]; + u8 raw_scr[8]; + + /* Sequential RW */ + int seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + + int cleanup_counter; + + int sd_clock; + + int mmc_dont_switch_bus; + +#ifdef SUPPORT_CPRM + int sd_pass_thru_en; + int pre_cmd_err; + u8 last_rsp_type; + u8 rsp[17]; +#endif + + u8 func_group1_mask; + u8 func_group2_mask; + u8 func_group3_mask; + u8 func_group4_mask; + + u8 sd_switch_fail; + u8 sd_read_phase; + +#ifdef SUPPORT_SD_LOCK + u8 sd_lock_status; + u8 sd_erase_status; + u8 sd_lock_notify; +#endif + int need_retune; +}; + +struct xd_delay_write_tag { + u32 old_phyblock; + u32 new_phyblock; + u32 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct xd_info { + u8 maker_code; + u8 device_code; + u8 block_shift; + u8 page_off; + u8 addr_cycle; + u16 cis_block; + u8 multi_flag; + u8 err_code; + u32 capacity; + + struct zone_entry *zone; + int zone_cnt; + + struct xd_delay_write_tag delay_write; + int cleanup_counter; + + int xd_clock; +}; + +#define MODE_512_SEQ 0x01 +#define MODE_2K_SEQ 0x02 + +#define TYPE_MS 0x0000 +#define TYPE_MSPRO 0x0001 + +#define MS_4BIT 0x0100 +#define MS_8BIT 0x0200 +#define MS_HG 0x0400 +#define MS_XC 0x0800 + +#define HG8BIT (MS_HG | MS_8BIT) + +#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) +#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT)) +#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC)) +#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG)) + +#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) +#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) + +struct ms_delay_write_tag { + u16 old_phyblock; + u16 new_phyblock; + u16 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct ms_info { + u16 ms_type; + u8 block_shift; + u8 page_off; + u16 total_block; + u16 boot_block; + u32 capacity; + + u8 check_ms_flow; + u8 switch_8bit_fail; + u8 err_code; + + struct zone_entry *segment; + int segment_cnt; + + int pro_under_formatting; + int format_status; + u16 progress; + u8 raw_sys_info[96]; +#ifdef SUPPORT_PCGL_1P18 + u8 raw_model_name[48]; +#endif + + u8 multi_flag; + + /* Sequential RW */ + u8 seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + u32 total_sec_cnt; + + struct ms_delay_write_tag delay_write; + + int cleanup_counter; + + int ms_clock; + +#ifdef SUPPORT_MAGIC_GATE + u8 magic_gate_id[16]; + u8 mg_entry_num; + int mg_auth; /* flag to indicate authentication process */ +#endif +}; + +struct spi_info { + u8 use_clk; + u8 write_en; + u16 clk_div; + u8 err_code; + + int spi_clock; +}; + + +#ifdef _MSG_TRACE +struct trace_msg_t { + u16 line; +#define MSG_FUNC_LEN 64 + char func[MSG_FUNC_LEN]; +#define MSG_FILE_LEN 32 + char file[MSG_FILE_LEN]; +#define TIME_VAL_LEN 16 + u8 timeval_buf[TIME_VAL_LEN]; + u8 valid; +}; +#endif + +/************/ +/* LUN mode */ +/************/ +/* Single LUN, support xD/SD/MS */ +#define DEFAULT_SINGLE 0 +/* 2 LUN mode, support SD/MS */ +#define SD_MS_2LUN 1 +/* Single LUN, but only support SD/MS, for Barossa LQFP */ +#define SD_MS_1LUN 2 + +#define LAST_LUN_MODE 2 + +/* Barossa package */ +#define QFN 0 +#define LQFP 1 + +/******************/ +/* sd_ctl bit map */ +/******************/ +/* SD push point control, bit 0, 1 */ +#define SD_PUSH_POINT_CTL_MASK 0x03 +#define SD_PUSH_POINT_DELAY 0x01 +#define SD_PUSH_POINT_AUTO 0x02 +/* SD sample point control, bit 2, 3 */ +#define SD_SAMPLE_POINT_CTL_MASK 0x0C +#define SD_SAMPLE_POINT_DELAY 0x04 +#define SD_SAMPLE_POINT_AUTO 0x08 +/* SD DDR Tx phase set by user, bit 4 */ +#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 +/* MMC DDR Tx phase set by user, bit 5 */ +#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 +/* Support MMC DDR mode, bit 6 */ +#define SUPPORT_MMC_DDR_MODE 0x40 +/* Reset MMC at first */ +#define RESET_MMC_FIRST 0x80 + +#define SEQ_START_CRITERIA 0x20 + +/* MS Power Class En */ +#define POWER_CLASS_2_EN 0x02 +#define POWER_CLASS_1_EN 0x01 + +#define MAX_SHOW_CNT 10 +#define MAX_RESET_CNT 3 + +#define SDIO_EXIST 0x01 +#define SDIO_IGNORED 0x02 + +#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST) +#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST) +#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST) + +#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED) +#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= SDIO_IGNORED) +#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= ~SDIO_IGNORED) + +struct rtsx_chip { + rtsx_dev_t *rtsx; + + u32 int_reg; /* Bus interrupt pending register */ + char max_lun; + void *context; + + void *host_cmds_ptr; /* host commands buffer pointer */ + dma_addr_t host_cmds_addr; + int ci; /* Command Index */ + + void *host_sg_tbl_ptr; /* SG descriptor table */ + dma_addr_t host_sg_tbl_addr; + int sgi; /* SG entry index */ + + struct scsi_cmnd *srb; /* current srb */ + struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; + + int cur_clk; /* current card clock */ + + /* Current accessed card */ + int cur_card; + + unsigned long need_release; /* need release bit map */ + unsigned long need_reset; /* need reset + * bit map */ + /* Flag to indicate that this card is just resumed from SS state, + * and need released before being resetted + */ + unsigned long need_reinit; + + int rw_need_retry; + +#ifdef SUPPORT_OCP + u32 ocp_int; + u8 ocp_stat; +#endif + + u8 card_exist; /* card exist bit map (physical exist) */ + u8 card_ready; /* card ready bit map (reset successfully) */ + u8 card_fail; /* card reset fail bit map */ + u8 card_ejected; /* card ejected bit map */ + u8 card_wp; /* card write protected bit map */ + + u8 lun_mc; /* flag to indicate whether to answer + * MediaChange */ + +#ifndef LED_AUTO_BLINK + int led_toggle_counter; +#endif + + int sd_reset_counter; + int xd_reset_counter; + int ms_reset_counter; + + /* card bus width */ + u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; + /* card capacity */ + u32 capacity[MAX_ALLOWED_LUN_CNT]; + /* read/write card function pointer */ + card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; + /* read/write capacity, used for GPIO Toggle */ + u32 rw_cap[MAX_ALLOWED_LUN_CNT]; + /* card to lun mapping table */ + u8 card2lun[32]; + /* lun to card mapping table */ + u8 lun2card[MAX_ALLOWED_LUN_CNT]; + + int rw_fail_cnt[MAX_ALLOWED_LUN_CNT]; + + int sd_show_cnt; + int xd_show_cnt; + int ms_show_cnt; + + /* card information */ + struct sd_info sd_card; + struct xd_info xd_card; + struct ms_info ms_card; + + struct spi_info spi; + +#ifdef _MSG_TRACE + struct trace_msg_t trace_msg[TRACE_ITEM_CNT]; + int msg_idx; +#endif + + int auto_delink_cnt; + int auto_delink_allowed; + + int aspm_enabled; + + int sdio_aspm; + int sdio_idle; + int sdio_counter; + u8 sdio_raw_data[12]; + + u8 sd_io; + u8 sd_int; + + u8 rtsx_flag; + + int ss_counter; + int idle_counter; + enum RTSX_STAT rtsx_stat; + + u16 vendor_id; + u16 product_id; + u8 ic_version; + + int driver_first_load; + +#ifdef HW_AUTO_SWITCH_SD_BUS + int sdio_in_charge; +#endif + + u8 aspm_level[2]; + + int chip_insert_with_sdio; + + /* Options */ + + int adma_mode; + + int auto_delink_en; + int ss_en; + u8 lun_mode; + u8 aspm_l0s_l1_en; + + int power_down_in_ss; + + int sdr104_en; + int ddr50_en; + int sdr50_en; + + int baro_pkg; + + int asic_code; + int phy_debug_mode; + int hw_bypass_sd; + int sdio_func_exist; + int aux_pwr_exist; + u8 ms_power_class_en; + + int mspro_formatter_enable; + + int remote_wakeup_en; + + int ignore_sd; + int use_hw_setting; + + int ss_idle_period; + + int dynamic_aspm; + + int fpga_sd_sdr104_clk; + int fpga_sd_ddr50_clk; + int fpga_sd_sdr50_clk; + int fpga_sd_hs_clk; + int fpga_mmc_52m_clk; + int fpga_ms_hg_clk; + int fpga_ms_4bit_clk; + int fpga_ms_1bit_clk; + + int asic_sd_sdr104_clk; + int asic_sd_ddr50_clk; + int asic_sd_sdr50_clk; + int asic_sd_hs_clk; + int asic_mmc_52m_clk; + int asic_ms_hg_clk; + int asic_ms_4bit_clk; + int asic_ms_1bit_clk; + + u8 ssc_depth_sd_sdr104; + u8 ssc_depth_sd_ddr50; + u8 ssc_depth_sd_sdr50; + u8 ssc_depth_sd_hs; + u8 ssc_depth_mmc_52m; + u8 ssc_depth_ms_hg; + u8 ssc_depth_ms_4bit; + u8 ssc_depth_low_speed; + + u8 card_drive_sel; + u8 sd30_drive_sel_1v8; + u8 sd30_drive_sel_3v3; + + u8 sd_400mA_ocp_thd; + u8 sd_800mA_ocp_thd; + u8 ms_ocp_thd; + + int ssc_en; + int msi_en; + + int xd_timeout; + int sd_timeout; + int ms_timeout; + int mspro_timeout; + + int auto_power_down; + + int sd_ddr_tx_phase; + int mmc_ddr_tx_phase; + int sd_default_tx_phase; + int sd_default_rx_phase; + + int pmos_pwr_on_interval; + int sd_voltage_switch_delay; + int s3_pwr_off_delay; + + int force_clkreq_0; + int ft2_fast_mode; + + int do_delink_before_power_down; + int polling_config; + int sdio_retry_cnt; + + int delink_stage1_step; + int delink_stage2_step; + int delink_stage3_step; + + int auto_delink_in_L1; + int hp_watch_bios_hotplug; + int support_ms_8bit; + + u8 blink_led; + u8 phy_voltage; + u8 max_payload; + + u32 sd_speed_prior; + u32 sd_current_prior; + u32 sd_ctl; +}; + +#define rtsx_set_stat(chip, stat) \ +do { \ + if ((stat) != RTSX_STAT_IDLE) { \ + (chip)->idle_counter = 0; \ + } \ + (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \ +} while (0) +#define rtsx_get_stat(chip) ((chip)->rtsx_stat) +#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat)) + +#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01) +#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE) +#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01) + +#define CHECK_PID(chip, pid) ((chip)->product_id == (pid)) +#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg)) +#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode)) + +/* Power down control */ +#define SSC_PDCTL 0x01 +#define OC_PDCTL 0x02 + +int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); +int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); + +void rtsx_disable_card_int(struct rtsx_chip *chip); +void rtsx_enable_card_int(struct rtsx_chip *chip); +void rtsx_enable_bus_int(struct rtsx_chip *chip); +void rtsx_disable_bus_int(struct rtsx_chip *chip); +int rtsx_reset_chip(struct rtsx_chip *chip); +int rtsx_init_chip(struct rtsx_chip *chip); +void rtsx_release_chip(struct rtsx_chip *chip); +void rtsx_polling_func(struct rtsx_chip *chip); +void rtsx_undo_delink(struct rtsx_chip *chip); +void rtsx_stop_cmd(struct rtsx_chip *chip, int card); +int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); +int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); +int rtsx_write_cfg_dw(struct rtsx_chip *chip, + u8 func_no, u16 addr, u32 mask, u32 val); +int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); +int rtsx_write_cfg_seq(struct rtsx_chip *chip, + u8 func, u16 addr, u8 *buf, int len); +int rtsx_read_cfg_seq(struct rtsx_chip *chip, + u8 func, u16 addr, u8 *buf, int len); +int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); +int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val); +int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); +int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); +int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); +int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); +int rtsx_check_link_ready(struct rtsx_chip *chip); +void rtsx_enter_ss(struct rtsx_chip *chip); +void rtsx_exit_ss(struct rtsx_chip *chip); +int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); +void rtsx_enter_L1(struct rtsx_chip *chip); +void rtsx_exit_L1(struct rtsx_chip *chip); +void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat); +void rtsx_enable_aspm(struct rtsx_chip *chip); +void rtsx_disable_aspm(struct rtsx_chip *chip); +int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); +int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); +int rtsx_check_chip_exist(struct rtsx_chip *chip); + +#define RTSX_WRITE_REG(chip, addr, mask, data) \ + do { \ + int retval = rtsx_write_register((chip), (addr), (mask), (data)); \ + if (retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), retval); \ + } \ + } while (0) + +#define RTSX_READ_REG(chip, addr, data) \ + do { \ + int retval = rtsx_read_register((chip), (addr), (data)); \ + if (retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), retval); \ + } \ + } while (0) + +#endif /* __REALTEK_RTSX_CHIP_H */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c new file mode 100644 index 000000000000..382e73a54f4d --- /dev/null +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -0,0 +1,3370 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/vmalloc.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_sys.h" +#include "rtsx_card.h" +#include "rtsx_chip.h" +#include "rtsx_scsi.h" +#include "sd.h" +#include "ms.h" +#include "spi.h" + +void scsi_show_command(struct scsi_cmnd *srb) +{ + char *what = NULL; + int i, unknown_cmd = 0; + + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: + what = "TEST_UNIT_READY"; + break; + case REZERO_UNIT: + what = "REZERO_UNIT"; + break; + case REQUEST_SENSE: + what = "REQUEST_SENSE"; + break; + case FORMAT_UNIT: + what = "FORMAT_UNIT"; + break; + case READ_BLOCK_LIMITS: + what = "READ_BLOCK_LIMITS"; + break; + case REASSIGN_BLOCKS: + what = "REASSIGN_BLOCKS"; + break; + case READ_6: + what = "READ_6"; + break; + case WRITE_6: + what = "WRITE_6"; + break; + case SEEK_6: + what = "SEEK_6"; + break; + case READ_REVERSE: + what = "READ_REVERSE"; + break; + case WRITE_FILEMARKS: + what = "WRITE_FILEMARKS"; + break; + case SPACE: + what = "SPACE"; + break; + case INQUIRY: + what = "INQUIRY"; + break; + case RECOVER_BUFFERED_DATA: + what = "RECOVER_BUFFERED_DATA"; + break; + case MODE_SELECT: + what = "MODE_SELECT"; + break; + case RESERVE: + what = "RESERVE"; + break; + case RELEASE: + what = "RELEASE"; + break; + case COPY: + what = "COPY"; + break; + case ERASE: + what = "ERASE"; + break; + case MODE_SENSE: + what = "MODE_SENSE"; + break; + case START_STOP: + what = "START_STOP"; + break; + case RECEIVE_DIAGNOSTIC: + what = "RECEIVE_DIAGNOSTIC"; + break; + case SEND_DIAGNOSTIC: + what = "SEND_DIAGNOSTIC"; + break; + case ALLOW_MEDIUM_REMOVAL: + what = "ALLOW_MEDIUM_REMOVAL"; + break; + case SET_WINDOW: + what = "SET_WINDOW"; + break; + case READ_CAPACITY: + what = "READ_CAPACITY"; + break; + case READ_10: + what = "READ_10"; + break; + case WRITE_10: + what = "WRITE_10"; + break; + case SEEK_10: + what = "SEEK_10"; + break; + case WRITE_VERIFY: + what = "WRITE_VERIFY"; + break; + case VERIFY: + what = "VERIFY"; + break; + case SEARCH_HIGH: + what = "SEARCH_HIGH"; + break; + case SEARCH_EQUAL: + what = "SEARCH_EQUAL"; + break; + case SEARCH_LOW: + what = "SEARCH_LOW"; + break; + case SET_LIMITS: + what = "SET_LIMITS"; + break; + case READ_POSITION: + what = "READ_POSITION"; + break; + case SYNCHRONIZE_CACHE: + what = "SYNCHRONIZE_CACHE"; + break; + case LOCK_UNLOCK_CACHE: + what = "LOCK_UNLOCK_CACHE"; + break; + case READ_DEFECT_DATA: + what = "READ_DEFECT_DATA"; + break; + case MEDIUM_SCAN: + what = "MEDIUM_SCAN"; + break; + case COMPARE: + what = "COMPARE"; + break; + case COPY_VERIFY: + what = "COPY_VERIFY"; + break; + case WRITE_BUFFER: + what = "WRITE_BUFFER"; + break; + case READ_BUFFER: + what = "READ_BUFFER"; + break; + case UPDATE_BLOCK: + what = "UPDATE_BLOCK"; + break; + case READ_LONG: + what = "READ_LONG"; + break; + case WRITE_LONG: + what = "WRITE_LONG"; + break; + case CHANGE_DEFINITION: + what = "CHANGE_DEFINITION"; + break; + case WRITE_SAME: + what = "WRITE_SAME"; + break; + case GPCMD_READ_SUBCHANNEL: + what = "READ SUBCHANNEL"; + break; + case READ_TOC: + what = "READ_TOC"; + break; + case GPCMD_READ_HEADER: + what = "READ HEADER"; + break; + case GPCMD_PLAY_AUDIO_10: + what = "PLAY AUDIO (10)"; + break; + case GPCMD_PLAY_AUDIO_MSF: + what = "PLAY AUDIO MSF"; + break; + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + what = "GET EVENT/STATUS NOTIFICATION"; + break; + case GPCMD_PAUSE_RESUME: + what = "PAUSE/RESUME"; + break; + case LOG_SELECT: + what = "LOG_SELECT"; + break; + case LOG_SENSE: + what = "LOG_SENSE"; + break; + case GPCMD_STOP_PLAY_SCAN: + what = "STOP PLAY/SCAN"; + break; + case GPCMD_READ_DISC_INFO: + what = "READ DISC INFORMATION"; + break; + case GPCMD_READ_TRACK_RZONE_INFO: + what = "READ TRACK INFORMATION"; + break; + case GPCMD_RESERVE_RZONE_TRACK: + what = "RESERVE TRACK"; + break; + case GPCMD_SEND_OPC: + what = "SEND OPC"; + break; + case MODE_SELECT_10: + what = "MODE_SELECT_10"; + break; + case GPCMD_REPAIR_RZONE_TRACK: + what = "REPAIR TRACK"; + break; + case 0x59: + what = "READ MASTER CUE"; + break; + case MODE_SENSE_10: + what = "MODE_SENSE_10"; + break; + case GPCMD_CLOSE_TRACK: + what = "CLOSE TRACK/SESSION"; + break; + case 0x5C: + what = "READ BUFFER CAPACITY"; + break; + case 0x5D: + what = "SEND CUE SHEET"; + break; + case GPCMD_BLANK: + what = "BLANK"; + break; + case REPORT_LUNS: + what = "REPORT LUNS"; + break; + case MOVE_MEDIUM: + what = "MOVE_MEDIUM or PLAY AUDIO (12)"; + break; + case READ_12: + what = "READ_12"; + break; + case WRITE_12: + what = "WRITE_12"; + break; + case WRITE_VERIFY_12: + what = "WRITE_VERIFY_12"; + break; + case SEARCH_HIGH_12: + what = "SEARCH_HIGH_12"; + break; + case SEARCH_EQUAL_12: + what = "SEARCH_EQUAL_12"; + break; + case SEARCH_LOW_12: + what = "SEARCH_LOW_12"; + break; + case SEND_VOLUME_TAG: + what = "SEND_VOLUME_TAG"; + break; + case READ_ELEMENT_STATUS: + what = "READ_ELEMENT_STATUS"; + break; + case GPCMD_READ_CD_MSF: + what = "READ CD MSF"; + break; + case GPCMD_SCAN: + what = "SCAN"; + break; + case GPCMD_SET_SPEED: + what = "SET CD SPEED"; + break; + case GPCMD_MECHANISM_STATUS: + what = "MECHANISM STATUS"; + break; + case GPCMD_READ_CD: + what = "READ CD"; + break; + case 0xE1: + what = "WRITE CONTINUE"; + break; + case WRITE_LONG_2: + what = "WRITE_LONG_2"; + break; + case VENDOR_CMND: + what = "Realtek's vendor command"; + break; + default: + what = "(unknown command)"; unknown_cmd = 1; + break; + } + + if (srb->cmnd[0] != TEST_UNIT_READY) + RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); + + if (unknown_cmd) { + RTSX_DEBUGP(""); + for (i = 0; i < srb->cmd_len && i < 16; i++) + RTSX_DEBUGPN(" %02x", srb->cmnd[i]); + RTSX_DEBUGPN("\n"); + } +} + +void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) +{ + switch (sense_type) { + case SENSE_TYPE_MEDIA_CHANGE: + set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_NOT_PRESENT: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_PROTECT: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); + break; + + case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: + set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, + ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); + break; + + case SENSE_TYPE_FORMAT_IN_PROGRESS: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); + break; + + case SENSE_TYPE_FORMAT_CMD_FAILED: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); + break; + +#ifdef SUPPORT_MAGIC_GATE + case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); + break; + + case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); + break; +#endif + +#ifdef SUPPORT_SD_LOCK + case SENSE_TYPE_MEDIA_READ_FORBIDDEN: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); + break; +#endif + + case SENSE_TYPE_NO_SENSE: + default: + set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); + break; + } +} + +void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, + u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, + u16 sns_key_info1) +{ + struct sense_data_t *sense = &(chip->sense_buffer[lun]); + + sense->err_code = err_code; + sense->sense_key = sense_key; + sense->info[0] = (u8)(info >> 24); + sense->info[1] = (u8)(info >> 16); + sense->info[2] = (u8)(info >> 8); + sense->info[3] = (u8)info; + + sense->ad_sense_len = sizeof(struct sense_data_t) - 8; + sense->asc = asc; + sense->ascq = ascq; + if (sns_key_info0 != 0) { + sense->sns_key_info[0] = SKSV | sns_key_info0; + sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; + sense->sns_key_info[2] = sns_key_info1 & 0x0f; + } +} + +static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + return TRANSPORT_FAILED; + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + +#ifdef SUPPORT_SD_LOCK + if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + if (sd_card->sd_lock_notify) { + sd_card->sd_lock_notify = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } else if (sd_card->sd_lock_status & SD_LOCKED) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_READ_FORBIDDEN); + return TRANSPORT_FAILED; + } + } +#endif + + return TRANSPORT_GOOD; +} + +static unsigned char formatter_inquiry_str[20] = { + 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', +#ifdef SUPPORT_MAGIC_GATE + '-', 'M', 'G', /* Byte[47:49] */ +#else + 0x20, 0x20, 0x20, /* Byte[47:49] */ +#endif + +#ifdef SUPPORT_MAGIC_GATE + 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ +#else + 0x09, /* Byte[50]: MS, MSPro, MSXC */ +#endif + 0x00, /* Byte[51]: Category Specific Commands */ + 0x00, /* Byte[52]: Access Control and feature */ + 0x20, 0x20, 0x20, /* Byte[53:55] */ +}; + +static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; + char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 "; + char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 "; + char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 "; + char *inquiry_string; + unsigned char sendbytes; + unsigned char *buf; + u8 card = get_lun_card(chip, lun); + int pro_formatter_flag = 0; + unsigned char inquiry_buf[] = { + QULIFIRE|DRCT_ACCESS_DEV, + RMB_DISC|0x0D, + 0x00, + 0x01, + 0x1f, + 0x02, + 0, + REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE, + }; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) + inquiry_string = inquiry_sd; + else + inquiry_string = inquiry_ms; + + } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { + inquiry_string = inquiry_sdms; + } else { + inquiry_string = inquiry_default; + } + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + +#ifdef SUPPORT_MAGIC_GATE + if ((chip->mspro_formatter_enable) && + (chip->lun2card[lun] & MS_CARD)) +#else + if (chip->mspro_formatter_enable) +#endif + { + if (!card || (card == MS_CARD)) + pro_formatter_flag = 1; + } + + if (pro_formatter_flag) { + if (scsi_bufflen(srb) < 56) + sendbytes = (unsigned char)(scsi_bufflen(srb)); + else + sendbytes = 56; + + } else { + if (scsi_bufflen(srb) < 36) + sendbytes = (unsigned char)(scsi_bufflen(srb)); + else + sendbytes = 36; + } + + if (sendbytes > 8) { + memcpy(buf, inquiry_buf, 8); + memcpy(buf + 8, inquiry_string, sendbytes - 8); + if (pro_formatter_flag) { + /* Additional Length */ + buf[4] = 0x33; + } + } else { + memcpy(buf, inquiry_buf, sendbytes); + } + + if (pro_formatter_flag) { + if (sendbytes > 36) + memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); + } + + scsi_set_resid(srb, 0); + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + return TRANSPORT_GOOD; +} + + +static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + scsi_set_resid(srb, scsi_bufflen(srb)); + + if (srb->cmnd[1] == 1) + return TRANSPORT_GOOD; + + switch (srb->cmnd[0x4]) { + case STOP_MEDIUM: + /* Media disabled */ + return TRANSPORT_GOOD; + + case UNLOAD_MEDIUM: + /* Media shall be unload */ + if (check_card_ready(chip, lun)) + eject_card(chip, lun); + return TRANSPORT_GOOD; + + case MAKE_MEDIUM_READY: + case LOAD_MEDIUM: + if (check_card_ready(chip, lun)) { + return TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + break; + } + + TRACE_RET(chip, TRANSPORT_ERROR); +} + + +static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int prevent; + + prevent = srb->cmnd[4] & 0x1; + + scsi_set_resid(srb, 0); + + if (prevent) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + + +static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sense_data_t *sense; + unsigned int lun = SCSI_LUN(srb); + struct ms_info *ms_card = &(chip->ms_card); + unsigned char *tmp, *buf; + + sense = &(chip->sense_buffer[lun]); + + if ((get_lun_card(chip, lun) == MS_CARD) && + ms_card->pro_under_formatting) { + if (ms_card->format_status == FORMAT_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16)(ms_card->progress)); + } else { + /* Format Command Failed */ + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } + + rtsx_set_stat(chip, RTSX_STAT_RUN); + } + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + tmp = (unsigned char *)sense; + memcpy(buf, tmp, scsi_bufflen(srb)); + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + scsi_set_resid(srb, 0); + /* Reset Sense Data */ + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + return TRANSPORT_GOOD; +} + +static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, + int lun, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int sys_info_offset; + int data_size = buf_len; + int support_format = 0; + int i = 0; + + if (cmd == MODE_SENSE) { + sys_info_offset = 8; + if (data_size > 0x68) + data_size = 0x68; + + buf[i++] = 0x67; /* Mode Data Length */ + } else { + sys_info_offset = 12; + if (data_size > 0x6C) + data_size = 0x6C; + + buf[i++] = 0x00; /* Mode Data Length (MSB) */ + buf[i++] = 0x6A; /* Mode Data Length (LSB) */ + } + + /* Medium Type Code */ + if (check_card_ready(chip, lun)) { + if (CHK_MSXC(ms_card)) { + support_format = 1; + buf[i++] = 0x40; + } else if (CHK_MSPRO(ms_card)) { + support_format = 1; + buf[i++] = 0x20; + } else { + buf[i++] = 0x10; + } + + /* WP */ + if (check_card_wp(chip, lun)) + buf[i++] = 0x80; + else + buf[i++] = 0x00; + + } else { + buf[i++] = 0x00; /* MediaType */ + buf[i++] = 0x00; /* WP */ + } + + buf[i++] = 0x00; /* Reserved */ + + if (cmd == MODE_SENSE_10) { + buf[i++] = 0x00; /* Reserved */ + buf[i++] = 0x00; /* Block descriptor length(MSB) */ + buf[i++] = 0x00; /* Block descriptor length(LSB) */ + + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 9) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 10) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 11) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 12) { + if (support_format) + buf[i++] = 0xC0; /* SF, SGM */ + else + buf[i++] = 0x00; + } + } else { + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 5) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 6) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 7) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 8) { + if (support_format) + buf[i++] = 0xC0; /* SF, SGM */ + else + buf[i++] = 0x00; + } + } + + if (data_size > sys_info_offset) { + /* 96 Bytes Attribute Data */ + int len = data_size - sys_info_offset; + len = (len < 96) ? len : 96; + + memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); + } +} + +static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned int dataSize; + int status; + int pro_formatter_flag; + unsigned char pageCode, *buf; + u8 card = get_lun_card(chip, lun); + +#ifndef SUPPORT_MAGIC_GATE + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + scsi_set_resid(srb, scsi_bufflen(srb)); + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif + + pro_formatter_flag = 0; + dataSize = 8; +#ifdef SUPPORT_MAGIC_GATE + if ((chip->lun2card[lun] & MS_CARD)) { + if (!card || (card == MS_CARD)) { + dataSize = 108; + if (chip->mspro_formatter_enable) + pro_formatter_flag = 1; + } + } +#else + if (card == MS_CARD) { + if (chip->mspro_formatter_enable) { + pro_formatter_flag = 1; + dataSize = 108; + } + } +#endif + + buf = kmalloc(dataSize, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + pageCode = srb->cmnd[2] & 0x3f; + + if ((pageCode == 0x3F) || (pageCode == 0x1C) || + (pageCode == 0x00) || + (pro_formatter_flag && (pageCode == 0x20))) { + if (srb->cmnd[0] == MODE_SENSE) { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], + lun, buf, dataSize); + } else { + dataSize = 4; + buf[0] = 0x03; + buf[1] = 0x00; + if (check_card_wp(chip, lun)) + buf[2] = 0x80; + else + buf[2] = 0x00; + + buf[3] = 0x00; + } + } else { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], + lun, buf, dataSize); + } else { + dataSize = 8; + buf[0] = 0x00; + buf[1] = 0x06; + buf[2] = 0x00; + if (check_card_wp(chip, lun)) + buf[3] = 0x80; + else + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x00; + } + } + status = TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + scsi_set_resid(srb, scsi_bufflen(srb)); + status = TRANSPORT_FAILED; + } + + if (status == TRANSPORT_GOOD) { + unsigned int len = min_t(unsigned int, scsi_bufflen(srb), + dataSize); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + } + kfree(buf); + + return status; +} + +static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + unsigned int lun = SCSI_LUN(srb); + int retval; + u32 start_sec; + u16 sec_cnt; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Accessing to any card is forbidden + * until the erase procedure of SD is completed + */ + RTSX_DEBUGP("SD card being erased!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) == SD_CARD) { + if (sd_card->sd_lock_status & SD_LOCKED) { + RTSX_DEBUGP("SD card locked!\n"); + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { + start_sec = ((u32)srb->cmnd[2] << 24) | + ((u32)srb->cmnd[3] << 16) | + ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); + sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { + start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | + ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); + sec_cnt = srb->cmnd[4]; + } else if ((srb->cmnd[0] == VENDOR_CMND) && + (srb->cmnd[1] == SCSI_APP_CMD) && + ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { + start_sec = ((u32)srb->cmnd[4] << 24) | + ((u32)srb->cmnd[5] << 16) | + ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); + sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + /* In some test, we will receive a start_sec like 0xFFFFFFFF. + * In this situation, start_sec + sec_cnt will overflow, so we + * need to judge start_sec at first + */ + if ((start_sec > get_card_size(chip, lun)) || + ((start_sec + sec_cnt) > get_card_size(chip, lun))) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sec_cnt == 0) { + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + if (chip->rw_fail_cnt[lun] == 3) { + RTSX_DEBUGP("read/write fail three times in succession\n"); + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (check_card_wp(chip, lun)) { + RTSX_DEBUGP("Write protected card!\n"); + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + retval = card_rw(srb, chip, start_sec, sec_cnt); + if (retval != STATUS_SUCCESS) { + if (chip->need_release & chip->lun2card[lun]) { + chip->rw_fail_cnt[lun] = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } else { + chip->rw_fail_cnt[lun]++; + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + } + retval = TRANSPORT_FAILED; + TRACE_GOTO(chip, Exit); + } else { + chip->rw_fail_cnt[lun] = 0; + retval = TRANSPORT_GOOD; + } + + scsi_set_resid(srb, 0); + +Exit: + return retval; +} + +static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + unsigned int buf_len; + u8 card = get_lun_card(chip, lun); + u32 card_size; + int desc_cnt; + int i = 0; + + if (!check_card_ready(chip, lun)) { + if (!chip->mspro_formatter_enable) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; + + buf = kmalloc(buf_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + buf[i++] = 0; + buf[i++] = 0; + buf[i++] = 0; + + /* Capacity List Length */ + if ((buf_len > 12) && chip->mspro_formatter_enable && + (chip->lun2card[lun] & MS_CARD) && + (!card || (card == MS_CARD))) { + buf[i++] = 0x10; + desc_cnt = 2; + } else { + buf[i++] = 0x08; + desc_cnt = 1; + } + + while (desc_cnt) { + if (check_card_ready(chip, lun)) { + card_size = get_card_size(chip, lun); + buf[i++] = (unsigned char)(card_size >> 24); + buf[i++] = (unsigned char)(card_size >> 16); + buf[i++] = (unsigned char)(card_size >> 8); + buf[i++] = (unsigned char)card_size; + + if (desc_cnt == 2) + buf[i++] = 2; + else + buf[i++] = 0; + } else { + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + + if (desc_cnt == 2) + buf[i++] = 3; + else + buf[i++] = 0; + } + + buf[i++] = 0x00; + buf[i++] = 0x02; + buf[i++] = 0x00; + + desc_cnt--; + } + + buf_len = min_t(unsigned int, scsi_bufflen(srb), buf_len); + rtsx_stor_set_xfer_buf(buf, buf_len, srb); + kfree(buf); + + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + u32 card_size; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + + buf = kmalloc(8, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + card_size = get_card_size(chip, lun); + buf[0] = (unsigned char)((card_size - 1) >> 24); + buf[1] = (unsigned char)((card_size - 1) >> 16); + buf[2] = (unsigned char)((card_size - 1) >> 8); + buf[3] = (unsigned char)(card_size - 1); + + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x02; + buf[7] = 0x00; + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + kfree(buf); + + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_read_eeprom(chip, i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (len == 511) { + retval = spi_erase_eeprom_chip(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), + len); + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + for (i = 0; i < len; i++) { + retval = spi_write_eeprom(chip, i, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xFC00) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_read_register(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xFC00) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) != SD_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 gpio = srb->cmnd[2]; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (gpio > 3) + gpio = 1; + toggle_gpio(chip, gpio); + + return TRANSPORT_GOOD; +} + +#ifdef _MSG_TRACE +static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *ptr, *buf = NULL; + int i, msg_cnt; + u8 clear; + unsigned int buf_len; + + buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * + TRACE_ITEM_CNT); + + if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + clear = srb->cmnd[2]; + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + ptr = buf; + + if (chip->trace_msg[chip->msg_idx].valid) + msg_cnt = TRACE_ITEM_CNT; + else + msg_cnt = chip->msg_idx; + + *(ptr++) = (u8)(msg_cnt >> 24); + *(ptr++) = (u8)(msg_cnt >> 16); + *(ptr++) = (u8)(msg_cnt >> 8); + *(ptr++) = (u8)msg_cnt; + RTSX_DEBUGP("Trace message count is %d\n", msg_cnt); + + for (i = 1; i <= msg_cnt; i++) { + int j, idx; + + idx = chip->msg_idx - i; + if (idx < 0) + idx += TRACE_ITEM_CNT; + + *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8); + *(ptr++) = (u8)(chip->trace_msg[idx].line); + for (j = 0; j < MSG_FUNC_LEN; j++) + *(ptr++) = chip->trace_msg[idx].func[j]; + + for (j = 0; j < MSG_FILE_LEN; j++) + *(ptr++) = chip->trace_msg[idx].file[j]; + + for (j = 0; j < TIME_VAL_LEN; j++) + *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; + } + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + if (clear) { + chip->msg_idx = 0; + for (i = 0; i < TRACE_ITEM_CNT; i++) + chip->trace_msg[i].valid = 0; + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 addr, buf[4]; + u32 val; + unsigned int len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + + val = rtsx_readl(chip, addr); + RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val); + + buf[0] = (u8)(val >> 24); + buf[1] = (u8)(val >> 16); + buf[2] = (u8)(val >> 8); + buf[3] = (u8)val; + + len = min_t(unsigned int, scsi_bufflen(srb), 4); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + return TRANSPORT_GOOD; +} + +static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 addr, buf[4]; + u32 val; + unsigned int len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + + len = min_t(unsigned int, scsi_bufflen(srb), 4); + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] + << 8) | buf[3]; + + rtsx_writel(chip, addr, val); + + return TRANSPORT_GOOD; +} + +static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned lun = SCSI_LUN(srb); + + if (srb->cmnd[3] == 1) { + /* Variable Clock */ + struct xd_info *xd_card = &(chip->xd_card); + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + + switch (srb->cmnd[4]) { + case XD_CARD: + xd_card->xd_clock = srb->cmnd[5]; + break; + + case SD_CARD: + sd_card->sd_clock = srb->cmnd[5]; + break; + + case MS_CARD: + ms_card->ms_clock = srb->cmnd[5]; + break; + + default: + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (srb->cmnd[3] == 2) { + if (srb->cmnd[4]) { + chip->blink_led = 1; + } else { + int retval; + + chip->blink_led = 0; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && + (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + turn_off_led(chip, LED_GPIO); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + if (srb->cmnd[3] == 1) { + struct xd_info *xd_card = &(chip->xd_card); + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + u8 tmp; + + switch (srb->cmnd[4]) { + case XD_CARD: + tmp = (u8)(xd_card->xd_clock); + break; + + case SD_CARD: + tmp = (u8)(sd_card->sd_clock); + break; + + case MS_CARD: + tmp = (u8)(ms_card->ms_clock); + break; + + default: + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_stor_set_xfer_buf(&tmp, 1, srb); + } else if (srb->cmnd[3] == 2) { + u8 tmp = chip->blink_led; + rtsx_stor_set_xfer_buf(&tmp, 1, srb); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + unsigned int lun = SCSI_LUN(srb); + u16 len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = min_t(u16, len, scsi_bufflen(srb)); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) + RTSX_DEBUGP("Read from device\n"); + else + RTSX_DEBUGP("Write to device\n"); + + retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, + scsi_sg_count(srb), srb->sc_data_direction, 1000); + if (retval < 0) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + + TRACE_RET(chip, TRANSPORT_FAILED); + } + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + int buf_len; + unsigned int lun = SCSI_LUN(srb); + u8 card = get_lun_card(chip, lun); + u8 status[32]; +#ifdef SUPPORT_OCP + u8 oc_now_mask = 0, oc_ever_mask = 0; +#endif + + memset(status, 0, 32); + + status[0] = (u8)(chip->product_id); + status[1] = chip->ic_version; + + if (chip->auto_delink_en) + status[2] = 0x10; + else + status[2] = 0x00; + + status[3] = 20; + status[4] = 10; + status[5] = 05; + status[6] = 21; + + if (chip->card_wp) + status[7] = 0x20; + else + status[7] = 0x00; + +#ifdef SUPPORT_OCP + status[8] = 0; + if (CHECK_LUN_MODE(chip, + SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) { + oc_now_mask = MS_OC_NOW; + oc_ever_mask = MS_OC_EVER; + } else { + oc_now_mask = SD_OC_NOW; + oc_ever_mask = SD_OC_EVER; + } + + if (chip->ocp_stat & oc_now_mask) + status[8] |= 0x02; + + if (chip->ocp_stat & oc_ever_mask) + status[8] |= 0x01; +#endif + + if (card == SD_CARD) { + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) { + if (sd_card->capacity > 0x4000000) + status[0x0E] = 0x02; + else + status[0x0E] = 0x01; + } else { + status[0x0E] = 0x00; + } + + if (CHK_SD_SDR104(sd_card)) + status[0x0F] = 0x03; + else if (CHK_SD_DDR50(sd_card)) + status[0x0F] = 0x04; + else if (CHK_SD_SDR50(sd_card)) + status[0x0F] = 0x02; + else if (CHK_SD_HS(sd_card)) + status[0x0F] = 0x01; + else + status[0x0F] = 0x00; + } else { + if (CHK_MMC_SECTOR_MODE(sd_card)) + status[0x0E] = 0x01; + else + status[0x0E] = 0x00; + + if (CHK_MMC_DDR52(sd_card)) + status[0x0F] = 0x03; + else if (CHK_MMC_52M(sd_card)) + status[0x0F] = 0x02; + else if (CHK_MMC_26M(sd_card)) + status[0x0F] = 0x01; + else + status[0x0F] = 0x00; + } + } else if (card == MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (CHK_MSXC(ms_card)) + status[0x0E] = 0x01; + else + status[0x0E] = 0x00; + + if (CHK_HG8BIT(ms_card)) + status[0x0F] = 0x01; + else + status[0x0F] = 0x00; + } + } + +#ifdef SUPPORT_SD_LOCK + if (card == SD_CARD) { + status[0x17] = 0x80; + if (sd_card->sd_erase_status) + status[0x17] |= 0x01; + if (sd_card->sd_lock_status & SD_LOCKED) { + status[0x17] |= 0x02; + status[0x07] |= 0x40; + } + if (sd_card->sd_lock_status & SD_PWD_EXIST) + status[0x17] |= 0x04; + } else { + status[0x17] = 0x00; + } + + RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); +#endif + + status[0x18] = 0x8A; + status[0x1A] = 0x28; +#ifdef SUPPORT_SD_LOCK + status[0x1F] = 0x01; +#endif + + buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status)); + rtsx_stor_set_xfer_buf(status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int phy_debug_mode; + int retval; + u16 reg; + + if (!CHECK_PID(chip, 0x5208)) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + phy_debug_mode = (int)(srb->cmnd[3]); + + if (phy_debug_mode) { + chip->phy_debug_mode = 1; + retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + rtsx_disable_bus_int(chip); + + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + reg |= 0x0001; + retval = rtsx_write_phy_register(chip, 0x1C, reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + chip->phy_debug_mode = 0; + retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + rtsx_enable_bus_int(chip); + + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + reg &= 0xFFFE; + retval = rtsx_write_phy_register(chip, 0x1C, reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = STATUS_SUCCESS; + unsigned int lun = SCSI_LUN(srb); + u8 cmd_type, mask, value, idx; + u16 addr; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + rtsx_init_cmd(chip); + break; + + case ADD_BATCHCMD: + cmd_type = srb->cmnd[4]; + if (cmd_type > 2) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; + mask = srb->cmnd[7]; + value = srb->cmnd[8]; + rtsx_add_cmd(chip, cmd_type, addr, mask, value); + break; + + case SEND_BATCHCMD: + retval = rtsx_send_cmd(chip, 0, 1000); + break; + + case GET_BATCHRSP: + idx = srb->cmnd[4]; + value = *(rtsx_get_cmd_data(chip) + idx); + if (scsi_bufflen(srb) < 1) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + rtsx_stor_set_xfer_buf(&value, 1, srb); + scsi_set_resid(srb, 0); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + case ADD_BATCHCMD: + case SEND_BATCHCMD: + case GET_BATCHRSP: + result = rw_mem_cmd_buf(srb, chip); + break; + default: + result = TRANSPORT_ERROR; + } + + return result; +} + +static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + u16 val; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + if (len % 2) + len -= len % 2; + + if (len) { + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len / 2; i++) { + retval = rtsx_read_phy_register(chip, addr + i, &val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf[2*i] = (u8)(val >> 8); + buf[2*i+1] = (u8)val; + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), + len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + u16 val; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + if (len % 2) + len -= len % 2; + + if (len) { + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), + len); + + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len / 2; i++) { + val = ((u16)buf[2*i] << 8) | buf[2*i+1]; + retval = rtsx_write_phy_register(chip, addr + i, val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr; + int retval; + u8 mode; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + mode = srb->cmnd[3]; + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (mode == 0) { + retval = spi_erase_eeprom_chip(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (mode == 1) { + retval = spi_erase_eeprom_byte(chip, addr); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_read_eeprom(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_write_eeprom(chip, addr + i, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 addr, len, i; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + len = srb->cmnd[5]; + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_read_efuse(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval, result = TRANSPORT_GOOD; + u16 val; + u8 addr, len, i; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + len = srb->cmnd[5]; + + len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + if (chip->asic_code) { + retval = rtsx_read_phy_register(chip, 0x08, &val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, + LDO3318_PWR_MASK, LDO_OFF); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(600); + + retval = rtsx_write_phy_register(chip, 0x08, + 0x4C00 | chip->phy_voltage); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, + LDO3318_PWR_MASK, LDO_ON); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(600); + } + + retval = card_power_on(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(50); + + for (i = 0; i < len; i++) { + retval = rtsx_write_efuse(chip, addr + i, buf[i]); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + result = TRANSPORT_FAILED; + TRACE_GOTO(chip, Exit); + } + } + +Exit: + vfree(buf); + + retval = card_power_off(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_ERROR); + + if (chip->asic_code) { + retval = rtsx_write_register(chip, PWR_GATE_CTRL, + LDO3318_PWR_MASK, LDO_OFF); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_ERROR); + + wait_timeout(600); + + retval = rtsx_write_phy_register(chip, 0x08, val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, + LDO3318_PWR_MASK, LDO_ON); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_ERROR); + } + + return result; +} + +static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 func, func_max; + u16 addr, len; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + func = srb->cmnd[3]; + addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; + + RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, + addr, len); + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) + func_max = 1; + else + func_max = 0; + + if (func > func_max) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + vfree(buf); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (u16)min_t(unsigned int, scsi_bufflen(srb), len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 func, func_max; + u16 addr, len; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + func = srb->cmnd[3]; + addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; + + RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr); + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) + func_max = 1; + else + func_max = 0; + + if (func > func_max) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + vfree(buf); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[2]) { + case PP_READ10: + case PP_WRITE10: + result = read_write(srb, chip); + break; + + case READ_HOST_REG: + result = read_host_reg(srb, chip); + break; + + case WRITE_HOST_REG: + result = write_host_reg(srb, chip); + break; + + case GET_VAR: + result = get_variable(srb, chip); + break; + + case SET_VAR: + result = set_variable(srb, chip); + break; + + case DMA_READ: + case DMA_WRITE: + result = dma_access_ring_buffer(srb, chip); + break; + + case READ_PHY: + result = read_phy_register(srb, chip); + break; + + case WRITE_PHY: + result = write_phy_register(srb, chip); + break; + + case ERASE_EEPROM2: + result = erase_eeprom2(srb, chip); + break; + + case READ_EEPROM2: + result = read_eeprom2(srb, chip); + break; + + case WRITE_EEPROM2: + result = write_eeprom2(srb, chip); + break; + + case READ_EFUSE: + result = read_efuse(srb, chip); + break; + + case WRITE_EFUSE: + result = write_efuse(srb, chip); + break; + + case READ_CFG: + result = read_cfg_byte(srb, chip); + break; + + case WRITE_CFG: + result = write_cfg_byte(srb, chip); + break; + + case SET_CHIP_MODE: + result = set_chip_mode(srb, chip); + break; + + case SUIT_CMD: + result = suit_cmd(srb, chip); + break; + + case GET_DEV_STATUS: + result = get_dev_status(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + + +static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 rtsx_status[16]; + int buf_len; + unsigned int lun = SCSI_LUN(srb); + + rtsx_status[0] = (u8)(chip->vendor_id >> 8); + rtsx_status[1] = (u8)(chip->vendor_id); + + rtsx_status[2] = (u8)(chip->product_id >> 8); + rtsx_status[3] = (u8)(chip->product_id); + + rtsx_status[4] = (u8)lun; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) + rtsx_status[5] = 2; + else + rtsx_status[5] = 3; + } else { + if (chip->card_exist) { + if (chip->card_exist & XD_CARD) + rtsx_status[5] = 4; + else if (chip->card_exist & SD_CARD) + rtsx_status[5] = 2; + else if (chip->card_exist & MS_CARD) + rtsx_status[5] = 3; + else + rtsx_status[5] = 7; + } else { + rtsx_status[5] = 7; + } + } + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + rtsx_status[6] = 2; + else + rtsx_status[6] = 1; + + rtsx_status[7] = (u8)(chip->product_id); + rtsx_status[8] = chip->ic_version; + + if (check_card_exist(chip, lun)) + rtsx_status[9] = 1; + else + rtsx_status[9] = 0; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + rtsx_status[10] = 0; + else + rtsx_status[10] = 1; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) + rtsx_status[11] = SD_CARD; + else + rtsx_status[11] = MS_CARD; + } else { + rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; + } + + if (check_card_ready(chip, lun)) + rtsx_status[12] = 1; + else + rtsx_status[12] = 0; + + if (get_lun_card(chip, lun) == XD_CARD) { + rtsx_status[13] = 0x40; + } else if (get_lun_card(chip, lun) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + + rtsx_status[13] = 0x20; + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) + rtsx_status[13] |= 0x04; + if (CHK_SD_HS(sd_card)) + rtsx_status[13] |= 0x02; + } else { + rtsx_status[13] |= 0x08; + if (CHK_MMC_52M(sd_card)) + rtsx_status[13] |= 0x02; + if (CHK_MMC_SECTOR_MODE(sd_card)) + rtsx_status[13] |= 0x04; + } + } else if (get_lun_card(chip, lun) == MS_CARD) { + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + rtsx_status[13] = 0x38; + if (CHK_HG8BIT(ms_card)) + rtsx_status[13] |= 0x04; +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) + rtsx_status[13] |= 0x01; +#endif + } else { + rtsx_status[13] = 0x30; + } + } else { + if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { +#ifdef SUPPORT_SDIO + if (chip->sd_io && chip->sd_int) + rtsx_status[13] = 0x60; + else + rtsx_status[13] = 0x70; +#else + rtsx_status[13] = 0x70; +#endif + } else { + if (chip->lun2card[lun] == SD_CARD) + rtsx_status[13] = 0x20; + else + rtsx_status[13] = 0x30; + } + } + + rtsx_status[14] = 0x78; + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) + rtsx_status[15] = 0x83; + else + rtsx_status[15] = 0x82; + + buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rtsx_status)); + rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + u8 card, bus_width; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + card = get_lun_card(chip, lun); + if ((card == SD_CARD) || (card == MS_CARD)) { + bus_width = chip->card_bus_width[lun]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + unsigned int lun = SCSI_LUN(srb); + u8 gpio_dir; + + if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL); + + rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); + + switch (srb->cmnd[2]) { + case SCSI_SPI_GETSTATUS: + result = spi_get_status(srb, chip); + break; + + case SCSI_SPI_SETPARAMETER: + result = spi_set_parameter(srb, chip); + break; + + case SCSI_SPI_READFALSHID: + result = spi_read_flash_id(srb, chip); + break; + + case SCSI_SPI_READFLASH: + result = spi_read_flash(srb, chip); + break; + + case SCSI_SPI_WRITEFLASH: + result = spi_write_flash(srb, chip); + break; + + case SCSI_SPI_WRITEFLASHSTATUS: + result = spi_write_flash_status(srb, chip); + break; + + case SCSI_SPI_ERASEFLASH: + result = spi_erase_flash(srb, chip); + break; + + default: + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); + + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); + + if (result != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + return TRANSPORT_GOOD; +} + +static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[1]) { + case READ_STATUS: + result = read_status(srb, chip); + break; + + case READ_MEM: + result = read_mem(srb, chip); + break; + + case WRITE_MEM: + result = write_mem(srb, chip); + break; + + case READ_EEPROM: + result = read_eeprom(srb, chip); + break; + + case WRITE_EEPROM: + result = write_eeprom(srb, chip); + break; + + case TOGGLE_GPIO: + result = toggle_gpio_cmd(srb, chip); + break; + + case GET_SD_CSD: + result = get_sd_csd(srb, chip); + break; + + case GET_BUS_WIDTH: + result = get_card_bus_width(srb, chip); + break; + +#ifdef _MSG_TRACE + case TRACE_MSG: + result = trace_msg_cmd(srb, chip); + break; +#endif + + case SCSI_APP_CMD: + result = app_cmd(srb, chip); + break; + + case SPI_VENDOR_COMMAND: + result = spi_vendor_cmd(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + +#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) +void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + u16 sec_cnt; + + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) + sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) + sec_cnt = srb->cmnd[4]; + else + return; + + if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { + toggle_gpio(chip, LED_GPIO); + chip->rw_cap[lun] = 0; + } else { + chip->rw_cap[lun] += sec_cnt; + } +} +#endif + +static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, quick_format; + + if (get_lun_card(chip, lun) != MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) || + (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) || + (srb->cmnd[7] != 0x74)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + + if (!check_card_ready(chip, lun) || + (get_card_size(chip, lun) == 0)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (srb->cmnd[8] & 0x01) + quick_format = 0; + else + quick_format = 1; + + if (!(chip->card_ready & MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (chip->card_wp & MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +#ifdef SUPPORT_PCGL_1P18 +static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + u8 dev_info_id, data_len; + u8 *buf; + unsigned int buf_len; + int i; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || + (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || + (srb->cmnd[7] != 0x44)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + dev_info_id = srb->cmnd[3]; + if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || + (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || + !CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (dev_info_id == 0x15) + buf_len = data_len = 0x3A; + else + buf_len = data_len = 0x6A; + + buf = kmalloc(buf_len, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + i = 0; + /* GET Memory Stick Media Information Response Header */ + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Device Information Type Code */ + if (CHK_MSXC(ms_card)) + buf[i++] = 0x03; + else + buf[i++] = 0x02; + + /* SGM bit */ + buf[i++] = 0x01; + /* Reserved */ + buf[i++] = 0x00; + buf[i++] = 0x00; + buf[i++] = 0x00; + /* Number of Device Information */ + buf[i++] = 0x01; + + /* Device Information Body */ + + /* Device Information ID Number */ + buf[i++] = dev_info_id; + /* Device Information Length */ + if (dev_info_id == 0x15) + data_len = 0x31; + else + data_len = 0x61; + + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Valid Bit */ + buf[i++] = 0x80; + if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) { + /* System Information */ + memcpy(buf+i, ms_card->raw_sys_info, 96); + } else { + /* Model Name */ + memcpy(buf+i, ms_card->raw_model_name, 48); + } + + rtsx_stor_set_xfer_buf(buf, buf_len, srb); + + if (dev_info_id == 0x15) + scsi_set_resid(srb, scsi_bufflen(srb)-0x3C); + else + scsi_set_resid(srb, scsi_bufflen(srb)-0x6C); + + kfree(buf); + return STATUS_SUCCESS; +} +#endif + +static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = TRANSPORT_ERROR; + + if (srb->cmnd[2] == MS_FORMAT) + retval = ms_format_cmnd(srb, chip); +#ifdef SUPPORT_PCGL_1P18 + else if (srb->cmnd[2] == GET_MS_INFORMATION) + retval = get_ms_information(srb, chip); +#endif + + return retval; +} + +#ifdef SUPPORT_CPRM +static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + int result; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + sd_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[0]) { + case SD_PASS_THRU_MODE: + result = sd_pass_thru_mode(srb, chip); + break; + + case SD_EXECUTE_NO_DATA: + result = sd_execute_no_data(srb, chip); + break; + + case SD_EXECUTE_READ: + result = sd_execute_read_data(srb, chip); + break; + + case SD_EXECUTE_WRITE: + result = sd_execute_write_data(srb, chip); + break; + + case SD_GET_RSP: + result = sd_get_cmd_rsp(srb, chip); + break; + + case SD_HW_RST: + result = sd_hw_rst(srb, chip); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} +#endif + +#ifdef SUPPORT_MAGIC_GATE +static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + RTSX_DEBUGP("--%s--\n", __func__); + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + RTSX_DEBUGP("key_format = 0x%x\n", key_format); + + switch (key_format) { + case KF_GET_LOC_EKB: + if ((scsi_bufflen(srb) == 0x41C) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x1C)) { + retval = mg_get_local_EKB(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_CHG: + if ((scsi_bufflen(srb) == 0x24) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x24)) { + retval = mg_get_rsp_chg(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_GET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && + (srb->cmnd[5] < 32)) { + retval = mg_get_ICV(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + RTSX_DEBUGP("--%s--\n", __func__); + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if (check_card_wp(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + RTSX_DEBUGP("key_format = 0x%x\n", key_format); + + switch (key_format) { + case KF_SET_LEAF_ID: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_set_leaf_id(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_CHG_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_chg(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_rsp(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_SET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && + (srb->cmnd[5] < 32)) { + retval = mg_set_ICV(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int result; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Block all SCSI command except for + * REQUEST_SENSE and rs_ppstatus + */ + if (!((srb->cmnd[0] == VENDOR_CMND) && + (srb->cmnd[1] == SCSI_APP_CMD) && + (srb->cmnd[2] == GET_DEV_STATUS)) && + (srb->cmnd[0] != REQUEST_SENSE)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, + 0x02, 0, 0x04, 0x04, 0, 0); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((get_lun_card(chip, lun) == MS_CARD) && + (ms_card->format_status == FORMAT_IN_PROGRESS)) { + if ((srb->cmnd[0] != REQUEST_SENSE) && + (srb->cmnd[0] != INQUIRY)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16)(ms_card->progress)); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + switch (srb->cmnd[0]) { + case READ_10: + case WRITE_10: + case READ_6: + case WRITE_6: + result = read_write(srb, chip); +#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) + led_shine(srb, chip); +#endif + break; + + case TEST_UNIT_READY: + result = test_unit_ready(srb, chip); + break; + + case INQUIRY: + result = inquiry(srb, chip); + break; + + case READ_CAPACITY: + result = read_capacity(srb, chip); + break; + + case START_STOP: + result = start_stop_unit(srb, chip); + break; + + case ALLOW_MEDIUM_REMOVAL: + result = allow_medium_removal(srb, chip); + break; + + case REQUEST_SENSE: + result = request_sense(srb, chip); + break; + + case MODE_SENSE: + case MODE_SENSE_10: + result = mode_sense(srb, chip); + break; + + case 0x23: + result = read_format_capacity(srb, chip); + break; + + case VENDOR_CMND: + result = vendor_cmnd(srb, chip); + break; + + case MS_SP_CMND: + result = ms_sp_cmnd(srb, chip); + break; + +#ifdef SUPPORT_CPRM + case SD_PASS_THRU_MODE: + case SD_EXECUTE_NO_DATA: + case SD_EXECUTE_READ: + case SD_EXECUTE_WRITE: + case SD_GET_RSP: + case SD_HW_RST: + result = sd_extention_cmnd(srb, chip); + break; +#endif + +#ifdef SUPPORT_MAGIC_GATE + case CMD_MSPRO_MG_RKEY: + result = mg_report_key(srb, chip); + break; + + case CMD_MSPRO_MG_SKEY: + result = mg_send_key(srb, chip); + break; +#endif + + case FORMAT_UNIT: + case MODE_SELECT: + case VERIFY: + result = TRANSPORT_GOOD; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + result = TRANSPORT_FAILED; + } + + return result; +} diff --git a/drivers/staging/rts5208/rtsx_scsi.h b/drivers/staging/rts5208/rtsx_scsi.h new file mode 100644 index 000000000000..d1750570dd38 --- /dev/null +++ b/drivers/staging/rts5208/rtsx_scsi.h @@ -0,0 +1,143 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_SCSI_H +#define __REALTEK_RTSX_SCSI_H + +#include "rtsx.h" +#include "rtsx_chip.h" + +#define MS_SP_CMND 0xFA +#define MS_FORMAT 0xA0 +#define GET_MS_INFORMATION 0xB0 + +#define VENDOR_CMND 0xF0 + +#define READ_STATUS 0x09 + +#define READ_EEPROM 0x04 +#define WRITE_EEPROM 0x05 +#define READ_MEM 0x0D +#define WRITE_MEM 0x0E +#define GET_BUS_WIDTH 0x13 +#define GET_SD_CSD 0x14 +#define TOGGLE_GPIO 0x15 +#define TRACE_MSG 0x18 + +#define SCSI_APP_CMD 0x10 + +#define PP_READ10 0x1A +#define PP_WRITE10 0x0A +#define READ_HOST_REG 0x1D +#define WRITE_HOST_REG 0x0D +#define SET_VAR 0x05 +#define GET_VAR 0x15 +#define DMA_READ 0x16 +#define DMA_WRITE 0x06 +#define GET_DEV_STATUS 0x10 +#define SET_CHIP_MODE 0x27 +#define SUIT_CMD 0xE0 +#define WRITE_PHY 0x07 +#define READ_PHY 0x17 +#define WRITE_EEPROM2 0x03 +#define READ_EEPROM2 0x13 +#define ERASE_EEPROM2 0x23 +#define WRITE_EFUSE 0x04 +#define READ_EFUSE 0x14 +#define WRITE_CFG 0x0E +#define READ_CFG 0x1E + +#define SPI_VENDOR_COMMAND 0x1C + +#define SCSI_SPI_GETSTATUS 0x00 +#define SCSI_SPI_SETPARAMETER 0x01 +#define SCSI_SPI_READFALSHID 0x02 +#define SCSI_SPI_READFLASH 0x03 +#define SCSI_SPI_WRITEFLASH 0x04 +#define SCSI_SPI_WRITEFLASHSTATUS 0x05 +#define SCSI_SPI_ERASEFLASH 0x06 + +#define INIT_BATCHCMD 0x41 +#define ADD_BATCHCMD 0x42 +#define SEND_BATCHCMD 0x43 +#define GET_BATCHRSP 0x44 + +#define CHIP_NORMALMODE 0x00 +#define CHIP_DEBUGMODE 0x01 + +/* SD Pass Through Command Extension */ +#define SD_PASS_THRU_MODE 0xD0 +#define SD_EXECUTE_NO_DATA 0xD1 +#define SD_EXECUTE_READ 0xD2 +#define SD_EXECUTE_WRITE 0xD3 +#define SD_GET_RSP 0xD4 +#define SD_HW_RST 0xD6 + +#ifdef SUPPORT_MAGIC_GATE +#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ +#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ + +/* CBWCB field: key class */ +#define KC_MG_R_PRO 0xBE /* MG-R PRO*/ + +/* CBWCB field: key format */ +#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ +#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ +#define KF_CHG_HOST 0x33 /* Challenge (host) */ +#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ +#define KF_RSP_HOST 0x35 /* Response (host) */ +#define KF_GET_ICV 0x36 /* Get ICV */ +#define KF_SET_ICV 0x37 /* SSet ICV */ +#endif + +/* Sense type */ +#define SENSE_TYPE_NO_SENSE 0 +#define SENSE_TYPE_MEDIA_CHANGE 1 +#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 +#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 +#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 +#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 +#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 +#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 +#define SENSE_TYPE_MEDIA_WRITE_ERR 8 +#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 +#define SENSE_TYPE_FORMAT_CMD_FAILED 10 +#ifdef SUPPORT_MAGIC_GATE +#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b +#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c +#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d +#define SENSE_TYPE_MG_WRITE_ERR 0x0e +#endif +#ifdef SUPPORT_SD_LOCK +/* FOR Locked SD card*/ +#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 +#endif + +void scsi_show_command(struct scsi_cmnd *srb); +void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type); +void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, + u8 sense_key, u32 info, u8 asc, u8 ascq, + u8 sns_key_info0, u16 sns_key_info1); +int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip); + +#endif /* __REALTEK_RTSX_SCSI_H */ diff --git a/drivers/staging/rts5208/rtsx_sys.h b/drivers/staging/rts5208/rtsx_sys.h new file mode 100644 index 000000000000..0b6b4d4f1fea --- /dev/null +++ b/drivers/staging/rts5208/rtsx_sys.h @@ -0,0 +1,50 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __RTSX_SYS_H +#define __RTSX_SYS_H + +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_card.h" + +typedef dma_addr_t ULONG_PTR; + +static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip) +{ + struct rtsx_dev *dev = chip->rtsx; + + spin_lock(&(dev->reg_lock)); + rtsx_enter_ss(chip); + spin_unlock(&(dev->reg_lock)); +} + +static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag) +{ + rtsx_reset_cards(chip); +} + +#define RTSX_MSG_IN_INT(x) + +#endif /* __RTSX_SYS_H */ + diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c new file mode 100644 index 000000000000..97b7b012983e --- /dev/null +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -0,0 +1,769 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> + +#include "rtsx.h" +#include "rtsx_scsi.h" +#include "rtsx_transport.h" +#include "rtsx_chip.h" +#include "rtsx_card.h" +#include "debug.h" + +/*********************************************************************** + * Scatter-gather transfer buffer access routines + ***********************************************************************/ + +/* Copy a buffer of length buflen to/from the srb's transfer buffer. + * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer + * points to a list of s-g entries and we ignore srb->request_bufflen. + * For non-scatter-gather transfers, srb->request_buffer points to the + * transfer buffer itself and srb->request_bufflen is the buffer's length.) + * Update the *index and *offset variables so that the next copy will + * pick up from where this one left off. */ + +unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, + unsigned int *offset, enum xfer_buf_dir dir) +{ + unsigned int cnt; + + /* If not using scatter-gather, just transfer the data directly. + * Make certain it will fit in the available buffer space. */ + if (scsi_sg_count(srb) == 0) { + if (*offset >= scsi_bufflen(srb)) + return 0; + cnt = min(buflen, scsi_bufflen(srb) - *offset); + if (dir == TO_XFER_BUF) + memcpy((unsigned char *) scsi_sglist(srb) + *offset, + buffer, cnt); + else + memcpy(buffer, (unsigned char *) scsi_sglist(srb) + + *offset, cnt); + *offset += cnt; + + /* Using scatter-gather. We have to go through the list one entry + * at a time. Each s-g entry contains some number of pages, and + * each page has to be kmap()'ed separately. If the page is already + * in kernel-addressable memory then kmap() will return its address. + * If the page is not directly accessible -- such as a user buffer + * located in high memory -- then kmap() will map it to a temporary + * position in the kernel's virtual address space. */ + } else { + struct scatterlist *sg = + (struct scatterlist *) scsi_sglist(srb) + + *index; + + /* This loop handles a single s-g list entry, which may + * include multiple pages. Find the initial page structure + * and the starting offset within the page, and update + * the *offset and *index values for the next loop. */ + cnt = 0; + while (cnt < buflen && *index < scsi_sg_count(srb)) { + struct page *page = sg_page(sg) + + ((sg->offset + *offset) >> PAGE_SHIFT); + unsigned int poff = + (sg->offset + *offset) & (PAGE_SIZE-1); + unsigned int sglen = sg->length - *offset; + + if (sglen > buflen - cnt) { + + /* Transfer ends within this s-g entry */ + sglen = buflen - cnt; + *offset += sglen; + } else { + + /* Transfer continues to next s-g entry */ + *offset = 0; + ++*index; + ++sg; + } + + /* Transfer the data for all the pages in this + * s-g entry. For each page: call kmap(), do the + * transfer, and call kunmap() immediately after. */ + while (sglen > 0) { + unsigned int plen = min(sglen, (unsigned int) + PAGE_SIZE - poff); + unsigned char *ptr = kmap(page); + + if (dir == TO_XFER_BUF) + memcpy(ptr + poff, buffer + cnt, plen); + else + memcpy(buffer + cnt, ptr + poff, plen); + kunmap(page); + + /* Start at the beginning of the next page */ + poff = 0; + ++page; + cnt += plen; + sglen -= plen; + } + } + } + + /* Return the amount actually transferred */ + return cnt; +} + +/* Store the contents of buffer into srb's transfer buffer and set the +* SCSI residue. */ +void rtsx_stor_set_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int index = 0, offset = 0; + + rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, + TO_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + +void rtsx_stor_get_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int index = 0, offset = 0; + + rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, + FROM_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + + +/*********************************************************************** + * Transport routines + ***********************************************************************/ + +/* Invoke the transport and basic error-handling/recovery methods + * + * This is used to send the message to the device and receive the response. + */ +void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + result = rtsx_scsi_handler(srb, chip); + + /* if the command gets aborted by the higher layers, we need to + * short-circuit all other processing + */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + RTSX_DEBUGP("-- command was aborted\n"); + srb->result = DID_ABORT << 16; + goto Handle_Errors; + } + + /* if there is a transport error, reset and don't auto-sense */ + if (result == TRANSPORT_ERROR) { + RTSX_DEBUGP("-- transport indicates error, resetting\n"); + srb->result = DID_ERROR << 16; + goto Handle_Errors; + } + + srb->result = SAM_STAT_GOOD; + + /* + * If we have a failure, we're going to do a REQUEST_SENSE + * automatically. Note that we differentiate between a command + * "failure" and an "error" in the transport mechanism. + */ + if (result == TRANSPORT_FAILED) { + /* set the result so the higher layers expect this data */ + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, + (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]), + sizeof(struct sense_data_t)); + } + + return; + + /* Error and abort processing: try to resynchronize with the device + * by issuing a port reset. If that fails, try a class-specific + * device reset. */ +Handle_Errors: + return; +} + +void rtsx_add_cmd(struct rtsx_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data) +{ + u32 *cb = (u32 *)(chip->host_cmds_ptr); + u32 val = 0; + + val |= (u32)(cmd_type & 0x03) << 30; + val |= (u32)(reg_addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + spin_lock_irq(&chip->rtsx->reg_lock); + if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) + cb[(chip->ci)++] = cpu_to_le32(val); + + spin_unlock_irq(&chip->rtsx->reg_lock); +} + +void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) +{ + u32 val = 1 << 31; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + val |= (u32)(chip->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_writel(chip, RTSX_HCBCTLR, val); +} + +int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u32 val = 1 << 31; + long timeleft; + int err = 0; + + if (card == SD_CARD) + rtsx->check_card_cd = SD_EXIST; + else if (card == MS_CARD) + rtsx->check_card_cd = MS_EXIST; + else if (card == XD_CARD) + rtsx->check_card_cd = XD_EXIST; + else + rtsx->check_card_cd = 0; + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + rtsx->trans_result = TRANS_NOT_READY; + init_completion(&trans_done); + rtsx->trans_state = STATE_TRANS_CMD; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + val |= (u32)(chip->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_writel(chip, RTSX_HCBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + TRACE_GOTO(chip, finish_send_cmd); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) + err = -EIO; + else if (rtsx->trans_result == TRANS_RESULT_OK) + err = 0; + + spin_unlock_irq(&rtsx->reg_lock); + +finish_send_cmd: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +static inline void rtsx_add_sg_tbl( + struct rtsx_chip *chip, u32 addr, u32 len, u8 option) +{ + u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr); + u64 val = 0; + u32 temp_len = 0; + u8 temp_opt = 0; + + do { + if (len > 0x80000) { + temp_len = 0x80000; + temp_opt = option & (~SG_END); + } else { + temp_len = len; + temp_opt = option; + } + val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt; + + if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8)) + sgb[(chip->sgi)++] = cpu_to_le64(val); + + len -= temp_len; + addr += temp_len; + } while (len); +} + +static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, + struct scatterlist *sg, int num_sg, unsigned int *index, + unsigned int *offset, int size, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u8 dir; + int sg_cnt, i, resid; + int err = 0; + long timeleft; + struct scatterlist *sg_ptr; + u32 val = TRIG_DMA; + + if ((sg == NULL) || (num_sg <= 0) || !offset || !index) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) + dir = HOST_TO_DEVICE; + else if (dma_dir == DMA_FROM_DEVICE) + dir = DEVICE_TO_HOST; + else + return -ENXIO; + + if (card == SD_CARD) + rtsx->check_card_cd = SD_EXIST; + else if (card == MS_CARD) + rtsx->check_card_cd = MS_EXIST; + else if (card == XD_CARD) + rtsx->check_card_cd = XD_EXIST; + else + rtsx->check_card_cd = 0; + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + rtsx->trans_state = STATE_TRANS_SG; + rtsx->trans_result = TRANS_NOT_READY; + + spin_unlock_irq(&rtsx->reg_lock); + + sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + resid = size; + sg_ptr = sg; + chip->sgi = 0; + /* Usually the next entry will be @sg@ + 1, but if this sg element + * is part of a chained scatterlist, it could jump to the start of + * a new scatterlist array. So here we use sg_next to move to + * the proper sg + */ + for (i = 0; i < *index; i++) + sg_ptr = sg_next(sg_ptr); + for (i = *index; i < sg_cnt; i++) { + dma_addr_t addr; + unsigned int len; + u8 option; + + addr = sg_dma_address(sg_ptr); + len = sg_dma_len(sg_ptr); + + RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", + (unsigned int)addr, len); + RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset); + + addr += *offset; + + if ((len - *offset) > resid) { + *offset += resid; + len = resid; + resid = 0; + } else { + resid -= (len - *offset); + len -= *offset; + *offset = 0; + *index = *index + 1; + } + if ((i == (sg_cnt - 1)) || !resid) + option = SG_VALID | SG_END | SG_TRANS_DATA; + else + option = SG_VALID | SG_TRANS_DATA; + + rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); + + if (!resid) + break; + + sg_ptr = sg_next(sg_ptr); + } + + RTSX_DEBUGP("SG table count = %d\n", chip->sgi); + + val |= (u32)(dir & 0x01) << 29; + val |= ADMA_MODE; + + spin_lock_irq(&rtsx->reg_lock); + + init_completion(&trans_done); + + rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + spin_unlock_irq(&rtsx->reg_lock); + goto out; + } + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_NOT_READY) { + init_completion(&trans_done); + spin_unlock_irq(&rtsx->reg_lock); + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + } else { + spin_unlock_irq(&rtsx->reg_lock); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) + err = -EIO; + else if (rtsx->trans_result == TRANS_RESULT_OK) + err = 0; + + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, + struct scatterlist *sg, int num_sg, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u8 dir; + int buf_cnt, i; + int err = 0; + long timeleft; + struct scatterlist *sg_ptr; + + if ((sg == NULL) || (num_sg <= 0)) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) + dir = HOST_TO_DEVICE; + else if (dma_dir == DMA_FROM_DEVICE) + dir = DEVICE_TO_HOST; + else + return -ENXIO; + + if (card == SD_CARD) + rtsx->check_card_cd = SD_EXIST; + else if (card == MS_CARD) + rtsx->check_card_cd = MS_EXIST; + else if (card == XD_CARD) + rtsx->check_card_cd = XD_EXIST; + else + rtsx->check_card_cd = 0; + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + rtsx->trans_state = STATE_TRANS_SG; + rtsx->trans_result = TRANS_NOT_READY; + + spin_unlock_irq(&rtsx->reg_lock); + + buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + sg_ptr = sg; + + for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) { + u32 val = TRIG_DMA; + int sg_cnt, j; + + if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) + sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); + else + sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); + + chip->sgi = 0; + for (j = 0; j < sg_cnt; j++) { + dma_addr_t addr = sg_dma_address(sg_ptr); + unsigned int len = sg_dma_len(sg_ptr); + u8 option; + + RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", + (unsigned int)addr, len); + + if (j == (sg_cnt - 1)) + option = SG_VALID | SG_END | SG_TRANS_DATA; + else + option = SG_VALID | SG_TRANS_DATA; + + rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); + + sg_ptr = sg_next(sg_ptr); + } + + RTSX_DEBUGP("SG table count = %d\n", chip->sgi); + + val |= (u32)(dir & 0x01) << 29; + val |= ADMA_MODE; + + spin_lock_irq(&rtsx->reg_lock); + + init_completion(&trans_done); + + rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + spin_unlock_irq(&rtsx->reg_lock); + goto out; + } + spin_unlock_irq(&rtsx->reg_lock); + + sg_ptr += sg_cnt; + } + + /* Wait for TRANS_OK_INT */ + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_NOT_READY) { + init_completion(&trans_done); + spin_unlock_irq(&rtsx->reg_lock); + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + } else { + spin_unlock_irq(&rtsx->reg_lock); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) + err = -EIO; + else if (rtsx->trans_result == TRANS_RESULT_OK) + err = 0; + + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + dma_addr_t addr; + u8 dir; + int err = 0; + u32 val = (1 << 31); + long timeleft; + + if ((buf == NULL) || (len <= 0)) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) + dir = HOST_TO_DEVICE; + else if (dma_dir == DMA_FROM_DEVICE) + dir = DEVICE_TO_HOST; + else + return -ENXIO; + + addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir); + if (!addr) + return -ENOMEM; + + if (card == SD_CARD) + rtsx->check_card_cd = SD_EXIST; + else if (card == MS_CARD) + rtsx->check_card_cd = MS_EXIST; + else if (card == XD_CARD) + rtsx->check_card_cd = XD_EXIST; + else + rtsx->check_card_cd = 0; + + val |= (u32)(dir & 0x01) << 29; + val |= (u32)(len & 0x00FFFFFF); + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + init_completion(&trans_done); + + rtsx->trans_state = STATE_TRANS_BUF; + rtsx->trans_result = TRANS_NOT_READY; + + rtsx_writel(chip, RTSX_HDBAR, addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) + err = -EIO; + else if (rtsx->trans_result == TRANS_RESULT_OK) + err = 0; + + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, + void *buf, size_t len, int use_sg, unsigned int *index, + unsigned int *offset, enum dma_data_direction dma_dir, + int timeout) +{ + int err = 0; + + /* don't transfer data during abort processing */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) + return -EIO; + + if (use_sg) { + err = rtsx_transfer_sglist_adma_partial(chip, card, + (struct scatterlist *)buf, use_sg, + index, offset, (int)len, dma_dir, timeout); + } else { + err = rtsx_transfer_buf(chip, card, + buf, len, dma_dir, timeout); + } + + if (err < 0) { + if (RTSX_TST_DELINK(chip)) { + RTSX_CLR_DELINK(chip); + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + } + } + + return err; +} + +int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + int use_sg, enum dma_data_direction dma_dir, int timeout) +{ + int err = 0; + + RTSX_DEBUGP("use_sg = %d\n", use_sg); + + /* don't transfer data during abort processing */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) + return -EIO; + + if (use_sg) { + err = rtsx_transfer_sglist_adma(chip, card, + (struct scatterlist *)buf, + use_sg, dma_dir, timeout); + } else { + err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); + } + + if (err < 0) { + if (RTSX_TST_DELINK(chip)) { + RTSX_CLR_DELINK(chip); + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + } + } + + return err; +} + diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h new file mode 100644 index 000000000000..b4b112372776 --- /dev/null +++ b/drivers/staging/rts5208/rtsx_transport.h @@ -0,0 +1,66 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_TRANSPORT_H +#define __REALTEK_RTSX_TRANSPORT_H + +#include "rtsx.h" +#include "rtsx_chip.h" + +#define WAIT_TIME 2000 + +unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, + unsigned int *offset, enum xfer_buf_dir dir); +void rtsx_stor_set_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb); +void rtsx_stor_get_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb); +void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip); + + +#define rtsx_init_cmd(chip) ((chip)->ci = 0) + +void rtsx_add_cmd(struct rtsx_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data); +void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); +int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); + +extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) +{ +#ifdef CMD_USING_SG + return (u8 *)(chip->host_sg_tbl_ptr); +#else + return (u8 *)(chip->host_cmds_ptr); +#endif +} + +int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + int use_sg, enum dma_data_direction dma_dir, int timeout); + +int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, + void *buf, size_t len, + int use_sg, unsigned int *index, unsigned int *offset, + enum dma_data_direction dma_dir, int timeout); + +#endif /* __REALTEK_RTSX_TRANSPORT_H */ diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c new file mode 100644 index 000000000000..c7c1f5410430 --- /dev/null +++ b/drivers/staging/rts5208/sd.c @@ -0,0 +1,4525 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "sd.h" + +#define SD_MAX_RETRY_COUNT 3 + +static u16 REG_SD_CFG1; +static u16 REG_SD_CFG2; +static u16 REG_SD_CFG3; +static u16 REG_SD_STAT1; +static u16 REG_SD_STAT2; +static u16 REG_SD_BUS_STAT; +static u16 REG_SD_PAD_CTL; +static u16 REG_SD_SAMPLE_POINT_CTL; +static u16 REG_SD_PUSH_POINT_CTL; +static u16 REG_SD_CMD0; +static u16 REG_SD_CMD1; +static u16 REG_SD_CMD2; +static u16 REG_SD_CMD3; +static u16 REG_SD_CMD4; +static u16 REG_SD_CMD5; +static u16 REG_SD_BYTE_CNT_L; +static u16 REG_SD_BYTE_CNT_H; +static u16 REG_SD_BLOCK_CNT_L; +static u16 REG_SD_BLOCK_CNT_H; +static u16 REG_SD_TRANSFER; +static u16 REG_SD_VPCLK0_CTL; +static u16 REG_SD_VPCLK1_CTL; +static u16 REG_SD_DCMPS0_CTL; +static u16 REG_SD_DCMPS1_CTL; + +static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code |= err_code; +} + +static inline void sd_clr_err_code(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code = 0; +} + +static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + return sd_card->err_code & err_code; +} + +static void sd_init_reg_addr(struct rtsx_chip *chip) +{ + REG_SD_CFG1 = 0xFD31; + REG_SD_CFG2 = 0xFD33; + REG_SD_CFG3 = 0xFD3E; + REG_SD_STAT1 = 0xFD30; + REG_SD_STAT2 = 0; + REG_SD_BUS_STAT = 0; + REG_SD_PAD_CTL = 0; + REG_SD_SAMPLE_POINT_CTL = 0; + REG_SD_PUSH_POINT_CTL = 0; + REG_SD_CMD0 = 0xFD34; + REG_SD_CMD1 = 0xFD35; + REG_SD_CMD2 = 0xFD36; + REG_SD_CMD3 = 0xFD37; + REG_SD_CMD4 = 0xFD38; + REG_SD_CMD5 = 0xFD5A; + REG_SD_BYTE_CNT_L = 0xFD39; + REG_SD_BYTE_CNT_H = 0xFD3A; + REG_SD_BLOCK_CNT_L = 0xFD3B; + REG_SD_BLOCK_CNT_H = 0xFD3C; + REG_SD_TRANSFER = 0xFD32; + REG_SD_VPCLK0_CTL = 0; + REG_SD_VPCLK1_CTL = 0; + REG_SD_DCMPS0_CTL = 0; + REG_SD_DCMPS1_CTL = 0; +} + +static int sd_check_data0_status(struct rtsx_chip *chip) +{ + u8 stat; + + RTSX_READ_REG(chip, REG_SD_STAT1, &stat); + + if (!(stat & SD_DAT0_STATUS)) { + sd_set_err_code(chip, SD_BUSY); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int timeout = 100; + u16 reg_addr; + u8 *ptr; + int stat_idx = 0; + int rty_cnt = 0; + + sd_clr_err_code(chip); + + RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + +RTY_SEND_CMD: + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | SD_STAT_IDLE); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + stat_idx = 16; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + stat_idx = 5; + } + + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + u8 val; + + rtsx_read_register(chip, REG_SD_STAT1, &val); + RTSX_DEBUGP("SD_STAT1: 0x%x\n", val); + + rtsx_read_register(chip, REG_SD_CFG3, &val); + RTSX_DEBUGP("SD_CFG3: 0x%x\n", val); + + if (retval == -ETIMEDOUT) { + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, retval); + } + } else { + sd_set_err_code(chip, SD_TO_ERR); + } + retval = STATUS_TIMEDOUT; + } else { + retval = STATUS_FAIL; + } + rtsx_clear_sd_error(chip); + + TRACE_RET(chip, retval); + } + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + ptr = rtsx_get_cmd_data(chip) + 1; + + if ((ptr[0] & 0xC0) != 0) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (ptr[stat_idx] & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) { + if ((cmd_idx != SEND_RELATIVE_ADDR) && + (cmd_idx != SEND_IF_COND)) { + if (cmd_idx != STOP_TRANSMISSION) { + if (ptr[1] & 0x80) + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef SUPPORT_SD_LOCK + if (ptr[1] & 0x7D) +#else + if (ptr[1] & 0x7F) +#endif + { + RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[2] & 0xFF) { + RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[3] & 0x80) { + RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[3] & 0x01) + sd_card->sd_data_buf_ready = 1; + else + sd_card->sd_data_buf_ready = 0; + } + } + + if (rsp && rsp_len) + memcpy(rsp, ptr, rsp_len); + + return STATUS_SUCCESS; +} + +static int sd_read_data(struct rtsx_chip *chip, + u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt, + u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, + int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + if (buf_len > 512) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + if (cmd_len) { + RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, + 0xFF, cmd[i]); + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, + (u8)byte_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, + (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, + (u8)blk_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, + (u8)(blk_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END| + SD_CHECK_CRC7 | SD_RSP_LEN_6); + if (trans_mode != SD_TM_AUTO_TUNING) + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + retval = rtsx_read_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, + u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width, + u8 *buf, int buf_len, int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + if (buf_len > 512) { + /* This function can't write data more than one page */ + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + retval = rtsx_write_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + if (cmd_len) { + RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + REG_SD_CMD0 + i, 0xFF, cmd[i]); + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, + (u8)byte_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, + (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, + (u8)blk_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, + (u8)(blk_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_csd(struct rtsx_chip *chip, char check_wp) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 csd_ver, trans_speed; + u8 rsp[16]; + + for (i = 0; i < 6; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, + SD_RSP_TYPE_R2, rsp, 16); + if (retval == STATUS_SUCCESS) + break; + } + + if (i == 6) + TRACE_RET(chip, STATUS_FAIL); + + memcpy(sd_card->raw_csd, rsp + 1, 15); + + RTSX_DEBUGP("CSD Response:\n"); + RTSX_DUMP(sd_card->raw_csd, 16); + + csd_ver = (rsp[1] & 0xc0) >> 6; + RTSX_DEBUGP("csd_ver = %d\n", csd_ver); + + trans_speed = rsp[4]; + if ((trans_speed & 0x07) == 0x02) { + if ((trans_speed & 0xf8) >= 0x30) { + if (chip->asic_code) + sd_card->sd_clock = 47; + else + sd_card->sd_clock = CLK_50; + + } else if ((trans_speed & 0xf8) == 0x28) { + if (chip->asic_code) + sd_card->sd_clock = 39; + else + sd_card->sd_clock = CLK_40; + + } else if ((trans_speed & 0xf8) == 0x20) { + if (chip->asic_code) + sd_card->sd_clock = 29; + else + sd_card->sd_clock = CLK_30; + + } else if ((trans_speed & 0xf8) >= 0x10) { + if (chip->asic_code) + sd_card->sd_clock = 23; + else + sd_card->sd_clock = CLK_20; + + } else if ((trans_speed & 0x08) >= 0x08) { + if (chip->asic_code) + sd_card->sd_clock = 19; + else + sd_card->sd_clock = CLK_20; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MMC_SECTOR_MODE(sd_card)) { + sd_card->capacity = 0; + } else { + if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) { + u8 blk_size, c_size_mult; + u16 c_size; + blk_size = rsp[6] & 0x0F; + c_size = ((u16)(rsp[7] & 0x03) << 10) + + ((u16)rsp[8] << 2) + + ((u16)(rsp[9] & 0xC0) >> 6); + c_size_mult = (u8)((rsp[10] & 0x03) << 1); + c_size_mult += (rsp[11] & 0x80) >> 7; + sd_card->capacity = (((u32)(c_size + 1)) * + (1 << (c_size_mult + 2))) + << (blk_size - 9); + } else { + u32 total_sector = 0; + total_sector = (((u32)rsp[8] & 0x3f) << 16) | + ((u32)rsp[9] << 8) | (u32)rsp[10]; + sd_card->capacity = (total_sector + 1) << 10; + } + } + + if (check_wp) { + if (rsp[15] & 0x30) + chip->card_wp |= SD_CARD; + + RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); + } + + return STATUS_SUCCESS; +} + +static int sd_set_sample_push_timing(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + u8 val = 0; + + if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) + val |= 0x10; + + if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { + if (chip->asic_code) { + if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { + if (val & 0x10) + val |= 0x04; + else + val |= 0x08; + } + } else { + if (val & 0x10) + val |= 0x04; + else + val |= 0x08; + } + } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == + SD_SAMPLE_POINT_DELAY) { + if (val & 0x10) + val |= 0x04; + else + val |= 0x08; + } + + RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val); + + return STATUS_SUCCESS; +} + +static void sd_choose_proper_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (CHK_SD_SDR104(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->asic_sd_sdr104_clk; + else + sd_card->sd_clock = chip->fpga_sd_sdr104_clk; + + } else if (CHK_SD_DDR50(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->asic_sd_ddr50_clk; + else + sd_card->sd_clock = chip->fpga_sd_ddr50_clk; + + } else if (CHK_SD_SDR50(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->asic_sd_sdr50_clk; + else + sd_card->sd_clock = chip->fpga_sd_sdr50_clk; + + } else if (CHK_SD_HS(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->asic_sd_hs_clk; + else + sd_card->sd_clock = chip->fpga_sd_hs_clk; + + } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->asic_mmc_52m_clk; + else + sd_card->sd_clock = chip->fpga_mmc_52m_clk; + + } else if (CHK_MMC_26M(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = 48; + else + sd_card->sd_clock = CLK_50; + } +} + +static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) +{ + u8 mask = 0, val = 0; + + mask = 0x60; + if (clk_div == SD_CLK_DIVIDE_0) + val = 0x00; + else if (clk_div == SD_CLK_DIVIDE_128) + val = 0x40; + else if (clk_div == SD_CLK_DIVIDE_256) + val = 0x20; + + RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val); + + return STATUS_SUCCESS; +} + +static int sd_set_init_para(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_set_sample_push_timing(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + sd_choose_proper_clock(chip); + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int sd_select_card(struct rtsx_chip *chip, int select) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd_idx, cmd_type; + u32 addr; + + if (select) { + cmd_idx = SELECT_CARD; + cmd_type = SD_RSP_TYPE_R1; + addr = sd_card->sd_addr; + } else { + cmd_idx = DESELECT_CARD; + cmd_type = SD_RSP_TYPE_R0; + addr = 0; + } + + retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_SD_LOCK +static int sd_update_lock_status(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 rsp[5]; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (rsp[1] & 0x02) + sd_card->sd_lock_status |= SD_LOCKED; + else + sd_card->sd_lock_status &= ~SD_LOCKED; + + RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n", + sd_card->sd_lock_status); + + if (rsp[1] & 0x01) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} +#endif + +static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, + u8 data_ready, int polling_cnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i; + u8 rsp[5]; + + for (i = 0; i < polling_cnt; i++) { + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, + 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (((rsp[3] & 0x1E) == state) && + ((rsp[3] & 0x01) == data_ready)) + return STATUS_SUCCESS; + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) +{ + int retval; + + if (voltage == SD_IO_3V3) { + if (chip->asic_code) { + retval = rtsx_write_phy_register(chip, 0x08, + 0x4FC0 | + chip->phy_voltage); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); + } + } else if (voltage == SD_IO_1V8) { + if (chip->asic_code) { + retval = rtsx_write_phy_register(chip, 0x08, + 0x4C40 | + chip->phy_voltage); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, + SD_IO_USING_1V8); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_voltage_switch(struct rtsx_chip *chip) +{ + int retval; + u8 stat; + + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, + SD_CLK_TOGGLE_EN); + + retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + udelay(chip->sd_voltage_switch_delay); + + RTSX_READ_REG(chip, SD_BUS_STAT, &stat); + if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP); + retval = sd_change_bank_voltage(chip, SD_IO_1V8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(50); + + RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); + wait_timeout(10); + + RTSX_READ_REG(chip, SD_BUS_STAT, &stat); + if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) != + (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) { + RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat); + rtsx_write_register(chip, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, + 0); + + return STATUS_SUCCESS; +} + +static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir) +{ + if (tune_dir == TUNE_RX) { + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_RX); + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RX); + } else { + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_TX); + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_TX); + } + + return STATUS_SUCCESS; +} + +static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) +{ + struct sd_info *sd_card = &(chip->sd_card); + u16 SD_VP_CTL, SD_DCMPS_CTL; + u8 val; + int retval; + int ddr_rx = 0; + + RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n", + sample_point, tune_dir); + + if (tune_dir == TUNE_RX) { + SD_VP_CTL = SD_VPRX_CTL; + SD_DCMPS_CTL = SD_DCMPS_RX_CTL; + if (CHK_SD_DDR50(sd_card)) + ddr_rx = 1; + } else { + SD_VP_CTL = SD_VPTX_CTL; + SD_DCMPS_CTL = SD_DCMPS_TX_CTL; + } + + if (chip->asic_code) { + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, + PHASE_NOT_RESET); + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); + } else { +#ifdef CONFIG_RTS5208_DEBUG + rtsx_read_register(chip, SD_VP_CTL, &val); + RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); + rtsx_read_register(chip, SD_DCMPS_CTL, &val); + RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + if (ddr_rx) { + RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, + PHASE_CHANGE); + udelay(50); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, + PHASE_CHANGE | PHASE_NOT_RESET | sample_point); + } else { + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); + udelay(50); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, + PHASE_NOT_RESET | sample_point); + } + udelay(100); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, + DCMPS_CHANGE); + rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, + DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, Fail); + + val = *rtsx_get_cmd_data(chip); + if (val & DCMPS_ERROR) + TRACE_GOTO(chip, Fail); + + if ((val & DCMPS_CURRENT_PHASE) != sample_point) + TRACE_GOTO(chip, Fail); + + RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + if (ddr_rx) + RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); + else + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); + + udelay(50); + } + + RTSX_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); + + return STATUS_SUCCESS; + +Fail: +#ifdef CONFIG_RTS5208_DEBUG + rtsx_read_register(chip, SD_VP_CTL, &val); + RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); + rtsx_read_register(chip, SD_DCMPS_CTL, &val); + RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); + wait_timeout(10); + sd_reset_dcm(chip, tune_dir); + return STATUS_FAIL; +} + +static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[8]; + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + cmd[0] = 0x40 | SEND_SCR; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, + buf, 8, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(sd_card->raw_scr, buf, 8); + + if ((buf[0] & 0x0F) == 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, + u8 func_to_switch, u8 *buf, int buf_len) +{ + u8 support_mask = 0, query_switch = 0, switch_busy = 0; + int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; + + if (func_group == SD_FUNC_GROUP_1) { + support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case HS_SUPPORT: + support_mask = HS_SUPPORT_MASK; + query_switch = HS_QUERY_SWITCH_OK; + switch_busy = HS_SWITCH_BUSY; + break; + + case SDR50_SUPPORT: + support_mask = SDR50_SUPPORT_MASK; + query_switch = SDR50_QUERY_SWITCH_OK; + switch_busy = SDR50_SWITCH_BUSY; + break; + + case SDR104_SUPPORT: + support_mask = SDR104_SUPPORT_MASK; + query_switch = SDR104_QUERY_SWITCH_OK; + switch_busy = SDR104_SWITCH_BUSY; + break; + + case DDR50_SUPPORT: + support_mask = DDR50_SUPPORT_MASK; + query_switch = DDR50_QUERY_SWITCH_OK; + switch_busy = DDR50_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_3) { + support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case DRIVING_TYPE_A: + support_mask = DRIVING_TYPE_A_MASK; + query_switch = TYPE_A_QUERY_SWITCH_OK; + switch_busy = TYPE_A_SWITCH_BUSY; + break; + + case DRIVING_TYPE_C: + support_mask = DRIVING_TYPE_C_MASK; + query_switch = TYPE_C_QUERY_SWITCH_OK; + switch_busy = TYPE_C_SWITCH_BUSY; + break; + + case DRIVING_TYPE_D: + support_mask = DRIVING_TYPE_D_MASK; + query_switch = TYPE_D_QUERY_SWITCH_OK; + switch_busy = TYPE_D_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_4) { + support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case CURRENT_LIMIT_400: + support_mask = CURRENT_LIMIT_400_MASK; + query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_600: + support_mask = CURRENT_LIMIT_600_MASK; + query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_800: + support_mask = CURRENT_LIMIT_800_MASK; + query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + if (func_group == SD_FUNC_GROUP_1) { + if (!(buf[support_offset] & support_mask) || + ((buf[query_switch_offset] & 0x0F) != query_switch)) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + /* Check 'Busy Status' */ + if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) && + ((buf[check_busy_offset] & switch_busy) == switch_busy)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[64]; + + RTSX_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n", + mode, func_group, func_to_switch); + + cmd[0] = 0x40 | SWITCH; + cmd[1] = mode; + + if (func_group == SD_FUNC_GROUP_1) { + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xF0 + func_to_switch; + } else if (func_group == SD_FUNC_GROUP_3) { + cmd[2] = 0xFF; + cmd[3] = 0xF0 + func_to_switch; + cmd[4] = 0xFF; + } else if (func_group == SD_FUNC_GROUP_4) { + cmd[2] = 0xFF; + cmd[3] = 0x0F + (func_to_switch << 4); + cmd[4] = 0xFF; + } else { + cmd[1] = SD_CHECK_MODE; + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xFF; + } + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, + buf, 64, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DUMP(buf, 64); + + if (func_group == NO_ARGUMENT) { + sd_card->func_group1_mask = buf[0x0D]; + sd_card->func_group2_mask = buf[0x0B]; + sd_card->func_group3_mask = buf[0x09]; + sd_card->func_group4_mask = buf[0x07]; + + RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]); + RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]); + RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]); + RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); + } else { + /* Maximum current consumption, check whether current is + * acceptable; bit[511:496] = 0x0000 means some error happened. + */ + u16 cc = ((u16)buf[0] << 8) | buf[1]; + RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc); + if ((cc == 0) || (cc > 800)) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_query_switch_result(chip, func_group, + func_to_switch, buf, 64); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) { + RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, + chip->sd_800mA_ocp_thd); + RTSX_WRITE_REG(chip, CARD_PWR_CTL, PMOS_STRG_MASK, + PMOS_STRG_800mA); + } + } + + return STATUS_SUCCESS; +} + +static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) +{ + if (func_group == SD_FUNC_GROUP_1) { + if (func_to_switch > HS_SUPPORT) + func_to_switch--; + + } else if (func_group == SD_FUNC_GROUP_4) { + if (func_to_switch > CURRENT_LIMIT_200) + func_to_switch--; + } + + return func_to_switch; +} + +static int sd_check_switch(struct rtsx_chip *chip, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + int retval; + int i; + int switch_good = 0; + + for (i = 0; i < 3; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, + func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + u8 stat; + + retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, + func_group, func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + switch_good = 1; + break; + } + + RTSX_READ_REG(chip, SD_STAT1, &stat); + if (stat & SD_CRC16_ERR) { + RTSX_DEBUGP("SD CRC16 error when switching mode\n"); + TRACE_RET(chip, STATUS_FAIL); + } + } + + func_to_switch = downgrade_switch_mode(func_group, + func_to_switch); + + wait_timeout(20); + } + + if (!switch_good) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 func_to_switch = 0; + + /* Get supported functions */ + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, + NO_ARGUMENT, NO_ARGUMENT, bus_width); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); + + /* Function Group 1: Access Mode */ + for (i = 0; i < 4; i++) { + switch ((u8)(chip->sd_speed_prior >> (i*8))) { + case SDR104_SUPPORT: + if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK) + && chip->sdr104_en) { + func_to_switch = SDR104_SUPPORT; + } + break; + + case DDR50_SUPPORT: + if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) + && chip->ddr50_en) { + func_to_switch = DDR50_SUPPORT; + } + break; + + case SDR50_SUPPORT: + if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) + && chip->sdr50_en) { + func_to_switch = SDR50_SUPPORT; + } + break; + + case HS_SUPPORT: + if (sd_card->func_group1_mask & HS_SUPPORT_MASK) + func_to_switch = HS_SUPPORT; + + break; + + default: + continue; + } + + + if (func_to_switch) + break; + + } + RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_SDR_RST) + && (DDR50_SUPPORT == func_to_switch) + && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { + func_to_switch = SDR50_SUPPORT; + RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); + } +#endif + + if (func_to_switch) { + retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, + bus_width); + if (retval != STATUS_SUCCESS) { + if (func_to_switch == SDR104_SUPPORT) { + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; + } else if (func_to_switch == DDR50_SUPPORT) { + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | + DDR50_SUPPORT_MASK; + } else if (func_to_switch == SDR50_SUPPORT) { + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | + DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (func_to_switch == SDR104_SUPPORT) + SET_SD_SDR104(sd_card); + else if (func_to_switch == DDR50_SUPPORT) + SET_SD_DDR50(sd_card); + else if (func_to_switch == SDR50_SUPPORT) + SET_SD_SDR50(sd_card); + else + SET_SD_HS(sd_card); + } + + if (CHK_SD_DDR50(sd_card)) { + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04); + retval = sd_set_sample_push_timing(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + if (!func_to_switch || (func_to_switch == HS_SUPPORT)) { + /* Do not try to switch current limit if the card doesn't + * support UHS mode or we don't want it to support UHS mode + */ + return STATUS_SUCCESS; + } + + /* Function Group 4: Current Limit */ + func_to_switch = 0xFF; + + for (i = 0; i < 4; i++) { + switch ((u8)(chip->sd_current_prior >> (i*8))) { + case CURRENT_LIMIT_800: + if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) + func_to_switch = CURRENT_LIMIT_800; + + break; + + case CURRENT_LIMIT_600: + if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) + func_to_switch = CURRENT_LIMIT_600; + + break; + + case CURRENT_LIMIT_400: + if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) + func_to_switch = CURRENT_LIMIT_400; + + break; + + case CURRENT_LIMIT_200: + if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) + func_to_switch = CURRENT_LIMIT_200; + + break; + + default: + continue; + } + + if (func_to_switch != 0xFF) + break; + } + + RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch); + + if (func_to_switch <= CURRENT_LIMIT_800) { + retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, + bus_width); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_NO_CARD)) + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval); + } + + if (CHK_SD_DDR50(sd_card)) + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0); + + return STATUS_SUCCESS; +} + +static int sd_wait_data_idle(struct rtsx_chip *chip) +{ + int retval = STATUS_TIMEDOUT; + int i; + u8 val = 0; + + for (i = 0; i < 100; i++) { + RTSX_READ_REG(chip, SD_DATA_STATE, &val); + if (val & SD_DATA_IDLE) { + retval = STATUS_SUCCESS; + break; + } + udelay(100); + } + RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val); + + return retval; +} + +static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + cmd[0] = 0x40 | SEND_TUNING_PATTERN; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_AUTO_TUNING, + cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("sd ddr tuning rx\n"); + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + cmd[0] = 0x40 | SD_STATUS; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("mmc ddr tuning rx\n"); + + cmd[0] = 0x40 | SEND_EXT_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 0x200, 1, bus_width, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { + rtsx_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_SD(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + } + + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + cmd[0] = 0x40 | PROGRAM_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, + cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + + return STATUS_SUCCESS; +} + +static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, + u8 tune_dir) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct timing_phase_path path[MAX_PHASE + 1]; + int i, j, cont_path_cnt; + int new_block, max_len, final_path_idx; + u8 final_phase = 0xFF; + + if (phase_map == 0xFFFFFFFF) { + if (tune_dir == TUNE_RX) + final_phase = (u8)chip->sd_default_rx_phase; + else + final_phase = (u8)chip->sd_default_tx_phase; + + goto Search_Finish; + } + + cont_path_cnt = 0; + new_block = 1; + j = 0; + for (i = 0; i < MAX_PHASE + 1; i++) { + if (phase_map & (1 << i)) { + if (new_block) { + new_block = 0; + j = cont_path_cnt++; + path[j].start = i; + path[j].end = i; + } else { + path[j].end = i; + } + } else { + new_block = 1; + if (cont_path_cnt) { + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - + path[idx].start + 1; + path[idx].mid = path[idx].start + + path[idx].len / 2; + } + } + } + + if (cont_path_cnt == 0) { + RTSX_DEBUGP("No continuous phase path\n"); + goto Search_Finish; + } else { + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - path[idx].start + 1; + path[idx].mid = path[idx].start + path[idx].len / 2; + } + + if ((path[0].start == 0) && + (path[cont_path_cnt - 1].end == MAX_PHASE)) { + path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; + path[0].len += path[cont_path_cnt - 1].len; + path[0].mid = path[0].start + path[0].len / 2; + if (path[0].mid < 0) + path[0].mid += MAX_PHASE + 1; + + cont_path_cnt--; + } + + max_len = 0; + final_phase = 0; + final_path_idx = 0; + for (i = 0; i < cont_path_cnt; i++) { + if (path[i].len > max_len) { + max_len = path[i].len; + final_phase = (u8)path[i].mid; + final_path_idx = i; + } + + RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start); + RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end); + RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len); + RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid); + RTSX_DEBUGP("\n"); + } + + if (tune_dir == TUNE_TX) { + if (CHK_SD_SDR104(sd_card)) { + if (max_len > 15) { + int temp_mid = (max_len - 16) / 2; + int temp_final_phase = + path[final_path_idx].end - + (max_len - (6 + temp_mid)); + + if (temp_final_phase < 0) + final_phase = (u8)(temp_final_phase + + MAX_PHASE + 1); + else + final_phase = (u8)temp_final_phase; + } + } else if (CHK_SD_SDR50(sd_card)) { + if (max_len > 12) { + int temp_mid = (max_len - 13) / 2; + int temp_final_phase = + path[final_path_idx].end - + (max_len - (3 + temp_mid)); + + if (temp_final_phase < 0) + final_phase = (u8)(temp_final_phase + + MAX_PHASE + 1); + else + final_phase = (u8)temp_final_phase; + } + } + } + +Search_Finish: + RTSX_DEBUGP("Final chosen phase: %d\n", final_phase); + return final_phase; +} + +static int sd_tuning_rx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + tuning_cmd = sd_ddr_tuning_rx_cmd; + else + tuning_cmd = sd_sdr_tuning_rx_cmd; + + } else { + if (CHK_MMC_DDR52(sd_card)) + tuning_cmd = mmc_ddr_tunning_rx_cmd; + else + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8)j); + if (retval == STATUS_SUCCESS) + raw_phase_map[i] |= 1 << j; + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) + RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i, + raw_phase_map[i]); + + RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); + if (final_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_change_phase(chip, final_phase, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u32 phase_map; + u8 final_phase; + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + phase_map = 0; + for (i = MAX_PHASE; i >= 0; i--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + rtsx_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, (u8)i, TUNE_TX); + if (retval != STATUS_SUCCESS) + continue; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, + 0); + if ((retval == STATUS_SUCCESS) || + !sd_check_err_code(chip, SD_RSP_TIMEOUT)) + phase_map |= 1 << i; + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); + if (final_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_change_phase(chip, final_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase); + + return STATUS_SUCCESS; +} + +static int sd_tuning_tx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + tuning_cmd = sd_ddr_tuning_tx_cmd; + else + tuning_cmd = sd_sdr_tuning_tx_cmd; + + } else { + if (CHK_MMC_DDR52(sd_card)) + tuning_cmd = sd_ddr_tuning_tx_cmd; + else + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + rtsx_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8)j); + if (retval == STATUS_SUCCESS) + raw_phase_map[i] |= 1 << j; + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) + RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n", + i, raw_phase_map[i]); + + RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); + if (final_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_change_phase(chip, final_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning(struct rtsx_chip *chip) +{ + int retval; + + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning(struct rtsx_chip *chip) +{ + int retval; + + if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, + TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tuning(struct rtsx_chip *chip) +{ + int retval; + + if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, + TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int sd_switch_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int re_tuning = 0; + + retval = select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (re_tuning) { + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + retval = sd_ddr_tuning(chip); + else + retval = sd_sdr_tuning(chip); + } else { + if (CHK_MMC_DDR52(sd_card)) + retval = mmc_ddr_tuning(chip); + } + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_prepare_reset(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) + sd_card->sd_clock = 29; + else + sd_card->sd_clock = CLK_30; + + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->sd_io = 0; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, 0x40); + + RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + + retval = select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | SD_D7_PD | SD_CLK_PD | SD_D5_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + SD_D6_PD | SD_D0_PD | SD_D1_PD | XD_D5_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + SD_D4_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +int sd_pull_ctl_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + 0xA8); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + 0x5A); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + 0x95); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + 0xAA); + } + } + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_init_power(struct rtsx_chip *chip) +{ + int retval; + + retval = sd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->ft2_fast_mode) + wait_timeout(250); + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, + 0); + } + + if (!chip->ft2_fast_mode) { + retval = card_power_on(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(260); + +#ifdef SUPPORT_OCP + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); + + return STATUS_SUCCESS; +} + +static int sd_dummy_clock(struct rtsx_chip *chip) +{ + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0x01); + wait_timeout(5); + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0); + + return STATUS_SUCCESS; +} + +static int sd_read_lba0(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + cmd[0] = 0x40 | READ_SINGLE_BLOCK; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + if (CHK_SD(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + } + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, + 5, 512, 1, bus_width, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_wp_state(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u32 val; + u16 sd_card_type; + u8 cmd[5], buf[64]; + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + cmd[0] = 0x40 | SD_STATUS; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, + SD_BUS_WIDTH_4, buf, 64, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("ACMD13:\n"); + RTSX_DUMP(buf, 64); + + sd_card_type = ((u16)buf[2] << 8) | buf[3]; + RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type); + if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) { + /* ROM card or OTP */ + chip->card_wp |= SD_CARD; + } + + /* Check SD Machanical Write-Protect Switch */ + val = rtsx_readl(chip, RTSX_BIPR); + if (val & SD_WRITE_PROTECT) + chip->card_wp |= SD_CARD; + + return STATUS_SUCCESS; +} + +static int reset_sd(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; + int sd_dont_switch = 0; + int support_1v8 = 0; + int try_sdio = 1; + u8 rsp[16]; + u8 switch_bus_width; + u32 voltage = 0; + int sd20_mode = 0; + + SET_SD(sd_card); + +Switch_Fail: + + i = 0; + j = 0; + k = 0; + hi_cap_flow = 0; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto SD_UNLOCK_ENTRY; +#endif + + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_dummy_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { + int rty_cnt = 0; + + for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, + SD_RSP_TYPE_R4, rsp, 5); + if (retval == STATUS_SUCCESS) { + int func_num = (rsp[1] >> 4) & 0x07; + if (func_num) { + RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num); + chip->sd_io = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + break; + } + + sd_init_power(chip); + + sd_dummy_clock(chip); + } + + RTSX_DEBUGP("Normal card!\n"); + } + + /* Start Initialization Process of SD Card */ +RTY_SD_RST: + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(20); + + retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, + SD_RSP_TYPE_R7, rsp, 5); + if (retval == STATUS_SUCCESS) { + if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) { + hi_cap_flow = 1; + voltage = SUPPORT_VOLTAGE | 0x40000000; + } + } + + if (!hi_cap_flow) { + voltage = SUPPORT_VOLTAGE; + + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, + SD_RSP_TYPE_R0, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(20); + } + + do { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + j++; + if (j < 3) + goto RTY_SD_RST; + else + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, + SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + k++; + if (k < 3) + goto RTY_SD_RST; + else + TRACE_RET(chip, STATUS_FAIL); + } + + i++; + wait_timeout(20); + } while (!(rsp[1] & 0x80) && (i < 255)); + + if (i == 255) + TRACE_RET(chip, STATUS_FAIL); + + if (hi_cap_flow) { + if (rsp[1] & 0x40) + SET_SD_HCXC(sd_card); + else + CLR_SD_HCXC(sd_card); + + support_1v8 = 0; + } else { + CLR_SD_HCXC(sd_card); + support_1v8 = 0; + } + RTSX_DEBUGP("support_1v8 = %d\n", support_1v8); + + if (support_1v8) { + retval = sd_voltage_switch(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < 3; i++) { + retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, + SD_RSP_TYPE_R6, rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + sd_card->sd_addr = (u32)rsp[1] << 24; + sd_card->sd_addr += (u32)rsp[2] << 16; + + if (sd_card->sd_addr) + break; + } + + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + +#ifdef SUPPORT_SD_LOCK +SD_UNLOCK_ENTRY: + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (sd_card->sd_lock_status & SD_LOCKED) { + sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); + return STATUS_SUCCESS; + } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + } +#endif + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (support_1v8) { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + switch_bus_width = SD_BUS_WIDTH_4; + } else { + switch_bus_width = SD_BUS_WIDTH_1; + } + + retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!(sd_card->raw_csd[4] & 0x40)) + sd_dont_switch = 1; + + if (!sd_dont_switch) { + if (sd20_mode) { + /* Set sd_switch_fail here, because we needn't + * switch to UHS mode + */ + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | + DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; + } + + /* Check the card whether follow SD1.1 spec or higher */ + retval = sd_check_spec(chip, switch_bus_width); + if (retval == STATUS_SUCCESS) { + retval = sd_switch_function(chip, switch_bus_width); + if (retval != STATUS_SUCCESS) { + sd_init_power(chip); + sd_dont_switch = 1; + try_sdio = 0; + + goto Switch_Fail; + } + } else { + if (support_1v8) { + sd_init_power(chip); + sd_dont_switch = 1; + try_sdio = 0; + + goto Switch_Fail; + } + } + } + + if (!support_1v8) { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + + if (!sd20_mode && CHK_SD30_SPEED(sd_card)) { + int read_lba0 = 1; + + RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, + chip->sd30_drive_sel_1v8); + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_SD_DDR50(sd_card)) + retval = sd_ddr_tuning(chip); + else + retval = sd_sdr_tuning(chip); + + if (retval != STATUS_SUCCESS) { + if (sd20_mode) { + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + try_sdio = 0; + sd20_mode = 1; + goto Switch_Fail; + } + } + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + + if (CHK_SD_DDR50(sd_card)) { + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) + read_lba0 = 0; + } + + if (read_lba0) { + retval = sd_read_lba0(chip); + if (retval != STATUS_SUCCESS) { + if (sd20_mode) { + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + try_sdio = 0; + sd20_mode = 1; + goto Switch_Fail; + } + } + } + } + + retval = sd_check_wp_state(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); + } +#endif + + return STATUS_SUCCESS; +} + + +static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 buf[8] = {0}, bus_width, *ptr; + u16 byte_cnt; + int len; + + retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, + 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, SWITCH_FAIL); + + if (width == MMC_8BIT_BUS) { + buf[0] = 0x55; + buf[1] = 0xAA; + len = 8; + byte_cnt = 8; + bus_width = SD_BUS_WIDTH_8; + } else { + buf[0] = 0x5A; + len = 4; + byte_cnt = 4; + bus_width = SD_BUS_WIDTH_4; + } + + retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, SWITCH_ERR); + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, + NULL, 0, byte_cnt, 1, bus_width, buf, len, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); + TRACE_RET(chip, SWITCH_ERR); + } + + retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, SWITCH_ERR); + + RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); + + if (width == MMC_8BIT_BUS) + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, + 0xFF, 0x08); + else + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, + 0xFF, 0x04); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END| + SD_CHECK_CRC7 | SD_RSP_LEN_6); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_NORMAL_READ | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); + if (width == MMC_8BIT_BUS) + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval < 0) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, SWITCH_ERR); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + if (width == MMC_8BIT_BUS) { + RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0], + ptr[1]); + if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) + arg = 0x03B70600; + else + arg = 0x03B70200; + + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, + SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) && + !(rsp[4] & MMC_SWITCH_ERR)) + return SWITCH_SUCCESS; + } + } else { + RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); + if (ptr[0] == 0xA5) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) + arg = 0x03B70500; + else + arg = 0x03B70100; + + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, + SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) && + !(rsp[4] & MMC_SWITCH_ERR)) + return SWITCH_SUCCESS; + } + } + + TRACE_RET(chip, SWITCH_FAIL); +} + + +static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 *ptr, card_type, card_type_mask = 0; + + CLR_MMC_HS(sd_card); + + RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, + 0x40 | SEND_EXT_CSD); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END| + SD_CHECK_CRC7 | SD_RSP_LEN_6); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_NORMAL_READ | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, 1000); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + rtsx_clear_sd_error(chip); + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip); + if (ptr[0] & SD_TRANSFER_ERR) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MMC_SECTOR_MODE(sd_card)) { + sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) | + ((u32)ptr[3] << 8) | ((u32)ptr[2]); + } + + card_type_mask = 0x03; + card_type = ptr[1] & card_type_mask; + if (card_type) { + u8 rsp[5]; + + if (card_type & 0x04) { + if (switch_ddr) + SET_MMC_DDR52(sd_card); + else + SET_MMC_52M(sd_card); + } else if (card_type & 0x02) { + SET_MMC_52M(sd_card); + } else { + SET_MMC_26M(sd_card); + } + + retval = sd_send_cmd_get_rsp(chip, SWITCH, + 0x03B90100, SD_RSP_TYPE_R1b, rsp, 5); + if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) + CLR_MMC_HS(sd_card); + } + + sd_choose_proper_clock(chip); + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* Test Bus Procedure */ + retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); + if (retval == SWITCH_SUCCESS) { + SET_MMC_8BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else if (retval == SWITCH_FAIL) { + retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS); + if (retval == SWITCH_SUCCESS) { + SET_MMC_4BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else if (retval == SWITCH_FAIL) { + CLR_MMC_8BIT(sd_card); + CLR_MMC_4BIT(sd_card); + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +static int reset_mmc(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0; + int switch_ddr = 1; + u8 rsp[16]; + u8 spec_ver = 0; + u32 temp; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto MMC_UNLOCK_ENTRY; +#endif + +Switch_Fail: + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + SET_MMC(sd_card); + +RTY_MMC_RST: + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + do { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, + (SUPPORT_VOLTAGE | 0x40000000), + SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_BUSY) || + sd_check_err_code(chip, SD_TO_ERR)) { + k++; + if (k < 20) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + j++; + if (j < 100) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + wait_timeout(20); + i++; + } while (!(rsp[1] & 0x80) && (i < 255)); + + if (i == 255) + TRACE_RET(chip, STATUS_FAIL); + + if ((rsp[1] & 0x60) == 0x40) + SET_MMC_SECTOR_MODE(sd_card); + else + CLR_MMC_SECTOR_MODE(sd_card); + + retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + sd_card->sd_addr = 0x00100000; + retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, + SD_RSP_TYPE_R6, rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; + + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + +#ifdef SUPPORT_SD_LOCK +MMC_UNLOCK_ENTRY: + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); +#endif + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; + + if (!sd_card->mmc_dont_switch_bus) { + if (spec_ver == 4) { + /* MMC 4.x Cards */ + retval = mmc_switch_timing_bus(chip, switch_ddr); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + sd_card->mmc_dont_switch_bus = 1; + TRACE_GOTO(chip, Switch_Fail); + } + } + + if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) + TRACE_RET(chip, STATUS_FAIL); + + if (switch_ddr && CHK_MMC_DDR52(sd_card)) { + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = mmc_ddr_tuning(chip); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + switch_ddr = 0; + TRACE_GOTO(chip, Switch_Fail); + } + + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval == STATUS_SUCCESS) { + retval = sd_read_lba0(chip); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + switch_ddr = 0; + TRACE_GOTO(chip, Switch_Fail); + } + } + } + } + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); + } +#endif + + temp = rtsx_readl(chip, RTSX_BIPR); + if (temp & SD_WRITE_PROTECT) + chip->card_wp |= SD_CARD; + + return STATUS_SUCCESS; +} + +int reset_sd_card(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + sd_init_reg_addr(chip); + + memset(sd_card, 0, sizeof(struct sd_info)); + chip->capacity[chip->card2lun[SD_CARD]] = 0; + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && + !CHK_SDIO_IGNORED(chip)) { + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = rtsx_write_register(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + retval = card_share_mode(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + chip->sd_io = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->sd_ctl & RESET_MMC_FIRST) { + retval = reset_mmc(chip); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_NO_CARD)) + TRACE_RET(chip, STATUS_FAIL); + + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_NO_CARD)) + TRACE_RET(chip, STATUS_FAIL); + + if (chip->sd_io) { + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = reset_mmc(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); + + return STATUS_SUCCESS; +} + +static int reset_mmc_only(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + sd_card->sd_switch_fail = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = reset_mmc(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n", + sd_card->sd_type); + + return STATUS_SUCCESS; +} + +#define WAIT_DATA_READY_RTY_CNT 255 + +static int wait_data_buf_ready(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int i, retval; + + for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->sd_data_buf_ready = 0; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (sd_card->sd_data_buf_ready) { + return sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + } + + sd_set_err_code(chip, SD_TO_ERR); + + TRACE_RET(chip, STATUS_FAIL); +} + +void sd_stop_seq_mode(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (sd_card->seq_mode) { + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + return; + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) + sd_set_err_code(chip, SD_STS_ERR); + + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) + sd_set_err_code(chip, SD_STS_ERR); + + sd_card->seq_mode = 0; + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } +} + +static inline int sd_auto_tune_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) { + if (sd_card->sd_clock > 30) + sd_card->sd_clock -= 20; + } else { + switch (sd_card->sd_clock) { + case CLK_200: + sd_card->sd_clock = CLK_150; + break; + + case CLK_150: + sd_card->sd_clock = CLK_120; + break; + + case CLK_120: + sd_card->sd_clock = CLK_100; + break; + + case CLK_100: + sd_card->sd_clock = CLK_80; + break; + + case CLK_80: + sd_card->sd_clock = CLK_60; + break; + + case CLK_60: + sd_card->sd_clock = CLK_50; + break; + + default: + break; + } + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + u32 data_addr; + u8 cfg2; + int retval; + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt, + (sector_cnt > 1) ? "sectors" : "sector", start_sector); + } else { + RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt, + (sector_cnt > 1) ? "sectors" : "sector", start_sector); + } + + sd_card->cleanup_counter = 0; + + if (!(chip->card_ready & SD_CARD)) { + sd_card->seq_mode = 0; + + retval = reset_sd_card(chip); + if (retval == STATUS_SUCCESS) { + chip->card_ready |= SD_CARD; + chip->card_fail &= ~SD_CARD; + } else { + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->rw_need_retry = 1; + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) + data_addr = start_sector << 9; + else + data_addr = start_sector; + + sd_clr_err_code(chip); + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_IO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (sd_card->seq_mode && + ((sd_card->pre_dir != srb->sc_data_direction) || + ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != + start_sector))) { + if ((sd_card->pre_sec_cnt < 0x80) + && (sd_card->pre_dir == DMA_FROM_DEVICE) + && !CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card)) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_STS_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + sd_card->seq_mode = 0; + + retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_IO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if ((sd_card->pre_sec_cnt < 0x80) + && !CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card)) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, + (u8)sector_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, + (u8)(sector_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + if (CHK_MMC_8BIT(sd_card)) + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, + 0x03, SD_BUS_WIDTH_8); + else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, + 0x03, SD_BUS_WIDTH_4); + else + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, + 0x03, SD_BUS_WIDTH_1); + + if (sd_card->seq_mode) { + cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16| + SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | + SD_RSP_LEN_0; + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, + DMA_512); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_3 | SD_TRANSFER_START); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + } + + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, + 0x40 | READ_MULTIPLE_BLOCK); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, + (u8)(data_addr >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, + (u8)(data_addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, + (u8)(data_addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, + (u8)data_addr); + + cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | + SD_RSP_LEN_6; + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, + sector_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } else { + retval = rtsx_send_cmd(chip, SD_CARD, 50); + if (retval < 0) { + rtsx_clear_sd_error(chip); + + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + retval = wait_data_buf_ready(chip); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, + data_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + TRACE_GOTO(chip, RW_FAIL); + } + + rtsx_init_cmd(chip); + + cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | + SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, + sector_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } + + sd_card->seq_mode = 1; + } + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), + scsi_bufflen(srb), scsi_sg_count(srb), + srb->sc_data_direction, chip->sd_timeout); + if (retval < 0) { + u8 stat = 0; + int err; + + sd_card->seq_mode = 0; + + if (retval == -ETIMEDOUT) + err = STATUS_TIMEDOUT; + else + err = STATUS_FAIL; + + rtsx_read_register(chip, REG_SD_STAT1, &stat); + rtsx_clear_sd_error(chip); + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit sd_rw\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + chip->rw_need_retry = 1; + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { + RTSX_DEBUGP("SD CRC error, tune clock!\n"); + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (err == STATUS_TIMEDOUT) { + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + TRACE_RET(chip, err); + } + + sd_card->pre_sec_addr = start_sector; + sd_card->pre_sec_cnt = sector_cnt; + sd_card->pre_dir = srb->sc_data_direction; + + return STATUS_SUCCESS; + +RW_FAIL: + sd_card->seq_mode = 0; + + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit sd_rw\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_check_err_code(chip, SD_CRC_ERR)) { + if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) { + sd_card->mmc_dont_switch_bus = 1; + reset_mmc_only(chip); + sd_card->mmc_dont_switch_bus = 0; + } else { + sd_card->need_retune = 1; + sd_auto_tune_clock(chip); + } + } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) { + retval = reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + +#ifdef SUPPORT_CPRM +int soft_reset_sd_card(struct rtsx_chip *chip) +{ + return reset_sd(chip); +} + +int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) +{ + int retval; + int timeout = 100; + u16 reg_addr; + u8 *ptr; + int stat_idx = 0; + int rty_cnt = 0; + + RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + +RTY_SEND_CMD: + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + stat_idx = 17; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + stat_idx = 6; + } + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); + + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + rtsx_clear_sd_error(chip); + + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + sd_set_err_code(chip, SD_TO_ERR); + } + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + ptr = rtsx_get_cmd_data(chip) + 1; + + if ((ptr[0] & 0xC0) != 0) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (ptr[stat_idx] & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || + (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { + if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { + if (ptr[1] & 0x80) + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef SUPPORT_SD_LOCK + if (ptr[1] & 0x7D) +#else + if (ptr[1] & 0x7F) +#endif + { + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[2] & 0xF8) + TRACE_RET(chip, STATUS_FAIL); + + if (cmd_idx == SELECT_CARD) { + if (rsp_type == SD_RSP_TYPE_R2) { + if ((ptr[3] & 0x1E) != 0x04) + TRACE_RET(chip, STATUS_FAIL); + + } else if (rsp_type == SD_RSP_TYPE_R0) { + if ((ptr[3] & 0x1E) != 0x03) + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if (rsp && rsp_len) + memcpy(rsp, ptr, rsp_len); + + return STATUS_SUCCESS; +} + +int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) +{ + int retval, rsp_len; + u16 reg_addr; + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + rtsx_init_cmd(chip); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + + rsp_len = 17; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; + reg_addr++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + + rsp_len = 6; + } + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (rsp) { + int min_len = (rsp_len < len) ? rsp_len : len; + + memcpy(rsp, rtsx_get_cmd_data(chip), min_len); + + RTSX_DEBUGP("min_len = %d\n", min_len); + RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", + rsp[0], rsp[1], rsp[2], rsp[3]); + } + + return STATUS_SUCCESS; +} + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int len; + u8 buf[18] = { + 0x00, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x44, + 0x20, + 0x43, + 0x61, + 0x72, + 0x64, + 0x00, + 0x00, + 0x00, + }; + + sd_card->pre_cmd_err = 0; + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || + (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) || + (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) || + (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: + sd_card->sd_pass_thru_en = 0; + break; + + case 1: + sd_card->sd_pass_thru_en = 1; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; + if (chip->card_wp & SD_CARD) + buf[5] |= 0x80; + + buf[6] = (u8)(sd_card->sd_addr >> 16); + buf[7] = (u8)(sd_card->sd_addr >> 24); + + buf[15] = chip->max_lun; + + len = min_t(int, 18, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, len, srb); + + return TRANSPORT_GOOD; +} + +static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, + int *rsp_len) +{ + if (!rsp_type || !rsp_len) + return STATUS_FAIL; + + switch (srb->cmnd[10]) { + case 0x03: + *rsp_type = SD_RSP_TYPE_R0; + *rsp_len = 0; + break; + + case 0x04: + *rsp_type = SD_RSP_TYPE_R1; + *rsp_len = 6; + break; + + case 0x05: + *rsp_type = SD_RSP_TYPE_R1b; + *rsp_len = 6; + break; + + case 0x06: + *rsp_type = SD_RSP_TYPE_R2; + *rsp_len = 17; + break; + + case 0x07: + *rsp_type = SD_RSP_TYPE_R3; + *rsp_len = 6; + break; + + default: + return STATUS_FAIL; + } + + return STATUS_SUCCESS; +} + +int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len; + u8 cmd_idx, rsp_type; + u8 standby = 0, acmd = 0; + u32 arg; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x02) + standby = 1; + + if (srb->cmnd[1] & 0x01) + acmd = 1; + + arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | + ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, + SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, + SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#else + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); +#endif + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + +#ifdef SUPPORT_SD_LOCK + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); +#endif + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len, i; + int cmd13_checkbit = 0, read_err = 0; + u8 cmd_idx, rsp_type, bus_width; + u8 send_cmd12 = 0, standby = 0, acmd = 0; + u32 data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) + send_cmd12 = 1; + + if (srb->cmnd[1] & 0x02) + standby = 1; + + if (srb->cmnd[1] & 0x01) + acmd = 1; + + data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] + << 8) | srb->cmnd[9]; + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + } else { + bus_width = SD_BUS_WIDTH_4; + } + RTSX_DEBUGP("bus_width = %d\n", bus_width); +#else + bus_width = SD_BUS_WIDTH_4; +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (data_len <= 512) { + int min_len; + u8 *buf; + u16 byte_cnt, blk_cnt; + u8 cmd[5]; + + byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9]; + blk_cnt = 1; + + cmd[0] = 0x40 | cmd_idx; + cmd[1] = srb->cmnd[3]; + cmd[2] = srb->cmnd[4]; + cmd[3] = srb->cmnd[5]; + cmd[4] = srb->cmnd[6]; + + buf = kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, + blk_cnt, bus_width, buf, data_len, 2000); + if (retval != STATUS_SUCCESS) { + read_err = 1; + kfree(buf); + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + min_len = min(data_len, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, min_len, srb); + + kfree(buf); + } else if (!(data_len & 0x1FF)) { + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, + 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, + 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, + 0xFF, (srb->cmnd[7] & 0xFE) >> 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, + 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, + 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, + srb->cmnd[3]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, + srb->cmnd[4]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, + srb->cmnd[5]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, + srb->cmnd[6]); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), + scsi_bufflen(srb), scsi_sg_count(srb), + DMA_FROM_DEVICE, 10000); + if (retval < 0) { + read_err = 1; + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + } else { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (send_cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) + cmd13_checkbit = 1; + + for (i = 0; i < 3; i++) { + retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, + cmd13_checkbit); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Read_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (read_err) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len, i; + int cmd13_checkbit = 0, write_err = 0; + u8 cmd_idx, rsp_type; + u8 send_cmd12 = 0, standby = 0, acmd = 0; + u32 data_len, arg; +#ifdef SUPPORT_SD_LOCK + int lock_cmd_fail = 0; + u8 sd_lock_state = 0; + u8 lock_cmd_type = 0; +#endif + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) + send_cmd12 = 1; + + if (srb->cmnd[1] & 0x02) + standby = 1; + + if (srb->cmnd[1] & 0x01) + acmd = 1; + + data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] + << 8) | srb->cmnd[9]; + arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | + ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + sd_lock_state = sd_card->sd_lock_status; + sd_lock_state &= SD_LOCKED; + } +#endif + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, + SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, + SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#else + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + if (data_len <= 512) { + u16 i; + u8 *buf; + + buf = kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rtsx_stor_get_xfer_buf(buf, data_len, srb); + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) + lock_cmd_type = buf[0] & 0x0F; +#endif + + if (data_len > 256) { + rtsx_init_cmd(chip); + for (i = 0; i < 256; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + rtsx_init_cmd(chip); + for (i = 256; i < data_len; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } else { + rtsx_init_cmd(chip); + for (i = 0; i < data_len; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + kfree(buf); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, + srb->cmnd[8] & 0x03); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, + srb->cmnd[9]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, + 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, + 0x01); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, 250); + } else if (!(data_len & 0x1FF)) { + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, + 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, + 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, + 0xFF, (srb->cmnd[7] & 0xFE) >> 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, + 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), + scsi_bufflen(srb), scsi_sg_count(srb), + DMA_TO_DEVICE, 10000); + + } else { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (retval < 0) { + write_err = 1; + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (lock_cmd_type == SD_ERASE) { + sd_card->sd_erase_status = SD_UNDER_ERASING; + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); + + rtsx_send_cmd(chip, SD_CARD, 250); + + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("Lock command fail!\n"); + lock_cmd_fail = 1; + } + } +#endif /* SUPPORT_SD_LOCK */ + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (send_cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) + cmd13_checkbit = 1; + + for (i = 0; i < 3; i++) { + retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, + cmd13_checkbit); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (!lock_cmd_fail) { + RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type); + if (lock_cmd_type & SD_CLR_PWD) + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + + if (lock_cmd_type & SD_SET_PWD) + sd_card->sd_lock_status |= SD_PWD_EXIST; + } + + RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", + sd_lock_state, sd_card->sd_lock_status); + if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { + sd_card->sd_lock_notify = 1; + if (sd_lock_state) { + if (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) { + sd_card->sd_lock_status |= ( + SD_UNLOCK_POW_ON | SD_SDR_RST); + if (CHK_SD(sd_card)) { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + } + } + } + } + + if (lock_cmd_fail) { + scsi_set_resid(srb, 0); + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif /* SUPPORT_SD_LOCK */ + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Write_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (write_err) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int count; + u16 data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8]; + + if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { + count = (data_len < 17) ? data_len : 17; + } else { + count = (data_len < 6) ? data_len : 6; + } + rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb); + + RTSX_DEBUGP("Response length: %d\n", data_len); + RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", sd_card->rsp[0], + sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]); + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || + (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) || + (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) || + (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: +#ifdef SUPPORT_SD_LOCK + if (0x64 == srb->cmnd[9]) + sd_card->sd_lock_status |= SD_SDR_RST; +#endif + retval = reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + break; + + case 1: + retval = soft_reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +void sd_cleanup_work(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (sd_card->seq_mode) { + RTSX_DEBUGP("SD: stop transmission\n"); + sd_stop_seq_mode(chip); + sd_card->cleanup_counter = 0; + } +} + +int sd_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0); + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(50); + } + + if (chip->asic_code) { + retval = sd_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT); + } + + return STATUS_SUCCESS; +} + +int release_sd_card(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + RTSX_DEBUGP("release_sd_card\n"); + + chip->card_ready &= ~SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->card_wp &= ~SD_CARD; + + chip->sd_io = 0; + chip->sd_int = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + memset(sd_card->raw_csd, 0, 16); + memset(sd_card->raw_scr, 0, 8); + + retval = sd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h new file mode 100644 index 000000000000..735b2d0f5a78 --- /dev/null +++ b/drivers/staging/rts5208/sd.h @@ -0,0 +1,301 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_SD_H +#define __REALTEK_RTSX_SD_H + +#include "rtsx_chip.h" + +#define SUPPORT_VOLTAGE 0x003C0000 + +/* Error Code */ +#define SD_NO_ERROR 0x0 +#define SD_CRC_ERR 0x80 +#define SD_TO_ERR 0x40 +#define SD_NO_CARD 0x20 +#define SD_BUSY 0x10 +#define SD_STS_ERR 0x08 +#define SD_RSP_TIMEOUT 0x04 +#define SD_IO_ERR 0x02 + +/* Return code for MMC switch bus */ +#define SWITCH_SUCCESS 0 +#define SWITCH_ERR 1 +#define SWITCH_FAIL 2 + +/* MMC/SD Command Index */ +/* Basic command (class 0) */ +#define GO_IDLE_STATE 0 +#define SEND_OP_COND 1 +#define ALL_SEND_CID 2 +#define SET_RELATIVE_ADDR 3 +#define SEND_RELATIVE_ADDR 3 +#define SET_DSR 4 +#define IO_SEND_OP_COND 5 +#define SWITCH 6 +#define SELECT_CARD 7 +#define DESELECT_CARD 7 +/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec + * while is "SEND_IF_COND" for SD 2.0 + */ +#define SEND_EXT_CSD 8 +#define SEND_IF_COND 8 + +#define SEND_CSD 9 +#define SEND_CID 10 +#define VOLTAGE_SWITCH 11 +#define READ_DAT_UTIL_STOP 11 +#define STOP_TRANSMISSION 12 +#define SEND_STATUS 13 +#define GO_INACTIVE_STATE 15 + +#define SET_BLOCKLEN 16 +#define READ_SINGLE_BLOCK 17 +#define READ_MULTIPLE_BLOCK 18 +#define SEND_TUNING_PATTERN 19 + +#define BUSTEST_R 14 +#define BUSTEST_W 19 + +#define WRITE_BLOCK 24 +#define WRITE_MULTIPLE_BLOCK 25 +#define PROGRAM_CSD 27 + +#define ERASE_WR_BLK_START 32 +#define ERASE_WR_BLK_END 33 +#define ERASE_CMD 38 + +#define LOCK_UNLOCK 42 +#define IO_RW_DIRECT 52 + +#define APP_CMD 55 +#define GEN_CMD 56 + +#define SET_BUS_WIDTH 6 +#define SD_STATUS 13 +#define SEND_NUM_WR_BLOCKS 22 +#define SET_WR_BLK_ERASE_COUNT 23 +#define SD_APP_OP_COND 41 +#define SET_CLR_CARD_DETECT 42 +#define SEND_SCR 51 + +#define SD_READ_COMPLETE 0x00 +#define SD_READ_TO 0x01 +#define SD_READ_ADVENCE 0x02 + +#define SD_CHECK_MODE 0x00 +#define SD_SWITCH_MODE 0x80 +#define SD_FUNC_GROUP_1 0x01 +#define SD_FUNC_GROUP_2 0x02 +#define SD_FUNC_GROUP_3 0x03 +#define SD_FUNC_GROUP_4 0x04 +#define SD_CHECK_SPEC_V1_1 0xFF + +#define NO_ARGUMENT 0x00 +#define CHECK_PATTERN 0x000000AA +#define VOLTAGE_SUPPLY_RANGE 0x00000100 +#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 +#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 +#define SUPPORT_1V8 0x01000000 + +#define SWTICH_NO_ERR 0x00 +#define CARD_NOT_EXIST 0x01 +#define SPEC_NOT_SUPPORT 0x02 +#define CHECK_MODE_ERR 0x03 +#define CHECK_NOT_READY 0x04 +#define SWITCH_CRC_ERR 0x05 +#define SWITCH_MODE_ERR 0x06 +#define SWITCH_PASS 0x07 + +#ifdef SUPPORT_SD_LOCK +#define SD_ERASE 0x08 +#define SD_LOCK 0x04 +#define SD_UNLOCK 0x00 +#define SD_CLR_PWD 0x02 +#define SD_SET_PWD 0x01 + +#define SD_PWD_LEN 0x10 + +#define SD_LOCKED 0x80 +#define SD_LOCK_1BIT_MODE 0x40 +#define SD_PWD_EXIST 0x20 +#define SD_UNLOCK_POW_ON 0x01 +#define SD_SDR_RST 0x02 + +#define SD_NOT_ERASE 0x00 +#define SD_UNDER_ERASING 0x01 +#define SD_COMPLETE_ERASE 0x02 + +#define SD_RW_FORBIDDEN 0x0F + +#endif + +#define HS_SUPPORT 0x01 +#define SDR50_SUPPORT 0x02 +#define SDR104_SUPPORT 0x03 +#define DDR50_SUPPORT 0x04 + +#define HS_SUPPORT_MASK 0x02 +#define SDR50_SUPPORT_MASK 0x04 +#define SDR104_SUPPORT_MASK 0x08 +#define DDR50_SUPPORT_MASK 0x10 + +#define HS_QUERY_SWITCH_OK 0x01 +#define SDR50_QUERY_SWITCH_OK 0x02 +#define SDR104_QUERY_SWITCH_OK 0x03 +#define DDR50_QUERY_SWITCH_OK 0x04 + +#define HS_SWITCH_BUSY 0x02 +#define SDR50_SWITCH_BUSY 0x04 +#define SDR104_SWITCH_BUSY 0x08 +#define DDR50_SWITCH_BUSY 0x10 + +#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D +#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 +#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D + +#define DRIVING_TYPE_A 0x01 +#define DRIVING_TYPE_B 0x00 +#define DRIVING_TYPE_C 0x02 +#define DRIVING_TYPE_D 0x03 + +#define DRIVING_TYPE_A_MASK 0x02 +#define DRIVING_TYPE_B_MASK 0x01 +#define DRIVING_TYPE_C_MASK 0x04 +#define DRIVING_TYPE_D_MASK 0x08 + +#define TYPE_A_QUERY_SWITCH_OK 0x01 +#define TYPE_B_QUERY_SWITCH_OK 0x00 +#define TYPE_C_QUERY_SWITCH_OK 0x02 +#define TYPE_D_QUERY_SWITCH_OK 0x03 + +#define TYPE_A_SWITCH_BUSY 0x02 +#define TYPE_B_SWITCH_BUSY 0x01 +#define TYPE_C_SWITCH_BUSY 0x04 +#define TYPE_D_SWITCH_BUSY 0x08 + +#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 +#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 + +#define CURRENT_LIMIT_200 0x00 +#define CURRENT_LIMIT_400 0x01 +#define CURRENT_LIMIT_600 0x02 +#define CURRENT_LIMIT_800 0x03 + +#define CURRENT_LIMIT_200_MASK 0x01 +#define CURRENT_LIMIT_400_MASK 0x02 +#define CURRENT_LIMIT_600_MASK 0x04 +#define CURRENT_LIMIT_800_MASK 0x08 + +#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 +#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 +#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 +#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 + +#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 +#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 +#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 +#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 + +#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 +#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 + +#define DATA_STRUCTURE_VER_OFFSET 0x11 + +#define MAX_PHASE 31 + +#define MMC_8BIT_BUS 0x0010 +#define MMC_4BIT_BUS 0x0020 + +#define MMC_SWITCH_ERR 0x80 + +#define SD_IO_3V3 0 +#define SD_IO_1V8 1 + +#define TUNE_TX 0x00 +#define TUNE_RX 0x01 + +#define CHANGE_TX 0x00 +#define CHANGE_RX 0x01 + +#define DCM_HIGH_FREQUENCY_MODE 0x00 +#define DCM_LOW_FREQUENCY_MODE 0x01 + +#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C +#define DCM_Low_FREQUENCY_MODE_SET 0x00 + +#define MULTIPLY_BY_1 0x00 +#define MULTIPLY_BY_2 0x01 +#define MULTIPLY_BY_3 0x02 +#define MULTIPLY_BY_4 0x03 +#define MULTIPLY_BY_5 0x04 +#define MULTIPLY_BY_6 0x05 +#define MULTIPLY_BY_7 0x06 +#define MULTIPLY_BY_8 0x07 +#define MULTIPLY_BY_9 0x08 +#define MULTIPLY_BY_10 0x09 + +#define DIVIDE_BY_2 0x01 +#define DIVIDE_BY_3 0x02 +#define DIVIDE_BY_4 0x03 +#define DIVIDE_BY_5 0x04 +#define DIVIDE_BY_6 0x05 +#define DIVIDE_BY_7 0x06 +#define DIVIDE_BY_8 0x07 +#define DIVIDE_BY_9 0x08 +#define DIVIDE_BY_10 0x09 + +struct timing_phase_path { + int start; + int end; + int mid; + int len; +}; + +int sd_select_card(struct rtsx_chip *chip, int select); +int sd_pull_ctl_enable(struct rtsx_chip *chip); +int reset_sd_card(struct rtsx_chip *chip); +int sd_switch_clock(struct rtsx_chip *chip); +void sd_stop_seq_mode(struct rtsx_chip *chip); +int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt); +void sd_cleanup_work(struct rtsx_chip *chip); +int sd_power_off_card3v3(struct rtsx_chip *chip); +int release_sd_card(struct rtsx_chip *chip); +#ifdef SUPPORT_CPRM +int soft_reset_sd_card(struct rtsx_chip *chip); +int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check); +int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_SD_H */ diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c new file mode 100644 index 000000000000..312b9f9c6456 --- /dev/null +++ b/drivers/staging/rts5208/spi.c @@ -0,0 +1,877 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "spi.h" + +static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct spi_info *spi = &(chip->spi); + + spi->err_code = err_code; +} + +static int spi_init(struct rtsx_chip *chip) +{ + RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, + CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | + SPI_AUTO); + RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); + + return STATUS_SUCCESS; +} + +static int spi_set_init_para(struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8)); + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div)); + + retval = switch_clock(chip, spi->spi_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = select_card(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); + RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); + + wait_timeout(10); + + retval = spi_init(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sf_polling_status(struct rtsx_chip *chip, int msec) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_POLLING_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, msec); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_BUSY_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sf_enable_write(struct rtsx_chip *chip, u8 ins) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + if (!spi->write_en) + return STATUS_SUCCESS; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_C_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sf_disable_write(struct rtsx_chip *chip, u8 ins) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + if (!spi->write_en) + return STATUS_SUCCESS; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_C_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, + u16 len) +{ + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8)); + if (addr_mode) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, + (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, + (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CADO_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CDO_MODE0); + } + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); +} + +static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + if (addr_mode) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, + (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, + (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CA_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_C_MODE0); + } + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int spi_init_eeprom(struct rtsx_chip *chip) +{ + int retval; + int clk; + + if (chip->asic_code) + clk = 30; + else + clk = CLK_30; + + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); + + retval = switch_clock(chip, clk); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = select_card(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); + RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); + + wait_timeout(10); + + RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, + CS_POLARITY_HIGH | SPI_EEPROM_AUTO); + RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); + + return STATUS_SUCCESS; +} + +static int spi_eeprom_program_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int spi_erase_eeprom_chip(struct rtsx_chip *chip) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + +int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + + +int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) +{ + int retval; + u8 data; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CADI_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(5); + RTSX_READ_REG(chip, SPI_DATA, &data); + + if (val) + *val = data; + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + +int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + + +int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + + RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code); + rtsx_stor_set_xfer_buf(&(spi->err_code), + min_t(int, scsi_bufflen(srb), 1), srb); + scsi_set_resid(srb, scsi_bufflen(srb) - 1); + + return STATUS_SUCCESS; +} + +int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + + spi_set_err_code(chip, SPI_NO_ERR); + + if (chip->asic_code) + spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; + else + spi->spi_clock = srb->cmnd[3]; + + spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + spi->write_en = srb->cmnd[6]; + + RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n", + spi->spi_clock, spi->clk_div, spi->write_en); + + return STATUS_SUCCESS; +} + +int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u16 len; + u8 *buf; + + spi_set_err_code(chip, SPI_NO_ERR); + + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + if (len > 512) { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]); + + if (len == 0) { + if (srb->cmnd[9]) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); + } + } else { + if (srb->cmnd[9]) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CADI_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CDI_MODE0); + } + } + + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (len) { + buf = kmalloc(len, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + retval = rtsx_read_ppbuf(chip, buf, len); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_READ_ERR); + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + scsi_set_resid(srb, 0); + + kfree(buf); + } + + return STATUS_SUCCESS; +} + +int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + unsigned int index = 0, offset = 0; + u8 ins, slow_read; + u32 addr; + u16 len; + u8 *buf; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) + << 8) | srb->cmnd[6]; + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + slow_read = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, STATUS_ERROR); + + while (len) { + u16 pagelen = SF_PAGE_LEN - (u8)addr; + + if (pagelen > len) + pagelen = len; + + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + + if (slow_read) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, + (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, + (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, + (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, + (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, + (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, + (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, + (u8)(pagelen >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, + (u8)pagelen); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CADI_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, + SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, + DMA_FROM_DEVICE, 10000); + if (retval < 0) { + kfree(buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, + TO_XFER_BUF); + + addr += pagelen; + len -= pagelen; + } + + scsi_set_resid(srb, 0); + kfree(buf); + + return STATUS_SUCCESS; +} + +int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, program_mode; + u32 addr; + u16 len; + u8 *buf; + unsigned int index = 0, offset = 0; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) + << 8) | srb->cmnd[6]; + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + program_mode = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (program_mode == BYTE_PROGRAM) { + buf = kmalloc(4, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + while (len) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, + FROM_XFER_BUF); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, + buf[0]); + sf_program(chip, ins, 1, addr, 1); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + kfree(buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + addr++; + len--; + } + + kfree(buf); + + } else if (program_mode == AAI_PROGRAM) { + int first_byte = 1; + + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + buf = kmalloc(4, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + while (len) { + rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, + FROM_XFER_BUF); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, + buf[0]); + if (first_byte) { + sf_program(chip, ins, 1, addr, 1); + first_byte = 0; + } else { + sf_program(chip, ins, 0, 0, 1); + } + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + kfree(buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + len--; + } + + kfree(buf); + + retval = sf_disable_write(chip, SPI_WRDI); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else if (program_mode == PAGE_PROGRAM) { + buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + while (len) { + u16 pagelen = SF_PAGE_LEN - (u8)addr; + + if (pagelen > len) + pagelen = len; + + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256); + sf_program(chip, ins, 1, addr, pagelen); + + rtsx_send_cmd_no_wait(chip); + + rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, + &offset, FROM_XFER_BUF); + + retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, + DMA_TO_DEVICE, 100); + if (retval < 0) { + kfree(buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + addr += pagelen; + len -= pagelen; + } + + kfree(buf); + } else { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, erase_mode; + u32 addr; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) + << 8) | srb->cmnd[6]; + erase_mode = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (erase_mode == PAGE_ERASE) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sf_erase(chip, ins, 1, addr); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else if (erase_mode == CHIP_ERASE) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = sf_erase(chip, ins, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, status, ewsr; + + ins = srb->cmnd[3]; + status = srb->cmnd[4]; + ewsr = srb->cmnd[5]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_enable_write(chip, ewsr); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, + SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, + SPI_TRANSFER0_START | SPI_CDO_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, + SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5208/spi.h b/drivers/staging/rts5208/spi.h new file mode 100644 index 000000000000..fc824b5d8d59 --- /dev/null +++ b/drivers/staging/rts5208/spi.h @@ -0,0 +1,65 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_SPI_H +#define __REALTEK_RTSX_SPI_H + +/* SPI operation error */ +#define SPI_NO_ERR 0x00 +#define SPI_HW_ERR 0x01 +#define SPI_INVALID_COMMAND 0x02 +#define SPI_READ_ERR 0x03 +#define SPI_WRITE_ERR 0x04 +#define SPI_ERASE_ERR 0x05 +#define SPI_BUSY_ERR 0x06 + +/* Serial flash instruction */ +#define SPI_READ 0x03 +#define SPI_FAST_READ 0x0B +#define SPI_WREN 0x06 +#define SPI_WRDI 0x04 +#define SPI_RDSR 0x05 + +#define SF_PAGE_LEN 256 + +#define BYTE_PROGRAM 0 +#define AAI_PROGRAM 1 +#define PAGE_PROGRAM 2 + +#define PAGE_ERASE 0 +#define CHIP_ERASE 1 + +int spi_erase_eeprom_chip(struct rtsx_chip *chip); +int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr); +int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val); +int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val); +int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); + + +#endif /* __REALTEK_RTSX_SPI_H */ diff --git a/drivers/staging/rts5208/trace.h b/drivers/staging/rts5208/trace.h new file mode 100644 index 000000000000..0f177fbaaf1f --- /dev/null +++ b/drivers/staging/rts5208/trace.h @@ -0,0 +1,93 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_TRACE_H +#define __REALTEK_RTSX_TRACE_H + +#define _MSG_TRACE + +#ifdef _MSG_TRACE +static inline char *filename(char *path) +{ + char *ptr; + + if (path == NULL) + return NULL; + + ptr = path; + + while (*ptr != '\0') { + if ((*ptr == '\\') || (*ptr == '/')) + path = ptr + 1; + + ptr++; + } + + return path; +} + +#define TRACE_RET(chip, ret) \ + do { \ + char *_file = filename(__FILE__); \ + RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + return ret; \ + } while (0) + +#define TRACE_GOTO(chip, label) \ + do { \ + char *_file = filename(__FILE__); \ + RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + goto label; \ + } while (0) +#else +#define TRACE_RET(chip, ret) return ret +#define TRACE_GOTO(chip, label) goto label +#endif + +#ifdef CONFIG_RTS5208_DEBUG +#define RTSX_DUMP(buf, buf_len) \ + print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \ + 16, 1, (buf), (buf_len), false) +#else +#define RTSX_DUMP(buf, buf_len) +#endif + +#endif /* __REALTEK_RTSX_TRACE_H */ diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c new file mode 100644 index 000000000000..6aef53d14e31 --- /dev/null +++ b/drivers/staging/rts5208/xd.c @@ -0,0 +1,2088 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/vmalloc.h> + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "xd.h" + +static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no); +static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, + u8 start_page, u8 end_page); + +static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + xd_card->err_code = err_code; +} + +static inline int xd_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + return (xd_card->err_code == err_code); +} + +static int xd_set_init_para(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + if (chip->asic_code) + xd_card->xd_clock = 47; + else + xd_card->xd_clock = CLK_50; + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int xd_switch_clock(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + retval = select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) +{ + int retval, i; + u8 *ptr; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_ID); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + for (i = 0; i < 4; i++) + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 20); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + ptr = rtsx_get_cmd_data(chip) + 1; + if (id_buf && buf_len) { + if (buf_len > 4) + buf_len = 4; + memcpy(id_buf, ptr, buf_len); + } + + return STATUS_SUCCESS; +} + +static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode) +{ + struct xd_info *xd_card = &(chip->xd_card); + + switch (mode) { + case XD_RW_ADDR: + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, + 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, + 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + xd_card->addr_cycle | XD_CALC_ECC | XD_BA_NO_TRANSFORM); + break; + + case XD_ERASE_ADDR: + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, + 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, + 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + (xd_card->addr_cycle - 1) | XD_CALC_ECC | + XD_BA_NO_TRANSFORM); + break; + + default: + break; + } +} + +static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, + u8 *buf, int buf_len) +{ + int retval, i; + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, + 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + for (i = 0; i < 6; i++) + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), + 0, 0); + for (i = 0; i < 4; i++) + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), + 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + if (buf && buf_len) { + u8 *ptr = rtsx_get_cmd_data(chip) + 1; + + if (buf_len > 11) + buf_len = 11; + memcpy(buf, ptr, buf_len); + } + + return STATUS_SUCCESS; +} + +static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, + u8 *buf, int buf_len) +{ + int retval, i; + + if (!buf || (buf_len < 0)) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + for (i = 0; i < buf_len; i++) + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, + 0, 0); + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(buf, rtsx_get_cmd_data(chip), buf_len); + + return STATUS_SUCCESS; +} + +static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, + int buf_len) +{ + int retval; + u8 reg; + + if (!buf || (buf_len < 10)) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 250); + if (retval == -ETIMEDOUT) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, XD_PAGE_STATUS, ®); + if (reg != XD_GPG) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, XD_CTL, ®); + if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { + retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + if (reg & XD_ECC1_ERROR) { + u8 ecc_bit, ecc_byte; + + RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit); + RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte); + + RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", + ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTSX_DEBUGP("Before correct: 0x%x\n", + buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTSX_DEBUGP("After correct: 0x%x\n", + buf[ecc_byte]); + } + } + } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { + rtsx_clear_xd_error(chip); + + retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + if (reg & XD_ECC2_ERROR) { + u8 ecc_bit, ecc_byte; + + RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit); + RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte); + + RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", + ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTSX_DEBUGP("Before correct: 0x%x\n", + buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTSX_DEBUGP("After correct: 0x%x\n", + buf[ecc_byte]); + } + } + } else { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, + 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, + 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, + 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, + 0xFF, 0x69); + } + } +} + +static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip) +{ + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + } +} + +static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, + 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, + 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, + 0xFF, 0x53); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, + 0xFF, 0xA9); + } + } +} + +static int xd_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +static int reset_xd(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, i, j; + u8 *ptr, id_buf[4], redunt[11]; + + retval = select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, + XD_PGSTS_NOT_FF); + if (chip->asic_code) { + if (!CHECK_PID(chip, 0x5288)) + xd_fill_pull_ctl_disable(chip); + else + xd_fill_pull_ctl_stage1_barossa(chip); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20); + } + + if (!chip->ft2_fast_mode) + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, + XD_NO_AUTO_PWR_OFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(250); + + rtsx_init_cmd(chip); + + if (chip->asic_code) { + xd_fill_pull_ctl_enable(chip); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | + 0x20); + } + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + retval = card_power_on(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + +#ifdef SUPPORT_OCP + wait_timeout(50); + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + rtsx_init_cmd(chip); + + if (chip->ft2_fast_mode) { + if (chip->asic_code) { + xd_fill_pull_ctl_enable(chip); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | + 0x20); + } + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->ft2_fast_mode) + wait_timeout(200); + + retval = xd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + /* Read ID to check if the timing setting is right */ + for (i = 0; i < 4; i++) { + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + + XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) + + XD_TIME_RWN_STEP * (3 + i)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_RESET); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + ptr = rtsx_get_cmd_data(chip) + 1; + + RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]); + + if (((ptr[0] & READY_FLAG) != READY_STATE) || + !(ptr[1] & XD_RDY)) + continue; + + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + + xd_card->device_code = id_buf[1]; + + /* Check if the xD card is supported */ + switch (xd_card->device_code) { + case XD_4M_X8_512_1: + case XD_4M_X8_512_2: + xd_card->block_shift = 4; + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 8000; + XD_SET_4MB(xd_card); + break; + case XD_8M_X8_512: + xd_card->block_shift = 4; + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 16000; + break; + case XD_16M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 32000; + break; + case XD_32M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 2; + xd_card->capacity = 64000; + break; + case XD_64M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 4; + xd_card->capacity = 128000; + break; + case XD_128M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 8; + xd_card->capacity = 256000; + break; + case XD_256M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 16; + xd_card->capacity = 512000; + break; + case XD_512M_X8: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 32; + xd_card->capacity = 1024000; + break; + case xD_1G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 64; + xd_card->capacity = 2048000; + break; + case xD_2G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 128; + xd_card->capacity = 4096000; + break; + default: + continue; + } + + /* Confirm timing setting */ + for (j = 0; j < 10; j++) { + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (id_buf[1] != xd_card->device_code) + break; + } + + if (j == 10) + break; + } + + if (i == 4) { + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + if (id_buf[2] != XD_ID_CODE) + TRACE_RET(chip, STATUS_FAIL); + + /* Search CIS block */ + for (i = 0; i < 24; i++) { + u32 page_addr; + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + page_addr = (u32)i << xd_card->block_shift; + + for (j = 0; j < 3; j++) { + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval == STATUS_SUCCESS) + break; + } + if (j == 3) + continue; + + if (redunt[BLOCK_STATUS] != XD_GBLK) + continue; + + j = 0; + if (redunt[PAGE_STATUS] != XD_GPG) { + for (j = 1; j <= 8; j++) { + retval = xd_read_redundant(chip, page_addr + j, + redunt, 11); + if (retval == STATUS_SUCCESS) { + if (redunt[PAGE_STATUS] == XD_GPG) + break; + } + } + + if (j == 9) + break; + } + + /* Check CIS data */ + if ((redunt[BLOCK_STATUS] == XD_GBLK) && + (redunt[PARITY] & XD_BA1_ALL0)) { + u8 buf[10]; + + page_addr += j; + + retval = xd_read_cis(chip, page_addr, buf, 10); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if ((buf[0] == 0x01) && (buf[1] == 0x03) && + (buf[2] == 0xD9) + && (buf[3] == 0x01) && (buf[4] == 0xFF) + && (buf[5] == 0x18) && (buf[6] == 0x02) + && (buf[7] == 0xDF) && (buf[8] == 0x01) + && (buf[9] == 0x20)) { + xd_card->cis_block = (u16)i; + } + } + + break; + } + + RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); + if (xd_card->cis_block == 0xFFFF) + TRACE_RET(chip, STATUS_FAIL); + + chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; + + return STATUS_SUCCESS; +} + +static int xd_check_data_blank(u8 *redunt) +{ + int i; + + for (i = 0; i < 6; i++) { + if (redunt[PAGE_STATUS + i] != 0xFF) + return 0; + } + + if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) + != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) + return 0; + + + for (i = 0; i < 4; i++) { + if (redunt[RESERVED0 + i] != 0xFF) + return 0; + } + + return 1; +} + +static u16 xd_load_log_block_addr(u8 *redunt) +{ + u16 addr = 0xFFFF; + + if (redunt[PARITY] & XD_BA1_BA2_EQL) + addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | + redunt[BLOCK_ADDR1_L]; + else if (redunt[PARITY] & XD_BA1_VALID) + addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | + redunt[BLOCK_ADDR1_L]; + else if (redunt[PARITY] & XD_BA2_VALID) + addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | + redunt[BLOCK_ADDR2_L]; + + return addr; +} + +static int xd_init_l2p_tbl(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int size, i; + + RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); + + if (xd_card->zone_cnt < 1) + TRACE_RET(chip, STATUS_FAIL); + + size = xd_card->zone_cnt * sizeof(struct zone_entry); + RTSX_DEBUGP("Buffer size for l2p table is %d\n", size); + + xd_card->zone = vmalloc(size); + if (!xd_card->zone) + TRACE_RET(chip, STATUS_ERROR); + + for (i = 0; i < xd_card->zone_cnt; i++) { + xd_card->zone[i].build_flag = 0; + xd_card->zone[i].l2p_table = NULL; + xd_card->zone[i].free_table = NULL; + xd_card->zone[i].get_index = 0; + xd_card->zone[i].set_index = 0; + xd_card->zone[i].unused_blk_cnt = 0; + } + + return STATUS_SUCCESS; +} + +static inline void free_zone(struct zone_entry *zone) +{ + RTSX_DEBUGP("free_zone\n"); + + if (!zone) + return; + + zone->build_flag = 0; + zone->set_index = 0; + zone->get_index = 0; + zone->unused_blk_cnt = 0; + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } +} + +static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int zone_no; + + zone_no = (int)phy_blk >> 10; + if (zone_no >= xd_card->zone_cnt) { + RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + return; + } + zone = &(xd_card->zone[zone_no]); + + if (zone->free_table == NULL) { + if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) + return; + } + + if ((zone->set_index >= XD_FREE_TABLE_CNT) + || (zone->set_index < 0)) { + free_zone(zone); + RTSX_DEBUGP("Set unused block fail, invalid set_index\n"); + return; + } + + RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index); + + zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff); + if (zone->set_index >= XD_FREE_TABLE_CNT) + zone->set_index = 0; + zone->unused_blk_cnt++; +} + +static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + u32 phy_blk; + + if (zone_no >= xd_card->zone_cnt) { + RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + return BLK_NOT_FOUND; + } + zone = &(xd_card->zone[zone_no]); + + if ((zone->unused_blk_cnt == 0) || + (zone->set_index == zone->get_index)) { + free_zone(zone); + RTSX_DEBUGP("Get unused block fail, no unused block available\n"); + return BLK_NOT_FOUND; + } + if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) { + free_zone(zone); + RTSX_DEBUGP("Get unused block fail, invalid get_index\n"); + return BLK_NOT_FOUND; + } + + RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index); + + phy_blk = zone->free_table[zone->get_index]; + zone->free_table[zone->get_index++] = 0xFFFF; + if (zone->get_index >= XD_FREE_TABLE_CNT) + zone->get_index = 0; + zone->unused_blk_cnt--; + + phy_blk += ((u32)(zone_no) << 10); + return phy_blk; +} + +static void xd_set_l2p_tbl(struct rtsx_chip *chip, + int zone_no, u16 log_off, u16 phy_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + + zone = &(xd_card->zone[zone_no]); + zone->l2p_table[log_off] = phy_off; +} + +static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + + zone = &(xd_card->zone[zone_no]); + if (zone->l2p_table[log_off] == 0xFFFF) { + u32 phy_blk = 0; + int i; + +#ifdef XD_DELAY_WRITE + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n"); + return BLK_NOT_FOUND; + } +#endif + + if (zone->unused_blk_cnt <= 0) { + RTSX_DEBUGP("No unused block!\n"); + return BLK_NOT_FOUND; + } + + for (i = 0; i < zone->unused_blk_cnt; i++) { + phy_blk = xd_get_unused_block(chip, zone_no); + if (phy_blk == BLK_NOT_FOUND) { + RTSX_DEBUGP("No unused block available!\n"); + return BLK_NOT_FOUND; + } + + retval = xd_init_page(chip, phy_blk, log_off, + 0, xd_card->page_off + 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i >= zone->unused_blk_cnt) { + RTSX_DEBUGP("No good unused block available!\n"); + return BLK_NOT_FOUND; + } + + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF)); + return phy_blk; + } + + return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10); +} + +int reset_xd_card(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + memset(xd_card, 0, sizeof(struct xd_info)); + + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + xd_card->zone_cnt = 0; + xd_card->cis_block = 0xFFFF; + xd_card->delay_write.delay_write_flag = 0; + + retval = enable_card_clock(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = reset_xd(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk); + + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); + + page_addr = phy_blk << xd_card->block_shift; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, + xd_card->page_off + 1); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) + xd_set_err_code(chip, XD_PRG_ERROR); + else + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, + u16 logoff, u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTSX_DEBUGP("Init block 0x%x\n", phy_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, + 0xFF, (u8)(logoff >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff); + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, + XD_BA_TRANSFORM, XD_BA_TRANSFORM); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, + 0xFF, (end_page - start_page)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, + 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, + u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 old_page, new_page; + u8 i, reg = 0; + int retval; + + RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n", + old_blk, new_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) + TRACE_RET(chip, STATUS_FAIL); + + old_page = (old_blk << xd_card->block_shift) + start_page; + new_page = (new_blk << xd_card->block_shift) + start_page; + + XD_CLR_BAD_NEWBLK(xd_card); + + RTSX_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + rtsx_clear_xd_error(chip); + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + reg = 0; + rtsx_read_register(chip, XD_CTL, ®); + if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { + wait_timeout(100); + + if (detect_card_cd(chip, + XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) == + (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) == + (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + rtsx_write_register(chip, + XD_PAGE_STATUS, 0xFF, + XD_BPG); + rtsx_write_register(chip, + XD_BLOCK_STATUS, 0xFF, + XD_GBLK); + XD_SET_BAD_OLDBLK(xd_card); + RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk); + } + } else { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (XD_CHK_BAD_OLDBLK(xd_card)) + rtsx_clear_xd_error(chip); + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 300); + if (retval < 0) { + rtsx_clear_xd_error(chip); + reg = 0; + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, new_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + XD_SET_BAD_NEWBLK(xd_card); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + old_page++; + new_page++; + } + + return STATUS_SUCCESS; +} + +static int xd_reset_cmd(struct rtsx_chip *chip) +{ + int retval; + u8 *ptr; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, + 0xFF, XD_TRANSFER_START | XD_RESET); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + ptr = rtsx_get_cmd_data(chip) + 1; + if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) + return STATUS_SUCCESS; + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + u8 reg = 0, *ptr; + int i, retval; + + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + page_addr = phy_blk << xd_card->block_shift; + + for (i = 0; i < 3; i++) { + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_ERASE); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 250); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + xd_set_err_code(chip, XD_ERASE_FAIL); + } + retval = xd_reset_cmd(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + continue; + } + + ptr = rtsx_get_cmd_data(chip) + 1; + if (*ptr & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; + } + + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_ERASE_FAIL); + TRACE_RET(chip, STATUS_FAIL); +} + + +static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + u32 start, end, i; + u16 max_logoff, cur_fst_page_logoff; + u16 cur_lst_page_logoff, ent_lst_page_logoff; + u8 redunt[11]; + + RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no); + + if (xd_card->zone == NULL) { + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + return retval; + } + + if (xd_card->zone[zone_no].build_flag) { + RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no); + return STATUS_SUCCESS; + } + + zone = &(xd_card->zone[zone_no]); + + if (zone->l2p_table == NULL) { + zone->l2p_table = vmalloc(2000); + if (zone->l2p_table == NULL) + TRACE_GOTO(chip, Build_Fail); + } + memset((u8 *)(zone->l2p_table), 0xff, 2000); + + if (zone->free_table == NULL) { + zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2); + if (zone->free_table == NULL) + TRACE_GOTO(chip, Build_Fail); + } + memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); + + if (zone_no == 0) { + if (xd_card->cis_block == 0xFFFF) + start = 0; + else + start = xd_card->cis_block + 1; + if (XD_CHK_4MB(xd_card)) { + end = 0x200; + max_logoff = 499; + } else { + end = 0x400; + max_logoff = 999; + } + } else { + start = (u32)(zone_no) << 10; + end = (u32)(zone_no + 1) << 10; + max_logoff = 999; + } + + RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end); + + zone->set_index = zone->get_index = 0; + zone->unused_blk_cnt = 0; + + for (i = start; i < end; i++) { + u32 page_addr = i << xd_card->block_shift; + u32 phy_block; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) + continue; + + if (redunt[BLOCK_STATUS] != 0xFF) { + RTSX_DEBUGP("bad block\n"); + continue; + } + + if (xd_check_data_blank(redunt)) { + RTSX_DEBUGP("blank block\n"); + xd_set_unused_block(chip, i); + continue; + } + + cur_fst_page_logoff = xd_load_log_block_addr(redunt); + if ((cur_fst_page_logoff == 0xFFFF) || + (cur_fst_page_logoff > max_logoff)) { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + continue; + } + + if ((zone_no == 0) && (cur_fst_page_logoff == 0) && + (redunt[PAGE_STATUS] != XD_GPG)) + XD_SET_MBR_FAIL(xd_card); + + if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { + zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); + continue; + } + + phy_block = zone->l2p_table[cur_fst_page_logoff] + + ((u32)((zone_no) << 10)); + + page_addr = ((i + 1) << xd_card->block_shift) - 1; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) + continue; + + cur_lst_page_logoff = xd_load_log_block_addr(redunt); + if (cur_lst_page_logoff == cur_fst_page_logoff) { + int m; + + page_addr = ((phy_block + 1) << + xd_card->block_shift) - 1; + + for (m = 0; m < 3; m++) { + retval = xd_read_redundant(chip, page_addr, + redunt, 11); + if (retval == STATUS_SUCCESS) + break; + } + + if (m == 3) { + zone->l2p_table[cur_fst_page_logoff] = + (u16)(i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, phy_block); + continue; + } + + ent_lst_page_logoff = xd_load_log_block_addr(redunt); + if (ent_lst_page_logoff != cur_fst_page_logoff) { + zone->l2p_table[cur_fst_page_logoff] = + (u16)(i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, phy_block); + continue; + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + } + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + } + } + + if (XD_CHK_4MB(xd_card)) + end = 500; + else + end = 1000; + + i = 0; + for (start = 0; start < end; start++) { + if (zone->l2p_table[start] == 0xFFFF) + i++; + } + + RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); + RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt); + + if ((zone->unused_blk_cnt - i) < 1) + chip->card_wp |= XD_CARD; + + zone->build_flag = 1; + + return STATUS_SUCCESS; + +Build_Fail: + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } + + return STATUS_FAIL; +} + +static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_SET_CMD); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 200); + if (retval < 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, + u32 log_blk, u8 start_page, u8 end_page, + u8 *buf, unsigned int *index, + unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr, new_blk; + u16 log_off; + u8 reg_val, page_cnt; + int zone_no, retval, i; + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if ((phy_blk & 0x3FF) == 0x3FF) { + for (i = 0; i < 256; i++) { + page_addr = ((u32)i) << xd_card->block_shift; + + retval = xd_read_redundant(chip, page_addr, NULL, 0); + if (retval == STATUS_SUCCESS) + break; + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + trans_dma_enable(chip->srb->sc_data_direction, chip, + page_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, + scsi_sg_count(chip->srb), + index, offset, DMA_FROM_DEVICE, + chip->xd_timeout); + if (retval < 0) { + rtsx_clear_xd_error(chip); + + if (retval == -ETIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_GOTO(chip, Fail); + } + } + + return STATUS_SUCCESS; + +Fail: + RTSX_READ_REG(chip, XD_PAGE_STATUS, ®_val); + + if (reg_val != XD_GPG) + xd_set_err_code(chip, XD_PRG_ERROR); + + RTSX_READ_REG(chip, XD_CTL, ®_val); + + if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) + == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + wait_timeout(100); + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + xd_set_err_code(chip, XD_ECC_ERROR); + + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == NO_NEW_BLK) { + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_copy_page(chip, phy_blk, new_blk, 0, + xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + } else { + XD_CLR_BAD_NEWBLK(xd_card); + } + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + xd_erase_block(chip, phy_blk); + xd_mark_bad_block(chip, phy_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_finish_write(struct rtsx_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, zone_no; + u16 log_off; + + RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", + old_blk, new_blk, log_blk); + + if (page_off > xd_card->page_off) + TRACE_RET(chip, STATUS_FAIL); + + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (old_blk == BLK_NOT_FOUND) { + retval = xd_init_page(chip, new_blk, log_off, + page_off, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = xd_copy_page(chip, old_blk, new_blk, + page_off, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + } + XD_CLR_BAD_NEWBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + + return STATUS_SUCCESS; +} + +static int xd_prepare_write(struct rtsx_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + int retval; + + RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n", + __func__, old_blk, new_blk, log_blk, (int)page_off); + + if (page_off) { + retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, + u32 new_blk, u32 log_blk, u8 start_page, + u8 end_page, u8 *buf, unsigned int *index, + unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + int zone_no, retval; + u16 log_off; + u8 page_cnt, reg_val; + + RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", + __func__, old_blk, new_blk, log_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + page_addr = (new_blk << xd_card->block_shift) + start_page; + + retval = xd_send_cmd(chip, READ1_1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, + 0xFF, (u8)(log_off >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, + XD_BA_TRANSFORM); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + trans_dma_enable(chip->srb->sc_data_direction, chip, + page_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, + 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, + scsi_sg_count(chip->srb), + index, offset, DMA_TO_DEVICE, chip->xd_timeout); + if (retval < 0) { + rtsx_clear_xd_error(chip); + + if (retval == -ETIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_GOTO(chip, Fail); + } + } + + if (end_page == (xd_card->page_off + 1)) { + xd_card->delay_write.delay_write_flag = 0; + + if (old_blk != BLK_NOT_FOUND) { + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + } + + return STATUS_SUCCESS; + +Fail: + RTSX_READ_REG(chip, XD_DAT, ®_val); + if (reg_val & PROGRAM_ERROR) { + xd_set_err_code(chip, XD_PRG_ERROR); + xd_mark_bad_block(chip, new_blk); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +#ifdef XD_DELAY_WRITE +int xd_delay_write(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + RTSX_DEBUGP("xd_delay_write\n"); + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + delay_write->delay_write_flag = 0; + retval = xd_finish_write(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->logblock, delay_write->pageoff); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt) +{ + struct xd_info *xd_card = &(chip->xd_card); + unsigned int lun = SCSI_LUN(srb); +#ifdef XD_DELAY_WRITE + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); +#endif + int retval, zone_no; + unsigned int index = 0, offset = 0; + u32 log_blk, old_blk = 0, new_blk = 0; + u16 log_off, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *ptr; + + xd_set_err_code(chip, XD_NO_ERROR); + + xd_card->cleanup_counter = 0; + + RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb)); + + ptr = (u8 *)scsi_sglist(srb); + + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + log_blk = start_sector >> xd_card->block_shift; + start_page = (u8)start_sector & xd_card->page_off; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { +#ifdef XD_DELAY_WRITE + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + if (delay_write->old_phyblock != BLK_NOT_FOUND) { + retval = xd_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->pageoff, start_page); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + new_blk = xd_get_unused_block(chip, zone_no); + if ((old_blk == BLK_NOT_FOUND) || + (new_blk == BLK_NOT_FOUND)) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_prepare_write(chip, old_blk, new_blk, + log_blk, start_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != + STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef XD_DELAY_WRITE + } +#endif + } else { +#ifdef XD_DELAY_WRITE + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("old_blk = 0x%x\n", old_blk); + + while (total_sec_cnt) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) + end_page = xd_card->page_off + 1; + else + end_page = start_page + (u8)total_sec_cnt; + + page_cnt = end_page - start_page; + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + retval = xd_read_multiple_pages(chip, old_blk, log_blk, + start_page, end_page, ptr, + &index, &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = xd_write_multiple_pages(chip, old_blk, + new_blk, log_blk, + start_page, end_page, ptr, + &index, &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + total_sec_cnt -= page_cnt; + if (scsi_sg_count(srb) == 0) + ptr += page_cnt * 512; + + if (total_sec_cnt == 0) + break; + + log_blk++; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + start_page = 0; + } + + if ((srb->sc_data_direction == DMA_TO_DEVICE) && + (end_page != (xd_card->page_off + 1))) { +#ifdef XD_DELAY_WRITE + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; +#else + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_finish_write(chip, old_blk, new_blk, + log_blk, end_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +void xd_free_l2p_tbl(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int i = 0; + + if (xd_card->zone != NULL) { + for (i = 0; i < xd_card->zone_cnt; i++) { + if (xd_card->zone[i].l2p_table != NULL) { + vfree(xd_card->zone[i].l2p_table); + xd_card->zone[i].l2p_table = NULL; + } + if (xd_card->zone[i].free_table != NULL) { + vfree(xd_card->zone[i].free_table); + xd_card->zone[i].free_table = NULL; + } + } + vfree(xd_card->zone); + xd_card->zone = NULL; + } +} + +void xd_cleanup_work(struct rtsx_chip *chip) +{ +#ifdef XD_DELAY_WRITE + struct xd_info *xd_card = &(chip->xd_card); + + if (xd_card->delay_write.delay_write_flag) { + RTSX_DEBUGP("xD: delay write\n"); + xd_delay_write(chip); + xd_card->cleanup_counter = 0; + } +#endif +} + +int xd_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0); + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + wait_timeout(50); + } + + if (chip->asic_code) { + retval = xd_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF); + } + + return STATUS_SUCCESS; +} + +int release_xd_card(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + RTSX_DEBUGP("release_xd_card\n"); + + chip->card_ready &= ~XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->card_wp &= ~XD_CARD; + + xd_card->delay_write.delay_write_flag = 0; + + xd_free_l2p_tbl(chip); + + retval = xd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5208/xd.h b/drivers/staging/rts5208/xd.h new file mode 100644 index 000000000000..938138c50bb5 --- /dev/null +++ b/drivers/staging/rts5208/xd.h @@ -0,0 +1,188 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * Wei WANG (wei_wang@realsil.com.cn) + * Micky Ching (micky_ching@realsil.com.cn) + */ + +#ifndef __REALTEK_RTSX_XD_H +#define __REALTEK_RTSX_XD_H + +#define XD_DELAY_WRITE + +/* Error Codes */ +#define XD_NO_ERROR 0x00 +#define XD_NO_MEMORY 0x80 +#define XD_PRG_ERROR 0x40 +#define XD_NO_CARD 0x20 +#define XD_READ_FAIL 0x10 +#define XD_ERASE_FAIL 0x08 +#define XD_WRITE_FAIL 0x04 +#define XD_ECC_ERROR 0x02 +#define XD_TO_ERROR 0x01 + +/* XD Commands */ +#define READ1_1 0x00 +#define READ1_2 0x01 +#define READ2 0x50 +#define READ_ID 0x90 +#define RESET 0xff +#define PAGE_PRG_1 0x80 +#define PAGE_PRG_2 0x10 +#define BLK_ERASE_1 0x60 +#define BLK_ERASE_2 0xD0 +#define READ_STS 0x70 +#define READ_xD_ID 0x9A +#define COPY_BACK_512 0x8A +#define COPY_BACK_2K 0x85 +#define READ1_1_2 0x30 +#define READ1_1_3 0x35 +#define CHG_DAT_OUT_1 0x05 +#define RDM_DAT_OUT_1 0x05 +#define CHG_DAT_OUT_2 0xE0 +#define RDM_DAT_OUT_2 0xE0 +#define CHG_DAT_OUT_2 0xE0 +#define CHG_DAT_IN_1 0x85 +#define CACHE_PRG 0x15 + +/* Redundant Area Related */ +#define XD_EXTRA_SIZE 0x10 +#define XD_2K_EXTRA_SIZE 0x40 + +#define NOT_WRITE_PROTECTED 0x80 +#define READY_STATE 0x40 +#define PROGRAM_ERROR 0x01 +#define PROGRAM_ERROR_N_1 0x02 +#define INTERNAL_READY 0x20 +#define READY_FLAG 0x5F + +#define XD_8M_X8_512 0xE6 +#define XD_16M_X8_512 0x73 +#define XD_32M_X8_512 0x75 +#define XD_64M_X8_512 0x76 +#define XD_128M_X8_512 0x79 +#define XD_256M_X8_512 0x71 +#define XD_128M_X8_2048 0xF1 +#define XD_256M_X8_2048 0xDA +#define XD_512M_X8 0xDC +#define XD_128M_X16_2048 0xC1 +#define XD_4M_X8_512_1 0xE3 +#define XD_4M_X8_512_2 0xE5 +#define xD_1G_X8_512 0xD3 +#define xD_2G_X8_512 0xD5 + +#define XD_ID_CODE 0xB5 + +#define VENDOR_BLOCK 0xEFFF +#define CIS_BLOCK 0xDFFF + +#define BLK_NOT_FOUND 0xFFFFFFFF + +#define NO_NEW_BLK 0xFFFFFFFF + +#define PAGE_CORRECTABLE 0x0 +#define PAGE_NOTCORRECTABLE 0x1 + +#define NO_OFFSET 0x0 +#define WITH_OFFSET 0x1 + +#define Sect_Per_Page 4 +#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A + +#define ZONE0_BAD_BLOCK 23 +#define NOT_ZONE0_BAD_BLOCK 24 + +#define XD_RW_ADDR 0x01 +#define XD_ERASE_ADDR 0x02 + +#define XD_PAGE_512(xd_card) \ +do { \ + (xd_card)->block_shift = 5; \ + (xd_card)->page_off = 0x1F; \ +} while (0) + +#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) +#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) +#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) + +#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) +#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) +#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) + +#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) +#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) +#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) + +#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) +#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) +#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) + +#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) +#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) +#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) + +#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) +#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) +#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) + +#define PAGE_STATUS 0 +#define BLOCK_STATUS 1 +#define BLOCK_ADDR1_L 2 +#define BLOCK_ADDR1_H 3 +#define BLOCK_ADDR2_L 4 +#define BLOCK_ADDR2_H 5 +#define RESERVED0 6 +#define RESERVED1 7 +#define RESERVED2 8 +#define RESERVED3 9 +#define PARITY 10 + +#define CIS0_0 0 +#define CIS0_1 1 +#define CIS0_2 2 +#define CIS0_3 3 +#define CIS0_4 4 +#define CIS0_5 5 +#define CIS0_6 6 +#define CIS0_7 7 +#define CIS0_8 8 +#define CIS0_9 9 +#define CIS1_0 256 +#define CIS1_1 (256 + 1) +#define CIS1_2 (256 + 2) +#define CIS1_3 (256 + 3) +#define CIS1_4 (256 + 4) +#define CIS1_5 (256 + 5) +#define CIS1_6 (256 + 6) +#define CIS1_7 (256 + 7) +#define CIS1_8 (256 + 8) +#define CIS1_9 (256 + 9) + +int reset_xd_card(struct rtsx_chip *chip); +#ifdef XD_DELAY_WRITE +int xd_delay_write(struct rtsx_chip *chip); +#endif +int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, + u32 start_sector, u16 sector_cnt); +void xd_free_l2p_tbl(struct rtsx_chip *chip); +void xd_cleanup_work(struct rtsx_chip *chip); +int xd_power_off_card3v3(struct rtsx_chip *chip); +int release_xd_card(struct rtsx_chip *chip); + +#endif /* __REALTEK_RTSX_XD_H */ diff --git a/drivers/staging/sb105x/sb_mp_register.h b/drivers/staging/sb105x/sb_mp_register.h index 16de497415ee..276c1bbcc18d 100644 --- a/drivers/staging/sb105x/sb_mp_register.h +++ b/drivers/staging/sb105x/sb_mp_register.h @@ -116,10 +116,10 @@ #define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */ #define SB105X_FCR_DMS 0x08 /* DMA Mode Select */ -#define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */ -#define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */ -#define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */ -#define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */ +#define SB105X_FCR_RTR08 0x00 /* Receive Trigger Level set at 8 */ +#define SB105X_FCR_RTR16 0x40 /* Receive Trigger Level set at 16 */ +#define SB105X_FCR_RTR56 0x80 /* Receive Trigger Level set at 56 */ +#define SB105X_FCR_RTR60 0xc0 /* Receive Trigger Level set at 60 */ #define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */ #define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */ #define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */ diff --git a/drivers/staging/sb105x/sb_pci_mp.c b/drivers/staging/sb105x/sb_pci_mp.c index 5cd3efff97d3..c9d6ee3903ad 100644 --- a/drivers/staging/sb105x/sb_pci_mp.c +++ b/drivers/staging/sb105x/sb_pci_mp.c @@ -182,7 +182,7 @@ static int sb1054_get_register(struct sb_uart_port *port, int page, int reg) if( page <= 0) { - printk(" page 0 can not use this fuction\n"); + printk(" page 0 can not use this function\n"); return -1; } @@ -243,7 +243,7 @@ static int sb1054_set_register(struct sb_uart_port *port, int page, int reg, int if( page <= 0) { - printk(" page 0 can not use this fuction\n"); + printk(" page 0 can not use this function\n"); return -1; } switch(page) diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 1e80a4013b8c..dca838d043e5 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -4292,7 +4292,7 @@ static void sep_remove(struct pci_dev *pdev) } /* Initialize struct pci_device_id for our driver */ -static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { +static const struct pci_device_id sep_pci_id_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0826)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08e9)}, {0} diff --git a/drivers/staging/silicom/bpctl_mod.c b/drivers/staging/silicom/bpctl_mod.c index 39dc92a271ab..20325f53328e 100644 --- a/drivers/staging/silicom/bpctl_mod.c +++ b/drivers/staging/silicom/bpctl_mod.c @@ -135,8 +135,6 @@ static int bp_get_dev_idx_bsf(struct net_device *dev, int *index) else return -EOPNOTSUPP; - if (!drvinfo.bus_info) - return -ENODATA; if (!strcmp(drvinfo.bus_info, "N/A")) return -ENODATA; diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c index ba0d23a1cfbe..dda1b2a6b84b 100644 --- a/drivers/staging/silicom/bypasslib/bypass.c +++ b/drivers/staging/silicom/bypasslib/bypass.c @@ -47,13 +47,13 @@ static int do_cmd(struct net_device *dev, struct ifreq *ifr, int cmd, int *data) { int ret = -1; struct if_bypass *bypass_cb; - static int (*ioctl) (struct net_device *, struct ifreq *, int); bypass_cb = (struct if_bypass *)ifr; bypass_cb->cmd = cmd; bypass_cb->data = *data; - if ((dev->netdev_ops) && (ioctl = dev->netdev_ops->ndo_do_ioctl)) { - ret = ioctl(dev, ifr, SIOCGIFBYPASS); + + if (dev->netdev_ops && dev->netdev_ops->ndo_do_ioctl) { + ret = dev->netdev_ops->ndo_do_ioctl(dev, ifr, SIOCGIFBYPASS); *data = bypass_cb->data; } @@ -480,7 +480,6 @@ static int get_bypass_info(int if_index, struct bp_info *bp_info) SET_BPLIB_INT_FN2(get_bypass_info, int, if_index, struct bp_info *, bp_info, ret); } else { - static int (*ioctl) (struct net_device *, struct ifreq *, int); struct net_device *dev; struct net_device *n; @@ -493,9 +492,10 @@ static int get_bypass_info(int if_index, struct bp_info *bp_info) bypass_cb = (struct if_bypass_info *)𝔦 bypass_cb->cmd = GET_BYPASS_INFO; - if ((dev->netdev_ops) && - (ioctl = dev->netdev_ops->ndo_do_ioctl)) { - ret = ioctl(dev, &ifr, SIOCGIFBYPASS); + if (dev->netdev_ops && + dev->netdev_ops->ndo_do_ioctl) { + ret = dev->netdev_ops->ndo_do_ioctl(dev, + &ifr, SIOCGIFBYPASS); } else diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README index cb04a87b2017..53052c4e78ae 100644 --- a/drivers/staging/slicoss/README +++ b/drivers/staging/slicoss/README @@ -14,7 +14,6 @@ TODO: - use net_device_ops - use dev->stats rather than adapter->stats - don't cast netdev_priv it is already void - - use compare_ether_addr - GET RID OF MACROS - work on all architectures - without CONFIG_X86_64 confusion diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 652272b96a56..1426ca49bfe8 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -136,7 +136,7 @@ MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting"); module_param(intagg_delay, int, 0); MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay"); -static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = { +static const struct pci_device_id slic_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_1GB_DEVICE_ID) }, { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_2GB_DEVICE_ID) }, { 0 } @@ -595,15 +595,12 @@ static void slic_adapter_set_hwaddr(struct adapter *adapter) memcpy(adapter->macaddr, card->config.MacInfo[adapter->functionnumber].macaddrA, sizeof(struct slic_config_mac)); - if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] || - adapter->currmacaddr[2] || adapter->currmacaddr[3] || - adapter->currmacaddr[4] || adapter->currmacaddr[5])) { - memcpy(adapter->currmacaddr, adapter->macaddr, 6); - } - if (adapter->netdev) { + if (is_zero_ether_addr(adapter->currmacaddr)) + memcpy(adapter->currmacaddr, adapter->macaddr, + ETH_ALEN); + if (adapter->netdev) memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, - 6); - } + ETH_ALEN); } } @@ -767,13 +764,11 @@ static bool slic_mac_filter(struct adapter *adapter, { struct net_device *netdev = adapter->netdev; u32 opts = adapter->macopts; - u32 *dhost4 = (u32 *)ðer_frame->ether_dhost[0]; - u16 *dhost2 = (u16 *)ðer_frame->ether_dhost[4]; if (opts & MAC_PROMISC) return true; - if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) { + if (is_broadcast_ether_addr(ether_frame->ether_dhost)) { if (opts & MAC_BCAST) { adapter->rcv_broadcasts++; return true; @@ -782,7 +777,7 @@ static bool slic_mac_filter(struct adapter *adapter, } } - if (ether_frame->ether_dhost[0] & 0x01) { + if (is_multicast_ether_addr(ether_frame->ether_dhost)) { if (opts & MAC_ALLMCAST) { adapter->rcv_multicasts++; netdev->stats.multicast++; @@ -2335,7 +2330,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address) if (mcaddr == NULL) return 1; - memcpy(mcaddr->address, address, 6); + memcpy(mcaddr->address, address, ETH_ALEN); mcaddr->next = adapter->mcastaddrs; adapter->mcastaddrs = mcaddr; diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c index ba199ffff178..805c3fa36d8f 100644 --- a/drivers/staging/sm7xxfb/sm7xxfb.c +++ b/drivers/staging/sm7xxfb/sm7xxfb.c @@ -920,7 +920,7 @@ failed_free: * 0x712 (LynxEM+) * 0x720 (Lynx3DM, Lynx3DM+) */ -static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { +static const struct pci_device_id smtcfb_pci_table[] = { { PCI_DEVICE(0x126f, 0x710), }, { PCI_DEVICE(0x126f, 0x712), }, { PCI_DEVICE(0x126f, 0x720), }, diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 47502fa5f3f6..ef5933b93590 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -37,8 +37,6 @@ #include <linux/input.h> #include <linux/kmod.h> -#include <linux/bootmem.h> /* for alloc_bootmem */ - /* speakup_*_selection */ #include <linux/module.h> #include <linux/sched.h> diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index 135428856d47..4e18fb405344 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c @@ -6,6 +6,10 @@ #include "spk_priv.h" #include "serialio.h" +#ifndef SERIAL_PORT_DFNS +#define SERIAL_PORT_DFNS +#endif + static void start_serial_interrupt(int irq); static const struct old_serial_port rs_table[] = { diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 55d68b5ad165..0a937732a190 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h @@ -36,30 +36,4 @@ struct old_serial_port { #define spk_serial_tx_busy() ((inb(speakup_info.port_tts + UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY) -/* 2.6.22 doesn't have them any more, hardcode it for now (these values should - * be fine for 99% cases) */ -#ifndef BASE_BAUD -#define BASE_BAUD (1843200 / 16) -#endif -#ifndef STD_COM_FLAGS -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF -#endif -#endif -#ifndef SERIAL_PORT_DFNS -#define SERIAL_PORT_DFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ -#endif -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif - #endif diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 4a800dadd703..f961e0ec9da8 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -359,7 +359,7 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) * Return the communication memory manager object for this device. * This is typically called from the client process. */ -int cmm_get_handle(void *hprocessor, struct cmm_object ** ph_cmm_mgr) +int cmm_get_handle(void *hprocessor, struct cmm_object **ph_cmm_mgr) { int status = 0; struct dev_object *hdev_obj; @@ -449,8 +449,7 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, struct cmm_mnode *new_node; s32 slot_seg; - dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x " - "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", + dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset, dw_dsp_base, ul_dsp_size, gpp_base_va); @@ -828,7 +827,7 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) * Purpose: * Set/Get translator info. */ -int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr, +int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 **paddr, u32 ul_size, u32 segm_id, bool set_info) { struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 41e88abe47af..996a02d27d34 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -378,8 +378,8 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, opened_doff = false; } - dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, " - "status 0x%x\n", __func__, lib, name, paddr, psize, status); + dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n", + __func__, lib, name, paddr, psize, status); return status; } @@ -705,8 +705,8 @@ func_cont: opened_doff = false; } - dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, " - "status 0x%x\n", __func__, lib, name, buf, size, status); + dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n", + __func__, lib, name, buf, size, status); return status; } @@ -915,10 +915,10 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, status = dbll_get_addr((struct dbll_library_obj *)lib, (char *)name, &dbll_sym); if (!status) { - status = - dbll_get_c_addr((struct dbll_library_obj *) - lib, (char *)name, - &dbll_sym); + status = dbll_get_c_addr( + (struct dbll_library_obj *) + lib, (char *)name, + &dbll_sym); } } } @@ -1172,8 +1172,7 @@ func_cont: if (!run_addr_flag) info->run_addr = info->load_addr; info->context = (u32) rmm_addr_obj.segid; - dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, " - "info->run_addr 0x%x, info->load_addr 0x%x\n", + dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n", __func__, info->name, info->load_addr / DSPWORDSIZE, info->size / DSPWORDSIZE, info->run_addr, info->load_addr); @@ -1399,7 +1398,7 @@ void find_symbol_callback(void *elem, void *user_data) * @sym_addr_output: Symbol Output address * @name_output: String with the dsp symbol * - * This function retrieves the dsp symbol from the dsp binary. + * This function retrieves the dsp symbol from the dsp binary. */ bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address, u32 offset_range, u32 *sym_addr_output, diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 6234ffb5e8a3..616dc1f63070 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -606,7 +606,7 @@ int dev_get_node_manager(struct dev_object *hdev_obj, * ======== dev_get_symbol ======== */ int dev_get_symbol(struct dev_object *hdev_obj, - const char *str_sym, u32 * pul_value) + const char *str_sym, u32 *pul_value) { int status = 0; struct cod_manager *cod_mgr; @@ -916,8 +916,8 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, /* Local helper macro: */ #define STORE_FXN(cast, pfn) \ - (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \ - (cast)fxn_not_implemented)) + (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \ + (cast)fxn_not_implemented)) bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version, drv_fxns->brd_api_minor_version); diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c index 7c9f83916068..fcf564aa566d 100644 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ b/drivers/staging/tidspbridge/pmgr/dmm.c @@ -217,8 +217,8 @@ int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size) status = -ENOENT; spin_unlock(&dmm_obj->dmm_lock); - dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, " - "chunk %p", __func__, dmm_mgr, addr, size, status, chunk); + dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, chunk %p", + __func__, dmm_mgr, addr, size, status, chunk); return status; } @@ -268,9 +268,9 @@ int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, spin_unlock(&dmm_obj->dmm_lock); - dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, " - "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size, - prsv_addr, status, rsv_addr, rsv_size); + dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, rsv_addr %x, rsv_size %x\n", + __func__, dmm_mgr, size, + prsv_addr, status, rsv_addr, rsv_size); return status; } @@ -299,8 +299,8 @@ int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize) } spin_unlock(&dmm_obj->dmm_lock); - dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, " - "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk); + dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, chunk %p\n", + __func__, dmm_mgr, addr, psize, status, chunk); return status; } @@ -475,11 +475,11 @@ u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr) } } spin_unlock(&dmm_mgr->dmm_lock); - printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n", + dev_info(bridge, "Total DSP VA FREE memory = %d Mbytes\n", freemem / (1024 * 1024)); - printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n", + dev_info(bridge, "Total DSP VA USED memory= %d Mbytes\n", (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024)); - printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n", + dev_info(bridge, "DSP VA - Biggest FREE block = %d Mbytes\n", (bigsize * PG_SIZE4K / (1024 * 1024))); return 0; diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 70db4ff99ec6..b7d5c8cbb2a1 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -162,7 +162,7 @@ static u8 size_cmd[] = { ARRAY_SIZE(cmm_cmd), }; -static inline void _cp_fm_usr(void *to, const void __user * from, +static inline void _cp_fm_usr(void *to, const void __user *from, int *err, unsigned long bytes) { if (*err) @@ -507,7 +507,7 @@ u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt) /* * ======== MGRWRAP_GetProcessResourceInfo ======== */ -u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args, +u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args *args, void *pr_ctxt) { pr_err("%s: deprecated dspbridge ioctl\n", __func__); @@ -581,7 +581,7 @@ func_end: /* * ======== procwrap_detach ======== */ -u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt) +u32 __deprecated procwrap_detach(union trapped_args *args, void *pr_ctxt) { /* proc_detach called at bridge_release only */ pr_err("%s: deprecated dspbridge ioctl\n", __func__); @@ -1564,7 +1564,7 @@ u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt) /* * ======== strmwrap_get_event_handle ======== */ -u32 __deprecated strmwrap_get_event_handle(union trapped_args * args, +u32 __deprecated strmwrap_get_event_handle(union trapped_args *args, void *pr_ctxt) { pr_err("%s: deprecated dspbridge ioctl\n", __func__); @@ -1793,7 +1793,7 @@ u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) /* * ======== cmmwrap_calloc_buf ======== */ -u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt) +u32 __deprecated cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt) { /* This operation is done in kernel */ pr_err("%s: deprecated dspbridge ioctl\n", __func__); @@ -1803,7 +1803,7 @@ u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt) /* * ======== cmmwrap_free_buf ======== */ -u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt) +u32 __deprecated cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt) { /* This operation is done in kernel */ pr_err("%s: deprecated dspbridge ioctl\n", __func__); diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index db48a789d308..5d1d4a183300 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -102,11 +102,13 @@ static int tweak_clear_halt_cmd(struct urb *urb) ret = usb_clear_halt(urb->dev, target_pipe); if (ret < 0) - dev_err(&urb->dev->dev, "usb_clear_halt error: devnum %d endp " - "%d ret %d\n", urb->dev->devnum, target_endp, ret); + dev_err(&urb->dev->dev, + "usb_clear_halt error: devnum %d endp %d ret %d\n", + urb->dev->devnum, target_endp, ret); else - dev_info(&urb->dev->dev, "usb_clear_halt done: devnum %d endp " - "%d\n", urb->dev->devnum, target_endp); + dev_info(&urb->dev->dev, + "usb_clear_halt done: devnum %d endp %d\n", + urb->dev->devnum, target_endp); return ret; } @@ -127,11 +129,13 @@ static int tweak_set_interface_cmd(struct urb *urb) ret = usb_set_interface(urb->dev, interface, alternate); if (ret < 0) - dev_err(&urb->dev->dev, "usb_set_interface error: inf %u alt " - "%u ret %d\n", interface, alternate, ret); + dev_err(&urb->dev->dev, + "usb_set_interface error: inf %u alt %u ret %d\n", + interface, alternate, ret); else - dev_info(&urb->dev->dev, "usb_set_interface done: inf %u alt " - "%u\n", interface, alternate); + dev_info(&urb->dev->dev, + "usb_set_interface done: inf %u alt %u\n", + interface, alternate); return ret; } diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index e3fc749c1e7e..4470cd321d65 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -155,8 +155,9 @@ static void usbip_dump_usb_device(struct usb_device *udev) dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus); - dev_dbg(dev, "descriptor %p, config %p, actconfig %p, " - "rawdescriptors %p\n", &udev->descriptor, udev->config, + dev_dbg(dev, + "descriptor %p, config %p, actconfig %p, rawdescriptors %p\n", + &udev->descriptor, udev->config, udev->actconfig, udev->rawdescriptors); dev_dbg(dev, "have_langid %d, string_langid %d\n", diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index e810ad53e2ac..72391ef87646 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -220,8 +220,7 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) memset(desc, 0, sizeof(*desc)); desc->bDescriptorType = 0x29; desc->bDescLength = 9; - desc->wHubCharacteristics = (__force __u16) - (__constant_cpu_to_le16(0x0001)); + desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001)); desc->bNbrPorts = VHCI_NPORTS; desc->u.hs.DeviceRemovable[0] = 0xff; desc->u.hs.DeviceRemovable[1] = 0xff; @@ -348,8 +347,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, USB_PORT_STAT_ENABLE; } } - ((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]); - ((u16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16); + ((__le16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]); + ((__le16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16); usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], ((u16 *)buf)[1]); @@ -537,7 +536,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, goto no_need_xmit; case USB_REQ_GET_DESCRIPTOR: - if (ctrlreq->wValue == (USB_DT_DEVICE << 8)) + if (ctrlreq->wValue == cpu_to_le16(USB_DT_DEVICE << 8)) usbip_dbg_vhci_hc("Not yet?: " "Get_Descriptor to device 0 " "(get max pipe size)\n"); @@ -918,7 +917,7 @@ static void vhci_stop(struct usb_hcd *hcd) sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group); /* 2. shutdown all the ports of vhci_hcd */ - for (rhport = 0 ; rhport < VHCI_NPORTS; rhport++) { + for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { struct vhci_device *vdev = &vhci->vdev[rhport]; usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); @@ -1108,7 +1107,7 @@ static struct platform_driver vhci_driver = { .suspend = vhci_hcd_suspend, .resume = vhci_hcd_resume, .driver = { - .name = (char *) driver_name, + .name = driver_name, .owner = THIS_MODULE, }, }; @@ -1125,7 +1124,7 @@ static void the_pdev_release(struct device *dev) static struct platform_device the_pdev = { /* should be the same name as driver_name */ - .name = (char *) driver_name, + .name = driver_name, .id = -1, .dev = { .release = the_pdev_release, diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index daec15565a43..bc4f8623c8cc 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -663,9 +663,16 @@ err_nocard: static int vme_user_match(struct vme_dev *vdev) { - if (vdev->num >= VME_USER_BUS_MAX) - return 0; - return 1; + int i; + + int cur_bus = vme_bus_num(vdev); + int cur_slot = vme_slot_num(vdev); + + for (i = 0; i < bus_num; i++) + if ((cur_bus == bus[i]) && (cur_slot == vdev->num)) + return 1; + + return 0; } /* diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 959568a1eb6a..fa14659ba43c 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1865,7 +1865,7 @@ BBvCalculateParameter( break; case RATE_5M: - if (bCCK == false) + if (!bCCK) cbBitCount++; cbUsCount = (cbBitCount * 10) / 55; cbTmp = (cbUsCount * 55) / 10; @@ -1879,7 +1879,7 @@ BBvCalculateParameter( case RATE_11M: - if (bCCK == false) + if (!bCCK) cbBitCount++; cbUsCount = cbBitCount / 11; cbTmp = cbUsCount * 11; diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index a23b591eeac3..d7efd0173a9a 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -64,7 +64,6 @@ /*--------------------- Static Variables --------------------------*/ static int msglevel = MSG_LEVEL_INFO; -//static int msglevel =MSG_LEVEL_DEBUG; const unsigned short awHWRetry0[5][5] = { {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, @@ -131,27 +130,26 @@ BSSpSearchBSSList( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && - (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) { + (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) pbyBSSID = pbyDesireBSSID; - } } if (pbyDesireSSID != NULL) { - if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) { + if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) pSSID = (PWLAN_IE_SSID) pbyDesireSSID; - } } if (pbyBSSID != NULL) { - // match BSSID first + /* match BSSID first */ for (ii = 0; ii < MAX_BSS_NUM; ii++) { pCurrBSS = &(pMgmt->sBSSList[ii]); - if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false; + if (!pDevice->bLinkPass) + pCurrBSS->bSelected = false; if ((pCurrBSS->bActive) && - (pCurrBSS->bSelected == false)) { + (!pCurrBSS->bSelected)) { if (ether_addr_equal(pCurrBSS->abyBSSID, pbyBSSID)) { if (pSSID != NULL) { - // compare ssid + /* compare ssid */ if (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, pSSID->len)) { @@ -176,26 +174,26 @@ BSSpSearchBSSList( } } } else { - // ignore BSSID + /* ignore BSSID */ for (ii = 0; ii < MAX_BSS_NUM; ii++) { pCurrBSS = &(pMgmt->sBSSList[ii]); - //2007-0721-01<Add>by MikeLiu + /* 2007-0721-01<Add>by MikeLiu */ pCurrBSS->bSelected = false; if (pCurrBSS->bActive) { if (pSSID != NULL) { - // matched SSID + /* matched SSID */ if (!!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID, pSSID->len) || (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) { - // SSID not match skip this BSS + /* SSID not match skip this BSS */ continue; } } if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) || ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ) { - // Type not match skip this BSS + /* Type not match skip this BSS */ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo); continue; } @@ -203,50 +201,23 @@ BSSpSearchBSSList( if (ePhyType != PHY_TYPE_AUTO) { if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) || ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) { - // PhyType not match skip this BSS + /* PhyType not match skip this BSS */ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse); continue; } } -/* - if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) { - if (pCurrBSS->bWPAValid == true) { - // WPA AP will reject connection of station without WPA enable. - continue; - } - } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) { - if (pCurrBSS->bWPAValid == false) { - // station with WPA enable can't join NonWPA AP. - continue; - } - } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || - (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { - if (pCurrBSS->bWPA2Valid == false) { - // station with WPA2 enable can't join NonWPA2 AP. - continue; - } - } -*/ + if (pSelect == NULL) { pSelect = pCurrBSS; } else { - // compare RSSI, select signal strong one - if (pCurrBSS->uRSSI < pSelect->uRSSI) { + /* compare RSSI, select signal strong one */ + if (pCurrBSS->uRSSI < pSelect->uRSSI) pSelect = pCurrBSS; - } } } } if (pSelect != NULL) { pSelect->bSelected = true; -/* - if (pDevice->bRoaming == false) { - // Einsn Add @20070907 - memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - }*/ - return pSelect; } } @@ -278,7 +249,6 @@ BSSvClearBSSList( if (pMgmt->sBSSList[ii].bActive && ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) { - // bKeepCurrBSSID = false; continue; } } @@ -385,7 +355,7 @@ BSSbInsertToBSSList( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n"); return false; } - // save the BSS info + /* save the BSS info */ pBSSList->bActive = true; memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); @@ -416,15 +386,14 @@ BSSbInsertToBSSList( pBSSList->sERP.byERP = psERP->byERP; pBSSList->sERP.bERPExist = psERP->bERPExist; - // Check if BSS is 802.11a/b/g + /* check if BSS is 802.11a/b/g */ if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; } else { - if (pBSSList->sERP.bERPExist == true) { + if (pBSSList->sERP.bERPExist) pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - } else { + else pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } } pBSSList->byRxRate = pRxPacket->byRxRate; @@ -434,10 +403,9 @@ BSSbInsertToBSSList( if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // assoc with BSS - if (pBSSList == pMgmt->pCurrBSS) { + /* assoc with BSS */ + if (pBSSList == pMgmt->pCurrBSS) bParsingQuiet = true; - } } WPA_ClearRSN(pBSSList); @@ -463,7 +431,7 @@ BSSbInsertToBSSList( } } - if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) { + if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || pBSSList->bWPA2Valid) { PSKeyItem pTransmitKey = NULL; bool bIs802_1x = false; @@ -473,13 +441,13 @@ BSSbInsertToBSSList( break; } } - if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && + if (bIs802_1x && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); - if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) || - (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) { + if (pDevice->bLinkPass && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { + if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) || + KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey)) { pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList; pDevice->gsPMKIDCandidate.Version = 1; @@ -490,7 +458,7 @@ BSSbInsertToBSSList( } if (pDevice->bUpdateBBVGA) { - // Moniter if RSSI is too strong. + /* monitor if RSSI is too strong */ pBSSList->byRSSIStatCnt = 0; RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX); pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX; @@ -498,16 +466,15 @@ BSSbInsertToBSSList( pBSSList->ldBmAverage[ii] = 0; } - if ((pIE_Country != NULL) && - (pMgmt->b11hEnable == true)) { + if ((pIE_Country != NULL) && pMgmt->b11hEnable) { set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, pIE_Country); } - if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { + if (bParsingQuiet && (pIE_Quiet != NULL)) { if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - // valid EID + /* valid EID */ if (pQuiet == NULL) { pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; CARDbSetQuiet(pMgmt->pAdapter, @@ -530,8 +497,7 @@ BSSbInsertToBSSList( } } - if ((bParsingQuiet == true) && - (pQuiet != NULL)) { + if (bParsingQuiet && (pQuiet != NULL)) { CARDbStartQuiet(pMgmt->pAdapter); } @@ -552,7 +518,7 @@ BSSbInsertToBSSList( * true if success. * -*/ -// TODO: input structure modify +/* TODO: input structure modify */ bool BSSbUpdateToBSSList( @@ -593,7 +559,6 @@ BSSbUpdateToBSSList( pBSSList->wCapInfo = cpu_to_le16(wCapInfo); pBSSList->uClearCount = 0; pBSSList->uChannel = byCurrChannel; -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel); if (pSSID->len > WLAN_SSID_MAXLEN) pSSID->len = WLAN_SSID_MAXLEN; @@ -602,23 +567,21 @@ BSSbUpdateToBSSList( memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN); - if (pExtSuppRates != NULL) { + if (pExtSuppRates != NULL) memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - } else { + else memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); - } pBSSList->sERP.byERP = psERP->byERP; pBSSList->sERP.bERPExist = psERP->bERPExist; - // Check if BSS is 802.11a/b/g + /* check if BSS is 802.11a/b/g */ if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) { pBSSList->eNetworkTypeInUse = PHY_TYPE_11A; } else { - if (pBSSList->sERP.bERPExist == true) { + if (pBSSList->sERP.bERPExist) pBSSList->eNetworkTypeInUse = PHY_TYPE_11G; - } else { + else pBSSList->eNetworkTypeInUse = PHY_TYPE_11B; - } } pBSSList->byRxRate = pRxPacket->byRxRate; @@ -629,13 +592,12 @@ BSSbUpdateToBSSList( if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { - // assoc with BSS - if (pBSSList == pMgmt->pCurrBSS) { + /* assoc with BSS */ + if (pBSSList == pMgmt->pCurrBSS) bParsingQuiet = true; - } } - WPA_ClearRSN(pBSSList); //mike update + WPA_ClearRSN(pBSSList); /* mike update */ if (pRSNWPA != NULL) { unsigned int uLen = pRSNWPA->len + 2; @@ -646,7 +608,7 @@ BSSbUpdateToBSSList( } } - WPA2_ClearRSN(pBSSList); //mike update + WPA2_ClearRSN(pBSSList); /* mike update */ if (pRSN != NULL) { unsigned int uLen = pRSN->len + 2; @@ -659,27 +621,25 @@ BSSbUpdateToBSSList( if (pRxPacket->uRSSI != 0) { RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm); - // Moniter if RSSI is too strong. + /* monitor if RSSI is too strong */ pBSSList->byRSSIStatCnt++; pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT; pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm; for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { - if (pBSSList->ldBmAverage[ii] != 0) { + if (pBSSList->ldBmAverage[ii] != 0) pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm); - } } } - if ((pIE_Country != NULL) && - (pMgmt->b11hEnable == true)) { + if ((pIE_Country != NULL) && pMgmt->b11hEnable) { set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse, pIE_Country); } - if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) { + if (bParsingQuiet && (pIE_Quiet != NULL)) { if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) && (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) { - // valid EID + /* valid EID */ if (pQuiet == NULL) { pQuiet = (PWLAN_IE_QUIET)pIE_Quiet; CARDbSetQuiet(pMgmt->pAdapter, @@ -702,8 +662,7 @@ BSSbUpdateToBSSList( } } - if ((bParsingQuiet == true) && - (pQuiet != NULL)) { + if (bParsingQuiet && (pQuiet != NULL)) { CARDbStartQuiet(pMgmt->pAdapter); } @@ -732,7 +691,7 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; unsigned int ii; - // Index = 0 reserved for AP Node + /* Index = 0 reserved for AP Node */ for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive) { if (ether_addr_equal(abyDstAddr, @@ -765,8 +724,10 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) unsigned int BigestCount = 0; unsigned int SelectIndex; struct sk_buff *skb; - // Index = 0 reserved for AP Node (In STA mode) - // Index = 0 reserved for Broadcast/MultiCast (In AP mode) + /* + * Index = 0 reserved for AP Node (In STA mode) + * Index = 0 reserved for Broadcast/MultiCast (In AP mode) + */ SelectIndex = 1; for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive) { @@ -779,11 +740,11 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) } } - // if not found replace uInActiveCount is largest one. + /* if not found replace uInActiveCount is largest one */ if (ii == (MAX_NODE_NUM + 1)) { *puNodeIndex = SelectIndex; DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex); - // clear ps buffer + /* clear ps buffer */ if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) { while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL) dev_kfree_skb(skb); @@ -795,7 +756,7 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB)); pMgmt->sNodeDBTable[*puNodeIndex].bActive = true; pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND; - // for AP mode PS queue + /* for AP mode PS queue */ skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; @@ -826,9 +787,9 @@ BSSvRemoveOneNode( while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL) dev_kfree_skb(skb); - // clear context + /* clear context */ memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB)); - // clear tx bit map + /* clear tx bit map */ pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7]; return; @@ -859,9 +820,8 @@ BSSvUpdateAPNode( memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); pMgmt->sNodeDBTable[0].bActive = true; - if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { + if (pDevice->eCurrentPHYType == PHY_TYPE_11B) uRateLen = WLAN_RATES_MAXLEN_11B; - } pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, uRateLen); @@ -882,12 +842,10 @@ BSSvUpdateAPNode( pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate; pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo); pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; -#ifdef PLICE_DEBUG - printk("BSSvUpdateAPNode:MaxSuppRate is %d\n", pMgmt->sNodeDBTable[0].wMaxSuppRate); -#endif - // Auto rate fallback function initiation. - // RATEbInit(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate); + netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n", + pMgmt->sNodeDBTable[0].wMaxSuppRate); + /* auto rate fallback function initiation */ + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); }; /*+ @@ -926,9 +884,9 @@ BSSvAddMulticastNode( &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) ); pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate; -#ifdef PLICE_DEBUG - printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); -#endif + netdev_dbg(pDevice->dev, + "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", + pMgmt->sNodeDBTable[0].wTxDataRate); pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND; }; @@ -944,7 +902,7 @@ BSSvAddMulticastNode( * none. * -*/ -//2008-4-14 <add> by chester for led issue +/* 2008-4-14 <add> by chester for led issue */ #ifdef FOR_LED_ON_NOTEBOOK bool cc = false; unsigned int status; @@ -961,7 +919,7 @@ BSSvSecondCallBack( unsigned int uSleepySTACnt = 0; unsigned int uNonShortSlotSTACnt = 0; unsigned int uLongPreambleSTACnt = 0; - viawget_wpa_header *wpahdr; //DavidWang + viawget_wpa_header *wpahdr; /* DavidWang */ spin_lock_irq(&pDevice->lock); @@ -969,51 +927,47 @@ BSSvSecondCallBack( pDevice->byERPFlag &= ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1)); - //2008-4-14 <add> by chester for led issue + /* 2008-4-14 <add> by chester for led issue */ #ifdef FOR_LED_ON_NOTEBOOK MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); - if (((!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == false)) || ((pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == true))) && (cc == false)) { + if (((!(pDevice->byGPIO & GPIO0_DATA) && (!pDevice->bHWRadioOff)) || + ((pDevice->byGPIO & GPIO0_DATA) && pDevice->bHWRadioOff)) && + (!cc)) { cc = true; - } else if (cc == true) { - if (pDevice->bHWRadioOff == true) { - if (!(pDevice->byGPIO & GPIO0_DATA)) -//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) - { - if (status == 1) goto start; + } else if (cc) { + if (pDevice->bHWRadioOff) { + if (!(pDevice->byGPIO & GPIO0_DATA)) { + if (status == 1) + goto start; status = 1; CARDbRadioPowerOff(pDevice); pMgmt->sNodeDBTable[0].bActive = false; pMgmt->eCurrMode = WMAC_MODE_STANDBY; pMgmt->eCurrState = WMAC_STATE_IDLE; - //netif_stop_queue(pDevice->dev); pDevice->bLinkPass = false; } - if (pDevice->byGPIO & GPIO0_DATA) -//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) - { - if (status == 2) goto start; + if (pDevice->byGPIO & GPIO0_DATA) { + if (status == 2) + goto start; status = 2; CARDbRadioPowerOn(pDevice); } } else { - if (pDevice->byGPIO & GPIO0_DATA) -//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) - { - if (status == 3) goto start; + if (pDevice->byGPIO & GPIO0_DATA) { + if (status == 3) + goto start; status = 3; CARDbRadioPowerOff(pDevice); pMgmt->sNodeDBTable[0].bActive = false; pMgmt->eCurrMode = WMAC_MODE_STANDBY; pMgmt->eCurrState = WMAC_STATE_IDLE; - //netif_stop_queue(pDevice->dev); pDevice->bLinkPass = false; } - if (!(pDevice->byGPIO & GPIO0_DATA)) -//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) - { - if (status == 4) goto start; + if (!(pDevice->byGPIO & GPIO0_DATA)) { + if (status == 4) + goto start; status = 4; CARDbRadioPowerOn(pDevice); } @@ -1025,14 +979,15 @@ start: if (pDevice->wUseProtectCntDown > 0) { pDevice->wUseProtectCntDown--; } else { - // disable protect mode + /* disable protect mode */ pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1)); } { pDevice->byReAssocCount++; - if ((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) { //10 sec timeout - printk("Re-association timeout!!!\n"); + /* 10 sec timeout */ + if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) { + netdev_info(pDevice->dev, "Re-association timeout!!!\n"); pDevice->byReAssocCount = 0; #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT { @@ -1043,7 +998,7 @@ start: wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } #endif - } else if (pDevice->bLinkPass == true) + } else if (pDevice->bLinkPass) pDevice->byReAssocCount = 0; } @@ -1053,7 +1008,7 @@ start: for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive) { - // Increase in-activity counter + /* increase in-activity counter */ pMgmt->sNodeDBTable[ii].uInActiveCount++; if (ii > 0) { @@ -1067,7 +1022,7 @@ start: if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) { pDevice->uAssocCount++; - // check if Non ERP exist + /* check if Non ERP exist */ if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) { if (!pMgmt->sNodeDBTable[ii].bShortPreamble) { pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1); @@ -1082,43 +1037,39 @@ start: } } - // check if any STA in PS mode + /* check if any STA in PS mode */ if (pMgmt->sNodeDBTable[ii].bPSEnable) uSleepySTACnt++; } - // Rate fallback check + /* rate fallback check */ if (!pDevice->bFixRate) { -/* - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0)) - RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii])); -*/ if (ii > 0) { - // ii = 0 for multicast node (AP & Adhoc) + /* ii = 0 for multicast node (AP & Adhoc) */ RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); } else { - // ii = 0 reserved for unicast AP node (Infra STA) + /* ii = 0 reserved for unicast AP node (Infra STA) */ if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) -#ifdef PLICE_DEBUG - printk("SecondCallback:Before:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); -#endif + netdev_dbg(pDevice->dev, + "SecondCallback:Before:TxDataRate is %d\n", + pMgmt->sNodeDBTable[0].wTxDataRate); RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); -#ifdef PLICE_DEBUG - printk("SecondCallback:After:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); -#endif + netdev_dbg(pDevice->dev, + "SecondCallback:After:TxDataRate is %d\n", + pMgmt->sNodeDBTable[0].wTxDataRate); } } - // check if pending PS queue + /* check if pending PS queue */ if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n", + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending\n", ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { BSSvRemoveOneNode(pDevice, ii); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii); + DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove\n", ii); continue; } } @@ -1127,7 +1078,7 @@ start: } if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) { - // on/off protect mode + /* on/off protect mode */ if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) { if (!pDevice->bProtectMode) { MACvEnableProtectMD(pDevice->PortOffset); @@ -1139,7 +1090,7 @@ start: pDevice->bProtectMode = false; } } - // on/off short slot time + /* on/off short slot time */ if (uNonShortSlotSTACnt > 0) { if (pDevice->bShortSlotTime) { @@ -1155,7 +1106,7 @@ start: } } - // on/off barker long preamble mode + /* on/off barker long preamble mode */ if (uLongPreambleSTACnt > 0) { if (!pDevice->bBarkerPreambleMd) { @@ -1171,7 +1122,7 @@ start: } - // Check if any STA in PS mode, enable DTIM multicast deliver + /* check if any STA in PS mode, enable DTIM multicast deliver */ if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { if (uSleepySTACnt > 0) pMgmt->sNodeDBTable[0].bPSEnable = true; @@ -1184,11 +1135,10 @@ start: if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { - if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS - if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((void *) pDevice); + /* assoc with BSS */ + if (pMgmt->sNodeDBTable[0].bActive) { + if (pDevice->bUpdateBBVGA) s_vCheckPreEDThreshold((void *)pDevice); - } if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) { @@ -1232,12 +1182,18 @@ start: if (pDevice->uAutoReConnectTime < 10) { pDevice->uAutoReConnectTime++; #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - //network manager support need not do Roaming scan??? - if (pDevice->bWPASuppWextEnabled == true) + /* + * network manager support need not do + * Roaming scan??? + */ + if (pDevice->bWPASuppWextEnabled) pDevice->uAutoReConnectTime = 0; #endif } else { - //mike use old encryption status for wpa reauthen + /* + * mike use old encryption status + * for wpa reauthentication + */ if (pDevice->bWPADEVUp) pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; @@ -1252,7 +1208,7 @@ start: } if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - // if adhoc started which essid is NULL string, rescanning. + /* if adhoc started which essid is NULL string, rescanning */ if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) { if (pDevice->uAutoReConnectTime < 10) { pDevice->uAutoReConnectTime++; @@ -1262,13 +1218,11 @@ start: bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); pDevice->uAutoReConnectTime = 0; - }; + } } if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (pDevice->bUpdateBBVGA) { - //s_vCheckSensitivity((void *) pDevice); + if (pDevice->bUpdateBBVGA) s_vCheckPreEDThreshold((void *)pDevice); - } if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) { DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); pMgmt->sNodeDBTable[0].uInActiveCount = 0; @@ -1318,40 +1272,31 @@ BSSvUpdateNodeTxCounter( unsigned short wFallBackRate = RATE_1M; unsigned char byFallBack; unsigned int ii; -// unsigned int txRetryTemp; -//PLICE_DEBUG-> - //txRetryTemp = byTxRetry; -//PLICE_DEBUG <- pTxBufHead = (PSTxBufHead) pbyBuffer; - if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) { + if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) byFallBack = AUTO_FB_0; - } else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) { + else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) byFallBack = AUTO_FB_1; - } else { + else byFallBack = AUTO_FB_NONE; - } - wRate = pTxBufHead->wReserved; //?wRate + wRate = pTxBufHead->wReserved; - // Only Unicast using support rates + /* Only Unicast using support rates */ if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1); if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) { pMgmt->sNodeDBTable[0].uTxAttempts += 1; if ((byTsr1 & TSR1_TERR) == 0) { - // transmit success, TxAttempts at least plus one + /* transmit success, TxAttempts at least plus one */ pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++; if ((byFallBack == AUTO_FB_NONE) || (wRate < RATE_18M)) { wFallBackRate = wRate; } else if (byFallBack == AUTO_FB_0) { -//PLICE_DEBUG if (byTxRetry < 5) wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry]; - //wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1; else wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][4]; } else if (byFallBack == AUTO_FB_1) { if (byTxRetry < 5) wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry]; @@ -1369,18 +1314,11 @@ BSSvUpdateNodeTxCounter( (wRate < RATE_18M)) { pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry; } else if (byFallBack == AUTO_FB_0) { -//PLICE_DEBUG - for (ii = 0; ii < byTxRetry; ii++) - //for (ii=0;ii<txRetryTemp;ii++) - { - if (ii < 5) { -//PLICE_DEBUG + for (ii = 0; ii < byTxRetry; ii++) { + if (ii < 5) wFallBackRate = awHWRetry0[wRate-RATE_18M][ii]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][ii]; - } else { + else wFallBackRate = awHWRetry0[wRate-RATE_18M][4]; - //wFallBackRate = awHWRetry0[wRate-RATE_12M][4]; - } pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++; } } else if (byFallBack == AUTO_FB_1) { @@ -1402,7 +1340,7 @@ BSSvUpdateNodeTxCounter( if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; if ((byTsr1 & TSR1_TERR) == 0) { - // transmit success, TxAttempts at least plus one + /* transmit success, TxAttempts at least plus one */ pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; if ((byFallBack == AUTO_FB_NONE) || (wRate < RATE_18M)) { @@ -1485,7 +1423,7 @@ BSSvClearNodeDBTable( for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive) { - // check if sTxPSQueue has been initial + /* check if sTxPSQueue has been initial */ if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii); @@ -1517,7 +1455,7 @@ void s_vCheckSensitivity( ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); if (pBSSList != NULL) { - // Updata BB Reg if RSSI is too strong. + /* Update BB Reg if RSSI is too strong */ long LocalldBmAverage = 0; long uNumofdBm = 0; for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { @@ -1556,9 +1494,8 @@ BSSvClearAnyBSSJoinRecord( PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int ii; - for (ii = 0; ii < MAX_BSS_NUM; ii++) { + for (ii = 0; ii < MAX_BSS_NUM; ii++) pMgmt->sBSSList[ii].bSelected = false; - } return; } @@ -1580,19 +1517,18 @@ void s_uCalculateLinkQual( pDevice->scStatistic.RxOkCnt; TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); -//decide link quality - if (pDevice->bLinkPass != true) { + /* decide link quality */ + if (!pDevice->bLinkPass) { pDevice->scStatistic.LinkQuality = 0; pDevice->scStatistic.SignalStren = 0; } else { RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); - if (-ldBm < 50) { + if (-ldBm < 50) RssiRatio = 4000; - } else if (-ldBm > 90) { + else if (-ldBm > 90) RssiRatio = 0; - } else { + else RssiRatio = (40-(-ldBm-50))*4000/40; - } pDevice->scStatistic.SignalStren = RssiRatio/40; pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; } @@ -1616,10 +1552,8 @@ void s_vCheckPreEDThreshold( if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); - if (pBSSList != NULL) { + if (pBSSList != NULL) pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1); - //BBvUpdatePreEDThreshold(pDevice, false); - } } return; } diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index fbf18e23e78e..db38ca051130 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1053,7 +1053,7 @@ CARDbAdd_PMKID_Candidate( for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { + if (bRSNCapExist && (wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); @@ -1064,7 +1064,7 @@ CARDbAdd_PMKID_Candidate( // New Candidate pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if ((bRSNCapExist == true) && (wRSNCap & BIT0)) { + if (bRSNCapExist && (wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); @@ -1190,7 +1190,7 @@ CARDbStartMeasure( } } while (pDevice->uNumOfMeasureEIDs != 0); - if (bExpired == false) { + if (!bExpired) { MACvSelectPage1(pDevice->PortOffset); VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF)); VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF)); @@ -1280,7 +1280,7 @@ CARDbSetQuiet( PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int ii = 0; - if (bResetQuiet == true) { + if (bResetQuiet) { MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN)); for (ii = 0; ii < MAX_QUIET_COUNT; ii++) { pDevice->sQuiet[ii].bEnable = false; @@ -2013,7 +2013,7 @@ QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1; } else { HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2); - }; + } return qwTSFOffset; } diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index ba9481fa654f..3198a31e2ed7 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -441,8 +441,8 @@ void init_channel_table(void *pDeviceHandler) break; } - if ((pDevice->dwDiagRefCount != 0) || (pDevice->b11hEnable == true)) { - if (bMultiBand == true) { + if ((pDevice->dwDiagRefCount != 0) || pDevice->b11hEnable) { + if (bMultiBand) { for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { sChannelTbl[ii + 1].bValid = true; pDevice->abyRegPwr[ii + 1] = pDevice->abyOFDMDefaultPwr[ii + 1]; @@ -463,7 +463,7 @@ void init_channel_table(void *pDeviceHandler) } } } else if (pDevice->byZoneType <= CCODE_MAX) { - if (bMultiBand == true) { + if (bMultiBand) { for (ii = 0; ii < CARD_MAX_CHANNEL_TBL; ii++) { if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) { sChannelTbl[ii + 1].bValid = true; @@ -531,7 +531,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) return bResult; } - if (sChannelTbl[uConnectionChannel].bValid == false) { + if (!sChannelTbl[uConnectionChannel].bValid) { return false; } @@ -557,7 +557,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) bResult &= RFbSelectChannel(pDevice->PortOffset, pDevice->byRFType, (unsigned char)uConnectionChannel); // Init Synthesizer Table - if (pDevice->bEnablePSMode == true) + if (pDevice->bEnablePSMode) RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel); //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDbSetMediaChannel: %d\n", (unsigned char)uConnectionChannel); @@ -766,7 +766,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) if (ePHYType == PHY_TYPE_11A) { for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (sChannelTbl[ii].bValid == true) { + if (sChannelTbl[ii].bValid) { if (byOptionChannel == 0) { byOptionChannel = (unsigned char) ii; } @@ -780,7 +780,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) } else { byOptionChannel = 0; for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if (sChannelTbl[ii].bValid == true) { + if (sChannelTbl[ii].bValid) { if (sChannelTbl[ii].byMAP == 0) { aiWeight[ii] += 100; } else if (sChannelTbl[ii].byMAP & 0x01) { @@ -807,7 +807,7 @@ unsigned char auto_channel_select(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) } } for (ii = 1; ii <= CB_MAX_CHANNEL_24G; ii++) { - if ((sChannelTbl[ii].bValid == true) && + if (sChannelTbl[ii].bValid && (aiWeight[ii] > aiWeight[byOptionChannel])) { byOptionChannel = (unsigned char) ii; } diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index e7b6bc7de4ac..c9a89cd7633c 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -218,8 +218,7 @@ RATEvParseMaxRate( for (ii = 0; ii < uRateLen; ii++) { byRate = (unsigned char)(pItemRates->abyRates[ii]); - if (WLAN_MGMT_IS_BASICRATE(byRate) && - (bUpdateBasicRate == true)) { + if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate) { // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); @@ -329,7 +328,7 @@ RATEvTxRateFallBack( for (ii = 0; ii < MAX_RATE; ii++) { if (psNodeDBTable->wSuppRate & (0x0001<<ii)) { - if (bAutoRate[ii] == true) { + if (bAutoRate[ii]) { wIdxUpRate = (unsigned short) ii; } } else { @@ -354,8 +353,7 @@ RATEvTxRateFallBack( wIdxDownRate = psNodeDBTable->wTxDataRate; for (ii = psNodeDBTable->wTxDataRate; ii > 0;) { ii--; - if ((dwThroughputTbl[ii] > dwThroughput) && - (bAutoRate[ii] == true)) { + if ((dwThroughputTbl[ii] > dwThroughput) && bAutoRate[ii]) { dwThroughput = dwThroughputTbl[ii]; wIdxDownRate = (unsigned short) ii; } diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index e93fdc88d844..a952df1bf9d6 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -267,7 +267,7 @@ static CHIP_INFO chip_info_table[] = { {0, NULL} }; -DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = { +const struct pci_device_id vt6655_pci_id_table[] = { { PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table}, { 0, } }; @@ -561,7 +561,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) pDevice->byTxAntennaMode = ANT_B; pDevice->dwTxAntennaSel = 1; pDevice->dwRxAntennaSel = 1; - if (pDevice->bTxRxAntInv == true) + if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_A; else pDevice->byRxAntennaMode = ANT_B; @@ -578,13 +578,13 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) pDevice->dwRxAntennaSel = 0; if (byValue & EEP_ANTENNA_AUX) { pDevice->byTxAntennaMode = ANT_A; - if (pDevice->bTxRxAntInv == true) + if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_B; else pDevice->byRxAntennaMode = ANT_A; } else { pDevice->byTxAntennaMode = ANT_B; - if (pDevice->bTxRxAntInv == true) + if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_A; else pDevice->byRxAntennaMode = ANT_B; @@ -635,7 +635,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) pDevice->byRFType &= RF_MASK; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType); - if (pDevice->bZoneRegExist == false) { + if (!pDevice->bZoneRegExist) { pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType); @@ -742,7 +742,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) if (!(pDevice->byGPIO & GPIO0_DATA)) { pDevice->bHWRadioOff = false; } } - if ((pDevice->bRadioControlOff == true)) { + if (pDevice->bRadioControlOff) { CARDbRadioPowerOff(pDevice); } else CARDbRadioPowerOn(pDevice); #else @@ -751,7 +751,7 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) pDevice->bHWRadioOff = true; } } - if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) { + if (pDevice->bHWRadioOff || pDevice->bRadioControlOff) { CARDbRadioPowerOff(pDevice); } @@ -809,7 +809,7 @@ static bool device_release_WPADEV(PSDevice pDevice) int ii = 0; // wait_queue_head_t Set_wait; //send device close to wpa_supplicnat layer - if (pDevice->bWPADEVUp == true) { + if (pDevice->bWPADEVUp) { wpahdr = (viawget_wpa_header *)pDevice->skb->data; wpahdr->type = VIAWGET_DEVICECLOSE_MSG; wpahdr->resp_ie_len = 0; @@ -826,7 +826,7 @@ static bool device_release_WPADEV(PSDevice pDevice) //wait release WPADEV // init_waitqueue_head(&Set_wait); // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait - while ((pDevice->bWPADEVUp == true)) { + while (pDevice->bWPADEVUp) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ / 20); //wait 50ms ii++; @@ -892,7 +892,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) #ifdef DEBUG printk("Before get pci_info memaddr is %x\n", pDevice->memaddr); #endif - if (device_get_pci_info(pDevice, pcid) == false) { + if (!device_get_pci_info(pDevice, pcid)) { printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n"); device_free_info(pDevice); return -ENODEV; @@ -1633,7 +1633,7 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) { bFull = true; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]); } - if (netif_queue_stopped(pDevice->dev) && (bFull == false)) { + if (netif_queue_stopped(pDevice->dev) && !bFull) { netif_wake_queue(pDevice->dev); } } @@ -1798,7 +1798,7 @@ static int device_open(struct net_device *dev) { pDevice->byReAssocCount = 0; pDevice->bWPADEVUp = false; // Patch: if WEP key already set by iwconfig but device not yet open - if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) { + if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) { KeybSetDefaultKey(&(pDevice->sKey), (unsigned long)(pDevice->byKeyIndex | (1 << 31)), pDevice->uKeyLength, @@ -1895,7 +1895,7 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) { return 0; } - if (pDevice->bStopTx0Pkt == true) { + if (pDevice->bStopTx0Pkt) { dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -1924,7 +1924,7 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI SKeyItem STempKey; // unsigned char byKeyIndex = 0; - if (pDevice->bStopTx0Pkt == true) { + if (pDevice->bStopTx0Pkt) { dev_kfree_skb_irq(skb); return false; } @@ -1993,14 +1993,14 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { byPktType = PK_TYPE_11A; } else { - if (pDevice->bProtectMode == true) { + if (pDevice->bProtectMode) { byPktType = PK_TYPE_11GB; } else { byPktType = PK_TYPE_11GA; } } - if (pDevice->bEncryptionEnable == true) + if (pDevice->bEncryptionEnable) bNeedEncryption = true; if (pDevice->bEnableHostWEP) { @@ -2076,7 +2076,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { bool bNodeExist = false; spin_lock_irq(&pDevice->lock); - if (pDevice->bLinkPass == false) { + if (!pDevice->bLinkPass) { dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -2130,7 +2130,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { } } - if (bNodeExist == false) { + if (!bNodeExist) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB \n"); dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); @@ -2149,7 +2149,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { cbFrameBodySize += 8; } - if (pDevice->bEncryptionEnable == true) { + if (pDevice->bEncryptionEnable) { bNeedEncryption = true; // get Transmit key do { @@ -2196,7 +2196,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { if (pDevice->bEnableHostWEP) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex); - if (pDevice->bEncryptionEnable == true) { + if (pDevice->bEncryptionEnable) { pTransmitKey = &STempKey; pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; @@ -2286,7 +2286,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) { byPktType = PK_TYPE_11A; } else { - if (pDevice->bProtectMode == true) { + if (pDevice->bProtectMode) { byPktType = PK_TYPE_11GB; } else { byPktType = PK_TYPE_11GA; @@ -2297,7 +2297,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { // printk("FIX RATE:CurrentRate is %d"); //#endif - if (bNeedEncryption == true) { + if (bNeedEncryption) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { bNeedEncryption = false; @@ -2306,7 +2306,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { if (pTransmitKey == NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n"); } else { - if (bTKIP_UseGTK == true) { + if (bTKIP_UseGTK) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n"); } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); @@ -2493,7 +2493,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { MACvSelectPage0(pDevice->PortOffset); //xxxx // WCMDbFlushCommandQueue(pDevice->pMgmt, true); - if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) { + if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) { pDevice->bMeasureInProgress = true; MACvSelectPage1(pDevice->PortOffset); MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY); @@ -2544,12 +2544,12 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { if (pDevice->dwIsr & ISR_QUIETSTART) { do { ; - } while (CARDbStartQuiet(pDevice) == false); + } while (!CARDbStartQuiet(pDevice)); } } if (pDevice->dwIsr & ISR_TBTT) { - if (pDevice->bEnableFirstQuiet == true) { + if (pDevice->bEnableFirstQuiet) { pDevice->byQuietStartCount--; if (pDevice->byQuietStartCount == 0) { pDevice->bEnableFirstQuiet = false; @@ -2558,7 +2558,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { MACvSelectPage0(pDevice->PortOffset); } } - if ((pDevice->bChannelSwitch == true) && + if (pDevice->bChannelSwitch && (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) { pDevice->byChannelSwitchCount--; if (pDevice->byChannelSwitchCount == 0) { @@ -2575,7 +2575,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { if (pDevice->eOPMode == OP_MODE_ADHOC) { //pDevice->bBeaconSent = false; } else { - if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) { + if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) { long ldBm; RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm); @@ -2642,7 +2642,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { } pDevice->bBeaconSent = true; - if (pDevice->bChannelSwitch == true) { + if (pDevice->bChannelSwitch) { pDevice->byChannelSwitchCount--; if (pDevice->byChannelSwitchCount == 0) { pDevice->bChannelSwitch = false; @@ -3237,7 +3237,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { netif_stop_queue(pDevice->dev); #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pMgmt->eScanType = WMAC_SCAN_ACTIVE; - if (pDevice->bWPASuppWextEnabled != true) + if (!pDevice->bWPASuppWextEnabled) #endif bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); @@ -3373,7 +3373,7 @@ viawget_resume(struct pci_dev *pcid) spin_lock_irq(&pDevice->lock); MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext); device_init_registers(pDevice, DEVICE_INIT_DXPL); - if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS + if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS pMgmt->sNodeDBTable[0].bActive = false; pDevice->bLinkPass = false; if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 0ff51cb4a207..0a29c9015419 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -169,7 +169,7 @@ s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr, } } else { cbHeaderSize += WLAN_HDR_ADDR3_LEN; - }; + } pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize); if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) { @@ -263,7 +263,7 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; } } - }; + } *pcbHeaderSize = cbHeaderSize; } @@ -379,7 +379,7 @@ device_receive_frame( pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8); //PLICE_DEBUG<- - if (pDevice->bMeasureInProgress == true) { + if (pDevice->bMeasureInProgress) { if ((*pbyRsr & RSR_CRCOK) != 0) { pDevice->byBasicMap |= 0x01; } @@ -436,7 +436,7 @@ device_receive_frame( } if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == true) { + if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex)) { return false; } } @@ -592,7 +592,7 @@ device_receive_frame( } } else { // Control Frame - }; + } return false; } else { if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { @@ -608,8 +608,7 @@ device_receive_frame( } } else { // discard DATA packet while not associate || BSSID error - if ((pDevice->bLinkPass == false) || - !(*pbyRsr & RSR_BSSIDOK)) { + if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", @@ -658,7 +657,7 @@ device_receive_frame( // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps if (pDevice->bDiversityEnable && (FrameSize > 50) && (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) && - (pDevice->bLinkPass == true)) { + pDevice->bLinkPass) { BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0); } @@ -683,7 +682,7 @@ device_receive_frame( // ----------------------------------------------- - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == true)) { + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnable8021x) { unsigned char abyMacHdr[24]; // Only 802.1x packet incoming allowed @@ -698,7 +697,7 @@ device_receive_frame( if (wEtherType == ETH_P_PAE) { skb->dev = pDevice->apdev; - if (bIsWEP == true) { + if (bIsWEP) { // strip IV header(8) memcpy(&abyMacHdr[0], (skb->data + 4), 24); memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24); @@ -770,8 +769,9 @@ device_receive_frame( //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R)); //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1); - if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || - (pDevice->bRxMICFail == true)) { + if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || + (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) || + pDevice->bRxMICFail) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC comparison is fail!\n"); pDevice->bRxMICFail = false; //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++; @@ -894,13 +894,13 @@ device_receive_frame( return false; if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - if (s_bAPModeRxData(pDevice, + if (!s_bAPModeRxData(pDevice, skb, FrameSize, cbHeaderOffset, iSANodeIndex, iDANodeIndex -) == false) { +)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", @@ -1123,7 +1123,7 @@ static bool s_bHandleRxEncryption( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey == NULL\n"); if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; } return false; @@ -1131,7 +1131,7 @@ static bool s_bHandleRxEncryption( if (byDecMode != pKey->byCipherSuite) { if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; } *pKeyOut = NULL; @@ -1234,7 +1234,7 @@ static bool s_bHostWepRxEncryption( if (byDecMode != pKey->byCipherSuite) { if (byDecMode == KEY_CTL_WEP) { // pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++; - } else if (pDevice->bLinkPass == true) { + } else if (pDevice->bLinkPass) { // pDevice->s802_11Counter.DecryptFailureCount.QuadPart++; } return false; @@ -1245,7 +1245,7 @@ static bool s_bHostWepRxEncryption( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP \n"); if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || - (bOnFly == false)) { + !bOnFly) { // Software WEP // 1. 3253A // 2. WEP 256 @@ -1277,7 +1277,7 @@ static bool s_bHostWepRxEncryption( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0); if (byDecMode == KEY_CTL_TKIP) { - if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == false)) { + if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || !bOnFly) { // Software TKIP // 1. 3253 A // 2. NotOnFly @@ -1297,7 +1297,7 @@ static bool s_bHostWepRxEncryption( } if (byDecMode == KEY_CTL_CCMP) { - if (bOnFly == false) { + if (!bOnFly) { // Software CCMP // NotOnFly DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_CCMP\n"); diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index ab8b2ba6eedd..ca54b793f9f0 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -495,11 +495,11 @@ static int hostap_set_encryption(PSDevice pDevice, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); if (param->u.crypt.alg == WPA_ALG_NONE) { - if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) { - if (KeybRemoveKey(&(pDevice->sKey), + if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) { + if (!KeybRemoveKey(&(pDevice->sKey), param->sta_addr, pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, - pDevice->PortOffset) == false) { + pDevice->PortOffset)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); } pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; @@ -557,7 +557,7 @@ static int hostap_set_encryption(PSDevice pDevice, (unsigned char *)abyKey, KEY_CTL_WEP, pDevice->PortOffset, - pDevice->byLocalID) == true) { + pDevice->byLocalID)) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { @@ -624,7 +624,7 @@ static int hostap_set_encryption(PSDevice pDevice, (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, - pDevice->byLocalID) == true) { + pDevice->byLocalID)) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { @@ -636,7 +636,7 @@ static int hostap_set_encryption(PSDevice pDevice, } - if (bKeyTableFull == true) { + if (bKeyTableFull) { wKeyCtl &= 0x7F00; // clear all key control filed wKeyCtl |= (byKeyDecMode << 4); wKeyCtl |= (byKeyDecMode); diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 4bff8aa96be7..2db4bc88e45e 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -1632,7 +1632,7 @@ int iwctl_giwsens(struct net_device *dev, wrq->value = ldBm; } else { wrq->value = 0; - }; + } wrq->disabled = (wrq->value == 0); wrq->fixed = 1; diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 04c1304d16e5..eab3b41f9e3c 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -64,13 +64,12 @@ s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase) int i; for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && - (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) && - (pTable->KeyTable[i].GroupKey[3].bKeyValid == false) -) { + if (pTable->KeyTable[i].bInUse && + !pTable->KeyTable[i].PairwiseKey.bKeyValid && + !pTable->KeyTable[i].GroupKey[0].bKeyValid && + !pTable->KeyTable[i].GroupKey[1].bKeyValid && + !pTable->KeyTable[i].GroupKey[2].bKeyValid && + !pTable->KeyTable[i].GroupKey[3].bKeyValid) { pTable->KeyTable[i].bInUse = false; pTable->KeyTable[i].wKeyCtl = 0; pTable->KeyTable[i].bSoftWEP = false; @@ -140,17 +139,17 @@ bool KeybGetKey( *pKey = NULL; for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && + if (pTable->KeyTable[i].bInUse && ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { if (dwKeyIndex == 0xFFFFFFFF) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { + if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { *pKey = &(pTable->KeyTable[i].PairwiseKey); return true; } else { return false; } } else if (dwKeyIndex < MAX_GROUP_KEY) { - if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) { + if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid) { *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]); return true; } else { @@ -202,12 +201,11 @@ bool KeybSetKey( j = (MAX_KEY_TABLE-1); for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { - if ((pTable->KeyTable[i].bInUse == false) && - (j == (MAX_KEY_TABLE-1))) { + if (!pTable->KeyTable[i].bInUse && (j == (MAX_KEY_TABLE-1))) { // found empty table j = i; } - if ((pTable->KeyTable[i].bInUse == true) && + if (pTable->KeyTable[i].bInUse && ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { // found table already exist if ((dwKeyIndex & PAIRWISE_KEY) != 0) { @@ -384,7 +382,7 @@ bool KeybRemoveKey( } for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && + if (pTable->KeyTable[i].bInUse && ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { if ((dwKeyIndex & PAIRWISE_KEY) != 0) { pTable->KeyTable[i].PairwiseKey.bKeyValid = false; @@ -428,7 +426,7 @@ bool KeybRemoveAllKey( int i, u; for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && + if (pTable->KeyTable[i].bInUse && ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { pTable->KeyTable[i].PairwiseKey.bKeyValid = false; for (u = 0; u < MAX_GROUP_KEY; u++) { @@ -461,7 +459,7 @@ void KeyvRemoveWEPKey( ) { if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) { + if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse) { if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) { pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false; if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) { @@ -511,10 +509,10 @@ bool KeybGetTransmitKey( *pKey = NULL; for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && + if (pTable->KeyTable[i].bInUse && ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) { if (dwKeyType == PAIRWISE_KEY) { - if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) { + if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { *pKey = &(pTable->KeyTable[i].PairwiseKey); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); @@ -535,7 +533,7 @@ bool KeybGetTransmitKey( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: dwGTKeyIndex == 0 !!!\n"); return false; } - if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) { + if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid) { *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); @@ -583,8 +581,8 @@ bool KeybCheckPairewiseKey( *pKey = NULL; for (i = 0; i < MAX_KEY_TABLE; i++) { - if ((pTable->KeyTable[i].bInUse == true) && - (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) { + if (pTable->KeyTable[i].bInUse && + pTable->KeyTable[i].PairwiseKey.bKeyValid) { *pKey = &(pTable->KeyTable[i].PairwiseKey); return true; } @@ -657,7 +655,7 @@ bool KeybSetDefaultKey( pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true; } else { - if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false) + if (!pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP) pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match } @@ -740,7 +738,7 @@ bool KeybSetAllGroupKey( } for (i = 0; i < MAX_KEY_TABLE - 1; i++) { - if (pTable->KeyTable[i].bInUse == true) { + if (pTable->KeyTable[i].bInUse) { // found table already exist // Group key pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]); diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 001d15c0fa40..21bd8a1126d7 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -957,13 +957,13 @@ bool MACbSafeStop(unsigned long dwIoBase) { MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX); - if (MACbSafeRxOff(dwIoBase) == false) { + if (!MACbSafeRxOff(dwIoBase)) { DBG_PORT80(0xA1); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n"); MACbSafeSoftwareReset(dwIoBase); return false; } - if (MACbSafeTxOff(dwIoBase) == false) { + if (!MACbSafeTxOff(dwIoBase)) { DBG_PORT80(0xA2); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n"); MACbSafeSoftwareReset(dwIoBase); diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 2340d2f0399b..4bd1ccb79515 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -260,7 +260,7 @@ PSvSendPSPOLL( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); } else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); - }; + } return; } @@ -284,16 +284,15 @@ PSbSendNullPacket( PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uIdx; - if (pDevice->bLinkPass == false) { + if (!pDevice->bLinkPass) { return false; } #ifdef TxInSleep - if ((pDevice->bEnablePSMode == false) && - (pDevice->fTxDataInSleep == false)) { + if (!pDevice->bEnablePSMode && !pDevice->fTxDataInSleep) { return false; } #else - if (pDevice->bEnablePSMode == false) { + if (!pDevice->bEnablePSMode) { return false; } #endif diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index ce173cc16c19..edb1b2768b17 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -976,7 +976,7 @@ bool RFbSetPower( } bResult = RFbRawSetPower(pDevice, byPwr, uRATE); - if (bResult == true) { + if (bResult) { pDevice->byCurPwr = byPwr; } return bResult; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 3a2661e2b27c..6affd6edac0d 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -435,7 +435,7 @@ s_uGetDataDuration( switch (byDurType) { case DATADUR_B: //DATADUR_B - if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag if (bNeedAck) { uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate); return pDevice->uSIFS + uAckTime; @@ -458,7 +458,7 @@ s_uGetDataDuration( break; case DATADUR_A: //DATADUR_A - if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag if (bNeedAck) { uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); return pDevice->uSIFS + uAckTime; @@ -481,7 +481,7 @@ s_uGetDataDuration( break; case DATADUR_A_F0: //DATADUR_A_F0 - if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag if (bNeedAck) { uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); return pDevice->uSIFS + uAckTime; @@ -523,7 +523,7 @@ s_uGetDataDuration( break; case DATADUR_A_F1: //DATADUR_A_F1 - if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag + if (((uMACfragNum == 1)) || bLastFrag) {//Non Frag or Last Frag if (bNeedAck) { uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate); return pDevice->uSIFS + uAckTime; @@ -2212,7 +2212,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { else { bNeedACK = true; pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - }; + } if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { @@ -2686,7 +2686,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un } bNeedACK = true; pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - }; + } if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index d2bdb71fe62d..e78aedf99077 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -494,7 +494,7 @@ VNTWIFIvUpdateNodeTxCounter( } } pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; - if (bTxOk == true) { + if (bTxOk) { // transmit success, TxAttempts at least plus one pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; @@ -584,7 +584,7 @@ VNTWIFIbyGetKeyCypher( { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; - if (bGroupKey == true) { + if (bGroupKey) { return pMgmt->byCSSGK; } else { return pMgmt->byCSSPK; @@ -731,7 +731,7 @@ VNTWIFIbMeasureReport( pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len); pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID; } - if (bEndOfReport == true) { + if (bEndOfReport) { IEEE11hbMSRRepTx(pMgmt); } //spin_unlock_irq(&pDevice->lock); diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 9c57eefe78fb..72caaa203ddc 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -317,7 +317,7 @@ vCommandTimer( if (pDevice->dwDiagRefCount != 0) return; - if (pDevice->bCmdRunning != true) + if (!pDevice->bCmdRunning) return; spin_lock_irq(&pDevice->lock); @@ -326,7 +326,7 @@ vCommandTimer( case WLAN_CMD_SCAN_START: pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { + if (pDevice->bRadioOff) { s_bCommandComplete(pDevice); spin_unlock_irq(&pDevice->lock); return; @@ -393,7 +393,7 @@ vCommandTimer( vAdHocBeaconStop(pDevice); - if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel) == true) { + if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel); } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel); @@ -408,7 +408,7 @@ vCommandTimer( } - if ((pMgmt->b11hEnable == false) || + if (!pMgmt->b11hEnable || (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { s_vProbeChannel(pDevice); spin_unlock_irq(&pDevice->lock); @@ -498,7 +498,7 @@ vCommandTimer( case WLAN_CMD_SSID_START: pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { + if (pDevice->bRadioOff) { s_bCommandComplete(pDevice); spin_unlock_irq(&pDevice->lock); return; @@ -659,7 +659,7 @@ vCommandTimer( netif_wake_queue(pDevice->dev); } #ifdef TxInSleep - if (pDevice->IsTxDataTrigger != false) { //TxDataTimer is not triggered at the first time + if (pDevice->IsTxDataTrigger) { //TxDataTimer is not triggered at the first time del_timer(&pDevice->sTimerTxData); init_timer(&pDevice->sTimerTxData); pDevice->sTimerTxData.data = (unsigned long) pDevice; @@ -694,7 +694,7 @@ vCommandTimer( pMgmt->eCurrState = WMAC_STATE_IDLE; pMgmt->eCurrMode = WMAC_MODE_STANDBY; pDevice->bLinkPass = false; - if (pDevice->bEnableHostWEP == true) + if (pDevice->bEnableHostWEP) BSSvClearNodeDBTable(pDevice, 1); else BSSvClearNodeDBTable(pDevice, 0); @@ -776,7 +776,7 @@ vCommandTimer( case WLAN_CMD_RADIO_START: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n"); - if (pDevice->bRadioCmd == true) + if (pDevice->bRadioCmd) CARDbRadioPowerOn(pDevice); else CARDbRadioPowerOff(pDevice); @@ -948,7 +948,7 @@ bool bScheduleCommand( ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); pDevice->cbFreeCmdQueue--; - if (pDevice->bCmdRunning == false) { + if (!pDevice->bCmdRunning) { s_bCommandComplete(pDevice); } else { } @@ -1031,8 +1031,8 @@ BSSvSecondTxData( spin_lock_irq(&pDevice->lock); #if 1 - if (((pDevice->bLinkPass == true) && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking - (pDevice->fWPA_Authened == true)) { //wpa linking + if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking + pDevice->fWPA_Authened) { //wpa linking #else if (pDevice->bLinkPass == true) { #endif diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c index f05f9f55398b..950039f6d128 100644 --- a/drivers/staging/vt6655/wctl.c +++ b/drivers/staging/vt6655/wctl.c @@ -110,7 +110,7 @@ unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader) unsigned int ii; for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if ((pDevice->sRxDFCB[ii].bInUse == true) && + if (pDevice->sRxDFCB[ii].bInUse && ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2, pMACHeader->abyAddr2)) { // @@ -141,7 +141,7 @@ unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader) if (pDevice->cbFreeDFCB == 0) return pDevice->cbDFCB; for (ii = 0; ii < pDevice->cbDFCB; ii++) { - if (pDevice->sRxDFCB[ii].bInUse == false) { + if (!pDevice->sRxDFCB[ii].bInUse) { pDevice->cbFreeDFCB--; pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; pDevice->sRxDFCB[ii].bInUse = true; @@ -174,7 +174,7 @@ bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, unsigned i { unsigned int uHeaderSize; - if (bWEP == true) { + if (bWEP) { uHeaderSize = 28; if (bExtIV) // ExtIV diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index ed4b32b6d9ce..5200a2a0ecca 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -468,15 +468,15 @@ vMgrAssocBeginSta( // ERP Phy (802.11g) should support short preamble. if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { + if (CARDbIsShorSlotTime(pMgmt->pAdapter)) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); } } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { + if (CARDbIsShortPreamble(pMgmt->pAdapter)) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); } } - if (pMgmt->b11hEnable == true) + if (pMgmt->b11hEnable) pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); /* build an assocreq frame and send it */ @@ -539,15 +539,15 @@ vMgrReAssocBeginSta( // ERP Phy (802.11g) should support short preamble. if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); - if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) { + if (CARDbIsShorSlotTime(pMgmt->pAdapter)) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1); } } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) { - if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) { + if (CARDbIsShortPreamble(pMgmt->pAdapter)) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1); } } - if (pMgmt->b11hEnable == true) + if (pMgmt->b11hEnable) pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); pTxPacket = s_MgrMakeReAssocRequest @@ -736,7 +736,7 @@ s_vMgrRxAssocRequest( pDevice->bProtectMode = true; pDevice->bNonERPPresent = true; } - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { + if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { pDevice->bBarkerPreambleMd = true; } @@ -891,7 +891,7 @@ s_vMgrRxReAssocRequest( pDevice->bProtectMode = true; pDevice->bNonERPPresent = true; } - if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) { + if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) { pDevice->bBarkerPreambleMd = true; } @@ -1719,7 +1719,7 @@ s_vMgrRxDeauthentication( } /* else, ignore it. TODO: IBSS authentication service would be implemented here */ - }; + } return; } @@ -1837,7 +1837,7 @@ s_vMgrRxBeacon( bChannelHit = true; } //2008-0730-01<Add>by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel) == true) + if (ChannelExceedZoneType(pDevice, byCurrChannel)) return; if (sFrame.pERP != NULL) { @@ -1957,9 +1957,9 @@ s_vMgrRxBeacon( } } - if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) == true) && - (bIsBSSIDEqual == true) && - (bIsSSIDEqual == true) && + if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) && + bIsBSSIDEqual && + bIsSSIDEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { // add state check to prevent reconnect fail since we'll receive Beacon @@ -2001,7 +2001,7 @@ s_vMgrRxBeacon( &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate), &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate) ); - if (bUpdatePhyParameter == true) { + if (bUpdatePhyParameter) { CARDbSetPhyParameter(pMgmt->pAdapter, pMgmt->eCurrentPHYMode, pMgmt->wCurrCapInfo, @@ -2023,7 +2023,7 @@ s_vMgrRxBeacon( sFrame.pIE_CHSW->byCount ); - } else if (bIsChannelEqual == false) { + } else if (!bIsChannelEqual) { set_channel(pMgmt->pAdapter, pBSSList->uChannel); } } @@ -2067,12 +2067,12 @@ s_vMgrRxBeacon( } // if infra mode - if (bIsAPBeacon == true) { + if (bIsAPBeacon) { // Infra mode: Local TSF always follow AP's TSF if Difference huge. if (bTSFLargeDiff) bUpdateTSF = true; - if ((pDevice->bEnablePSMode == true) && (sFrame.pTIM != 0)) { + if (pDevice->bEnablePSMode && (sFrame.pTIM != 0)) { // deal with DTIM, analysis TIM pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false; pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; @@ -2092,10 +2092,10 @@ s_vMgrRxBeacon( pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false; } else { pMgmt->bInTIM = false; - }; + } } else { pMgmt->bInTIM = false; - }; + } if (pMgmt->bInTIM || (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) { @@ -2110,7 +2110,7 @@ s_vMgrRxBeacon( } else { pMgmt->bInTIMWake = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n"); - if (pDevice->bPWBitOn == false) { + if (!pDevice->bPWBitOn) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n"); if (PSbSendNullPacket(pDevice)) pDevice->bPWBitOn = true; @@ -2332,10 +2332,10 @@ vMgrCreateOwnIBSS( } // Disable Protect Mode - pDevice->bProtectMode = 0; + pDevice->bProtectMode = false; MACvDisableProtectMD(pDevice->PortOffset); - pDevice->bBarkerPreambleMd = 0; + pDevice->bBarkerPreambleMd = false; MACvDisableBarkerPreambleMd(pDevice->PortOffset); // Kyle Test 2003.11.04 @@ -2480,7 +2480,7 @@ vMgrCreateOwnIBSS( pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1)); } - if ((pMgmt->b11hEnable == true) && + if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1); } else { @@ -2530,7 +2530,7 @@ vMgrJoinBSSBegin( unsigned char byTopOFDMBasicRate = RATE_1M; for (ii = 0; ii < MAX_BSS_NUM; ii++) { - if (pMgmt->sBSSList[ii].bActive == true) + if (pMgmt->sBSSList[ii].bActive) break; } @@ -2656,7 +2656,7 @@ vMgrJoinBSSBegin( if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult); - if (bResult == false) { + if (!bResult) { vFlush_PMKID_Candidate((void *)pDevice); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n"); bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); @@ -2671,19 +2671,19 @@ vMgrJoinBSSBegin( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n"); } else { pMgmt->eCurrState = WMAC_STATE_IDLE; - }; + } } else { // ad-hoc mode BSS if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) { - if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) { + if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) { // encryption mode error pMgmt->eCurrState = WMAC_STATE_IDLE; return; } } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { - if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) { + if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) { // encryption mode error pMgmt->eCurrState = WMAC_STATE_IDLE; return; @@ -2740,8 +2740,8 @@ vMgrJoinBSSBegin( bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); } else { pMgmt->eCurrState = WMAC_STATE_IDLE; - }; - }; + } + } return; } @@ -2776,10 +2776,10 @@ s_vMgrSynchBSS( *pStatus = CMD_STATUS_FAILURE; - if (s_bCipherMatch(pCurr, + if (!s_bCipherMatch(pCurr, pDevice->eEncryptionStatus, &(pMgmt->byCSSPK), - &(pMgmt->byCSSGK)) == false) { + &(pMgmt->byCSSGK))) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n"); return; } @@ -2869,18 +2869,17 @@ s_vMgrSynchBSS( CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC); } - if (CARDbSetPhyParameter(pMgmt->pAdapter, + if (!CARDbSetPhyParameter(pMgmt->pAdapter, ePhyType, pCurr->wCapInfo, pCurr->sERP.byERP, pMgmt->abyCurrSuppRates, - pMgmt->abyCurrExtSuppRates - ) != true) { + pMgmt->abyCurrExtSuppRates)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); return; } // set channel and clear NAV - if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) { + if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel); return; } @@ -2924,7 +2923,7 @@ static void Encyption_Rebuild( if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection, (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info. - if (pCurr->bWPAValid == true) { //WPA-PSK + if (pCurr->bWPAValid) { //WPA-PSK pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; if (pCurr->abyPKType[0] == WPA_TKIP) { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP @@ -2933,7 +2932,7 @@ static void Encyption_Rebuild( pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n"); } - } else if (pCurr->bWPA2Valid == true) { //WPA2-PSK + } else if (pCurr->bWPA2Valid) { //WPA2-PSK pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) { pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP @@ -3150,8 +3149,7 @@ s_MgrMakeBeacon( } } - if ((pMgmt->b11hEnable == true) && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { + if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { // Country IE pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); set_country_IE(pMgmt->pAdapter, pbyBuffer); @@ -3164,7 +3162,7 @@ s_MgrMakeBeacon( ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; pbyBuffer += (1) + WLAN_IEHDR_LEN; uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel == true) { + if (pMgmt->bSwitchChannel) { // Channel Switch IE ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; @@ -3193,7 +3191,7 @@ s_MgrMakeBeacon( pbyBuffer += (7) + WLAN_IEHDR_LEN; uLength += (7) + WLAN_IEHDR_LEN; for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { + if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { pbyBuffer += 2; uLength += 2; pIBSSDFS->len += 2; @@ -3209,11 +3207,11 @@ s_MgrMakeBeacon( sFrame.pERP->byElementID = WLAN_EID_ERP; sFrame.pERP->len = 1; sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode == true) + if (pDevice->bProtectMode) sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent == true) + if (pDevice->bNonERPPresent) sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd == true) + if (pDevice->bBarkerPreambleMd) sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; } if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) { @@ -3225,7 +3223,7 @@ s_MgrMakeBeacon( ); } // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { if (pMgmt->wWPAIELen != 0) { sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); @@ -3338,16 +3336,15 @@ s_MgrMakeProbeResponse( sFrame.pERP->byElementID = WLAN_EID_ERP; sFrame.pERP->len = 1; sFrame.pERP->byContext = 0; - if (pDevice->bProtectMode == true) + if (pDevice->bProtectMode) sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION; - if (pDevice->bNonERPPresent == true) + if (pDevice->bNonERPPresent) sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT; - if (pDevice->bBarkerPreambleMd == true) + if (pDevice->bBarkerPreambleMd) sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE; } - if ((pMgmt->b11hEnable == true) && - (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { + if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) { // Country IE pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len); set_country_IE(pMgmt->pAdapter, pbyBuffer); @@ -3360,7 +3357,7 @@ s_MgrMakeProbeResponse( ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0; pbyBuffer += (1) + WLAN_IEHDR_LEN; uLength += (1) + WLAN_IEHDR_LEN; - if (pMgmt->bSwitchChannel == true) { + if (pMgmt->bSwitchChannel) { // Channel Switch IE ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH; ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3; @@ -3389,7 +3386,7 @@ s_MgrMakeProbeResponse( pbyBuffer += (7) + WLAN_IEHDR_LEN; uLength += (7) + WLAN_IEHDR_LEN; for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) { - if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) { + if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) { pbyBuffer += 2; uLength += 2; pIBSSDFS->len += 2; @@ -3409,7 +3406,7 @@ s_MgrMakeProbeResponse( } // hostapd wpa/wpa2 IE - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) { + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) { if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) { if (pMgmt->wWPAIELen != 0) { sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len); @@ -3507,7 +3504,7 @@ s_MgrMakeAssocRequest( pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN; // for 802.11h - if (pMgmt->b11hEnable == true) { + if (pMgmt->b11hEnable) { if (sFrame.pCurrPowerCap == NULL) { sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len); sFrame.len += (2 + WLAN_IEHDR_LEN); @@ -3650,7 +3647,7 @@ s_MgrMakeAssocRequest( sFrame.pRSN->len += 6; // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { + if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); } else { sFrame.pRSN->abyRSN[16] = 0; @@ -3658,7 +3655,7 @@ s_MgrMakeAssocRequest( } sFrame.pRSN->len += 2; - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { + if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { // RSN PMKID pbyRSN = &sFrame.pRSN->abyRSN[18]; pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count @@ -3896,7 +3893,7 @@ s_MgrMakeReAssocRequest( sFrame.pRSN->len += 6; // RSN Capabilities - if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) { + if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) { memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2); } else { sFrame.pRSN->abyRSN[16] = 0; @@ -3904,7 +3901,7 @@ s_MgrMakeReAssocRequest( } sFrame.pRSN->len += 2; - if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { + if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { // RSN PMKID pbyRSN = &sFrame.pRSN->abyRSN[18]; pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count @@ -4141,7 +4138,7 @@ s_vMgrRxProbeResponse( } //2008-0730-01<Add>by MikeLiu - if (ChannelExceedZoneType(pDevice, byCurrChannel) == true) + if (ChannelExceedZoneType(pDevice, byCurrChannel)) return; if (sFrame.pERP != NULL) { @@ -4578,7 +4575,7 @@ bAdd_PMKID_Candidate( for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { - if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { + if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); @@ -4589,7 +4586,7 @@ bAdd_PMKID_Candidate( // New Candidate pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates]; - if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) { + if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); @@ -4650,7 +4647,7 @@ s_bCipherMatch( } if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (pBSSNode->bWPA2Valid == true) && + pBSSNode->bWPA2Valid && //20080123-01,<Add> by Einsn Liu ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { //WPA2 @@ -4684,7 +4681,7 @@ s_bCipherMatch( } } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) && - (pBSSNode->bWPAValid == true) && + pBSSNode->bWPAValid && ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) { //WPA // check Group Key Cipher diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index b697fa6c3b16..990ea0f9e9fb 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -241,7 +241,7 @@ WPA_SearchRSN( int ii; unsigned char byPKType = WPA_NONE; - if (pBSSList->bWPAValid == false) + if (!pBSSList->bWPAValid) return false; switch (byCmd) { diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 089788dfba63..2013122e92b2 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -42,14 +42,14 @@ static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ -const unsigned char abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; -const unsigned char abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const unsigned char abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; -const unsigned char abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -const unsigned char abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; +static const unsigned char abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; +static const unsigned char abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +static const unsigned char abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; +static const unsigned char abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +static const unsigned char abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; -const unsigned char abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const unsigned char abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +static const unsigned char abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +static const unsigned char abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; /*--------------------- Static Functions --------------------------*/ @@ -192,7 +192,7 @@ WPA2vParseRSN( break; } //for - if (bUseGK == true) { + if (bUseGK) { if (j != 1) { // invalid CSS, This should be only PK CSS. return; @@ -335,7 +335,7 @@ WPA2uSetIEs( pRSNIEs->len += 2; if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && - (pMgmt->bRoaming == true) && + pMgmt->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { // RSN PMKID pwPMKID = (unsigned short *)(&pRSNIEs->abyRSN[18]); // Point to PMKID count diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 044368a46c53..ee83704e4401 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -341,22 +341,22 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel) // If is_broadcast_ether_addr, set the key as every key entry's group key. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); - if ((KeybSetAllGroupKey(&(pDevice->sKey), + if (KeybSetAllGroupKey(&(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, (PQWORD) &(KeyRSC), (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, - pDevice->byLocalID) == true) && - (KeybSetDefaultKey(&(pDevice->sKey), + pDevice->byLocalID) && + KeybSetDefaultKey(&(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, (PQWORD) &(KeyRSC), (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, - pDevice->byLocalID) == true)) { + pDevice->byLocalID)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); } else { @@ -389,7 +389,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel) (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, - pDevice->byLocalID) == true) { + pDevice->byLocalID)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); } else { @@ -804,7 +804,7 @@ static int wpa_set_associate(PSDevice pDevice, else pDevice->bEncryptionEnable = false; if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || - ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bWepEnabled == true)))) //DavidWang //20080717-06,<Modify> by chester//Not to initial WEP + ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && bWepEnabled))) //DavidWang //20080717-06,<Modify> by chester//Not to initial WEP KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); spin_lock_irq(&pDevice->lock); pDevice->bLinkPass = false; diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index 6c7693911cd6..61b9f7bdb858 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -37,7 +37,7 @@ * SBOX Table */ -u8 sbox_table[256] = { +static u8 sbox_table[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, @@ -56,7 +56,7 @@ u8 sbox_table[256] = { 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; -u8 dot2_table[256] = { +static u8 dot2_table[256] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, @@ -75,7 +75,7 @@ u8 dot2_table[256] = { 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 }; -u8 dot3_table[256] = { +static u8 dot3_table[256] = { 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, @@ -115,7 +115,7 @@ static void xor_32(u8 *a, u8 *b, u8 *out) (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } -void AddRoundKey(u8 *key, int round) +static void AddRoundKey(u8 *key, int round) { u8 sbox_key[4]; u8 rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; @@ -133,7 +133,7 @@ void AddRoundKey(u8 *key, int round) xor_32(&key[12], &key[8], &key[12]); } -void SubBytes(u8 *in, u8 *out) +static void SubBytes(u8 *in, u8 *out) { int i; @@ -141,7 +141,7 @@ void SubBytes(u8 *in, u8 *out) out[i] = sbox_table[in[i]]; } -void ShiftRows(u8 *in, u8 *out) +static void ShiftRows(u8 *in, u8 *out) { out[0] = in[0]; out[1] = in[5]; @@ -161,7 +161,7 @@ void ShiftRows(u8 *in, u8 *out) out[15] = in[11]; } -void MixColumns(u8 *in, u8 *out) +static void MixColumns(u8 *in, u8 *out) { out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; @@ -170,7 +170,7 @@ void MixColumns(u8 *in, u8 *out) out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; } -void AESv128(u8 *key, u8 *data, u8 *ciphertext) +static void AESv128(u8 *key, u8 *data, u8 *ciphertext) { int i; int round; diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 4aa5ef54b683..3d4610e25fca 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -48,7 +48,7 @@ static int msglevel =MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; -u8 abyVT3184_AGC[] = { +static u8 abyVT3184_AGC[] = { 0x00, //0 0x00, //1 0x02, //2 @@ -115,7 +115,7 @@ u8 abyVT3184_AGC[] = { 0x3E //3F }; -u8 abyVT3184_AL2230[] = { +static u8 abyVT3184_AL2230[] = { 0x31,//00 0x00, 0x00, @@ -375,7 +375,7 @@ u8 abyVT3184_AL2230[] = { }; //{{RobertYu:20060515, new BB setting for VT3226D0 -u8 abyVT3184_VT3226D0[] = { +static u8 abyVT3184_VT3226D0[] = { 0x31,//00 0x00, 0x00, @@ -634,7 +634,7 @@ u8 abyVT3184_VT3226D0[] = { 0x00, }; -const u16 awcFrameTime[MAX_RATE] = +static const u16 awcFrameTime[MAX_RATE] = {10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216}; /* @@ -931,191 +931,177 @@ void BBvSetAntennaMode(struct vnt_private *pDevice, u8 byAntennaMode) * */ -int BBbVT3184Init(struct vnt_private *pDevice) +int BBbVT3184Init(struct vnt_private *priv) { - int ntStatus; - u16 wLength; - u8 * pbyAddr; - u8 * pbyAgc; - u16 wLengthAgc; - u8 abyArray[256]; + int status; + u16 lenght; + u8 *addr; + u8 *agc; + u16 lenght_agc; + u8 array[256]; u8 data; - ntStatus = CONTROLnsRequestIn(pDevice, - MESSAGE_TYPE_READ, - 0, - MESSAGE_REQUEST_EEPROM, - EEP_MAX_CONTEXT_SIZE, - pDevice->abyEEPROM); - if (ntStatus != STATUS_SUCCESS) { - return false; - } + status = CONTROLnsRequestIn(priv, MESSAGE_TYPE_READ, 0, + MESSAGE_REQUEST_EEPROM, EEP_MAX_CONTEXT_SIZE, + priv->abyEEPROM); + if (status != STATUS_SUCCESS) + return false; + + /* zonetype initial */ + priv->byOriginalZonetype = priv->abyEEPROM[EEP_OFS_ZONETYPE]; + + if (priv->config_file.ZoneType >= 0) { + if ((priv->config_file.ZoneType == 0) && + (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { + priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0; + priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Init Zone Type :USA\n"); + } else if ((priv->config_file.ZoneType == 1) && + (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { + priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; + priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Init Zone Type :Japan\n"); + } else if ((priv->config_file.ZoneType == 2) && + (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { + priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; + priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Init Zone Type :Europe\n"); + } else { + if (priv->config_file.ZoneType != + priv->abyEEPROM[EEP_OFS_ZONETYPE]) + printk("zonetype in file[%02x]\ + mismatch with in EEPROM[%02x]\n", + priv->config_file.ZoneType, + priv->abyEEPROM[EEP_OFS_ZONETYPE]); + else + printk("Read Zonetype file success,\ + use default zonetype setting[%02x]\n", + priv->config_file.ZoneType); + } + } -// if ((pDevice->abyEEPROM[EEP_OFS_RADIOCTL]&0x06)==0x04) -// return false; - -//zonetype initial - pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - if(pDevice->config_file.ZoneType >= 0) { //read zonetype file ok! - if ((pDevice->config_file.ZoneType == 0)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){ //for USA - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n"); - } - else if((pDevice->config_file.ZoneType == 1)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){ //for Japan - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Japan\n"); - } - else if((pDevice->config_file.ZoneType == 2)&& - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){ //for Europe - pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; - pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n"); - } -else { - if(pDevice->config_file.ZoneType !=pDevice->abyEEPROM[EEP_OFS_ZONETYPE]) - printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",pDevice->config_file.ZoneType,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]); - else - printk("Read Zonetype file success,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType); - } -} + if (!priv->bZoneRegExist) + priv->byZoneType = priv->abyEEPROM[EEP_OFS_ZONETYPE]; + + priv->byRFType = priv->abyEEPROM[EEP_OFS_RFTYPE]; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Zone Type %x\n", + priv->byZoneType); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RF Type %d\n", priv->byRFType); + + if ((priv->byRFType == RF_AL2230) || + (priv->byRFType == RF_AL2230S)) { + priv->byBBRxConf = abyVT3184_AL2230[10]; + lenght = sizeof(abyVT3184_AL2230); + addr = abyVT3184_AL2230; + agc = abyVT3184_AGC; + lenght_agc = sizeof(abyVT3184_AGC); + + priv->abyBBVGA[0] = 0x1C; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; + } else if (priv->byRFType == RF_AIROHA7230) { + priv->byBBRxConf = abyVT3184_AL2230[10]; + lenght = sizeof(abyVT3184_AL2230); + addr = abyVT3184_AL2230; + agc = abyVT3184_AGC; + lenght_agc = sizeof(abyVT3184_AGC); + + addr[0xd7] = 0x06; + + priv->abyBBVGA[0] = 0x1c; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; + } else if ((priv->byRFType == RF_VT3226) || + (priv->byRFType == RF_VT3226D0)) { + priv->byBBRxConf = abyVT3184_VT3226D0[10]; + lenght = sizeof(abyVT3184_VT3226D0); + addr = abyVT3184_VT3226D0; + agc = abyVT3184_AGC; + lenght_agc = sizeof(abyVT3184_AGC); + + priv->abyBBVGA[0] = 0x20; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; + /* Fix VT3226 DFC system timing issue */ + MACvRegBitsOn(priv, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT); + } else if ((priv->byRFType == RF_VT3342A0)) { + priv->byBBRxConf = abyVT3184_VT3226D0[10]; + lenght = sizeof(abyVT3184_VT3226D0); + addr = abyVT3184_VT3226D0; + agc = abyVT3184_AGC; + lenght_agc = sizeof(abyVT3184_AGC); + + priv->abyBBVGA[0] = 0x20; + priv->abyBBVGA[1] = 0x10; + priv->abyBBVGA[2] = 0x0; + priv->abyBBVGA[3] = 0x0; + priv->ldBmThreshold[0] = -70; + priv->ldBmThreshold[1] = -48; + priv->ldBmThreshold[2] = 0; + priv->ldBmThreshold[3] = 0; + /* Fix VT3226 DFC system timing issue */ + MACvRegBitsOn(priv, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT); + } else { + return true; + } - if ( !pDevice->bZoneRegExist ) { - pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - } - pDevice->byRFType = pDevice->abyEEPROM[EEP_OFS_RFTYPE]; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Zone Type %x\n", pDevice->byZoneType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RF Type %d\n", pDevice->byRFType); - - if ((pDevice->byRFType == RF_AL2230) || (pDevice->byRFType == RF_AL2230S)) { - pDevice->byBBRxConf = abyVT3184_AL2230[10]; - wLength = sizeof(abyVT3184_AL2230); - pbyAddr = abyVT3184_AL2230; - pbyAgc = abyVT3184_AGC; - wLengthAgc = sizeof(abyVT3184_AGC); - - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - } - else if (pDevice->byRFType == RF_AIROHA7230) { - pDevice->byBBRxConf = abyVT3184_AL2230[10]; - wLength = sizeof(abyVT3184_AL2230); - pbyAddr = abyVT3184_AL2230; - pbyAgc = abyVT3184_AGC; - wLengthAgc = sizeof(abyVT3184_AGC); - - // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //pbyAddr[0x09] = 0x41; - // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) - //pbyAddr[0x0a] = 0x28; - // Select VC1/VC2, CR215 = 0x02->0x06 - pbyAddr[0xd7] = 0x06; - - pDevice->abyBBVGA[0] = 0x1C; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - } - else if ( (pDevice->byRFType == RF_VT3226) || (pDevice->byRFType == RF_VT3226D0) ) { - pDevice->byBBRxConf = abyVT3184_VT3226D0[10]; //RobertYu:20060515 - wLength = sizeof(abyVT3184_VT3226D0); //RobertYu:20060515 - pbyAddr = abyVT3184_VT3226D0; //RobertYu:20060515 - pbyAgc = abyVT3184_AGC; - wLengthAgc = sizeof(abyVT3184_AGC); - - pDevice->abyBBVGA[0] = 0x20; //RobertYu:20060104, reguest by Jack - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - // Fix VT3226 DFC system timing issue - MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT); - //}} - //{{RobertYu:20060609 - } else if ( (pDevice->byRFType == RF_VT3342A0) ) { - pDevice->byBBRxConf = abyVT3184_VT3226D0[10]; - wLength = sizeof(abyVT3184_VT3226D0); - pbyAddr = abyVT3184_VT3226D0; - pbyAgc = abyVT3184_AGC; - wLengthAgc = sizeof(abyVT3184_AGC); - - pDevice->abyBBVGA[0] = 0x20; - pDevice->abyBBVGA[1] = 0x10; - pDevice->abyBBVGA[2] = 0x0; - pDevice->abyBBVGA[3] = 0x0; - pDevice->ldBmThreshold[0] = -70; - pDevice->ldBmThreshold[1] = -48; - pDevice->ldBmThreshold[2] = 0; - pDevice->ldBmThreshold[3] = 0; - // Fix VT3226 DFC system timing issue - MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT); - //}} - } else { - return true; - } + memcpy(array, addr, lenght); - memcpy(abyArray, pbyAddr, wLength); - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_WRITE, - 0, - MESSAGE_REQUEST_BBREG, - wLength, - abyArray - ); - - memcpy(abyArray, pbyAgc, wLengthAgc); - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_WRITE, - 0, - MESSAGE_REQUEST_BBAGC, - wLengthAgc, - abyArray - ); - - if ((pDevice->byRFType == RF_VT3226) || //RobertYu:20051116, 20060111 remove VT3226D0 - (pDevice->byRFType == RF_VT3342A0) //RobertYu:20060609 - ) { - ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x23); - MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01); - } - else if (pDevice->byRFType == RF_VT3226D0) - { - ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x11); - MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01); - } + CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, 0, + MESSAGE_REQUEST_BBREG, lenght, array); - ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x04,0x7F); - ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01); + memcpy(array, agc, lenght_agc); + + CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, 0, + MESSAGE_REQUEST_BBAGC, lenght_agc, array); + + if ((priv->byRFType == RF_VT3226) || + (priv->byRFType == RF_VT3342A0)) { + ControlvWriteByte(priv, MESSAGE_REQUEST_MACREG, + MAC_REG_ITRTMSET, 0x23); + MACvRegBitsOn(priv, MAC_REG_PAPEDELAY, 0x01); + } else if (priv->byRFType == RF_VT3226D0) { + ControlvWriteByte(priv, MESSAGE_REQUEST_MACREG, + MAC_REG_ITRTMSET, 0x11); + MACvRegBitsOn(priv, MAC_REG_PAPEDELAY, 0x01); + } + + ControlvWriteByte(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f); + ControlvWriteByte(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01); + + RFbRFTableDownload(priv); - RFbRFTableDownload(pDevice); /* Fix for TX USB resets from vendors driver */ - CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, USB_REG4, + CONTROLnsRequestIn(priv, MESSAGE_TYPE_READ, USB_REG4, MESSAGE_REQUEST_MEM, sizeof(data), &data); data |= 0x2; - CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_WRITE, USB_REG4, + CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, USB_REG4, MESSAGE_REQUEST_MEM, sizeof(data), &data); - return true;//ntStatus; + return true; } /* @@ -1464,7 +1450,6 @@ void BBvUpdatePreEDThreshold(struct vnt_private *pDevice, int bScanning) if( bScanning ) { // need Max sensitivity //RSSI -69, -70,.... - if(pDevice->byBBPreEDIndex == 0) break; pDevice->byBBPreEDIndex = 0; ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE) @@ -1607,7 +1592,6 @@ void BBvUpdatePreEDThreshold(struct vnt_private *pDevice, int bScanning) if( bScanning ) { // need Max sensitivity //RSSI -69, -70, ... - if(pDevice->byBBPreEDIndex == 0) break; pDevice->byBBPreEDIndex = 0; ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE) @@ -1759,7 +1743,6 @@ void BBvUpdatePreEDThreshold(struct vnt_private *pDevice, int bScanning) case RF_VT3342A0: //RobertYu:20060627, testing table if( bScanning ) { // need Max sensitivity //RSSI -67, -68, ... - if(pDevice->byBBPreEDIndex == 0) break; pDevice->byBBPreEDIndex = 0; ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9) ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE) diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index dad3f8c78e21..c3fab7b7b5b6 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -62,14 +62,14 @@ static int msglevel =MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; -const u16 awHWRetry0[5][5] = { +static const u16 awHWRetry0[5][5] = { {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M}, {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M}, {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M}, {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M}, {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M} }; -const u16 awHWRetry1[5][5] = { +static const u16 awHWRetry1[5][5] = { {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M}, {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M}, {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M}, @@ -1160,10 +1160,10 @@ else { * -*/ -void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, - PSStatCounter pStatistic, u8 byTSR, u8 byPktNO) +void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, u8 byTSR, u8 byPktNO) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; + struct vnt_tx_pkt_info *pkt_info = pDevice->pkt_info; u32 uNodeIndex = 0; u8 byTxRetry; u16 wRate; @@ -1177,8 +1177,8 @@ void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, byPktNum = (byPktNO & 0x0F) >> 4; byTxRetry = (byTSR & 0xF0) >> 4; wRate = (u16) (byPktNO & 0xF0) >> 4; - wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl; - pbyDestAddr = (u8 *) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]); + wFIFOCtl = pkt_info[byPktNum].fifo_ctl; + pbyDestAddr = pkt_info[byPktNum].dest_addr; if (wFIFOCtl & FIFOCTL_AUTO_FB_0) { byFallBack = AUTO_FB_0; @@ -1384,39 +1384,43 @@ static void s_vCheckSensitivity(struct vnt_private *pDevice) static void s_uCalculateLinkQual(struct vnt_private *pDevice) { + struct net_device_stats *stats = &pDevice->stats; unsigned long TxOkRatio, TxCnt; unsigned long RxOkRatio, RxCnt; unsigned long RssiRatio; + unsigned long qual; long ldBm; -TxCnt = pDevice->scStatistic.TxNoRetryOkCount + - pDevice->scStatistic.TxRetryOkCount + - pDevice->scStatistic.TxFailCount; -RxCnt = pDevice->scStatistic.RxFcsErrCnt + - pDevice->scStatistic.RxOkCnt; -TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt); -RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt); -//decide link quality -if(pDevice->bLinkPass !=true) -{ - pDevice->scStatistic.LinkQuality = 0; - pDevice->scStatistic.SignalStren = 0; -} -else -{ - RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); - if(-ldBm < 50) { - RssiRatio = 4000; - } - else if(-ldBm > 90) { - RssiRatio = 0; - } - else { - RssiRatio = (40-(-ldBm-50))*4000/40; - } - pDevice->scStatistic.SignalStren = RssiRatio/40; - pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100; -} + TxCnt = stats->tx_packets + pDevice->wstats.discard.retries; + + RxCnt = stats->rx_packets + stats->rx_frame_errors; + + TxOkRatio = (TxCnt < 6) ? 4000:((stats->tx_packets * 4000) / TxCnt); + + RxOkRatio = (RxCnt < 6) ? 2000 : + ((stats->rx_packets * 2000) / RxCnt); + + /* decide link quality */ + if (pDevice->bLinkPass != true) { + pDevice->wstats.qual.qual = 0; + pDevice->scStatistic.SignalStren = 0; + } else { + RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); + if (-ldBm < 50) + RssiRatio = 4000; + else if (-ldBm > 90) + RssiRatio = 0; + else + RssiRatio = (40-(-ldBm-50)) * 4000 / 40; + + pDevice->scStatistic.SignalStren = RssiRatio / 40; + qual = (RssiRatio + TxOkRatio + RxOkRatio) / 100; + if (qual < 100) + pDevice->wstats.qual.qual = (u8)qual; + else + pDevice->wstats.qual.qual = 100; + } + pDevice->scStatistic.RxFcsErrCnt = 0; pDevice->scStatistic.RxOkCnt = 0; pDevice->scStatistic.TxFailCount = 0; diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index fc418555bc4d..8b28ef6bd98f 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -264,8 +264,7 @@ void BSSvUpdateAPNode(struct vnt_private *, u16 *pwCapInfo, void BSSvSecondCallBack(struct work_struct *work); -void BSSvUpdateNodeTxCounter(struct vnt_private *, PSStatCounter pStatistic, - u8 byTSR, u8 byPktNO); +void BSSvUpdateNodeTxCounter(struct vnt_private *, u8 byTSR, u8 byPktNO); void BSSvRemoveOneNode(struct vnt_private *, u32 uNodeIndex); diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 19d3cf451b88..662cfea7527e 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -66,7 +66,7 @@ static int msglevel =MSG_LEVEL_INFO; //const u16 cwRXBCNTSFOff[MAX_RATE] = //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; -const u16 cwRXBCNTSFOff[MAX_RATE] = +static const u16 cwRXBCNTSFOff[MAX_RATE] = {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3}; /* @@ -205,7 +205,7 @@ static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx) * Return Value: none * */ -void +static void CARDvCalculateOFDMRParameter ( u16 wRate, u8 byBBType, diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index e430b35463b6..5a4fa0e2581b 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -423,8 +423,7 @@ void CHvInitChannelTable(struct vnt_private *pDevice) break; } - if ((pDevice->dwDiagRefCount != 0) || - (pDevice->b11hEable == true)) { + if (pDevice->b11hEable == true) { if (bMultiBand == true) { for (ii = 0; ii < CB_MAX_CHANNEL; ii++) { sChannelTbl[ii+1].bValid = true; diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index af9eab0c00a3..547db6f0c53f 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -45,7 +45,7 @@ /* static int msglevel = MSG_LEVEL_DEBUG; */ static int msglevel = MSG_LEVEL_INFO; -const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, +static const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; #define AUTORATE_TXOK_CNT 0x0400 diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 43cb77894b66..96252adf1ea6 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -52,7 +52,6 @@ #define RATE_48M 10 #define RATE_54M 11 #define RATE_AUTO 12 -#define MAX_RATE 12 void RATEvParseMaxRate(struct vnt_private *, PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, int bUpdateBasicRate, diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index afe7074c3037..7c6dd5f52295 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -146,14 +146,6 @@ /* * TX FIFO header */ - -typedef struct tagSTxShortBufHead { - u16 wFIFOCtl; - u16 wTimeStamp; -} __attribute__ ((__packed__)) -STxShortBufHead, *PSTxShortBufHead; -typedef const STxShortBufHead *PCSTxShortBufHead; - typedef struct tagSBEACONCtl { u32 BufReady:1; u32 TSF:15; diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 62b7de19b371..c58c69a3170b 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -44,6 +44,7 @@ #include <net/cfg80211.h> #include <linux/timer.h> #include <linux/usb.h> +#include <linux/crc32.h> #ifdef SIOCETHTOOL #define DEVICE_ETHTOOL_IOCTL_SUPPORT @@ -75,6 +76,7 @@ #include "desc.h" #include "key.h" #include "card.h" +#include "rndis.h" #define VNT_USB_VENDOR_ID 0x160a #define VNT_USB_PRODUCT_ID 0x3184 @@ -149,11 +151,9 @@ typedef enum __device_msg_level { MSG_LEVEL_DEBUG = 4 /* Only for debug purpose. */ } DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL; -typedef enum __device_init_type { - DEVICE_INIT_COLD = 0, /* cold init */ - DEVICE_INIT_RESET, /* reset init or Dx to D0 power remain */ - DEVICE_INIT_DXPL /* Dx to D0 power lost init */ -} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE; +#define DEVICE_INIT_COLD 0x0 /* cold init */ +#define DEVICE_INIT_RESET 0x1 /* reset init or Dx to D0 power remain */ +#define DEVICE_INIT_DXPL 0x2 /* Dx to D0 power lost init */ /* USB */ @@ -189,6 +189,12 @@ struct vnt_usb_send_context { unsigned char Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS]; }; +/* tx packet info for rxtx */ +struct vnt_tx_pkt_info { + u16 fifo_ctl; + u8 dest_addr[ETH_ALEN]; +}; + /* structure got from configuration file as user-desired default settings */ typedef struct _DEFAULT_CONFIG { signed int ZoneType; @@ -430,6 +436,7 @@ struct vnt_private { /* Variables to track resources for the BULK Out Pipe */ struct vnt_usb_send_context *apTD[CB_MAX_TX_DESC]; u32 cbTD; + struct vnt_tx_pkt_info pkt_info[16]; /* Variables to track resources for the Interrupt In Pipe */ INT_BUFFER intBuf; @@ -467,6 +474,8 @@ struct vnt_private { u8 byOriginalZonetype; int bLinkPass; /* link status: OK or fail */ + struct vnt_cmd_card_init init_command; + struct vnt_rsp_card_init init_response; u8 abyCurrentNetAddr[ETH_ALEN]; u8 abyPermanentNetAddr[ETH_ALEN]; @@ -596,7 +605,6 @@ struct vnt_private { int bCCK; int bEncryptionEnable; - int bLongHeader; int bShortSlotTime; int bProtectMode; int bNonERPPresent; @@ -666,8 +674,6 @@ struct vnt_private { u8 abyPRNG[WLAN_WEPMAX_KEYLEN+3]; u8 byKeyIndex; - int bAES; - u32 uKeyLength; u8 abyKey[WLAN_WEP232_KEYLEN]; @@ -695,7 +701,6 @@ struct vnt_private { u8 byBBPreEDIndex; int bRadioCmd; - u32 dwDiagRefCount; /* For FOE Tuning */ u8 byFOETuning; diff --git a/drivers/staging/vt6656/device_cfg.h b/drivers/staging/vt6656/device_cfg.h index a97f7bb13db8..0b9d8349c2e4 100644 --- a/drivers/staging/vt6656/device_cfg.h +++ b/drivers/staging/vt6656/device_cfg.h @@ -65,6 +65,8 @@ struct _version { #define DEVICE_VERSION "1.19_12" #endif +#define MAX_RATE 12 + /* config file */ #include <linux/fs.h> #include <linux/fcntl.h> diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 75dc92d64056..84901c1e3b59 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -59,7 +59,7 @@ //static int msglevel =MSG_LEVEL_DEBUG; static int msglevel =MSG_LEVEL_INFO; -const u8 acbyRxRate[MAX_RATE] = +static const u8 acbyRxRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; static u8 s_byGetRateIdx(u8 byRate); @@ -291,12 +291,14 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB, if (BytesToIndicate != FrameSize) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n"); + pStats->rx_frame_errors++; return false; } if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) { // Frame Size error drop this packet. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); + pStats->rx_frame_errors++; return false; } @@ -314,6 +316,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB, (BytesToIndicate < (*pwPLCP_Length)) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length); + pStats->rx_frame_errors++; return false; } for ( ii=RATE_1M;ii<MAX_RATE;ii++) { diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index a2b4ba6d4f01..512bb5d8d3e4 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -86,45 +86,46 @@ void INTnsProcessData(struct vnt_private *pDevice) pINTData = (PSINTData) pDevice->intBuf.pDataBuf; if (pINTData->byTSR0 & TSR_VALID) { - STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (u8)(pINTData->byPkt0 & 0x0F), - (u8)(pINTData->byPkt0>>4), - pINTData->byTSR0); + if (pINTData->byTSR0 & (TSR_TMO | TSR_RETRYTMO)) + pDevice->wstats.discard.retries++; + else + pStats->tx_packets++; + BSSvUpdateNodeTxCounter(pDevice, - &(pDevice->scStatistic), pINTData->byTSR0, pINTData->byPkt0); /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/ } if (pINTData->byTSR1 & TSR_VALID) { - STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (u8)(pINTData->byPkt1 & 0x0F), - (u8)(pINTData->byPkt1>>4), - pINTData->byTSR1); + if (pINTData->byTSR1 & (TSR_TMO | TSR_RETRYTMO)) + pDevice->wstats.discard.retries++; + else + pStats->tx_packets++; + + BSSvUpdateNodeTxCounter(pDevice, - &(pDevice->scStatistic), pINTData->byTSR1, pINTData->byPkt1); /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/ } if (pINTData->byTSR2 & TSR_VALID) { - STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (u8)(pINTData->byPkt2 & 0x0F), - (u8)(pINTData->byPkt2>>4), - pINTData->byTSR2); + if (pINTData->byTSR2 & (TSR_TMO | TSR_RETRYTMO)) + pDevice->wstats.discard.retries++; + else + pStats->tx_packets++; + BSSvUpdateNodeTxCounter(pDevice, - &(pDevice->scStatistic), pINTData->byTSR2, pINTData->byPkt2); /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/ } if (pINTData->byTSR3 & TSR_VALID) { - STAvUpdateTDStatCounter(&(pDevice->scStatistic), - (u8)(pINTData->byPkt3 & 0x0F), - (u8)(pINTData->byPkt3>>4), - pINTData->byTSR3); + if (pINTData->byTSR3 & (TSR_TMO | TSR_RETRYTMO)) + pDevice->wstats.discard.retries++; + else + pStats->tx_packets++; + BSSvUpdateNodeTxCounter(pDevice, - &(pDevice->scStatistic), pINTData->byTSR3, pINTData->byPkt3); /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/ @@ -193,10 +194,6 @@ void INTnsProcessData(struct vnt_private *pDevice) pDevice->intBuf.uDataLen = 0; pDevice->intBuf.bInUse = false; - pStats->tx_packets = pDevice->scStatistic.ullTsrOK; - pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes + - pDevice->scStatistic.ullTxMulticastBytes + - pDevice->scStatistic.ullTxBroadcastBytes; - pStats->tx_errors = pDevice->scStatistic.dwTsrErr; - pStats->tx_dropped = pDevice->scStatistic.dwTsrErr; + pStats->tx_errors = pDevice->wstats.discard.retries; + pStats->tx_dropped = pDevice->wstats.discard.retries; } diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 63917abbbd00..058df6516784 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -58,9 +58,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) long ldBm; pDevice->wstats.status = pDevice->eOPMode; - if (pDevice->scStatistic.LinkQuality > 100) - pDevice->scStatistic.LinkQuality = 100; - pDevice->wstats.qual.qual = (u8)pDevice->scStatistic.LinkQuality; RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; pDevice->wstats.qual.noise = 0; @@ -68,7 +65,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) pDevice->wstats.discard.nwid = 0; pDevice->wstats.discard.code = 0; pDevice->wstats.discard.fragment = 0; - pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr; pDevice->wstats.discard.misc = 0; pDevice->wstats.miss.beacon = 0; return &pDevice->wstats; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index aae228c533ef..4cb7aa737a99 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -67,7 +67,6 @@ #include "datarate.h" #include "rf.h" #include "firmware.h" -#include "rndis.h" #include "control.h" #include "channel.h" #include "int.h" @@ -215,8 +214,7 @@ static void device_set_multi(struct net_device *dev); static int device_close(struct net_device *dev); static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static int device_init_registers(struct vnt_private *pDevice, - DEVICE_INIT_TYPE InitType); +static int device_init_registers(struct vnt_private *pDevice); static bool device_init_defrag_cb(struct vnt_private *pDevice); static void device_init_diversity_timer(struct vnt_private *pDevice); static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev); @@ -296,343 +294,352 @@ static void device_init_diversity_timer(struct vnt_private *pDevice) /* * initialization of MAC & BBP registers */ - -static int device_init_registers(struct vnt_private *pDevice, - DEVICE_INIT_TYPE InitType) +static int device_init_registers(struct vnt_private *pDevice) { struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; + struct vnt_cmd_card_init *init_cmd = &pDevice->init_command; + struct vnt_rsp_card_init *init_rsp = &pDevice->init_response; u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u8 abySNAP_RFC1042[ETH_ALEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8}; u8 byAntenna; int ii; - CMD_CARD_INIT sInitCmd; int ntStatus = STATUS_SUCCESS; - RSP_CARD_INIT sInitRsp; u8 byTmp; u8 byCalibTXIQ = 0, byCalibTXDC = 0, byCalibRXIQ = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", + DEVICE_INIT_COLD, pDevice->byPacketType); + spin_lock_irq(&pDevice->lock); - if (InitType == DEVICE_INIT_COLD) { - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); - memcpy(pDevice->abySNAP_Bridgetunnel, - abySNAP_Bridgetunnel, - ETH_ALEN); - - if ( !FIRMWAREbCheckVersion(pDevice) ) { - if (FIRMWAREbDownload(pDevice) == true) { - if (FIRMWAREbBrach2Sram(pDevice) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n"); - spin_unlock_irq(&pDevice->lock); - return false; - } - } else { - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n"); - spin_unlock_irq(&pDevice->lock); - return false; - } - } - if ( !BBbVT3184Init(pDevice) ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n"); - spin_unlock_irq(&pDevice->lock); - return false; - } - } + memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); + memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); + memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); + + if (!FIRMWAREbCheckVersion(pDevice)) { + if (FIRMWAREbDownload(pDevice) == true) { + if (FIRMWAREbBrach2Sram(pDevice) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + " FIRMWAREbBrach2Sram fail\n"); + spin_unlock_irq(&pDevice->lock); + return false; + } + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + " FIRMWAREbDownload fail\n"); + spin_unlock_irq(&pDevice->lock); + return false; + } + } - sInitCmd.byInitClass = (u8)InitType; - sInitCmd.bExistSWNetAddr = (u8) pDevice->bExistSWNetAddr; - for (ii = 0; ii < 6; ii++) - sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii]; - sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit; - sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit; - - /* issue card_init command to device */ - ntStatus = CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_CARDINIT, - 0, - 0, - sizeof(CMD_CARD_INIT), - (u8 *) &(sInitCmd)); - - if ( ntStatus != STATUS_SUCCESS ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n"); - spin_unlock_irq(&pDevice->lock); - return false; - } - if (InitType == DEVICE_INIT_COLD) { + if (!BBbVT3184Init(pDevice)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail\n"); + spin_unlock_irq(&pDevice->lock); + return false; + } - ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (u8 *) &(sInitRsp)); + init_cmd->init_class = DEVICE_INIT_COLD; + init_cmd->exist_sw_net_addr = (u8) pDevice->bExistSWNetAddr; + for (ii = 0; ii < 6; ii++) + init_cmd->sw_net_addr[ii] = pDevice->abyCurrentNetAddr[ii]; + init_cmd->short_retry_limit = pDevice->byShortRetryLimit; + init_cmd->long_retry_limit = pDevice->byLongRetryLimit; + + /* issue card_init command to device */ + ntStatus = CONTROLnsRequestOut(pDevice, + MESSAGE_TYPE_CARDINIT, 0, 0, + sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd); + if (ntStatus != STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail\n"); + spin_unlock_irq(&pDevice->lock); + return false; + } - if (ntStatus != STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n"); - spin_unlock_irq(&pDevice->lock); - return false; - } + ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_INIT_RSP, 0, 0, + sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp); + if (ntStatus != STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Cardinit request in status fail!\n"); + spin_unlock_irq(&pDevice->lock); + return false; + } /* local ID for AES functions */ - ntStatus = CONTROLnsRequestIn(pDevice, - MESSAGE_TYPE_READ, - MAC_REG_LOCALID, - MESSAGE_REQUEST_MACREG, - 1, - &pDevice->byLocalID); - - if ( ntStatus != STATUS_SUCCESS ) { - spin_unlock_irq(&pDevice->lock); - return false; - } + ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, + MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1, + &pDevice->byLocalID); + if (ntStatus != STATUS_SUCCESS) { + spin_unlock_irq(&pDevice->lock); + return false; + } /* do MACbSoftwareReset in MACvInitialize */ /* force CCK */ - pDevice->bCCK = true; + pDevice->bCCK = true; pDevice->bProtectMode = false; /* only used in 11g type, sync with ERP IE */ - pDevice->bNonERPPresent = false; - pDevice->bBarkerPreambleMd = false; - if ( pDevice->bFixRate ) { - pDevice->wCurrentRate = (u16) pDevice->uConnectionRate; - } else { - if ( pDevice->byBBType == BB_TYPE_11B ) - pDevice->wCurrentRate = RATE_11M; - else - pDevice->wCurrentRate = RATE_54M; - } + pDevice->bNonERPPresent = false; + pDevice->bBarkerPreambleMd = false; + if (pDevice->bFixRate) { + pDevice->wCurrentRate = (u16)pDevice->uConnectionRate; + } else { + if (pDevice->byBBType == BB_TYPE_11B) + pDevice->wCurrentRate = RATE_11M; + else + pDevice->wCurrentRate = RATE_54M; + } - CHvInitChannelTable(pDevice); + CHvInitChannelTable(pDevice); - pDevice->byTopOFDMBasicRate = RATE_24M; - pDevice->byTopCCKBasicRate = RATE_1M; + pDevice->byTopOFDMBasicRate = RATE_24M; + pDevice->byTopCCKBasicRate = RATE_1M; pDevice->byRevId = 0; /* target to IF pin while programming to RF chip */ - pDevice->byCurPwr = 0xFF; + pDevice->byCurPwr = 0xFF; - pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK]; - pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG]; + pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK]; + pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG]; /* load power table */ for (ii = 0; ii < 14; ii++) { - pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL]; - if (pDevice->abyCCKPwrTbl[ii] == 0) - pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr; - pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL]; - if (pDevice->abyOFDMPwrTbl[ii] == 0) - pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG; - } + pDevice->abyCCKPwrTbl[ii] = + pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL]; + + if (pDevice->abyCCKPwrTbl[ii] == 0) + pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr; + pDevice->abyOFDMPwrTbl[ii] = + pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL]; + if (pDevice->abyOFDMPwrTbl[ii] == 0) + pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG; + } /* * original zonetype is USA, but custom zonetype is Europe, * then need to recover 12, 13, 14 channels with 11 channel */ - if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || - (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&& - (pDevice->byOriginalZonetype == ZoneType_USA)) { + if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) || + (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) && + (pDevice->byOriginalZonetype == ZoneType_USA)) { for (ii = 11; ii < 14; ii++) { pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; } - } + } - pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */ + pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */ - /* load OFDM A power table */ - for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { - pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL]; - if (pDevice->abyOFDMAPwrTbl[ii] == 0) - pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA; - } + /* load OFDM A power table */ + for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { + pDevice->abyOFDMAPwrTbl[ii] = + pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL]; + + if (pDevice->abyOFDMAPwrTbl[ii] == 0) + pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA; + } - byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA]; - if (byAntenna & EEP_ANTINV) - pDevice->bTxRxAntInv = true; - else - pDevice->bTxRxAntInv = false; + byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA]; - byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); + if (byAntenna & EEP_ANTINV) + pDevice->bTxRxAntInv = true; + else + pDevice->bTxRxAntInv = false; + + byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); if (byAntenna == 0) /* if not set default is both */ - byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); - - if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { - pDevice->byAntennaCount = 2; - pDevice->byTxAntennaMode = ANT_B; - pDevice->dwTxAntennaSel = 1; - pDevice->dwRxAntennaSel = 1; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_A; - else - pDevice->byRxAntennaMode = ANT_B; - - if (pDevice->bDiversityRegCtlON) - pDevice->bDiversityEnable = true; - else - pDevice->bDiversityEnable = false; - } else { - pDevice->bDiversityEnable = false; - pDevice->byAntennaCount = 1; - pDevice->dwTxAntennaSel = 0; - pDevice->dwRxAntennaSel = 0; - if (byAntenna & EEP_ANTENNA_AUX) { - pDevice->byTxAntennaMode = ANT_A; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_B; - else - pDevice->byRxAntennaMode = ANT_A; - } else { - pDevice->byTxAntennaMode = ANT_B; - if (pDevice->bTxRxAntInv == true) - pDevice->byRxAntennaMode = ANT_A; - else - pDevice->byRxAntennaMode = ANT_B; - } - } - pDevice->ulDiversityNValue = 100*255; - pDevice->ulDiversityMValue = 100*16; - pDevice->byTMax = 1; - pDevice->byTMax2 = 4; - pDevice->ulSQ3TH = 0; - pDevice->byTMax3 = 64; + byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); + + if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { + pDevice->byAntennaCount = 2; + pDevice->byTxAntennaMode = ANT_B; + pDevice->dwTxAntennaSel = 1; + pDevice->dwRxAntennaSel = 1; + + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_A; + else + pDevice->byRxAntennaMode = ANT_B; + + if (pDevice->bDiversityRegCtlON) + pDevice->bDiversityEnable = true; + else + pDevice->bDiversityEnable = false; + } else { + pDevice->bDiversityEnable = false; + pDevice->byAntennaCount = 1; + pDevice->dwTxAntennaSel = 0; + pDevice->dwRxAntennaSel = 0; + + if (byAntenna & EEP_ANTENNA_AUX) { + pDevice->byTxAntennaMode = ANT_A; + + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_B; + else + pDevice->byRxAntennaMode = ANT_A; + } else { + pDevice->byTxAntennaMode = ANT_B; + + if (pDevice->bTxRxAntInv == true) + pDevice->byRxAntennaMode = ANT_A; + else + pDevice->byRxAntennaMode = ANT_B; + } + } + + pDevice->ulDiversityNValue = 100 * 255; + pDevice->ulDiversityMValue = 100 * 16; + pDevice->byTMax = 1; + pDevice->byTMax2 = 4; + pDevice->ulSQ3TH = 0; + pDevice->byTMax3 = 64; /* get Auto Fall Back type */ - pDevice->byAutoFBCtrl = AUTO_FB_0; + pDevice->byAutoFBCtrl = AUTO_FB_0; /* set SCAN Time */ - pDevice->uScanTime = WLAN_SCAN_MINITIME; + pDevice->uScanTime = WLAN_SCAN_MINITIME; /* default Auto Mode */ /* pDevice->NetworkType = Ndis802_11Automode; */ - pDevice->eConfigPHYMode = PHY_TYPE_AUTO; - pDevice->byBBType = BB_TYPE_11G; + pDevice->eConfigPHYMode = PHY_TYPE_AUTO; + pDevice->byBBType = BB_TYPE_11G; /* initialize BBP registers */ - pDevice->ulTxPower = 25; + pDevice->ulTxPower = 25; /* get channel range */ - pDevice->byMinChannel = 1; - pDevice->byMaxChannel = CB_MAX_CHANNEL; + pDevice->byMinChannel = 1; + pDevice->byMaxChannel = CB_MAX_CHANNEL; /* get RFType */ - pDevice->byRFType = sInitRsp.byRFType; + pDevice->byRFType = init_rsp->rf_type; - if ((pDevice->byRFType & RF_EMU) != 0) { + if ((pDevice->byRFType & RF_EMU) != 0) { /* force change RevID for VT3253 emu */ pDevice->byRevId = 0x80; - } + } /* load vt3266 calibration parameters in EEPROM */ - if (pDevice->byRFType == RF_VT3226D0) { - if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) && - (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) { - byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ]; - byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC]; - byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ]; - if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) { + if (pDevice->byRFType == RF_VT3226D0) { + if ((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) && + (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) { + + byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ]; + byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC]; + byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ]; + if (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) { /* CR255, enable TX/RX IQ and DC compensation mode */ - ControlvWriteByte(pDevice, - MESSAGE_REQUEST_BBREG, - 0xFF, - 0x03); + ControlvWriteByte(pDevice, + MESSAGE_REQUEST_BBREG, + 0xff, + 0x03); /* CR251, TX I/Q Imbalance Calibration */ - ControlvWriteByte(pDevice, - MESSAGE_REQUEST_BBREG, - 0xFB, - byCalibTXIQ); + ControlvWriteByte(pDevice, + MESSAGE_REQUEST_BBREG, + 0xfb, + byCalibTXIQ); /* CR252, TX DC-Offset Calibration */ - ControlvWriteByte(pDevice, - MESSAGE_REQUEST_BBREG, - 0xFC, - byCalibTXDC); + ControlvWriteByte(pDevice, + MESSAGE_REQUEST_BBREG, + 0xfC, + byCalibTXDC); /* CR253, RX I/Q Imbalance Calibration */ - ControlvWriteByte(pDevice, - MESSAGE_REQUEST_BBREG, - 0xFD, - byCalibRXIQ); - } else { + ControlvWriteByte(pDevice, + MESSAGE_REQUEST_BBREG, + 0xfd, + byCalibRXIQ); + } else { /* CR255, turn off BB Calibration compensation */ - ControlvWriteByte(pDevice, - MESSAGE_REQUEST_BBREG, - 0xFF, - 0x0); - } - } - } - pMgmt->eScanType = WMAC_SCAN_PASSIVE; - pMgmt->uCurrChannel = pDevice->uChannel; - pMgmt->uIBSSChannel = pDevice->uChannel; - CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel); + ControlvWriteByte(pDevice, + MESSAGE_REQUEST_BBREG, + 0xff, + 0x0); + } + } + } + + pMgmt->eScanType = WMAC_SCAN_PASSIVE; + pMgmt->uCurrChannel = pDevice->uChannel; + pMgmt->uIBSSChannel = pDevice->uChannel; + CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel); /* get permanent network address */ - memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6); + memcpy(pDevice->abyPermanentNetAddr, init_rsp->net_addr, 6); memcpy(pDevice->abyCurrentNetAddr, - pDevice->abyPermanentNetAddr, - ETH_ALEN); + pDevice->abyPermanentNetAddr, ETH_ALEN); /* if exist SW network address, use it */ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n", pDevice->abyCurrentNetAddr); - } - /* - * set BB and packet type at the same time - * set Short Slot Time, xIFS, and RSPINF - */ - if (pDevice->byBBType == BB_TYPE_11A) { - CARDbAddBasicRate(pDevice, RATE_6M); - pDevice->bShortSlotTime = true; - } else { - CARDbAddBasicRate(pDevice, RATE_1M); - pDevice->bShortSlotTime = false; - } - BBvSetShortSlotTime(pDevice); - CARDvSetBSSMode(pDevice); + /* + * set BB and packet type at the same time + * set Short Slot Time, xIFS, and RSPINF + */ + if (pDevice->byBBType == BB_TYPE_11A) { + CARDbAddBasicRate(pDevice, RATE_6M); + pDevice->bShortSlotTime = true; + } else { + CARDbAddBasicRate(pDevice, RATE_1M); + pDevice->bShortSlotTime = false; + } - if (pDevice->bUpdateBBVGA) { - pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; - pDevice->byBBVGANew = pDevice->byBBVGACurrent; - BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); - } + BBvSetShortSlotTime(pDevice); + CARDvSetBSSMode(pDevice); - pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL]; - pDevice->bHWRadioOff = false; - if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) { - ntStatus = CONTROLnsRequestIn(pDevice, - MESSAGE_TYPE_READ, - MAC_REG_GPIOCTL1, - MESSAGE_REQUEST_MACREG, - 1, - &byTmp); - - if ( ntStatus != STATUS_SUCCESS ) { - spin_unlock_irq(&pDevice->lock); - return false; - } - if ( (byTmp & GPIO3_DATA) == 0 ) { - pDevice->bHWRadioOff = true; - MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD); - } else { - MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD); - pDevice->bHWRadioOff = false; - } + if (pDevice->bUpdateBBVGA) { + pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; + pDevice->byBBVGANew = pDevice->byBBVGACurrent; - } + BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); + } - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38); - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); - MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01); + pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL]; + pDevice->bHWRadioOff = false; - if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) { - CARDbRadioPowerOff(pDevice); - } else { - CARDbRadioPowerOn(pDevice); - } + if ((pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0) { + ntStatus = CONTROLnsRequestIn(pDevice, MESSAGE_TYPE_READ, + MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &byTmp); - spin_unlock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n"); - return true; + if (ntStatus != STATUS_SUCCESS) { + spin_unlock_irq(&pDevice->lock); + return false; + } + + if ((byTmp & GPIO3_DATA) == 0) { + pDevice->bHWRadioOff = true; + MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD); + } else { + MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD); + pDevice->bHWRadioOff = false; + } + + } + + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, + MAC_REG_PAPEDELAY, LEDSTS_TMLEN, 0x38); + + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, + MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW); + + MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL0, 0x01); + + if ((pDevice->bHWRadioOff == true) || + (pDevice->bRadioControlOff == true)) { + CARDbRadioPowerOff(pDevice); + } else { + CARDbRadioPowerOn(pDevice); + } + + + spin_unlock_irq(&pDevice->lock); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n"); + + return true; } #ifdef CONFIG_PM /* Minimal support for suspend and resume */ @@ -962,10 +969,10 @@ static int device_open(struct net_device *dev) /* read config file */ Read_config_file(pDevice); - if (device_init_registers(pDevice, DEVICE_INIT_COLD) == false) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n"); - goto free_all; - } + if (device_init_registers(pDevice) == false) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n"); + goto free_all; + } device_set_multi(pDevice->dev); @@ -1187,22 +1194,6 @@ out: return NETDEV_TX_OK; } -static unsigned const ethernet_polynomial = 0x04c11db7U; -static inline u32 ether_crc(int length, unsigned char *data) -{ - int crc = -1; - - while(--length >= 0) { - unsigned char current_octet = *data++; - int bit; - for (bit = 0; bit < 8; bit++, current_octet >>= 1) { - crc = (crc << 1) ^ - ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); - } - } - return crc; -} - /* find out the start position of str2 from str1 */ static unsigned char *kstrstr(const unsigned char *str1, const unsigned char *str2) { diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index 12333cdcbc6a..002f2b29a636 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -334,95 +334,6 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic, } /* - * Description: Update Tx Statistic Counter - * - * Parameters: - * In: - * pStatistic - Pointer to Statistic Counter Data Structure - * byTSR0 - Tx Status - * byTSR1 - Tx Status - * pbyBuffer - Tx Buffer - * cbFrameLength - Tx Length - * uIdx - Index of Tx DMA - * Out: - * none - * - * Return Value: none - * - */ -void -STAvUpdateTDStatCounter ( - PSStatCounter pStatistic, - u8 byPktNum, - u8 byRate, - u8 byTSR - ) -{ - u8 byRetyCnt; - // increase tx packet count - pStatistic->dwTsrTxPacket++; - - byRetyCnt = (byTSR & 0xF0) >> 4; - if (byRetyCnt != 0) { - pStatistic->dwTsrRetry++; - pStatistic->dwTsrTotalRetry += byRetyCnt; - pStatistic->dwTxFail[byRate]+= byRetyCnt; - pStatistic->dwTxFail[MAX_RATE] += byRetyCnt; - - if ( byRetyCnt == 0x1) - pStatistic->dwTsrOnceRetry++; - else - pStatistic->dwTsrMoreThanOnceRetry++; - - if (byRetyCnt <= 8) - pStatistic->dwTxRetryCount[byRetyCnt-1]++; - - } - if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) { - - if (byRetyCnt < 2) - pStatistic->TxNoRetryOkCount ++; - else - pStatistic->TxRetryOkCount ++; - - pStatistic->ullTsrOK++; - pStatistic->CustomStat.ullTsrAllOK++; - // update counters in case that successful transmit - pStatistic->dwTxOk[byRate]++; - pStatistic->dwTxOk[MAX_RATE]++; - - if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD ) { - pStatistic->ullTxBroadcastFrames++; - pStatistic->ullTxBroadcastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength; - } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) { - pStatistic->ullTxMulticastFrames++; - pStatistic->ullTxMulticastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength; - } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) { - pStatistic->ullTxDirectedFrames++; - pStatistic->ullTxDirectedBytes += pStatistic->abyTxPktInfo[byPktNum].wLength; - } - } - else { - - pStatistic->TxFailCount ++; - - pStatistic->dwTsrErr++; - if (byTSR & TSR_RETRYTMO) - pStatistic->dwTsrRetryTimeout++; - if (byTSR & TSR_TMO) - pStatistic->dwTsrTransmitTimeout++; - } - - if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD ) { - pStatistic->dwTsrBroadcast++; - } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) { - pStatistic->dwTsrMulticast++; - } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) { - pStatistic->dwTsrDirected++; - } -} - -/* * Description: Update 802.11 mib counter * * Parameters: diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 35375325a777..c342dadf2546 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -222,7 +222,6 @@ typedef struct tagSTxPktInfo { u8 abyDestAddr[ETH_ALEN]; } STxPktInfo, *PSTxPktInfo; -#define MAX_RATE 12 // // statistic counter // @@ -360,9 +359,6 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic, u8 byRxRate, u8 * pbyBuffer, unsigned int cbFrameLength); -void STAvUpdateTDStatCounter(PSStatCounter pStatistic, u8 byPktNum, - u8 byRate, u8 byTSR); - void STAvUpdate802_11Counter( PSDot11Counters p802_11Counter, diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index d27fa434550d..1e8f64bff03c 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -419,7 +419,7 @@ static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = { ///}}RobertYu //{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode -const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = { +static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = { 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz @@ -597,7 +597,7 @@ static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = { * -*/ -const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = { +static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = { 0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, 0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, 0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, @@ -740,9 +740,6 @@ int RFbSetPower(struct vnt_private *priv, u32 rate, u32 channel) int ret = true; u8 power = priv->byCCKPwr; - if (priv->dwDiagRefCount) - return true; - if (channel == 0) return -EINVAL; diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h index 5cf5e732a36f..3661f82766e0 100644 --- a/drivers/staging/vt6656/rndis.h +++ b/drivers/staging/vt6656/rndis.h @@ -79,23 +79,23 @@ typedef struct _CMD_WRITE_MASK u8 byMask; } CMD_WRITE_MASK, *PCMD_WRITE_MASK; -typedef struct _CMD_CARD_INIT +struct vnt_cmd_card_init { - u8 byInitClass; - u8 bExistSWNetAddr; - u8 bySWNetAddr[6]; - u8 byShortRetryLimit; - u8 byLongRetryLimit; -} CMD_CARD_INIT, *PCMD_CARD_INIT; - -typedef struct _RSP_CARD_INIT + u8 init_class; + u8 exist_sw_net_addr; + u8 sw_net_addr[6]; + u8 short_retry_limit; + u8 long_retry_limit; +}; + +struct vnt_rsp_card_init { - u8 byStatus; - u8 byNetAddr[6]; - u8 byRFType; - u8 byMinChannel; - u8 byMaxChannel; -} RSP_CARD_INIT, *PRSP_CARD_INIT; + u8 status; + u8 net_addr[6]; + u8 rf_type; + u8 min_channel; + u8 max_channel; +}; typedef struct _CMD_SET_KEY { diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 35a3ddb41a6a..3186971eaa3f 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -64,16 +64,16 @@ static int msglevel = MSG_LEVEL_INFO; -const u16 wTimeStampOff[2][MAX_RATE] = { +static const u16 wTimeStampOff[2][MAX_RATE] = { {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble }; -const u16 wFB_Opt0[2][5] = { +static const u16 wFB_Opt0[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1 }; -const u16 wFB_Opt1[2][5] = { +static const u16 wFB_Opt1[2][5] = { {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1 }; @@ -96,7 +96,7 @@ const u16 wFB_Opt1[2][5] = { static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum, u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl); -static void *s_vGetFreeContext(struct vnt_private *pDevice); +static struct vnt_usb_send_context *s_vGetFreeContext(struct vnt_private *); static u16 s_vGenerateTxParameter(struct vnt_private *pDevice, u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer, @@ -136,48 +136,43 @@ static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck, u8 byFBOption); -static void *s_vGetFreeContext(struct vnt_private *pDevice) +static struct vnt_usb_send_context + *s_vGetFreeContext(struct vnt_private *priv) { - struct vnt_usb_send_context *pContext = NULL; - struct vnt_usb_send_context *pReturnContext = NULL; + struct vnt_usb_send_context *context = NULL; int ii; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n"); - - for (ii = 0; ii < pDevice->cbTD; ii++) { - if (!pDevice->apTD[ii]) - return NULL; - pContext = pDevice->apTD[ii]; - if (pContext->bBoolInUse == false) { - pContext->bBoolInUse = true; - memset(pContext->Data, 0, MAX_TOTAL_SIZE_WITH_ALL_HEADERS); - pReturnContext = pContext; - break; - } - } - if ( ii == pDevice->cbTD ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n"); - } - return (void *) pReturnContext; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n"); + + for (ii = 0; ii < priv->cbTD; ii++) { + if (!priv->apTD[ii]) + return NULL; + + context = priv->apTD[ii]; + if (context->bBoolInUse == false) { + context->bBoolInUse = true; + memset(context->Data, 0, + MAX_TOTAL_SIZE_WITH_ALL_HEADERS); + return context; + } + } + + if (ii == priv->cbTD) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n"); + + return NULL; } static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum, u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl) { - PSStatCounter pStatistic = &pDevice->scStatistic; - - if (is_broadcast_ether_addr(pbyDestAddr)) - pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD; - else if (is_multicast_ether_addr(pbyDestAddr)) - pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI; - else - pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI; - - pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength; - pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl; - memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr, - pbyDestAddr, - ETH_ALEN); + struct net_device_stats *stats = &pDevice->stats; + struct vnt_tx_pkt_info *pkt_info = pDevice->pkt_info; + + pkt_info[byPktNum].fifo_ctl = wFIFOCtl; + memcpy(pkt_info[byPktNum].dest_addr, pbyDestAddr, ETH_ALEN); + + stats->tx_bytes += wPktLength; } static void s_vFillTxKey(struct vnt_private *pDevice, @@ -278,7 +273,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice, mic_hdr->tsc_15_0 = cpu_to_be16(pTransmitKey->wTSC15_0); /* MICHDR1 */ - if (pDevice->bLongHeader) + if (ieee80211_has_a4(pMACHeader->frame_control)) mic_hdr->hlen = cpu_to_be16(28); else mic_hdr->hlen = cpu_to_be16(22); @@ -292,7 +287,7 @@ static void s_vFillTxKey(struct vnt_private *pDevice, & 0xc78f); mic_hdr->seq_ctrl = cpu_to_le16(pMACHeader->seq_ctrl & 0xf); - if (pDevice->bLongHeader) + if (ieee80211_has_a4(pMACHeader->frame_control)) memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN); } } @@ -790,7 +785,6 @@ static u16 s_vGenerateTxParameter(struct vnt_private *pDevice, { struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head; union vnt_tx_data_head *head = NULL; - u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */ u16 wFifoCtl; u8 byFBOption = AUTO_FB_NONE; @@ -805,9 +799,6 @@ static u16 s_vGenerateTxParameter(struct vnt_private *pDevice, if (!pFifoHead) return 0; - if (pDevice->bLongHeader) - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (need_rts) { struct vnt_rrv_time_rts *pBuf = @@ -978,28 +969,19 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, bSoftWEP = true; /* WEP 256 */ } - // Get pkt type - if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) { - if (pDevice->dwDiagRefCount == 0) { - cb802_1_H_len = 8; - } else { - cb802_1_H_len = 2; - } - } else { - cb802_1_H_len = 0; - } + /* Get pkt type */ + if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) + cb802_1_H_len = 8; + else + cb802_1_H_len = 0; cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len; //Set packet type pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8); - if (pDevice->dwDiagRefCount != 0) { - bNeedACK = false; - pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK); - } else { //if (pDevice->dwDiagRefCount != 0) { if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { + (pDevice->eOPMode == OP_MODE_AP)) { if (is_multicast_ether_addr(psEthHeader->h_dest)) { bNeedACK = false; pTxBufHead->wFIFOCtl = @@ -1008,26 +990,17 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, bNeedACK = true; pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; } - } - else { - // MSDUs in Infra mode always need ACK - bNeedACK = true; - pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; - } - } //if (pDevice->dwDiagRefCount != 0) { + } else { + /* MSDUs in Infra mode always need ACK */ + bNeedACK = true; + pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK; + } pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us; - //Set FIFOCTL_LHEAD - if (pDevice->bLongHeader) - pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD; - //Set FRAGCTL_MACHDCNT - if (pDevice->bLongHeader) { - cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6; - } else { - cbMACHdLen = WLAN_HDR_ADDR3_LEN; - } + cbMACHdLen = WLAN_HDR_ADDR3_LEN; + pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10); //Set FIFOCTL_GrpAckPolicy @@ -1183,24 +1156,19 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType, } } - // 802.1H - if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) { - if (pDevice->dwDiagRefCount == 0) { + /* 802.1H */ + if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) { if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) || - (psEthHeader->h_proto == cpu_to_le16(0xF380))) { + (psEthHeader->h_proto == cpu_to_le16(0xF380))) memcpy((u8 *) (pbyPayloadHead), - abySNAP_Bridgetunnel, 6); - } else { - memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); - } - pbyType = (u8 *) (pbyPayloadHead + 6); - memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16)); - } else { - memcpy((u8 *) (pbyPayloadHead), &(psEthHeader->h_proto), sizeof(u16)); + abySNAP_Bridgetunnel, 6); + else + memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6); - } + pbyType = (u8 *) (pbyPayloadHead + 6); - } + memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16)); + } if (pPacket != NULL) { // Copy the Packet into a tx Buffer @@ -1352,11 +1320,6 @@ static void s_vGenerateMACHeader(struct vnt_private *pDevice, pMACHeader->duration_id = cpu_to_le16(wDuration); - if (pDevice->bLongHeader) { - PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr; - pMACHeader->frame_control |= (FC_TODS | FC_FROMDS); - memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN); - } pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); //Set FragNumber in Sequence Control @@ -1409,7 +1372,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, u32 cbMacHdLen; u16 wCurrentRate = RATE_1M; - pContext = (struct vnt_usb_send_context *)s_vGetFreeContext(pDevice); + pContext = s_vGetFreeContext(pDevice); if (NULL == pContext) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n"); @@ -1494,7 +1457,6 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, // Notes: // Although spec says MMPDU can be fragmented; In most case, // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) { if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { @@ -1515,7 +1477,6 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, cbIVlen = 8;//RSN Header cbICVlen = 8;//MIC pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; } //MAC Header should be padding 0 to DW alignment. uPadding = 4 - (cbMacHdLen%4); @@ -1659,20 +1620,17 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, struct vnt_tx_mgmt *pPacket) { struct vnt_beacon_buffer *pTX_Buffer; + struct vnt_tx_short_buf_head *short_head; u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; u32 cbHeaderSize = 0; - u16 wTxBufSize = sizeof(STxShortBufHead); - PSTxShortBufHead pTxBufHead; struct ieee80211_hdr *pMACHeader; - struct vnt_tx_datahead_ab *pTxDataHead; u16 wCurrentRate; u32 cbFrameBodySize; u32 cbReqCount; - u8 *pbyTxBufferAddr; struct vnt_usb_send_context *pContext; CMD_STATUS status; - pContext = (struct vnt_usb_send_context *)s_vGetFreeContext(pDevice); + pContext = s_vGetFreeContext(pDevice); if (NULL == pContext) { status = CMD_STATUS_RESOURCES; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n"); @@ -1680,49 +1638,50 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, } pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->Data[0]; - pbyTxBufferAddr = (u8 *)&(pTX_Buffer->wFIFOCtl); + short_head = &pTX_Buffer->short_head; cbFrameBodySize = pPacket->cbPayloadLen; - pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr; - wTxBufSize = sizeof(STxShortBufHead); + cbHeaderSize = sizeof(struct vnt_tx_short_buf_head); - if (pDevice->byBBType == BB_TYPE_11A) { - wCurrentRate = RATE_6M; - pTxDataHead = (struct vnt_tx_datahead_ab *) - (pbyTxBufferAddr + wTxBufSize); - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A, - &pTxDataHead->ab); - //Get Duration and TimeStampOff - pTxDataHead->wDuration = s_uGetDataDuration(pDevice, - PK_TYPE_11A, false); - pTxDataHead->wTimeStampOff = vnt_time_stamp_off(pDevice, wCurrentRate); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab); - } else { - wCurrentRate = RATE_1M; - pTxBufHead->wFIFOCtl |= FIFOCTL_11B; - pTxDataHead = (struct vnt_tx_datahead_ab *) - (pbyTxBufferAddr + wTxBufSize); - //Get SignalField,ServiceField,Length - BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B, - &pTxDataHead->ab); - //Get Duration and TimeStampOff - pTxDataHead->wDuration = s_uGetDataDuration(pDevice, + if (pDevice->byBBType == BB_TYPE_11A) { + wCurrentRate = RATE_6M; + + /* Get SignalField,ServiceField,Length */ + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, + PK_TYPE_11A, &short_head->ab); + + /* Get Duration and TimeStampOff */ + short_head->duration = s_uGetDataDuration(pDevice, + PK_TYPE_11A, false); + short_head->time_stamp_off = + vnt_time_stamp_off(pDevice, wCurrentRate); + } else { + wCurrentRate = RATE_1M; + short_head->fifo_ctl |= FIFOCTL_11B; + + /* Get SignalField,ServiceField,Length */ + BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate, + PK_TYPE_11B, &short_head->ab); + + /* Get Duration and TimeStampOff */ + short_head->duration = s_uGetDataDuration(pDevice, PK_TYPE_11B, false); - pTxDataHead->wTimeStampOff = vnt_time_stamp_off(pDevice, wCurrentRate); - cbHeaderSize = wTxBufSize + sizeof(struct vnt_tx_datahead_ab); - } + short_head->time_stamp_off = + vnt_time_stamp_off(pDevice, wCurrentRate); + } - //Generate Beacon Header - pMACHeader = (struct ieee80211_hdr *)(pbyTxBufferAddr + cbHeaderSize); - memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); - pMACHeader->duration_id = 0; - pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); - pDevice->wSeqCounter++ ; - if (pDevice->wSeqCounter > 0x0fff) - pDevice->wSeqCounter = 0; + /* Generate Beacon Header */ + pMACHeader = &pTX_Buffer->hdr; + + memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen); + + pMACHeader->duration_id = 0; + pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4); + pDevice->wSeqCounter++; + if (pDevice->wSeqCounter > 0x0fff) + pDevice->wSeqCounter = 0; cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize; @@ -1781,7 +1740,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) } p80211Header = (PUWLAN_80211HDR)skb->data; - pContext = (struct vnt_usb_send_context *)s_vGetFreeContext(pDevice); + pContext = s_vGetFreeContext(pDevice); if (NULL == pContext) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n"); @@ -1892,7 +1851,6 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) // Notes: // Although spec says MMPDU can be fragmented; In most case, // no one will send a MMPDU under fragmentation. With RTS may occur. - pDevice->bAES = false; //Set FRAGCTL_WEPTYP if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) { if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) { @@ -1914,7 +1872,6 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb) cbICVlen = 8;//MIC cbMICHDR = sizeof(struct vnt_mic_hdr); pTxBufHead->wFragCtl |= FRAGCTL_AES; - pDevice->bAES = true; } //MAC Header should be padding 0 to DW alignment. uPadding = 4 - (cbMacHdLen%4); @@ -2204,7 +2161,7 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, } } - pContext = (struct vnt_usb_send_context *)s_vGetFreeContext(pDevice); + pContext = s_vGetFreeContext(pDevice); if (pContext == NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n"); @@ -2529,7 +2486,7 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen, u32 status; u16 wKeepRate = pDevice->wCurrentRate; - pContext = (struct vnt_usb_send_context *)s_vGetFreeContext(pDevice); + pContext = s_vGetFreeContext(pDevice); if (NULL == pContext) { return false; diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index eecbe890027e..b3ee6d01aa88 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -230,12 +230,20 @@ struct vnt_tx_buffer { union vnt_tx_head tx_head; } __packed; +struct vnt_tx_short_buf_head { + u16 fifo_ctl; + u16 time_stamp; + struct vnt_phy_field ab; + u16 duration; + u16 time_stamp_off; +} __packed; + struct vnt_beacon_buffer { u8 byType; u8 byPKTNO; u16 wTxByteCount; - u16 wFIFOCtl; - u16 wTimeStamp; + struct vnt_tx_short_buf_head short_head; + struct ieee80211_hdr hdr; } __packed; void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb); diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index 9d643e449ac3..28282f345901 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -39,7 +39,7 @@ /* The 2nd table is the same as the 1st but with the upper and lower */ /* bytes swapped. To allow an endian tolerant implementation, the byte */ /* halves have been expressed independently here. */ -const u8 TKIP_Sbox_Lower[256] = { +static const u8 TKIP_Sbox_Lower[256] = { 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, @@ -74,7 +74,7 @@ const u8 TKIP_Sbox_Lower[256] = { 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A }; -const u8 TKIP_Sbox_Upper[256] = { +static const u8 TKIP_Sbox_Upper[256] = { 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 2f8e2a875331..6b9522914634 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -55,8 +55,8 @@ #include "channel.h" #include "iowpa.h" -static int msglevel =MSG_LEVEL_INFO; -//static int msglevel =MSG_LEVEL_DEBUG; +static int msglevel = MSG_LEVEL_INFO; +//static int msglevel = MSG_LEVEL_DEBUG; static void s_vProbeChannel(struct vnt_private *); @@ -87,38 +87,33 @@ static void vAdHocBeaconStop(struct vnt_private *pDevice) struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; int bStop; - /* - * temporarily stop Beacon packet for AdHoc Server - * if all of the following coditions are met: - * (1) STA is in AdHoc mode - * (2) VT3253 is programmed as automatic Beacon Transmitting - * (3) One of the following conditions is met - * (3.1) AdHoc channel is in B/G band and the - * current scan channel is in A band - * or - * (3.2) AdHoc channel is in A mode - */ - bStop = false; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) - { - if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && - (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) - { - bStop = true; - } - if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) - { - bStop = true; - } - } - - if (bStop) - { - //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n", - // pMgmt->uIBSSChannel, pMgmt->uScanChannel)); - MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX); - } + /* + * temporarily stop Beacon packet for AdHoc Server + * if all of the following coditions are met: + * (1) STA is in AdHoc mode + * (2) VT3253 is programmed as automatic Beacon Transmitting + * (3) One of the following conditions is met + * (3.1) AdHoc channel is in B/G band and the + * current scan channel is in A band + * or + * (3.2) AdHoc channel is in A mode + */ + bStop = false; + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { + if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) && + (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { + bStop = true; + } + if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G) + bStop = true; + } + + if (bStop) { + //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n", + // pMgmt->uIBSSChannel, pMgmt->uScanChannel)); + MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX); + } } /* vAdHocBeaconStop */ @@ -145,12 +140,11 @@ static void vAdHocBeaconRestart(struct vnt_private *pDevice) * (1) STA is in AdHoc mode * (2) VT3253 is programmed as automatic Beacon Transmitting */ - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && - (pMgmt->eCurrState >= WMAC_STATE_STARTED)) - { - //PMESG(("RESTART_BEACON\n")); - MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX); - } + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && + (pMgmt->eCurrState >= WMAC_STATE_STARTED)) { + //PMESG(("RESTART_BEACON\n")); + MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX); + } } @@ -182,34 +176,33 @@ static void s_vProbeChannel(struct vnt_private *pDevice) u8 *pbyRate; int ii; - if (pDevice->byBBType == BB_TYPE_11A) { - pbyRate = &abyCurrSuppRatesA[0]; - } else if (pDevice->byBBType == BB_TYPE_11B) { - pbyRate = &abyCurrSuppRatesB[0]; - } else { - pbyRate = &abyCurrSuppRatesG[0]; - } - // build an assocreq frame and send it - pTxPacket = s_MgrMakeProbeRequest - ( - pDevice, - pMgmt, - pMgmt->abyScanBSSID, - (PWLAN_IE_SSID)pMgmt->abyScanSSID, - (PWLAN_IE_SUPP_RATES)pbyRate, - (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG - ); - - if (pTxPacket != NULL ){ - for (ii = 0; ii < 1 ; ii++) { - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n"); - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n"); - } - } - } + if (pDevice->byBBType == BB_TYPE_11A) + pbyRate = &abyCurrSuppRatesA[0]; + else if (pDevice->byBBType == BB_TYPE_11B) + pbyRate = &abyCurrSuppRatesB[0]; + else + pbyRate = &abyCurrSuppRatesG[0]; + + // build an assocreq frame and send it + pTxPacket = s_MgrMakeProbeRequest + ( + pDevice, + pMgmt, + pMgmt->abyScanBSSID, + (PWLAN_IE_SSID)pMgmt->abyScanSSID, + (PWLAN_IE_SUPP_RATES)pbyRate, + (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG + ); + + if (pTxPacket != NULL) { + for (ii = 0; ii < 1; ii++) { + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n"); + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n"); + } + } + } } @@ -224,7 +217,7 @@ static void s_vProbeChannel(struct vnt_private *pDevice) * -*/ -struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID, PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates) { @@ -236,37 +229,38 @@ struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice, + WLAN_PROBEREQ_FR_MAXLEN); pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); - sFrame.pBuf = (u8 *)pTxPacket->p80211Header; - sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; - vMgrEncodeProbeRequest(&sFrame); - sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) - )); - memcpy( sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy( sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); - // Copy the SSID, pSSID->len=0 indicate broadcast SSID - sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); - sFrame.len += pSSID->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); - sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); - // Copy the extension rate set - if (pDevice->byBBType == BB_TYPE_11G) { - sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); - sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; - memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); - } - pTxPacket->cbMPDULen = sFrame.len; - pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; - - return pTxPacket; + sFrame.pBuf = (u8 *)pTxPacket->p80211Header; + sFrame.len = WLAN_PROBEREQ_FR_MAXLEN; + vMgrEncodeProbeRequest(&sFrame); + sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ) + )); + memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN); + // Copy the SSID, pSSID->len=0 indicate broadcast SSID + sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len); + sFrame.len += pSSID->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN); + sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN); + // Copy the extension rate set + if (pDevice->byBBType == BB_TYPE_11G) { + sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len); + sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN; + memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN); + } + pTxPacket->cbMPDULen = sFrame.len; + pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; + + return pTxPacket; } -void vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond) +static void +vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond) { schedule_delayed_work(&pDevice->run_command_work, msecs_to_jiffies(MSecond)); @@ -289,661 +283,639 @@ void vRunCommand(struct work_struct *work) if (pDevice->Flags & fMP_DISCONNECTED) return; - if (pDevice->dwDiagRefCount != 0) - return; - if (pDevice->bCmdRunning != true) - return; + if (pDevice->bCmdRunning != true) + return; - spin_lock_irq(&pDevice->lock); + spin_lock_irq(&pDevice->lock); - switch ( pDevice->eCommandState ) { + switch (pDevice->eCommandState) { - case WLAN_CMD_SCAN_START: + case WLAN_CMD_SCAN_START: pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; - - if (pMgmt->uScanChannel == 0 ) { - pMgmt->uScanChannel = pDevice->byMinChannel; - } - if (pMgmt->uScanChannel > pDevice->byMaxChannel) { - pDevice->eCommandState = WLAN_CMD_SCAN_END; - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - - } else { - if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel); + if (pDevice->bRadioOff == true) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + + if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID; + + if (pMgmt->uScanChannel == 0) + pMgmt->uScanChannel = pDevice->byMinChannel; + if (pMgmt->uScanChannel > pDevice->byMaxChannel) { + pDevice->eCommandState = WLAN_CMD_SCAN_END; + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } else { + if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel); + pMgmt->uScanChannel++; + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + if (pMgmt->uScanChannel == pDevice->byMinChannel) { + // pMgmt->eScanType = WMAC_SCAN_ACTIVE; //mike mark + pMgmt->abyScanBSSID[0] = 0xFF; + pMgmt->abyScanBSSID[1] = 0xFF; + pMgmt->abyScanBSSID[2] = 0xFF; + pMgmt->abyScanBSSID[3] = 0xFF; + pMgmt->abyScanBSSID[4] = 0xFF; + pMgmt->abyScanBSSID[5] = 0xFF; + pItemSSID->byElementID = WLAN_EID_SSID; + // clear bssid list + /* BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); */ + pMgmt->eScanState = WMAC_IS_SCANNING; + pDevice->byScanBBType = pDevice->byBBType; //lucas + pDevice->bStopDataPkt = true; + // Turn off RCR_BSSID filter every time + MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID); + pDevice->byRxMode &= ~RCR_BSSID; + } + //lucas + vAdHocBeaconStop(pDevice); + if ((pDevice->byBBType != BB_TYPE_11A) && + (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { + pDevice->byBBType = BB_TYPE_11A; + CARDvSetBSSMode(pDevice); + } else if ((pDevice->byBBType == BB_TYPE_11A) && + (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) { + pDevice->byBBType = BB_TYPE_11G; + CARDvSetBSSMode(pDevice); + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning.... channel: [%d]\n", pMgmt->uScanChannel); + // Set channel + CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel); + // Set Baseband to be more sensitive. + + if (pDevice->bUpdateBBVGA) { + BBvSetShortSlotTime(pDevice); + BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); + BBvUpdatePreEDThreshold(pDevice, true); + } pMgmt->uScanChannel++; - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - if (pMgmt->uScanChannel == pDevice->byMinChannel) { - // pMgmt->eScanType = WMAC_SCAN_ACTIVE; //mike mark - pMgmt->abyScanBSSID[0] = 0xFF; - pMgmt->abyScanBSSID[1] = 0xFF; - pMgmt->abyScanBSSID[2] = 0xFF; - pMgmt->abyScanBSSID[3] = 0xFF; - pMgmt->abyScanBSSID[4] = 0xFF; - pMgmt->abyScanBSSID[5] = 0xFF; - pItemSSID->byElementID = WLAN_EID_SSID; - // clear bssid list - /* BSSvClearBSSList((void *) pDevice, - pDevice->bLinkPass); */ - pMgmt->eScanState = WMAC_IS_SCANNING; - pDevice->byScanBBType = pDevice->byBBType; //lucas - pDevice->bStopDataPkt = true; - // Turn off RCR_BSSID filter every time - MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID); - pDevice->byRxMode &= ~RCR_BSSID; - - } - //lucas - vAdHocBeaconStop(pDevice); - if ((pDevice->byBBType != BB_TYPE_11A) && (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) { - pDevice->byBBType = BB_TYPE_11A; - CARDvSetBSSMode(pDevice); - } - else if ((pDevice->byBBType == BB_TYPE_11A) && (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) { - pDevice->byBBType = BB_TYPE_11G; - CARDvSetBSSMode(pDevice); - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning.... channel: [%d]\n", pMgmt->uScanChannel); - // Set channel - CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel); - // Set Baseband to be more sensitive. - - if (pDevice->bUpdateBBVGA) { - BBvSetShortSlotTime(pDevice); - BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); - BBvUpdatePreEDThreshold(pDevice, true); - } - pMgmt->uScanChannel++; - - while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) && - pMgmt->uScanChannel <= pDevice->byMaxChannel ){ - pMgmt->uScanChannel++; - } - - if (pMgmt->uScanChannel > pDevice->byMaxChannel) { - // Set Baseband to be not sensitive and rescan - pDevice->eCommandState = WLAN_CMD_SCAN_END; - - } - if ((pMgmt->b11hEnable == false) || - (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { - s_vProbeChannel(pDevice); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *) pDevice, 100); - return; - } else { - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME); - return; - } - - } - - break; - - case WLAN_CMD_SCAN_END: - - // Set Baseband's sensitivity back. - if (pDevice->byBBType != pDevice->byScanBBType) { - pDevice->byBBType = pDevice->byScanBBType; - CARDvSetBSSMode(pDevice); - } - - if (pDevice->bUpdateBBVGA) { - BBvSetShortSlotTime(pDevice); - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - BBvUpdatePreEDThreshold(pDevice, false); - } - - // Set channel back - vAdHocBeaconRestart(pDevice); - // Set channel back - CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel); - // Set Filter - if (pMgmt->bCurrBSSIDFilterOn) { - MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID); - pDevice->byRxMode |= RCR_BSSID; - } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); + + while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) && + pMgmt->uScanChannel <= pDevice->byMaxChannel){ + pMgmt->uScanChannel++; + } + + if (pMgmt->uScanChannel > pDevice->byMaxChannel) { + // Set Baseband to be not sensitive and rescan + pDevice->eCommandState = WLAN_CMD_SCAN_END; + } + if ((pMgmt->b11hEnable == false) || + (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { + s_vProbeChannel(pDevice); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, 100); + return; + } else { + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME); + return; + } + } + + break; + + case WLAN_CMD_SCAN_END: + + // Set Baseband's sensitivity back. + if (pDevice->byBBType != pDevice->byScanBBType) { + pDevice->byBBType = pDevice->byScanBBType; + CARDvSetBSSMode(pDevice); + } + + if (pDevice->bUpdateBBVGA) { + BBvSetShortSlotTime(pDevice); + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); + BBvUpdatePreEDThreshold(pDevice, false); + } + + // Set channel back + vAdHocBeaconRestart(pDevice); + // Set channel back + CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel); + // Set Filter + if (pMgmt->bCurrBSSIDFilterOn) { + MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID); + pDevice->byRxMode |= RCR_BSSID; + } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel); pMgmt->uScanChannel = 0; - pMgmt->eScanState = WMAC_NO_SCANNING; - pDevice->bStopDataPkt = false; + pMgmt->eScanState = WMAC_NO_SCANNING; + pDevice->bStopDataPkt = false; /*send scan event to wpa_Supplicant*/ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); memset(&wrqu, 0, sizeof(wrqu)); wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); - s_bCommandComplete(pDevice); - break; + s_bCommandComplete(pDevice); + break; - case WLAN_CMD_DISASSOCIATE_START : + case WLAN_CMD_DISASSOCIATE_START: pDevice->byReAssocCount = 0; - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && - (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } else { - - pDevice->bwextstep0 = false; - pDevice->bwextstep1 = false; - pDevice->bwextstep2 = false; - pDevice->bwextstep3 = false; - pDevice->bWPASuppWextEnabled = false; - pDevice->fWPA_Authened = false; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); - // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((void *) pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - (8), - &Status); - pDevice->bLinkPass = false; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); - // unlock command busy - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->sNodeDBTable[0].bActive = false; -// pDevice->bBeaconBufReady = false; - } - netif_stop_queue(pDevice->dev); - if (pDevice->bNeedRadioOFF == true) - CARDbRadioPowerOff(pDevice); - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_SSID_START: + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && + (pMgmt->eCurrState != WMAC_STATE_ASSOC)) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } else { + pDevice->bwextstep0 = false; + pDevice->bwextstep1 = false; + pDevice->bwextstep2 = false; + pDevice->bwextstep3 = false; + pDevice->bWPASuppWextEnabled = false; + pDevice->fWPA_Authened = false; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); + // reason = 8 : disassoc because sta has left + vMgrDisassocBeginSta((void *) pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (8), + &Status); + pDevice->bLinkPass = false; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW); + // unlock command busy + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID->len = 0; + memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->sNodeDBTable[0].bActive = false; +// pDevice->bBeaconBufReady = false; + } + netif_stop_queue(pDevice->dev); + if (pDevice->bNeedRadioOFF == true) + CARDbRadioPowerOff(pDevice); + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_SSID_START: pDevice->byReAssocCount = 0; - if (pDevice->bRadioOff == true) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - - memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID, - ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN); - - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); - - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID); - } - - if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || - ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)&& (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { - - if (pItemSSID->len == pItemSSIDCurr->len) { - if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - } - netif_stop_queue(pDevice->dev); - pDevice->bLinkPass = false; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); - } - // set initial state - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((void *) pDevice); - BSSvClearNodeDBTable(pDevice, 0); - vMgrJoinBSSBegin((void *) pDevice, &Status); - // if Infra mode - if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { - // Call mgr to begin the deauthentication - // reason = (3) because sta has left ESS - if (pMgmt->eCurrState >= WMAC_STATE_AUTH) { - vMgrDeAuthenBeginSta((void *)pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - (3), - &Status); - } - // Call mgr to begin the authentication - vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - pDevice->byLinkWaitCount = 0; - pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); - return; - } - } - // if Adhoc mode - else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { - if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pDevice->bLinkPass = true; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); - pMgmt->sNodeDBTable[0].bActive = true; - pMgmt->sNodeDBTable[0].uInActiveCount = 0; - } - else { - // start own IBSS - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n"); - vMgrCreateOwnIBSS((void *) pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); - } - BSSvAddMulticastNode(pDevice); - } - s_bClearBSSID_SCAN(pDevice); - } - // if SSID not found - else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { - if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || - pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { - // start own IBSS - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n"); - vMgrCreateOwnIBSS((void *) pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); - } - BSSvAddMulticastNode(pDevice); - s_bClearBSSID_SCAN(pDevice); + if (pDevice->bRadioOff == true) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + + memcpy(pMgmt->abyAdHocSSID, pMgmt->abyDesireSSID, + ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN); + + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); + + if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n", pItemSSID->len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID); + } + + if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) || + ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { + if (pItemSSID->len == pItemSSIDCurr->len) { + if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + } + netif_stop_queue(pDevice->dev); + pDevice->bLinkPass = false; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW); + } + // set initial state + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + PSvDisablePowerSaving((void *) pDevice); + BSSvClearNodeDBTable(pDevice, 0); + vMgrJoinBSSBegin((void *) pDevice, &Status); + // if Infra mode + if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { + // Call mgr to begin the deauthentication + // reason = (3) because sta has left ESS + if (pMgmt->eCurrState >= WMAC_STATE_AUTH) { + vMgrDeAuthenBeginSta((void *)pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (3), + &Status); + } + // Call mgr to begin the authentication + vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status); + if (Status == CMD_STATUS_SUCCESS) { + pDevice->byLinkWaitCount = 0; + pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; + vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT); + spin_unlock_irq(&pDevice->lock); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); + return; + } + } + // if Adhoc mode + else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { + if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { + if (netif_queue_stopped(pDevice->dev)) + netif_wake_queue(pDevice->dev); + pDevice->bLinkPass = true; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER); + pMgmt->sNodeDBTable[0].bActive = true; + pMgmt->sNodeDBTable[0].uInActiveCount = 0; + } else { + // start own IBSS + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n"); + vMgrCreateOwnIBSS((void *) pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); + } + BSSvAddMulticastNode(pDevice); + } + s_bClearBSSID_SCAN(pDevice); + } + // if SSID not found + else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) { + if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || + pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { + // start own IBSS + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n"); + vMgrCreateOwnIBSS((void *) pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); + } + BSSvAddMulticastNode(pDevice); + s_bClearBSSID_SCAN(pDevice); /* - pDevice->bLinkPass = true; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - s_bClearBSSID_SCAN(pDevice); + pDevice->bLinkPass = true; + ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); + if (netif_queue_stopped(pDevice->dev)){ + netif_wake_queue(pDevice->dev); + } + s_bClearBSSID_SCAN(pDevice); */ - } - else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - } - } - s_bCommandComplete(pDevice); - break; - - case WLAN_AUTHENTICATE_WAIT : - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n"); - if (pMgmt->eCurrState == WMAC_STATE_AUTH) { + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); + // if(pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } + } + } + s_bCommandComplete(pDevice); + break; + + case WLAN_AUTHENTICATE_WAIT: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n"); + if (pMgmt->eCurrState == WMAC_STATE_AUTH) { + pDevice->byLinkWaitCount = 0; + // Call mgr to begin the association + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n"); + vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status); + if (Status == CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n"); + pDevice->byLinkWaitCount = 0; + pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; + vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT); + spin_unlock_irq(&pDevice->lock); + return; + } + } else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { + printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); + } else if (pDevice->byLinkWaitCount <= 4) { + //mike add:wait another 2 sec if authenticated_frame delay! + pDevice->byLinkWaitCount++; + printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2); + return; + } pDevice->byLinkWaitCount = 0; - // Call mgr to begin the association - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status); - if (Status == CMD_STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n"); - pDevice->byLinkWaitCount = 0; - pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT); - spin_unlock_irq(&pDevice->lock); - return; - } - } - else if(pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) { - printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n"); - } - else if(pDevice->byLinkWaitCount <= 4){ //mike add:wait another 2 sec if authenticated_frame delay! - pDevice->byLinkWaitCount ++; - printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2); - return; - } - pDevice->byLinkWaitCount = 0; - - s_bCommandComplete(pDevice); - break; - - case WLAN_ASSOCIATE_WAIT : - if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n"); - if (pDevice->ePSMode != WMAC_POWER_CAM) { - PSvEnablePowerSaving((void *) pDevice, - pMgmt->wListenInterval); - } + + s_bCommandComplete(pDevice); + break; + + case WLAN_ASSOCIATE_WAIT: + if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n"); + if (pDevice->ePSMode != WMAC_POWER_CAM) { + PSvEnablePowerSaving((void *) pDevice, + pMgmt->wListenInterval); + } /* - if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { - KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID); - } + if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { + KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID); + } */ - pDevice->byLinkWaitCount = 0; - pDevice->byReAssocCount = 0; - pDevice->bLinkPass = true; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); - s_bClearBSSID_SCAN(pDevice); - - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - - } - else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { - printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); - } - else if(pDevice->byLinkWaitCount <= 4){ //mike add:wait another 2 sec if associated_frame delay! - pDevice->byLinkWaitCount ++; - printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); - spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2); - return; - } - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_AP_MODE_START : - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n"); - - if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { - cancel_delayed_work_sync(&pDevice->second_callback_work); - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->eCurrMode = WMAC_MODE_STANDBY; - pDevice->bLinkPass = false; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); - if (pDevice->bEnableHostWEP == true) - BSSvClearNodeDBTable(pDevice, 1); - else - BSSvClearNodeDBTable(pDevice, 0); - pDevice->uAssocCount = 0; - pMgmt->eCurrState = WMAC_STATE_IDLE; - pDevice->bFixRate = false; - - vMgrCreateOwnIBSS((void *) pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "vMgrCreateOwnIBSS fail!\n"); - } - // always turn off unicast bit - MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST); - pDevice->byRxMode &= ~RCR_UNICAST; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode ); - BSSvAddMulticastNode(pDevice); - if (netif_queue_stopped(pDevice->dev)){ - netif_wake_queue(pDevice->dev); - } - pDevice->bLinkPass = true; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); - schedule_delayed_work(&pDevice->second_callback_work, HZ); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_TX_PSPACKET_START : - // DTIM Multicast tx - if (pMgmt->sNodeDBTable[0].bRxPSPoll) { - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { - pMgmt->abyPSTxMap[0] &= ~byMask[0]; - pDevice->bMoreData = false; - } - else { - pDevice->bMoreData = true; - } - - if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n"); - } - - pMgmt->sNodeDBTable[0].wEnQueueCnt--; - } - } - - // PS nodes tx - for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { - if (pMgmt->sNodeDBTable[ii].bActive && - pMgmt->sNodeDBTable[ii].bRxPSPoll) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", - ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); - while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - pDevice->bMoreData = false; - } - else { - pDevice->bMoreData = true; - } - - if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n"); - } - - pMgmt->sNodeDBTable[ii].wEnQueueCnt--; - // check if sta ps enable, wait next pspoll - // if sta ps disable, send all pending buffers. - if (pMgmt->sNodeDBTable[ii].bPSEnable) - break; - } - if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { - // clear tx map - pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= - ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii); - } - pMgmt->sNodeDBTable[ii].bRxPSPoll = false; - } - } - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_RADIO_START: - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n"); - // if (pDevice->bRadioCmd == true) - // CARDbRadioPowerOn(pDevice); - // else - // CARDbRadioPowerOff(pDevice); - - { - int ntStatus = STATUS_SUCCESS; - u8 byTmp; - - ntStatus = CONTROLnsRequestIn(pDevice, - MESSAGE_TYPE_READ, - MAC_REG_GPIOCTL1, - MESSAGE_REQUEST_MACREG, - 1, - &byTmp); - - if ( ntStatus != STATUS_SUCCESS ) { - s_bCommandComplete(pDevice); - spin_unlock_irq(&pDevice->lock); - return; - } - if ( (byTmp & GPIO3_DATA) == 0 ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n"); - // Old commands are useless. - // empty command Q - pDevice->cbFreeCmdQueue = CMD_Q_SIZE; - pDevice->uCmdDequeueIdx = 0; - pDevice->uCmdEnqueueIdx = 0; - //0415pDevice->bCmdRunning = false; - pDevice->bCmdClear = true; - pDevice->bStopTx0Pkt = false; - pDevice->bStopDataPkt = true; - - pDevice->byKeyIndex = 0; - pDevice->bTransmitKey = false; - spin_unlock_irq(&pDevice->lock); - KeyvInitTable(pDevice,&pDevice->sKey); - spin_lock_irq(&pDevice->lock); - pMgmt->byCSSPK = KEY_CTL_NONE; - pMgmt->byCSSGK = KEY_CTL_NONE; - - if (pDevice->bLinkPass == true) { - // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((void *) pDevice, - pMgmt, - pMgmt->abyCurrBSSID, - (8), - &Status); - pDevice->bLinkPass = false; - // unlock command busy - pMgmt->eCurrState = WMAC_STATE_IDLE; - pMgmt->sNodeDBTable[0].bActive = false; - // if(pDevice->bWPASuppWextEnabled == true) - { - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof (wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); - wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); - } - } - pDevice->bwextstep0 = false; - pDevice->bwextstep1 = false; - pDevice->bwextstep2 = false; - pDevice->bwextstep3 = false; - pDevice->bWPASuppWextEnabled = false; - //clear current SSID - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - //clear desired SSID - pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - pItemSSID->len = 0; - memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); - - netif_stop_queue(pDevice->dev); - CARDbRadioPowerOff(pDevice); - MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD); - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_OFF); - pDevice->bHWRadioOff = true; - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n"); - pDevice->bHWRadioOff = false; - CARDbRadioPowerOn(pDevice); - MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD); - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_ON); - } - } - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_CHANGE_BBSENSITIVITY_START: - - pDevice->bStopDataPkt = true; - pDevice->byBBVGACurrent = pDevice->byBBVGANew; - BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent); - pDevice->bStopDataPkt = false; - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_TBTT_WAKEUP_START: - PSbIsNextTBTTWakeUp(pDevice); - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_BECON_SEND_START: - bMgrPrepareBeaconToSend(pDevice, pMgmt); - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_SETPOWER_START: - - RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel); - - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_CHANGE_ANTENNA_START: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel); - if ( pDevice->dwRxAntennaSel == 0) { - pDevice->dwRxAntennaSel=1; - if (pDevice->bTxRxAntInv == true) - BBvSetAntennaMode(pDevice, ANT_RXA); - else - BBvSetAntennaMode(pDevice, ANT_RXB); - } else { - pDevice->dwRxAntennaSel=0; - if (pDevice->bTxRxAntInv == true) - BBvSetAntennaMode(pDevice, ANT_RXB); - else - BBvSetAntennaMode(pDevice, ANT_RXA); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_REMOVE_ALLKEY_START: - KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID); - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_MAC_DISPOWERSAVING_START: - ControlvReadByte (pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); - if ( (byData & PSCTL_PS) != 0 ) { - // disable power saving hw function - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_DISABLE_PS, - 0, - 0, - 0, - NULL - ); - } - s_bCommandComplete(pDevice); - break; - - case WLAN_CMD_11H_CHSW_START: - CARDbSetMediaChannel(pDevice, pDevice->byNewChannel); - pDevice->bChannelSwitch = false; - pMgmt->uCurrChannel = pDevice->byNewChannel; - pDevice->bStopDataPkt = false; - s_bCommandComplete(pDevice); - break; - - default: - s_bCommandComplete(pDevice); - break; - } //switch - - spin_unlock_irq(&pDevice->lock); - return; + pDevice->byLinkWaitCount = 0; + pDevice->byReAssocCount = 0; + pDevice->bLinkPass = true; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER); + s_bClearBSSID_SCAN(pDevice); + + if (netif_queue_stopped(pDevice->dev)) + netif_wake_queue(pDevice->dev); + + } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { + printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); + } else if (pDevice->byLinkWaitCount <= 4) { + //mike add:wait another 2 sec if associated_frame delay! + pDevice->byLinkWaitCount++; + printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount); + spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2); + return; + } + + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_AP_MODE_START: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n"); + + if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { + cancel_delayed_work_sync(&pDevice->second_callback_work); + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->eCurrMode = WMAC_MODE_STANDBY; + pDevice->bLinkPass = false; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW); + if (pDevice->bEnableHostWEP == true) + BSSvClearNodeDBTable(pDevice, 1); + else + BSSvClearNodeDBTable(pDevice, 0); + pDevice->uAssocCount = 0; + pMgmt->eCurrState = WMAC_STATE_IDLE; + pDevice->bFixRate = false; + + vMgrCreateOwnIBSS((void *) pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "vMgrCreateOwnIBSS fail!\n"); + } + // always turn off unicast bit + MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST); + pDevice->byRxMode &= ~RCR_UNICAST; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); + BSSvAddMulticastNode(pDevice); + if (netif_queue_stopped(pDevice->dev)) + netif_wake_queue(pDevice->dev); + pDevice->bLinkPass = true; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_INTER); + schedule_delayed_work(&pDevice->second_callback_work, HZ); + } + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_TX_PSPACKET_START: + // DTIM Multicast tx + if (pMgmt->sNodeDBTable[0].bRxPSPoll) { + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) { + if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) { + pMgmt->abyPSTxMap[0] &= ~byMask[0]; + pDevice->bMoreData = false; + } else { + pDevice->bMoreData = true; + } + + if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n"); + + pMgmt->sNodeDBTable[0].wEnQueueCnt--; + } + } + + // PS nodes tx + for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { + if (pMgmt->sNodeDBTable[ii].bActive && + pMgmt->sNodeDBTable[ii].bRxPSPoll) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", + ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); + while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { + if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { + // clear tx map + pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= + ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; + pDevice->bMoreData = false; + } else { + pDevice->bMoreData = true; + } + + if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n"); + + pMgmt->sNodeDBTable[ii].wEnQueueCnt--; + // check if sta ps enable, wait next pspoll + // if sta ps disable, send all pending buffers. + if (pMgmt->sNodeDBTable[ii].bPSEnable) + break; + } + if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) { + // clear tx map + pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= + ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii); + } + pMgmt->sNodeDBTable[ii].bRxPSPoll = false; + } + } + + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_RADIO_START: + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n"); +// if (pDevice->bRadioCmd == true) +// CARDbRadioPowerOn(pDevice); +// else +// CARDbRadioPowerOff(pDevice); + { + int ntStatus = STATUS_SUCCESS; + u8 byTmp; + + ntStatus = CONTROLnsRequestIn(pDevice, + MESSAGE_TYPE_READ, + MAC_REG_GPIOCTL1, + MESSAGE_REQUEST_MACREG, + 1, + &byTmp); + + if (ntStatus != STATUS_SUCCESS) { + s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); + return; + } + if ((byTmp & GPIO3_DATA) == 0) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n"); + // Old commands are useless. + // empty command Q + pDevice->cbFreeCmdQueue = CMD_Q_SIZE; + pDevice->uCmdDequeueIdx = 0; + pDevice->uCmdEnqueueIdx = 0; + //0415pDevice->bCmdRunning = false; + pDevice->bCmdClear = true; + pDevice->bStopTx0Pkt = false; + pDevice->bStopDataPkt = true; + + pDevice->byKeyIndex = 0; + pDevice->bTransmitKey = false; + spin_unlock_irq(&pDevice->lock); + KeyvInitTable(pDevice, &pDevice->sKey); + spin_lock_irq(&pDevice->lock); + pMgmt->byCSSPK = KEY_CTL_NONE; + pMgmt->byCSSGK = KEY_CTL_NONE; + + if (pDevice->bLinkPass == true) { + // reason = 8 : disassoc because sta has left + vMgrDisassocBeginSta((void *) pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (8), + &Status); + pDevice->bLinkPass = false; + // unlock command busy + pMgmt->eCurrState = WMAC_STATE_IDLE; + pMgmt->sNodeDBTable[0].bActive = false; + // if(pDevice->bWPASuppWextEnabled == true) + { + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); + wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); + } + } + pDevice->bwextstep0 = false; + pDevice->bwextstep1 = false; + pDevice->bwextstep2 = false; + pDevice->bwextstep3 = false; + pDevice->bWPASuppWextEnabled = false; + //clear current SSID + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; + pItemSSID->len = 0; + memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); + //clear desired SSID + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSID->len = 0; + memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN); + + netif_stop_queue(pDevice->dev); + CARDbRadioPowerOff(pDevice); + MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD); + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_OFF); + pDevice->bHWRadioOff = true; + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n"); + pDevice->bHWRadioOff = false; + CARDbRadioPowerOn(pDevice); + MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD); + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_ON); + } + } + + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_CHANGE_BBSENSITIVITY_START: + + pDevice->bStopDataPkt = true; + pDevice->byBBVGACurrent = pDevice->byBBVGANew; + BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent); + pDevice->bStopDataPkt = false; + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_TBTT_WAKEUP_START: + PSbIsNextTBTTWakeUp(pDevice); + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_BECON_SEND_START: + bMgrPrepareBeaconToSend(pDevice, pMgmt); + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_SETPOWER_START: + + RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel); + + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_CHANGE_ANTENNA_START: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel); + if (pDevice->dwRxAntennaSel == 0) { + pDevice->dwRxAntennaSel = 1; + if (pDevice->bTxRxAntInv == true) + BBvSetAntennaMode(pDevice, ANT_RXA); + else + BBvSetAntennaMode(pDevice, ANT_RXB); + } else { + pDevice->dwRxAntennaSel = 0; + if (pDevice->bTxRxAntInv == true) + BBvSetAntennaMode(pDevice, ANT_RXB); + else + BBvSetAntennaMode(pDevice, ANT_RXA); + } + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_REMOVE_ALLKEY_START: + KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID); + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_MAC_DISPOWERSAVING_START: + ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); + if ((byData & PSCTL_PS) != 0) { + // disable power saving hw function + CONTROLnsRequestOut(pDevice, + MESSAGE_TYPE_DISABLE_PS, + 0, + 0, + 0, + NULL + ); + } + s_bCommandComplete(pDevice); + break; + + case WLAN_CMD_11H_CHSW_START: + CARDbSetMediaChannel(pDevice, pDevice->byNewChannel); + pDevice->bChannelSwitch = false; + pMgmt->uCurrChannel = pDevice->byNewChannel; + pDevice->bStopDataPkt = false; + s_bCommandComplete(pDevice); + break; + + default: + s_bCommandComplete(pDevice); + break; + } //switch + + spin_unlock_irq(&pDevice->lock); + return; } static int s_bCommandComplete(struct vnt_private *pDevice) @@ -953,152 +925,146 @@ static int s_bCommandComplete(struct vnt_private *pDevice) int bRadioCmd = false; int bForceSCAN = true; - pDevice->eCommandState = WLAN_CMD_IDLE; - if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { - //Command Queue Empty - pDevice->bCmdRunning = false; - return true; - } - else { - pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; - pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; - bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; - bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue++; - pDevice->bCmdRunning = true; - switch ( pDevice->eCommand ) { - case WLAN_CMD_BSSID_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n"); - pDevice->eCommandState = WLAN_CMD_SCAN_START; - pMgmt->uScanChannel = 0; - if (pSSID->len != 0) { - memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - } else { - memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - } + pDevice->eCommandState = WLAN_CMD_IDLE; + if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) { + //Command Queue Empty + pDevice->bCmdRunning = false; + return true; + } else { + pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd; + pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID; + bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd; + bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN; + ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE); + pDevice->cbFreeCmdQueue++; + pDevice->bCmdRunning = true; + switch (pDevice->eCommand) { + case WLAN_CMD_BSSID_SCAN: + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n"); + pDevice->eCommandState = WLAN_CMD_SCAN_START; + pMgmt->uScanChannel = 0; + if (pSSID->len != 0) + memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + else + memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); /* - if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) { - if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) && - ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) { - pDevice->eCommandState = WLAN_CMD_IDLE; - } - } + if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) { + if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) && + ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) { + pDevice->eCommandState = WLAN_CMD_IDLE; + } + } */ - break; - case WLAN_CMD_SSID: - pDevice->eCommandState = WLAN_CMD_SSID_START; - if (pSSID->len > WLAN_SSID_MAXLEN) - pSSID->len = WLAN_SSID_MAXLEN; - if (pSSID->len != 0) - memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n"); - break; - case WLAN_CMD_DISASSOCIATE: - pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; - break; - case WLAN_CMD_RX_PSPOLL: - pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; - break; - case WLAN_CMD_RUN_AP: - pDevice->eCommandState = WLAN_CMD_AP_MODE_START; - break; - case WLAN_CMD_RADIO: - pDevice->eCommandState = WLAN_CMD_RADIO_START; - pDevice->bRadioCmd = bRadioCmd; - break; - case WLAN_CMD_CHANGE_BBSENSITIVITY: - pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START; - break; - - case WLAN_CMD_TBTT_WAKEUP: - pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START; - break; - - case WLAN_CMD_BECON_SEND: - pDevice->eCommandState = WLAN_CMD_BECON_SEND_START; - break; - - case WLAN_CMD_SETPOWER: - pDevice->eCommandState = WLAN_CMD_SETPOWER_START; - break; - - case WLAN_CMD_CHANGE_ANTENNA: - pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START; - break; - - case WLAN_CMD_REMOVE_ALLKEY: - pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START; - break; - - case WLAN_CMD_MAC_DISPOWERSAVING: - pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START; - break; - - case WLAN_CMD_11H_CHSW: - pDevice->eCommandState = WLAN_CMD_11H_CHSW_START; - break; - - default: - break; - - } - vCommandTimerWait(pDevice, 0); - } - - return true; + break; + case WLAN_CMD_SSID: + pDevice->eCommandState = WLAN_CMD_SSID_START; + if (pSSID->len > WLAN_SSID_MAXLEN) + pSSID->len = WLAN_SSID_MAXLEN; + if (pSSID->len != 0) + memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n"); + break; + case WLAN_CMD_DISASSOCIATE: + pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; + break; + case WLAN_CMD_RX_PSPOLL: + pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START; + break; + case WLAN_CMD_RUN_AP: + pDevice->eCommandState = WLAN_CMD_AP_MODE_START; + break; + case WLAN_CMD_RADIO: + pDevice->eCommandState = WLAN_CMD_RADIO_START; + pDevice->bRadioCmd = bRadioCmd; + break; + case WLAN_CMD_CHANGE_BBSENSITIVITY: + pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START; + break; + + case WLAN_CMD_TBTT_WAKEUP: + pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START; + break; + + case WLAN_CMD_BECON_SEND: + pDevice->eCommandState = WLAN_CMD_BECON_SEND_START; + break; + + case WLAN_CMD_SETPOWER: + pDevice->eCommandState = WLAN_CMD_SETPOWER_START; + break; + + case WLAN_CMD_CHANGE_ANTENNA: + pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START; + break; + + case WLAN_CMD_REMOVE_ALLKEY: + pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START; + break; + + case WLAN_CMD_MAC_DISPOWERSAVING: + pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START; + break; + + case WLAN_CMD_11H_CHSW: + pDevice->eCommandState = WLAN_CMD_11H_CHSW_START; + break; + + default: + break; + } + vCommandTimerWait(pDevice, 0); + } + + return true; } int bScheduleCommand(struct vnt_private *pDevice, CMD_CODE eCommand, u8 *pbyItem0) { - if (pDevice->cbFreeCmdQueue == 0) { - return (false); - } - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; - memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - if (pbyItem0 != NULL) { - switch (eCommand) { - case WLAN_CMD_BSSID_SCAN: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - break; - - case WLAN_CMD_SSID: - memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, - pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - break; - - case WLAN_CMD_DISASSOCIATE: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); - break; + if (pDevice->cbFreeCmdQueue == 0) + return false; + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand; + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true; + memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + if (pbyItem0 != NULL) { + switch (eCommand) { + case WLAN_CMD_BSSID_SCAN: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false; + memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, + pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + break; + + case WLAN_CMD_SSID: + memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, + pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + break; + + case WLAN_CMD_DISASSOCIATE: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0); + break; /* - case WLAN_CMD_DEAUTH: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0); - break; + case WLAN_CMD_DEAUTH: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0); + break; */ - case WLAN_CMD_RADIO: - pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); - break; + case WLAN_CMD_RADIO: + pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0); + break; + + default: + break; + } + } - default: - break; - } - } + ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); + pDevice->cbFreeCmdQueue--; - ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE); - pDevice->cbFreeCmdQueue--; + if (pDevice->bCmdRunning == false) + s_bCommandComplete(pDevice); - if (pDevice->bCmdRunning == false) { - s_bCommandComplete(pDevice); - } - else { - } - return (true); + return true; } @@ -1121,16 +1087,16 @@ static int s_bClearBSSID_SCAN(struct vnt_private *pDevice) unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; unsigned int ii; - if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { - for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) { - if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) - pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; - ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); - if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) - break; - } - } - return true; + if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { + for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) { + if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN) + pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE; + ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE); + if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx) + break; + } + } + return true; } //mike add:reset command timer diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index e26c41519b15..d74b0e7cb171 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -2961,7 +2961,7 @@ static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice, * -*/ -struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod, u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr, PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID, @@ -3081,7 +3081,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice, * -*/ -struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo, u16 wListenInterval, PWLAN_IE_SSID pCurrSSID, @@ -3329,7 +3329,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice, * -*/ -struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo, u16 wListenInterval, PWLAN_IE_SSID pCurrSSID, PWLAN_IE_SUPP_RATES pCurrRates, @@ -3576,7 +3576,7 @@ struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice, * -*/ -struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus, u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates) @@ -3642,7 +3642,7 @@ struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice, * -*/ -struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice, +static struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice, struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus, u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates) diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 01db4e7154da..403c295cc02c 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -43,12 +43,12 @@ static int msglevel =MSG_LEVEL_INFO; -const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; -const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; -const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; -const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; -const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; -const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; +static const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 }; +static const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 }; +static const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 }; +static const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 }; +static const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 }; +static const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; /*+ * diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index aa2216184345..df5541794e0f 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -37,14 +37,14 @@ static int msglevel =MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; -const u8 abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; -const u8 abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const u8 abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; -const u8 abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -const u8 abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; - -const u8 abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -const u8 abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +static const u8 abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 }; +static const u8 abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +static const u8 abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; +static const u8 abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; +static const u8 abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; + +static const u8 abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 }; +static const u8 abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; /*+ * diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index cac7720bef2b..aef0855f4c68 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -56,7 +56,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, RTS_on = true; /* Using RTS */ else { if (pT01->T01_modulation_type) { /* Is using OFDM */ - if (CURRENT_PROTECT_MECHANISM) /* Is using protect */ + /* Is using protect */ + if (CURRENT_PROTECT_MECHANISM) CTS_on = true; /* Using CTS */ } } @@ -69,9 +70,9 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, * ACK Rate : 24 Mega bps * ACK frame length = 14 bytes */ Duration = 2*DEFAULT_SIFSTIME + - 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + - ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym + - ((112 + 22 + 95)/96)*Tsym; + 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + + ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym + + ((112 + 22 + 95)/96)*Tsym; } else { /* DSSS */ /* CTS duration * 2 SIFS + DATA transmit time + 1 ACK @@ -92,13 +93,15 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, * CTS Rate : 24 Mega bps * CTS frame length = 14 bytes */ Duration += (DEFAULT_SIFSTIME + - PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + - ((112 + 22 + 95)/96)*Tsym); + PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + + ((112 + 22 + 95)/96)*Tsym); } else { /* CTS + 1 SIFS + CTS duration * CTS Rate : ?? Mega bps - * CTS frame length = 14 bytes */ - if (pT01->T01_plcp_header_length) /* long preamble */ + * CTS frame length = 14 bytes + */ + /* long preamble */ + if (pT01->T01_plcp_header_length) Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME; else Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME; @@ -149,8 +152,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, + Rate-1) / Rate + DEFAULT_SIFSTIME*3); } - - ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ + /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ + ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* ----20061009 add by anson's endian */ pNextT00->value = cpu_to_le32(pNextT00->value); @@ -159,7 +162,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, buffer += OffsetSize; pT01 = (struct T01_descriptor *)(buffer+4); - if (i != 1) /* The last fragment will not have the next fragment */ + /* The last fragment will not have the next fragment */ + if (i != 1) pNextT00 = (struct T00_descriptor *)(buffer+OffsetSize); } @@ -189,7 +193,8 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, } } - ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ + /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ + ((u16 *)buffer)[5] = cpu_to_le16(Duration); pT00->value = cpu_to_le32(pT00->value); pT01->value = cpu_to_le32(pT01->value); /* --end 20061009 add */ @@ -221,9 +226,10 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, CopySize = SizeLeft; if (SizeLeft > pDes->FragmentThreshold) { CopySize = pDes->FragmentThreshold; - pT00->T00_frame_length = 24 + CopySize; /* Set USB length */ - } else - pT00->T00_frame_length = 24 + SizeLeft; /* Set USB length */ + /* Set USB length */ + pT00->T00_frame_length = 24 + CopySize; + } else /* Set USB length */ + pT00->T00_frame_length = 24 + SizeLeft; SizeLeft -= CopySize; @@ -267,21 +273,27 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, /* 931130.5.n */ if (pMds->MicAdd) { if (!SizeLeft) { - pMds->MicWriteAddress[pMds->MicWriteIndex] = buffer - pMds->MicAdd; - pMds->MicWriteSize[pMds->MicWriteIndex] = pMds->MicAdd; + pMds->MicWriteAddress[pMds->MicWriteIndex] = + buffer - pMds->MicAdd; + pMds->MicWriteSize[pMds->MicWriteIndex] = + pMds->MicAdd; pMds->MicAdd = 0; } else if (SizeLeft < 8) { /* 931130.5.p */ pMds->MicAdd = SizeLeft; - pMds->MicWriteAddress[pMds->MicWriteIndex] = buffer - (8 - SizeLeft); - pMds->MicWriteSize[pMds->MicWriteIndex] = 8 - SizeLeft; + pMds->MicWriteAddress[pMds->MicWriteIndex] = + buffer - (8 - SizeLeft); + pMds->MicWriteSize[pMds->MicWriteIndex] = + 8 - SizeLeft; pMds->MicWriteIndex++; } } /* Does it need to generate the new header for next mpdu? */ if (SizeLeft) { - buffer = TargetBuffer + Size; /* Get the next 4n start address */ - memcpy(buffer, TargetBuffer, 32); /* Copy 8B USB +24B 802.11 */ + /* Get the next 4n start address */ + buffer = TargetBuffer + Size; + /* Copy 8B USB +24B 802.11 */ + memcpy(buffer, TargetBuffer, 32); pT00 = (struct T00_descriptor *)buffer; pT00->T00_first_mpdu = 0; } @@ -293,7 +305,8 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, pT00->T00_IsLastMpdu = 1; buffer = (u8 *)pT00 + 8; /* +8 for USB hdr */ buffer[1] &= ~0x04; /* Clear more frag bit of 802.11 frame control */ - pDes->FragmentCount = FragmentCount; /* Update the correct fragment number */ + /* Update the correct fragment number */ + pDes->FragmentCount = FragmentCount; return Size; } @@ -330,7 +343,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; /* Do not fragment */ /* Copy full data, the 1'st buffer contain all the data 931130.5.j */ - memcpy(TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE); /* Copy header */ + /* Copy header */ + memcpy(TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE); pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE; pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE; pDes->buffer_size[0] = pDes->buffer_total_size; @@ -358,8 +372,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, for (i = 0; i < 2; i++) { if (i == 1) ctmp1 = ctmpf; - - pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; /* backup the ta rate and fall back rate */ + /* backup the ta rate and fall back rate */ + pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; if (ctmp1 == 108) ctmp2 = 7; @@ -395,7 +409,8 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, /* * Set preamble type */ - if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) /* RATE_1M */ + /* RATE_1M */ + if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG; else pDes->PreambleMode = CURRENT_PREAMBLE_MODE; @@ -468,12 +483,14 @@ Mds_Tx(struct wbsoft_priv *adapter) /* Start to fill the data */ do { FillIndex = pMds->TxFillIndex; - if (pMds->TxOwner[FillIndex]) { /* Is owned by software 0:Yes 1:No */ + /* Is owned by software 0:Yes 1:No */ + if (pMds->TxOwner[FillIndex]) { pr_debug("[Mds_Tx] Tx Owner is H/W.\n"); break; } - XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); /* Get buffer */ + /* Get buffer */ + XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); XmitBufSize = 0; FillCount = 0; do { @@ -485,7 +502,8 @@ Mds_Tx(struct wbsoft_priv *adapter) FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD; /* 931130.5.b */ FragmentCount = PacketSize/FragmentThreshold + 1; - stmp = PacketSize + FragmentCount*32 + 8; /* 931130.5.c 8:MIC */ + /* 931130.5.c 8:MIC */ + stmp = PacketSize + FragmentCount*32 + 8; if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) break; /* buffer is not enough */ @@ -499,18 +517,23 @@ Mds_Tx(struct wbsoft_priv *adapter) TxDesIndex = pMds->TxDesIndex; /* Get the current ID */ pTxDes->Descriptor_ID = TxDesIndex; - pMds->TxDesFrom[TxDesIndex] = 2; /* Storing the information of source coming from */ + /* Storing the information of source coming from */ + pMds->TxDesFrom[TxDesIndex] = 2; pMds->TxDesIndex++; pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR; MLME_GetNextPacket(adapter, pTxDes); - /* Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type */ + /* + * Copy header. 8byte USB + 24byte 802.11Hdr. + * Set TxRate, Preamble type + */ Mds_HeaderCopy(adapter, pTxDes, XmitBufAddress); /* For speed up Key setting */ if (pTxDes->EapFix) { - pr_debug("35: EPA 4th frame detected. Size = %d\n", PacketSize); + pr_debug("35: EPA 4th frame detected. Size = %d\n", + PacketSize); pHwData->IsKeyPreSet = 1; } @@ -524,7 +547,9 @@ Mds_Tx(struct wbsoft_priv *adapter) XmitBufSize += CurrentSize; XmitBufAddress += CurrentSize; - /* Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data */ + /* Get packet to transmit completed, + * 1:TESTSTA 2:MLME 3: Ndis data + */ MLME_SendComplete(adapter, 0, true); /* Software TSC count 20060214 */ @@ -533,7 +558,12 @@ Mds_Tx(struct wbsoft_priv *adapter) pMds->TxTsc_2++; FillCount++; /* 20060928 */ - } while (HAL_USB_MODE_BURST(pHwData)); /* End of multiple MSDU copy loop. false = single true = multiple sending */ + /* + * End of multiple MSDU copy loop. + * false = single + * true = multiple sending + */ + } while (HAL_USB_MODE_BURST(pHwData)); /* Move to the next one, if necessary */ if (BufferFilled) { @@ -594,7 +624,8 @@ Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pT02) pHwData->tx_retry_count[RetryCount] += RetryCount; else pHwData->tx_retry_count[7] += RetryCount; - pr_debug("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count); + pr_debug("dto_tx_retry_count =%d\n", + pHwData->dto_tx_retry_count); MTO_SetTxCount(adapter, TxRate, RetryCount); } pHwData->dto_tx_frag_count += (RetryCount+1); diff --git a/drivers/staging/wlags49_h2/sta_h25.c b/drivers/staging/wlags49_h2/sta_h25.c index 5b6f670d8ef2..eccd780ef135 100644 --- a/drivers/staging/wlags49_h2/sta_h25.c +++ b/drivers/staging/wlags49_h2/sta_h25.c @@ -5211,7 +5211,7 @@ static const CFG_PROG_STRCT fw_image_code[] = { 0000, 0x000F429B, // Start execution address }, - { 0000, 0000, 0000, 0000, 00000000, 0000, 00000000} + { 0000, 0000, 0000, 0000, 00000000, 0000, NULL} }; static const CFG_RANGE20_STRCT fw_image_infocompat[] = { @@ -5247,8 +5247,8 @@ memimage fw_image = { "FUPU7D37dhfwci\001C", //signature, <format number>, C/Bin type (CFG_PROG_STRCT *) fw_image_code, 0x000F429B, - 00000000, //(dummy) pdaplug - 00000000, //(dummy) priplug + NULL, //(dummy) pdaplug + NULL, //(dummy) priplug (CFG_RANGE20_STRCT *) fw_image_infocompat, (CFG_IDENTITY_STRCT *) fw_image_infoidentity, }; diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index a4fd5c4717a8..a7d24c95191d 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -73,7 +73,8 @@ static int prism2_result2err(int prism2_result) static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data) { struct p80211msg_dot11req_mibset msg; - p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data; + p80211item_uint32_t *mibitem = + (p80211item_uint32_t *) &msg.mibattribute.data; msg.msgcode = DIDmsg_dot11req_mibset; mibitem->did = did; @@ -86,7 +87,8 @@ static int prism2_domibset_pstr32(wlandevice_t *wlandev, u32 did, u8 len, u8 *data) { struct p80211msg_dot11req_mibset msg; - p80211item_pstr32_t *mibitem = (p80211item_pstr32_t *) &msg.mibattribute.data; + p80211item_pstr32_t *mibitem = + (p80211item_pstr32_t *) &msg.mibattribute.data; msg.msgcode = DIDmsg_dot11req_mibset; mibitem->did = did; @@ -182,7 +184,8 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, goto exit; } - result = prism2_domibset_pstr32(wlandev, did, params->key_len, params->key); + result = prism2_domibset_pstr32(wlandev, did, + params->key_len, params->key); if (result) goto exit; break; @@ -328,7 +331,8 @@ static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, return result; } -static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) +static int prism2_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) { struct net_device *dev; struct prism2_wiphy_private *priv = wiphy_priv(wiphy); @@ -380,7 +384,8 @@ static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *reques (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels); i++) msg1.channellist.data.data[i] = - ieee80211_frequency_to_channel(request->channels[i]->center_freq); + ieee80211_frequency_to_channel( + request->channels[i]->center_freq); msg1.channellist.data.len = request->n_channels; msg1.maxchanneltime.data = 250; @@ -410,7 +415,8 @@ static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *reques ie_len = ie_buf[1] + 2; memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len); bss = cfg80211_inform_bss(wiphy, - ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), + ieee80211_get_channel(wiphy, + ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), (const u8 *) &(msg2.bssid.data.data), msg2.timestamp.data, msg2.capinfo.data, msg2.beaconperiod.data, diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 3dfa85ccc504..333a2f693e49 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -350,10 +350,10 @@ PD Record codes /*-------------------------------------------------------------*/ /* Commonly used basic types */ -typedef struct hfa384x_bytestr { +struct hfa384x_bytestr { u16 len; u8 data[0]; -} __packed hfa384x_bytestr_t; +} __packed; typedef struct hfa384x_bytestr32 { u16 len; diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index d22db43e8031..a9909f6b0001 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -525,7 +525,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp) p80211pstrd_t *pstr; u8 bytebuf[80]; - hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf; + struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf; u16 word; wlandev->macmode = WLAN_MACMODE_NONE; @@ -1019,7 +1019,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp) struct p80211msg_lnxreq_autojoin *msg = msgp; p80211pstrd_t *pstr; u8 bytebuf[256]; - hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf; + struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf; wlandev->macmode = WLAN_MACMODE_NONE; diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h index 07eecebeb6cc..190d390c8490 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ b/drivers/staging/wlan-ng/prism2mgmt.h @@ -92,8 +92,10 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr); void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len); /* byte string conversion functions*/ -void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); -void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); +void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr, + p80211pstrd_t *pstr); +void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr, + p80211pstrd_t *pstr); /* functions to convert Group Addresses */ void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv); diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index d3a06fa0b4f6..9b5f3b72d3ca 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -763,7 +763,8 @@ static int prism2mib_priv(struct mibrec *mib, * ----------------------------------------------------------------*/ -void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr, + p80211pstrd_t *pstr) { bytestr->len = cpu_to_le16((u16) (pstr->len)); memcpy(bytestr->data, pstr->data, pstr->len); @@ -804,7 +805,8 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr) * ----------------------------------------------------------------*/ -void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr, + p80211pstrd_t *pstr) { pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len))); memcpy(pstr->data, bytestr->data, pstr->len); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 76374b220228..46f9491d10d3 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1279,7 +1279,7 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); return; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, + prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, (p80211pstrd_t *) & wlandev->ssid); @@ -1361,7 +1361,7 @@ void prism2sta_processing_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); return; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, + prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, (p80211pstrd_t *) &wlandev->ssid); hw->link_status = HFA384x_LINK_CONNECTED; @@ -2037,7 +2037,7 @@ void prism2sta_commsqual_defer(struct work_struct *data) HFA384x_RID_CURRENTSSID, result); return; } - prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid, + prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, (p80211pstrd_t *) &wlandev->ssid); /* Reschedule timer */ diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index c033da408a58..95ce9708cec9 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -11,7 +11,7 @@ #define PCI_DEVICE_ID_XGI_27 0x027 #endif -static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = { +static const struct pci_device_id xgifb_pci_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_20)}, {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_27)}, {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_40)}, diff --git a/drivers/staging/xillybus/Kconfig b/drivers/staging/xillybus/Kconfig index b15f778b4c68..75c38c8c26eb 100644 --- a/drivers/staging/xillybus/Kconfig +++ b/drivers/staging/xillybus/Kconfig @@ -4,7 +4,7 @@ config XILLYBUS tristate "Xillybus generic FPGA interface" - depends on PCI || (OF_ADDRESS && OF_IRQ) && m + depends on PCI || (OF_ADDRESS && OF_IRQ) help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 1811aa764213..0564f97bdde4 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -30,7 +30,7 @@ MODULE_LICENSE("GPL v2"); static const char xillyname[] = "xillybus_pcie"; -static DEFINE_PCI_DEVICE_TABLE(xillyids) = { +static const struct pci_device_id xillyids[] = { {PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILLYBUS)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_XILLYBUS)}, {PCI_DEVICE(PCI_VENDOR_ID_ACTEL, PCI_DEVICE_ID_XILLYBUS)}, diff --git a/drivers/staging/zsmalloc/Kconfig b/drivers/staging/zsmalloc/Kconfig index 0ae13cd0908e..9d1f2a24ad62 100644 --- a/drivers/staging/zsmalloc/Kconfig +++ b/drivers/staging/zsmalloc/Kconfig @@ -9,3 +9,16 @@ config ZSMALLOC non-standard allocator interface where a handle, not a pointer, is returned by an alloc(). This handle must be mapped in order to access the allocated space. + +config PGTABLE_MAPPING + bool "Use page table mapping to access object in zsmalloc" + depends on ZSMALLOC + help + By default, zsmalloc uses a copy-based object mapping method to + access allocations that span two pages. However, if a particular + architecture (ex, ARM) performs VM mapping faster than copying, + then you should select this. This causes zsmalloc to use page table + mapping rather than copying for object mapping. + + You can check speed with zsmalloc benchmark[1]. + [1] https://github.com/spartacus06/zsmalloc diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 3b950e5a918f..b453d84af7b5 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -10,16 +10,14 @@ * Released under the terms of GNU General Public License Version 2.0 */ - /* - * This allocator is designed for use with zcache and zram. Thus, the - * allocator is supposed to work well under low memory conditions. In - * particular, it never attempts higher order page allocation which is - * very likely to fail under memory pressure. On the other hand, if we - * just use single (0-order) pages, it would suffer from very high - * fragmentation -- any object of size PAGE_SIZE/2 or larger would occupy - * an entire page. This was one of the major issues with its predecessor - * (xvmalloc). + * This allocator is designed for use with zram. Thus, the allocator is + * supposed to work well under low memory conditions. In particular, it + * never attempts higher order page allocation which is very likely to + * fail under memory pressure. On the other hand, if we just use single + * (0-order) pages, it would suffer from very high fragmentation -- + * any object of size PAGE_SIZE/2 or larger would occupy an entire page. + * This was one of the major issues with its predecessor (xvmalloc). * * To overcome these issues, zsmalloc allocates a bunch of 0-order pages * and links them together using various 'struct page' fields. These linked @@ -27,6 +25,21 @@ * page boundaries. The code refers to these linked pages as a single entity * called zspage. * + * For simplicity, zsmalloc can only allocate objects of size up to PAGE_SIZE + * since this satisfies the requirements of all its current users (in the + * worst case, page is incompressible and is thus stored "as-is" i.e. in + * uncompressed form). For allocation requests larger than this size, failure + * is returned (see zs_malloc). + * + * Additionally, zs_malloc() does not return a dereferenceable pointer. + * Instead, it returns an opaque handle (unsigned long) which encodes actual + * location of the allocated object. The reason for this indirection is that + * zsmalloc does not keep zspages permanently mapped since that would cause + * issues on 32-bit systems where the VA region for kernel space mappings + * is very small. So, before using the allocating memory, the object has to + * be mapped using zs_map_object() to get a usable pointer and subsequently + * unmapped using zs_unmap_object(). + * * Following is how we use various fields and flags of underlying * struct page(s) to form a zspage. * @@ -98,7 +111,7 @@ /* * Object location (<PFN>, <obj_idx>) is encoded as - * as single (void *) handle value. + * as single (unsigned long) handle value. * * Note that object index <obj_idx> is relative to system * page <PFN> it is stored in, so for each sub-page belonging @@ -218,19 +231,8 @@ struct zs_pool { #define CLASS_IDX_MASK ((1 << CLASS_IDX_BITS) - 1) #define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1) -/* - * By default, zsmalloc uses a copy-based object mapping method to access - * allocations that span two pages. However, if a particular architecture - * performs VM mapping faster than copying, then it should be added here - * so that USE_PGTABLE_MAPPING is defined. This causes zsmalloc to use - * page table mapping rather than copying for object mapping. - */ -#if defined(CONFIG_ARM) && !defined(MODULE) -#define USE_PGTABLE_MAPPING -#endif - struct mapping_area { -#ifdef USE_PGTABLE_MAPPING +#ifdef CONFIG_PGTABLE_MAPPING struct vm_struct *vm; /* vm area for mapping object that span pages */ #else char *vm_buf; /* copy buffer for objects that span pages */ @@ -275,6 +277,13 @@ static void set_zspage_mapping(struct page *page, unsigned int class_idx, page->mapping = (struct address_space *)m; } +/* + * zsmalloc divides the pool into various size classes where each + * class maintains a list of zspages where each zspage is divided + * into equal sized chunks. Each allocation falls into one of these + * classes depending on its size. This function returns index of the + * size class which has chunk size big enough to hold the give size. + */ static int get_size_class_index(int size) { int idx = 0; @@ -286,6 +295,13 @@ static int get_size_class_index(int size) return idx; } +/* + * For each size class, zspages are divided into different groups + * depending on how "full" they are. This was done so that we could + * easily find empty or nearly empty zspages when we try to shrink + * the pool (not yet implemented). This function returns fullness + * status of the given page. + */ static enum fullness_group get_fullness_group(struct page *page) { int inuse, max_objects; @@ -307,6 +323,12 @@ static enum fullness_group get_fullness_group(struct page *page) return fg; } +/* + * Each size class maintains various freelists and zspages are assigned + * to one of these freelists based on the number of live objects they + * have. This functions inserts the given zspage into the freelist + * identified by <class, fullness_group>. + */ static void insert_zspage(struct page *page, struct size_class *class, enum fullness_group fullness) { @@ -324,6 +346,10 @@ static void insert_zspage(struct page *page, struct size_class *class, *head = page; } +/* + * This function removes the given zspage from the freelist identified + * by <class, fullness_group>. + */ static void remove_zspage(struct page *page, struct size_class *class, enum fullness_group fullness) { @@ -345,6 +371,15 @@ static void remove_zspage(struct page *page, struct size_class *class, list_del_init(&page->lru); } +/* + * Each size class maintains zspages in different fullness groups depending + * on the number of live objects they contain. When allocating or freeing + * objects, the fullness status of the page can change, say, from ALMOST_FULL + * to ALMOST_EMPTY when freeing an object. This function checks if such + * a status change has occurred for the given page and accordingly moves the + * page from the freelist of the old fullness group to that of the new + * fullness group. + */ static enum fullness_group fix_fullness_group(struct zs_pool *pool, struct page *page) { @@ -631,7 +666,7 @@ static struct page *find_get_zspage(struct size_class *class) return page; } -#ifdef USE_PGTABLE_MAPPING +#ifdef CONFIG_PGTABLE_MAPPING static inline int __zs_cpu_up(struct mapping_area *area) { /* @@ -669,7 +704,7 @@ static inline void __zs_unmap_object(struct mapping_area *area, unmap_kernel_range(addr, PAGE_SIZE * 2); } -#else /* USE_PGTABLE_MAPPING */ +#else /* CONFIG_PGTABLE_MAPPING */ static inline int __zs_cpu_up(struct mapping_area *area) { @@ -747,7 +782,7 @@ out: pagefault_enable(); } -#endif /* USE_PGTABLE_MAPPING */ +#endif /* CONFIG_PGTABLE_MAPPING */ static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) diff --git a/drivers/staging/zsmalloc/zsmalloc.h b/drivers/staging/zsmalloc/zsmalloc.h index fbe6bec421aa..c2eb174b97ee 100644 --- a/drivers/staging/zsmalloc/zsmalloc.h +++ b/drivers/staging/zsmalloc/zsmalloc.h @@ -18,12 +18,19 @@ /* * zsmalloc mapping modes * - * NOTE: These only make a difference when a mapped object spans pages + * NOTE: These only make a difference when a mapped object spans pages. + * They also have no effect when PGTABLE_MAPPING is selected. */ enum zs_mapmode { ZS_MM_RW, /* normal read-write mapping */ ZS_MM_RO, /* read-only (no copy-out at unmap time) */ ZS_MM_WO /* write-only (no copy-in at map time) */ + /* + * NOTE: ZS_MM_WO should only be used for initializing new + * (uninitialized) allocations. Partial writes to already + * initialized allocations should use ZS_MM_RW to preserve the + * existing data. + */ }; struct zs_pool; diff --git a/drivers/vme/boards/vme_vmivme7805.c b/drivers/vme/boards/vme_vmivme7805.c index cf74aee2cef0..ac422121f9bb 100644 --- a/drivers/vme/boards/vme_vmivme7805.c +++ b/drivers/vme/boards/vme_vmivme7805.c @@ -27,7 +27,7 @@ static void __iomem *vmic_base; static const char driver_name[] = "vmivme_7805"; -static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { +static const struct pci_device_id vmic_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, { }, }; diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c index f8448573d030..a06edbfa95ca 100644 --- a/drivers/vme/bridges/vme_ca91cx42.c +++ b/drivers/vme/bridges/vme_ca91cx42.c @@ -42,7 +42,7 @@ static int geoid; static const char driver_name[] = "vme_ca91cx42"; -static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { +static const struct pci_device_id ca91cx42_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, { }, }; diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 9cf88337e4e9..16830d8b777c 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -45,7 +45,7 @@ static int geoid; static const char driver_name[] = "vme_tsi148"; -static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { +static const struct pci_device_id tsi148_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, { }, }; diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index f6856b427496..96562c9a8b1b 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c @@ -1274,7 +1274,7 @@ void vme_lm_free(struct vme_resource *resource) } EXPORT_SYMBOL(vme_lm_free); -int vme_slot_get(struct vme_dev *vdev) +int vme_slot_num(struct vme_dev *vdev) { struct vme_bridge *bridge; @@ -1285,14 +1285,27 @@ int vme_slot_get(struct vme_dev *vdev) } if (bridge->slot_get == NULL) { - printk(KERN_WARNING "vme_slot_get not supported\n"); + printk(KERN_WARNING "vme_slot_num not supported\n"); return -EINVAL; } return bridge->slot_get(bridge); } -EXPORT_SYMBOL(vme_slot_get); +EXPORT_SYMBOL(vme_slot_num); +int vme_bus_num(struct vme_dev *vdev) +{ + struct vme_bridge *bridge; + + bridge = vdev->bridge; + if (bridge == NULL) { + pr_err("Can't find VME bus\n"); + return -EINVAL; + } + + return bridge->num; +} +EXPORT_SYMBOL(vme_bus_num); /* - Bridge Registration --------------------------------------------------- */ |