linux/drivers/comedi/comedi_fops.c

3451 lines
80 KiB

staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging/comedi: bug fix for module usage count on device removal When a dynamically created comedi device is being automatically removed by a call to `comedi_auto_unconfig()` from the lower level driver, `comedi_device_cleanup()` is called to perform the detachment from the lower level driver. If the comedi device is open at the time, `dev->use_count` will be the the number of outstanding opens. The function currently decrements the the module counts of the "comedi" module and the low-level driver module by this amount and reduces `dev->use_count` to zero. There are various problems with this as the `release` file operation handler `comedi_close()` also decrements `dev->use_count` and decrements the module usage counts. This means that `dev->use_count` and the module counts can end up negative. Also, the assumed one-to-one relationship between the file open count and the low-level module usage count is invalid and can get screwed up. We only want to stop the low-level module being unloaded while a comedi device using the module has an open file object. Also, there is no need to manipulate the module count of the core "comedi" module at all since the comedi module is the owner of the file operations structure and the system will not unload the module while there are open file objects using it. Correct the bugs and simplify as follows: 1. Get rid of the module count manipulations of the core "comedi" module (`THIS_MODULE`) altogether. 2. Don't alter `dev->use_count` in `comedi_device_cleanup()` as it should only be altered by the `open` and `release` file operation handlers `comedi_open()` and `comedi_close()`. 3. Increment the low-level module count for the following reasons: a) In `comedi_open()` if the open count was zero and the comedi device is attached to the low-level driver. b) When the `COMEDI_DEVCONFIG` ioctl is used to manually attach an unattached comedi device to a low-level driver. The open count will be greater than zero at this time. The actual increment of the low-level module count is already done by `comedi_device_attach()`. 4. Decrement the low-level module count for the following reasons: a) In `comedi_close()` if the open count was 1 and the comedi device is attached to the low-level driver. b) In `comedi_device_cleanup()` (called via `comedi_auto_unconfig()` --> `comedi_release_hardware_device()` --> `comedi_free_board_dev()` when the comedi device is automatically unconfigured due to action by the low-level driver) if the device was attached (which it should be) and open count was non-zero (greater than zero). c) When the `COMEDI_DEVCONFIG` ioctl is used to manually detach the comedi device from the low-level driver. The open count will be greater than zero at this time. The open count should never go negative. Parts 3 and 4 ensure that the low-level module usage count is incremented on entering the state where the comedi device is attached to the low-level driver AND the open count is greater than zero, and is decremented on leaving that state. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-11 14:51:03 +00:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: simplify driver module counting For a legacy device attachment with the `COMEDI_DEVCONFIG` ioctl, `do_devconfig_ioctl()` calls `comedi_device_attach()` to find a matching device driver and attach the device. It then tries to increment the device driver's module count and if that fails it detaches the device. So on successful attachment of a device by the `COMEDI_DEVCONFIG` ioctl, the device driver's module count will have been incremented. `comedi_device_attach()` is called from nowhere else. It already increments the device driver's module count temporarily and decrements it again; if it gets as far as calling `comedi_device_postconfig()` the module count is decremented within that function. Simplify the above by removing the decrement of the device driver module count from `comedi_device_postconfig()`. If the call to `comedi_device_postconfig()` succeeds, `comedi_device_attach()` will return with the module count still incremented, otherwise decrement the module count before returning the error. Don't try and increment the module count in `do_devconfig_ioctl()` after a successful return from `comedi_device_attach()` as the module count has now already been incremented. `comedi_device_postconfig()` is also called by `comedi_auto_config()` which currently has to increment the device driver's module count temporarily so that `comedi_device_postconfig()` can decrement it, but always returns with no overall change to the module count. Remove all the module count manipulations from `comedi_device_postconfig()`. There is no other reason for `comedi_auto_config()` to increment the device driver's module count temporarily, since it is only called (indirectly) from the device driver itself (usually via one of the wrappers `comedi_pci_auto_config()` or `comedi_usb_auto_config()`). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:58:56 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: fix a race between do_cmd_ioctl() and read/write `do_cmd_ioctl()` is called with the comedi device's mutex locked to process the `COMEDI_CMD` ioctl to set up comedi's asynchronous command handling on a comedi subdevice. `comedi_read()` and `comedi_write()` are the `read` and `write` handlers for the comedi device, but do not lock the mutex (for performance reasons, as some things can hold the mutex for quite a long time). There is a race condition if `comedi_read()` or `comedi_write()` is running at the same time and for the same file object and comedi subdevice as `do_cmd_ioctl()`. `do_cmd_ioctl()` sets the subdevice's `busy` pointer to the file object way before it sets the `SRF_RUNNING` flag in the subdevice's `runflags` member. `comedi_read() and `comedi_write()` check the subdevice's `busy` pointer is pointing to the current file object, then if the `SRF_RUNNING` flag is not set, will call `do_become_nonbusy()` to shut down the asyncronous command. Bad things can happen if the asynchronous command is being shutdown and set up at the same time. To prevent the race, don't set the `busy` pointer until after the `SRF_RUNNING` flag has been set. Also, make sure the mutex is held in `comedi_read()` and `comedi_write()` while calling `do_become_nonbusy()` in order to avoid moving the race condition to a point within that function. Change some error handling `goto cleanup` statements in `do_cmd_ioctl()` to simple `return -ERRFOO` statements as a result of changing when the `busy` pointer is set. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-05 16:49:34 +01:00
staging: comedi: fix a race between do_cmd_ioctl() and read/write `do_cmd_ioctl()` is called with the comedi device's mutex locked to process the `COMEDI_CMD` ioctl to set up comedi's asynchronous command handling on a comedi subdevice. `comedi_read()` and `comedi_write()` are the `read` and `write` handlers for the comedi device, but do not lock the mutex (for performance reasons, as some things can hold the mutex for quite a long time). There is a race condition if `comedi_read()` or `comedi_write()` is running at the same time and for the same file object and comedi subdevice as `do_cmd_ioctl()`. `do_cmd_ioctl()` sets the subdevice's `busy` pointer to the file object way before it sets the `SRF_RUNNING` flag in the subdevice's `runflags` member. `comedi_read() and `comedi_write()` check the subdevice's `busy` pointer is pointing to the current file object, then if the `SRF_RUNNING` flag is not set, will call `do_become_nonbusy()` to shut down the asyncronous command. Bad things can happen if the asynchronous command is being shutdown and set up at the same time. To prevent the race, don't set the `busy` pointer until after the `SRF_RUNNING` flag has been set. Also, make sure the mutex is held in `comedi_read()` and `comedi_write()` while calling `do_become_nonbusy()` in order to avoid moving the race condition to a point within that function. Change some error handling `goto cleanup` statements in `do_cmd_ioctl()` to simple `return -ERRFOO` statements as a result of changing when the `busy` pointer is set. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-05 16:49:34 +01:00
staging: comedi: (regression) channel list must be set for COMEDI_CMD ioctl `do_cmd_ioctl()`, the handler for the `COMEDI_CMD` ioctl can incorrectly call the Comedi subdevice's `do_cmd()` handler with a NULL channel list pointer. This is a regression as the `do_cmd()` handler has never been expected to deal with that, leading to a kernel OOPS when it tries to dereference it. A NULL channel list pointer is allowed for the `COMEDI_CMDTEST` ioctl, handled by `do_cmdtest_ioctl()` and the subdevice's `do_cmdtest()` handler, but not for the `COMEDI_CMD` ioctl and its handlers. Both `do_cmd_ioctl()` and `do_cmdtest_ioctl()` call `__comedi_get_user_chanlist()` to copy the channel list from user memory into dynamically allocated kernel memory and check it for consistency. That function currently returns 0 if the `user_chanlist` parameter (pointing to the channel list in user memory) is NULL. That's fine for `do_cmdtest_ioctl()`, but `do_cmd_ioctl()` incorrectly assumes the kernel copy of the channel list has been set-up correctly. Fix it by not allowing the `user_chanlist` parameter to be NULL in `__comedi_get_user_chanlist()`, and only calling it from `do_cmdtest_ioctl()` if the parameter is non-NULL. Thanks to Bernd Porr for reporting the bug via an initial patch sent privately. Fixes: c6cd0eefb27b ("staging: comedi: comedi_fops: introduce __comedi_get_user_chanlist()") Reported-by: Bernd Porr <mail@berndporr.me.uk> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Bernd Porr <mail@berndporr.me.uk> Cc: <stable@vger.kernel.org> # 3.15.y 3.16.y 3.17.y Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-10-08 16:09:14 +01:00
staging: comedi: (regression) channel list must be set for COMEDI_CMD ioctl `do_cmd_ioctl()`, the handler for the `COMEDI_CMD` ioctl can incorrectly call the Comedi subdevice's `do_cmd()` handler with a NULL channel list pointer. This is a regression as the `do_cmd()` handler has never been expected to deal with that, leading to a kernel OOPS when it tries to dereference it. A NULL channel list pointer is allowed for the `COMEDI_CMDTEST` ioctl, handled by `do_cmdtest_ioctl()` and the subdevice's `do_cmdtest()` handler, but not for the `COMEDI_CMD` ioctl and its handlers. Both `do_cmd_ioctl()` and `do_cmdtest_ioctl()` call `__comedi_get_user_chanlist()` to copy the channel list from user memory into dynamically allocated kernel memory and check it for consistency. That function currently returns 0 if the `user_chanlist` parameter (pointing to the channel list in user memory) is NULL. That's fine for `do_cmdtest_ioctl()`, but `do_cmd_ioctl()` incorrectly assumes the kernel copy of the channel list has been set-up correctly. Fix it by not allowing the `user_chanlist` parameter to be NULL in `__comedi_get_user_chanlist()`, and only calling it from `do_cmdtest_ioctl()` if the parameter is non-NULL. Thanks to Bernd Porr for reporting the bug via an initial patch sent privately. Fixes: c6cd0eefb27b ("staging: comedi: comedi_fops: introduce __comedi_get_user_chanlist()") Reported-by: Bernd Porr <mail@berndporr.me.uk> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Bernd Porr <mail@berndporr.me.uk> Cc: <stable@vger.kernel.org> # 3.15.y 3.16.y 3.17.y Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-10-08 16:09:14 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: protect buffer from being freed while mmapped If a comedi device is automatically detached by `comedi_auto_unconfig()` any data buffers associated with subdevices that support asynchronous commands will be freed. If the buffer is mmapped at the time, bad things are likely to happen! Prevent this by moving some of the buffer details from `struct comedi_async` into a new, dynamically allocated, and kref-counted `struct comedi_buf_map`. This holds a list of pages, a reference count, and enough information to free the pages. The new member `buf_map` of `struct comedi_async` points to a `struct comedi_buf_map` when the buffer size is non-zero. Provide a new helper function `comedi_buf_is_mapped()` to check whether an a buffer is mmapped. If it is mmapped, the buffer is not allowed to be resized and the device is not allowed to be manually detached by the `COMEDI_DEVCONFIG` ioctl. Provide helper functions `comedi_buf_map_get()` and `comedi_buf_map_put()` to manipulate the reference count of the `struct comedi_buf_map`, which will be freed along with its contents via the 'release' callback of the `kref_put()` call. The reference count is manipulated by the vma operations and the mmap file operation. Now, when the comedi device is automatically detached, the buffer will be effectively freed by calling `comedi_buf_alloc()` with a new buffer size of 0. That calls local function `__comedi_buf_free()` which calls `comedi_buf_map_put()` on the `buf_map` member to free it. It won't actually be freed until the final 'put'. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-08 15:03:43 +00:00
staging: comedi: protect buffer from being freed while mmapped If a comedi device is automatically detached by `comedi_auto_unconfig()` any data buffers associated with subdevices that support asynchronous commands will be freed. If the buffer is mmapped at the time, bad things are likely to happen! Prevent this by moving some of the buffer details from `struct comedi_async` into a new, dynamically allocated, and kref-counted `struct comedi_buf_map`. This holds a list of pages, a reference count, and enough information to free the pages. The new member `buf_map` of `struct comedi_async` points to a `struct comedi_buf_map` when the buffer size is non-zero. Provide a new helper function `comedi_buf_is_mapped()` to check whether an a buffer is mmapped. If it is mmapped, the buffer is not allowed to be resized and the device is not allowed to be manually detached by the `COMEDI_DEVCONFIG` ioctl. Provide helper functions `comedi_buf_map_get()` and `comedi_buf_map_put()` to manipulate the reference count of the `struct comedi_buf_map`, which will be freed along with its contents via the 'release' callback of the `kref_put()` call. The reference count is manipulated by the vma operations and the mmap file operation. Now, when the comedi device is automatically detached, the buffer will be effectively freed by calling `comedi_buf_alloc()` with a new buffer size of 0. That calls local function `__comedi_buf_free()` which calls `comedi_buf_map_put()` on the `buf_map` member to free it. It won't actually be freed until the final 'put'. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-08 15:03:43 +00:00
staging: comedi: protect buffer from being freed while mmapped If a comedi device is automatically detached by `comedi_auto_unconfig()` any data buffers associated with subdevices that support asynchronous commands will be freed. If the buffer is mmapped at the time, bad things are likely to happen! Prevent this by moving some of the buffer details from `struct comedi_async` into a new, dynamically allocated, and kref-counted `struct comedi_buf_map`. This holds a list of pages, a reference count, and enough information to free the pages. The new member `buf_map` of `struct comedi_async` points to a `struct comedi_buf_map` when the buffer size is non-zero. Provide a new helper function `comedi_buf_is_mapped()` to check whether an a buffer is mmapped. If it is mmapped, the buffer is not allowed to be resized and the device is not allowed to be manually detached by the `COMEDI_DEVCONFIG` ioctl. Provide helper functions `comedi_buf_map_get()` and `comedi_buf_map_put()` to manipulate the reference count of the `struct comedi_buf_map`, which will be freed along with its contents via the 'release' callback of the `kref_put()` call. The reference count is manipulated by the vma operations and the mmap file operation. Now, when the comedi device is automatically detached, the buffer will be effectively freed by calling `comedi_buf_alloc()` with a new buffer size of 0. That calls local function `__comedi_buf_free()` which calls `comedi_buf_map_put()` on the `buf_map` member to free it. It won't actually be freed until the final 'put'. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-08 15:03:43 +00:00
staging: comedi: protect buffer from being freed while mmapped If a comedi device is automatically detached by `comedi_auto_unconfig()` any data buffers associated with subdevices that support asynchronous commands will be freed. If the buffer is mmapped at the time, bad things are likely to happen! Prevent this by moving some of the buffer details from `struct comedi_async` into a new, dynamically allocated, and kref-counted `struct comedi_buf_map`. This holds a list of pages, a reference count, and enough information to free the pages. The new member `buf_map` of `struct comedi_async` points to a `struct comedi_buf_map` when the buffer size is non-zero. Provide a new helper function `comedi_buf_is_mapped()` to check whether an a buffer is mmapped. If it is mmapped, the buffer is not allowed to be resized and the device is not allowed to be manually detached by the `COMEDI_DEVCONFIG` ioctl. Provide helper functions `comedi_buf_map_get()` and `comedi_buf_map_put()` to manipulate the reference count of the `struct comedi_buf_map`, which will be freed along with its contents via the 'release' callback of the `kref_put()` call. The reference count is manipulated by the vma operations and the mmap file operation. Now, when the comedi device is automatically detached, the buffer will be effectively freed by calling `comedi_buf_alloc()` with a new buffer size of 0. That calls local function `__comedi_buf_free()` which calls `comedi_buf_map_put()` on the `buf_map` member to free it. It won't actually be freed until the final 'put'. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-08 15:03:43 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [<ffffffff810c96fe>] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff810ce3bc>] might_fault+0x6d/0x90 [<ffffffffa0031ffb>] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [<ffffffffa003227f>] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [<ffffffff810f7fcd>] vfs_ioctl+0x18/0x34 [<ffffffff810f87fd>] do_vfs_ioctl+0x382/0x43c [<ffffffff810f88f9>] sys_ioctl+0x42/0x65 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [<ffffffff8106c528>] __lock_acquire+0x101d/0x1591 [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff8140c894>] mutex_lock_nested+0x46/0x2a4 [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] [<ffffffff810d5816>] mmap_region+0x281/0x492 [<ffffffff810d5c92>] do_mmap_pgoff+0x26b/0x2a7 [<ffffffff810c971a>] vm_mmap_pgoff+0x5d/0x76 [<ffffffff810d493f>] sys_mmap_pgoff+0xc7/0x10d [<ffffffff81004d36>] sys_mmap+0x16/0x20 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: <stable@vger.kernel.org> # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-10 19:41:57 +01:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [<ffffffff810c96fe>] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff810ce3bc>] might_fault+0x6d/0x90 [<ffffffffa0031ffb>] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [<ffffffffa003227f>] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [<ffffffff810f7fcd>] vfs_ioctl+0x18/0x34 [<ffffffff810f87fd>] do_vfs_ioctl+0x382/0x43c [<ffffffff810f88f9>] sys_ioctl+0x42/0x65 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [<ffffffff8106c528>] __lock_acquire+0x101d/0x1591 [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff8140c894>] mutex_lock_nested+0x46/0x2a4 [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] [<ffffffff810d5816>] mmap_region+0x281/0x492 [<ffffffff810d5c92>] do_mmap_pgoff+0x26b/0x2a7 [<ffffffff810c971a>] vm_mmap_pgoff+0x5d/0x76 [<ffffffff810d493f>] sys_mmap_pgoff+0xc7/0x10d [<ffffffff81004d36>] sys_mmap+0x16/0x20 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: <stable@vger.kernel.org> # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-10 19:41:57 +01:00
staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [<ffffffff810c96fe>] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff810ce3bc>] might_fault+0x6d/0x90 [<ffffffffa0031ffb>] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [<ffffffffa003227f>] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [<ffffffff810f7fcd>] vfs_ioctl+0x18/0x34 [<ffffffff810f87fd>] do_vfs_ioctl+0x382/0x43c [<ffffffff810f88f9>] sys_ioctl+0x42/0x65 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [<ffffffff8106c528>] __lock_acquire+0x101d/0x1591 [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff8140c894>] mutex_lock_nested+0x46/0x2a4 [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] [<ffffffff810d5816>] mmap_region+0x281/0x492 [<ffffffff810d5c92>] do_mmap_pgoff+0x26b/0x2a7 [<ffffffff810c971a>] vm_mmap_pgoff+0x5d/0x76 [<ffffffff810d493f>] sys_mmap_pgoff+0xc7/0x10d [<ffffffff81004d36>] sys_mmap+0x16/0x20 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: <stable@vger.kernel.org> # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-10 19:41:57 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [<ffffffff810c96fe>] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff810ce3bc>] might_fault+0x6d/0x90 [<ffffffffa0031ffb>] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [<ffffffffa003227f>] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [<ffffffff810f7fcd>] vfs_ioctl+0x18/0x34 [<ffffffff810f87fd>] do_vfs_ioctl+0x382/0x43c [<ffffffff810f88f9>] sys_ioctl+0x42/0x65 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [<ffffffff8106c528>] __lock_acquire+0x101d/0x1591 [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff8140c894>] mutex_lock_nested+0x46/0x2a4 [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] [<ffffffff810d5816>] mmap_region+0x281/0x492 [<ffffffff810d5c92>] do_mmap_pgoff+0x26b/0x2a7 [<ffffffff810c971a>] vm_mmap_pgoff+0x5d/0x76 [<ffffffff810d493f>] sys_mmap_pgoff+0xc7/0x10d [<ffffffff81004d36>] sys_mmap+0x16/0x20 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: <stable@vger.kernel.org> # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-10 19:41:57 +01:00
staging: comedi: protect buffer from being freed while mmapped If a comedi device is automatically detached by `comedi_auto_unconfig()` any data buffers associated with subdevices that support asynchronous commands will be freed. If the buffer is mmapped at the time, bad things are likely to happen! Prevent this by moving some of the buffer details from `struct comedi_async` into a new, dynamically allocated, and kref-counted `struct comedi_buf_map`. This holds a list of pages, a reference count, and enough information to free the pages. The new member `buf_map` of `struct comedi_async` points to a `struct comedi_buf_map` when the buffer size is non-zero. Provide a new helper function `comedi_buf_is_mapped()` to check whether an a buffer is mmapped. If it is mmapped, the buffer is not allowed to be resized and the device is not allowed to be manually detached by the `COMEDI_DEVCONFIG` ioctl. Provide helper functions `comedi_buf_map_get()` and `comedi_buf_map_put()` to manipulate the reference count of the `struct comedi_buf_map`, which will be freed along with its contents via the 'release' callback of the `kref_put()` call. The reference count is manipulated by the vma operations and the mmap file operation. Now, when the comedi device is automatically detached, the buffer will be effectively freed by calling `comedi_buf_alloc()` with a new buffer size of 0. That calls local function `__comedi_buf_free()` which calls `comedi_buf_map_put()` on the `buf_map` member to free it. It won't actually be freed until the final 'put'. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-11-08 15:03:43 +00:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: use dma_mmap_coherent for DMA-able buffer mmap Comedi's acquisition buffer allocation code can allocate the buffer from normal kernel memory or from DMA coherent memory depending on the `dma_async_dir` value in the comedi subdevice. (A value of `DMA_NONE` causes the buffer to be allocated from normal kernel memory. Other values cause the buffer to be allocated from DMA coherent memory.) The buffer currently consists of a bunch of page-sized blocks that are vmap'ed into a contiguous range of virtual addresses. The pages are also mmap'able into user address space. For DMA'able buffers, these page-sized blocks are allocated by `dma_alloc_coherent()`. For DMA-able buffers, the DMA API is currently abused in various ways, the most serious abuse being the calling of `virt_to_page()` on the blocks allocated by `dma_alloc_coherent()` and passing those pages to `vmap()` (for mapping to the kernels vmalloc address space) and via `page_to_pfn()` to `remap_pfn_range()` (for mmap'ing to user space). it also uses the `__GFP_COMP` flag when allocating the blocks, and marks the allocated pages as reserved (which is unnecessary for DMA coherent allocations). The code can be changed to get rid of the vmap'ed address altogether if necessary, since there are only a few places in the comedi code that use the vmap'ed address directly and we also keep a list of the kernel addresses for the individual pages prior to the vmap operation. This would add some run-time overhead to buffer accesses. The real killer is the mmap operation. For mmap, the address range specified in the VMA needs to be mmap'ed to the individually allocated page-sized blocks. That is not a problem when the pages are allocated from normal kernel memory as the individual pages can be remapped by `remap_pfn_range()`, but it is a problem when the page-sized blocks are allocated by `dma_alloc_coherent()` because the DMA API currently has no support for splitting a VMA across multiple blocks of DMA coherent memory (or rather, no support for mapping part of a VMA range to a single block of DMA coherent memory). In order to comply with the DMA API and allow the buffer to be mmap'ed, the buffer needs to be allocated as a single block by a single call to `dma_alloc_coherent()`, freed by a single call to `dma_free_coherent()`, and mmap'ed to user space by a single call to `dma_mmap_coherent()`. This patch changes the buffer allocation, freeing, and mmap'ing code to do that, with the unfortunate consequence that buffer allocation is more likely to fail. It also no longer uses the `__GFP_COMP` flag when allocating DMA coherent memory, no longer marks the allocated pages of DMA coherent memory as reserved, and no longer vmap's the DMA coherent memory pages (since they are contiguous anyway). Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-25 12:26:59 +01:00
staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [<ffffffff810c96fe>] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff810ce3bc>] might_fault+0x6d/0x90 [<ffffffffa0031ffb>] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [<ffffffffa003227f>] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [<ffffffff810f7fcd>] vfs_ioctl+0x18/0x34 [<ffffffff810f87fd>] do_vfs_ioctl+0x382/0x43c [<ffffffff810f88f9>] sys_ioctl+0x42/0x65 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [<ffffffff8106c528>] __lock_acquire+0x101d/0x1591 [<ffffffff8106d0e8>] lock_acquire+0x97/0x105 [<ffffffff8140c894>] mutex_lock_nested+0x46/0x2a4 [<ffffffffa00313f4>] comedi_mmap+0x57/0x1d9 [comedi] [<ffffffff810d5816>] mmap_region+0x281/0x492 [<ffffffff810d5c92>] do_mmap_pgoff+0x26b/0x2a7 [<ffffffff810c971a>] vm_mmap_pgoff+0x5d/0x76 [<ffffffff810d493f>] sys_mmap_pgoff+0xc7/0x10d [<ffffffff81004d36>] sys_mmap+0x16/0x20 [<ffffffff81415c62>] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: <stable@vger.kernel.org> # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-10 19:41:57 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: fix a race between do_cmd_ioctl() and read/write `do_cmd_ioctl()` is called with the comedi device's mutex locked to process the `COMEDI_CMD` ioctl to set up comedi's asynchronous command handling on a comedi subdevice. `comedi_read()` and `comedi_write()` are the `read` and `write` handlers for the comedi device, but do not lock the mutex (for performance reasons, as some things can hold the mutex for quite a long time). There is a race condition if `comedi_read()` or `comedi_write()` is running at the same time and for the same file object and comedi subdevice as `do_cmd_ioctl()`. `do_cmd_ioctl()` sets the subdevice's `busy` pointer to the file object way before it sets the `SRF_RUNNING` flag in the subdevice's `runflags` member. `comedi_read() and `comedi_write()` check the subdevice's `busy` pointer is pointing to the current file object, then if the `SRF_RUNNING` flag is not set, will call `do_become_nonbusy()` to shut down the asyncronous command. Bad things can happen if the asynchronous command is being shutdown and set up at the same time. To prevent the race, don't set the `busy` pointer until after the `SRF_RUNNING` flag has been set. Also, make sure the mutex is held in `comedi_read()` and `comedi_write()` while calling `do_become_nonbusy()` in order to avoid moving the race condition to a point within that function. Change some error handling `goto cleanup` statements in `do_cmd_ioctl()` to simple `return -ERRFOO` statements as a result of changing when the `busy` pointer is set. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-05 16:49:34 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: fix a race between do_cmd_ioctl() and read/write `do_cmd_ioctl()` is called with the comedi device's mutex locked to process the `COMEDI_CMD` ioctl to set up comedi's asynchronous command handling on a comedi subdevice. `comedi_read()` and `comedi_write()` are the `read` and `write` handlers for the comedi device, but do not lock the mutex (for performance reasons, as some things can hold the mutex for quite a long time). There is a race condition if `comedi_read()` or `comedi_write()` is running at the same time and for the same file object and comedi subdevice as `do_cmd_ioctl()`. `do_cmd_ioctl()` sets the subdevice's `busy` pointer to the file object way before it sets the `SRF_RUNNING` flag in the subdevice's `runflags` member. `comedi_read() and `comedi_write()` check the subdevice's `busy` pointer is pointing to the current file object, then if the `SRF_RUNNING` flag is not set, will call `do_become_nonbusy()` to shut down the asyncronous command. Bad things can happen if the asynchronous command is being shutdown and set up at the same time. To prevent the race, don't set the `busy` pointer until after the `SRF_RUNNING` flag has been set. Also, make sure the mutex is held in `comedi_read()` and `comedi_write()` while calling `do_become_nonbusy()` in order to avoid moving the race condition to a point within that function. Change some error handling `goto cleanup` statements in `do_cmd_ioctl()` to simple `return -ERRFOO` statements as a result of changing when the `busy` pointer is set. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-05 16:49:34 +01:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging/comedi: bug fix for module usage count on device removal When a dynamically created comedi device is being automatically removed by a call to `comedi_auto_unconfig()` from the lower level driver, `comedi_device_cleanup()` is called to perform the detachment from the lower level driver. If the comedi device is open at the time, `dev->use_count` will be the the number of outstanding opens. The function currently decrements the the module counts of the "comedi" module and the low-level driver module by this amount and reduces `dev->use_count` to zero. There are various problems with this as the `release` file operation handler `comedi_close()` also decrements `dev->use_count` and decrements the module usage counts. This means that `dev->use_count` and the module counts can end up negative. Also, the assumed one-to-one relationship between the file open count and the low-level module usage count is invalid and can get screwed up. We only want to stop the low-level module being unloaded while a comedi device using the module has an open file object. Also, there is no need to manipulate the module count of the core "comedi" module at all since the comedi module is the owner of the file operations structure and the system will not unload the module while there are open file objects using it. Correct the bugs and simplify as follows: 1. Get rid of the module count manipulations of the core "comedi" module (`THIS_MODULE`) altogether. 2. Don't alter `dev->use_count` in `comedi_device_cleanup()` as it should only be altered by the `open` and `release` file operation handlers `comedi_open()` and `comedi_close()`. 3. Increment the low-level module count for the following reasons: a) In `comedi_open()` if the open count was zero and the comedi device is attached to the low-level driver. b) When the `COMEDI_DEVCONFIG` ioctl is used to manually attach an unattached comedi device to a low-level driver. The open count will be greater than zero at this time. The actual increment of the low-level module count is already done by `comedi_device_attach()`. 4. Decrement the low-level module count for the following reasons: a) In `comedi_close()` if the open count was 1 and the comedi device is attached to the low-level driver. b) In `comedi_device_cleanup()` (called via `comedi_auto_unconfig()` --> `comedi_release_hardware_device()` --> `comedi_free_board_dev()` when the comedi device is automatically unconfigured due to action by the low-level driver) if the device was attached (which it should be) and open count was non-zero (greater than zero). c) When the `COMEDI_DEVCONFIG` ioctl is used to manually detach the comedi device from the low-level driver. The open count will be greater than zero at this time. The open count should never go negative. Parts 3 and 4 ensure that the low-level module usage count is incremented on entering the state where the comedi device is attached to the low-level driver AND the open count is greater than zero, and is decremented on leaving that state. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-11 14:51:03 +00:00
staging/comedi: bug fix for module usage count on device removal When a dynamically created comedi device is being automatically removed by a call to `comedi_auto_unconfig()` from the lower level driver, `comedi_device_cleanup()` is called to perform the detachment from the lower level driver. If the comedi device is open at the time, `dev->use_count` will be the the number of outstanding opens. The function currently decrements the the module counts of the "comedi" module and the low-level driver module by this amount and reduces `dev->use_count` to zero. There are various problems with this as the `release` file operation handler `comedi_close()` also decrements `dev->use_count` and decrements the module usage counts. This means that `dev->use_count` and the module counts can end up negative. Also, the assumed one-to-one relationship between the file open count and the low-level module usage count is invalid and can get screwed up. We only want to stop the low-level module being unloaded while a comedi device using the module has an open file object. Also, there is no need to manipulate the module count of the core "comedi" module at all since the comedi module is the owner of the file operations structure and the system will not unload the module while there are open file objects using it. Correct the bugs and simplify as follows: 1. Get rid of the module count manipulations of the core "comedi" module (`THIS_MODULE`) altogether. 2. Don't alter `dev->use_count` in `comedi_device_cleanup()` as it should only be altered by the `open` and `release` file operation handlers `comedi_open()` and `comedi_close()`. 3. Increment the low-level module count for the following reasons: a) In `comedi_open()` if the open count was zero and the comedi device is attached to the low-level driver. b) When the `COMEDI_DEVCONFIG` ioctl is used to manually attach an unattached comedi device to a low-level driver. The open count will be greater than zero at this time. The actual increment of the low-level module count is already done by `comedi_device_attach()`. 4. Decrement the low-level module count for the following reasons: a) In `comedi_close()` if the open count was 1 and the comedi device is attached to the low-level driver. b) In `comedi_device_cleanup()` (called via `comedi_auto_unconfig()` --> `comedi_release_hardware_device()` --> `comedi_free_board_dev()` when the comedi device is automatically unconfigured due to action by the low-level driver) if the device was attached (which it should be) and open count was non-zero (greater than zero). c) When the `COMEDI_DEVCONFIG` ioctl is used to manually detach the comedi device from the low-level driver. The open count will be greater than zero at this time. The open count should never go negative. Parts 3 and 4 ensure that the low-level module usage count is incremented on entering the state where the comedi device is attached to the low-level driver AND the open count is greater than zero, and is decremented on leaving that state. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-11 14:51:03 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
staging/comedi: bug fix for module usage count on device removal When a dynamically created comedi device is being automatically removed by a call to `comedi_auto_unconfig()` from the lower level driver, `comedi_device_cleanup()` is called to perform the detachment from the lower level driver. If the comedi device is open at the time, `dev->use_count` will be the the number of outstanding opens. The function currently decrements the the module counts of the "comedi" module and the low-level driver module by this amount and reduces `dev->use_count` to zero. There are various problems with this as the `release` file operation handler `comedi_close()` also decrements `dev->use_count` and decrements the module usage counts. This means that `dev->use_count` and the module counts can end up negative. Also, the assumed one-to-one relationship between the file open count and the low-level module usage count is invalid and can get screwed up. We only want to stop the low-level module being unloaded while a comedi device using the module has an open file object. Also, there is no need to manipulate the module count of the core "comedi" module at all since the comedi module is the owner of the file operations structure and the system will not unload the module while there are open file objects using it. Correct the bugs and simplify as follows: 1. Get rid of the module count manipulations of the core "comedi" module (`THIS_MODULE`) altogether. 2. Don't alter `dev->use_count` in `comedi_device_cleanup()` as it should only be altered by the `open` and `release` file operation handlers `comedi_open()` and `comedi_close()`. 3. Increment the low-level module count for the following reasons: a) In `comedi_open()` if the open count was zero and the comedi device is attached to the low-level driver. b) When the `COMEDI_DEVCONFIG` ioctl is used to manually attach an unattached comedi device to a low-level driver. The open count will be greater than zero at this time. The actual increment of the low-level module count is already done by `comedi_device_attach()`. 4. Decrement the low-level module count for the following reasons: a) In `comedi_close()` if the open count was 1 and the comedi device is attached to the low-level driver. b) In `comedi_device_cleanup()` (called via `comedi_auto_unconfig()` --> `comedi_release_hardware_device()` --> `comedi_free_board_dev()` when the comedi device is automatically unconfigured due to action by the low-level driver) if the device was attached (which it should be) and open count was non-zero (greater than zero). c) When the `COMEDI_DEVCONFIG` ioctl is used to manually detach the comedi device from the low-level driver. The open count will be greater than zero at this time. The open count should never go negative. Parts 3 and 4 ensure that the low-level module usage count is incremented on entering the state where the comedi device is attached to the low-level driver AND the open count is greater than zero, and is decremented on leaving that state. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-11 14:51:03 +00:00
staging/comedi: bug fix for module usage count on device removal When a dynamically created comedi device is being automatically removed by a call to `comedi_auto_unconfig()` from the lower level driver, `comedi_device_cleanup()` is called to perform the detachment from the lower level driver. If the comedi device is open at the time, `dev->use_count` will be the the number of outstanding opens. The function currently decrements the the module counts of the "comedi" module and the low-level driver module by this amount and reduces `dev->use_count` to zero. There are various problems with this as the `release` file operation handler `comedi_close()` also decrements `dev->use_count` and decrements the module usage counts. This means that `dev->use_count` and the module counts can end up negative. Also, the assumed one-to-one relationship between the file open count and the low-level module usage count is invalid and can get screwed up. We only want to stop the low-level module being unloaded while a comedi device using the module has an open file object. Also, there is no need to manipulate the module count of the core "comedi" module at all since the comedi module is the owner of the file operations structure and the system will not unload the module while there are open file objects using it. Correct the bugs and simplify as follows: 1. Get rid of the module count manipulations of the core "comedi" module (`THIS_MODULE`) altogether. 2. Don't alter `dev->use_count` in `comedi_device_cleanup()` as it should only be altered by the `open` and `release` file operation handlers `comedi_open()` and `comedi_close()`. 3. Increment the low-level module count for the following reasons: a) In `comedi_open()` if the open count was zero and the comedi device is attached to the low-level driver. b) When the `COMEDI_DEVCONFIG` ioctl is used to manually attach an unattached comedi device to a low-level driver. The open count will be greater than zero at this time. The actual increment of the low-level module count is already done by `comedi_device_attach()`. 4. Decrement the low-level module count for the following reasons: a) In `comedi_close()` if the open count was 1 and the comedi device is attached to the low-level driver. b) In `comedi_device_cleanup()` (called via `comedi_auto_unconfig()` --> `comedi_release_hardware_device()` --> `comedi_free_board_dev()` when the comedi device is automatically unconfigured due to action by the low-level driver) if the device was attached (which it should be) and open count was non-zero (greater than zero). c) When the `COMEDI_DEVCONFIG` ioctl is used to manually detach the comedi device from the low-level driver. The open count will be greater than zero at this time. The open count should never go negative. Parts 3 and 4 ensure that the low-level module usage count is incremented on entering the state where the comedi device is attached to the low-level driver AND the open count is greater than zero, and is decremented on leaving that state. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-12-11 14:51:03 +00:00
staging: comedi: prepare support for per-file read and write subdevices Comedi devices may have several subdevices that support "read" and/or "write" asynchronous commands that use the "read" or "write" file operations for data transfer. The low-level Comedi drivers may nominate a default "read" subdevice and/or a default "write" subdevice, but it may have other subdevices that support asynchronous commands. The Comedi core provides a somewhat clunky mechanism to provide access to the asynchronous command support of the non-default subdevices. When a low-level device is "attached" to a core Comedi device, it dynamically allocates a minor device number for each of the subdevices that support asynchrounous commands and associates them with files created in SysFS named "comediX_subdY", where "X" is the minor device number of the main comedi device, and "Y" is the subdevice number. An application can open these subdevice-specific files and they behave like the regular "comediX" files except that the "read" and/or "write" subdevice may be different to the default chosen by the low-level driver. This patch adds a layer of indirection between the file object and the comedi device object to allow the current "read" and/or "write" subdevice to be altered after opening the Comedi device, on a per-file object basis. The advantage is that an application only needs to open the main Comedi device file and can then choose which subdevice it wants to "read" or "write". The main Comedi device file can be opened more than once, and each file object can choose the "read" and "write" subdevices independently. The new `struct comedi_file` is created on "open" and freed on "release". It includes pointers to the main Comedi device structure, and to the current "read" and "write" subdevice structures (which may be NULL). It also has information to keep track of when a low-level device has been attached or detached since the previous time the file object was used. In that case, the current "read" and "write" subdevices in the `struct comedi_file` will be changed to the new defaults (or set to NULL). (The change to new defaults is done by `comedi_file_reset()`. The checking for attach/detach is done by `comedi_file_check()` which will call `comedi_file_reset()` if there have been any attach/detach operations since the previous call.) A subsequent patch will add the ioctls to change the current "read" and "write" subdevices. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-11-04 18:09:00 +00:00
llseek: automatically add .llseek fop All file_operations should get a .llseek operation so we can make nonseekable_open the default for future file operations without a .llseek pointer. The three cases that we can automatically detect are no_llseek, seq_lseek and default_llseek. For cases where we can we can automatically prove that the file offset is always ignored, we use noop_llseek, which maintains the current behavior of not returning an error from a seek. New drivers should normally not use noop_llseek but instead use no_llseek and call nonseekable_open at open time. Existing drivers can be converted to do the same when the maintainer knows for certain that no user code relies on calling seek on the device file. The generated code is often incorrectly indented and right now contains comments that clarify for each added line why a specific variant was chosen. In the version that gets submitted upstream, the comments will be gone and I will manually fix the indentation, because there does not seem to be a way to do that using coccinelle. Some amount of new code is currently sitting in linux-next that should get the same modifications, which I will do at the end of the merge window. Many thanks to Julia Lawall for helping me learn to write a semantic patch that does all this. ===== begin semantic patch ===== // This adds an llseek= method to all file operations, // as a preparation for making no_llseek the default. // // The rules are // - use no_llseek explicitly if we do nonseekable_open // - use seq_lseek for sequential files // - use default_llseek if we know we access f_pos // - use noop_llseek if we know we don't access f_pos, // but we still want to allow users to call lseek // @ open1 exists @ identifier nested_open; @@ nested_open(...) { <+... nonseekable_open(...) ...+> } @ open exists@ identifier open_f; identifier i, f; identifier open1.nested_open; @@ int open_f(struct inode *i, struct file *f) { <+... ( nonseekable_open(...) | nested_open(...) ) ...+> } @ read disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ read_no_fpos disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { ... when != off } @ write @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ write_no_fpos @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { ... when != off } @ fops0 @ identifier fops; @@ struct file_operations fops = { ... }; @ has_llseek depends on fops0 @ identifier fops0.fops; identifier llseek_f; @@ struct file_operations fops = { ... .llseek = llseek_f, ... }; @ has_read depends on fops0 @ identifier fops0.fops; identifier read_f; @@ struct file_operations fops = { ... .read = read_f, ... }; @ has_write depends on fops0 @ identifier fops0.fops; identifier write_f; @@ struct file_operations fops = { ... .write = write_f, ... }; @ has_open depends on fops0 @ identifier fops0.fops; identifier open_f; @@ struct file_operations fops = { ... .open = open_f, ... }; // use no_llseek if we call nonseekable_open //////////////////////////////////////////// @ nonseekable1 depends on !has_llseek && has_open @ identifier fops0.fops; identifier nso ~= "nonseekable_open"; @@ struct file_operations fops = { ... .open = nso, ... +.llseek = no_llseek, /* nonseekable */ }; @ nonseekable2 depends on !has_llseek @ identifier fops0.fops; identifier open.open_f; @@ struct file_operations fops = { ... .open = open_f, ... +.llseek = no_llseek, /* open uses nonseekable */ }; // use seq_lseek for sequential files ///////////////////////////////////// @ seq depends on !has_llseek @ identifier fops0.fops; identifier sr ~= "seq_read"; @@ struct file_operations fops = { ... .read = sr, ... +.llseek = seq_lseek, /* we have seq_read */ }; // use default_llseek if there is a readdir /////////////////////////////////////////// @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier readdir_e; @@ // any other fop is used that changes pos struct file_operations fops = { ... .readdir = readdir_e, ... +.llseek = default_llseek, /* readdir is present */ }; // use default_llseek if at least one of read/write touches f_pos ///////////////////////////////////////////////////////////////// @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read.read_f; @@ // read fops use offset struct file_operations fops = { ... .read = read_f, ... +.llseek = default_llseek, /* read accesses f_pos */ }; @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, ... + .llseek = default_llseek, /* write accesses f_pos */ }; // Use noop_llseek if neither read nor write accesses f_pos /////////////////////////////////////////////////////////// @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; identifier write_no_fpos.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, .read = read_f, ... +.llseek = noop_llseek, /* read and write both use no f_pos */ }; @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write_no_fpos.write_f; @@ struct file_operations fops = { ... .write = write_f, ... +.llseek = noop_llseek, /* write uses no f_pos */ }; @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; @@ struct file_operations fops = { ... .read = read_f, ... +.llseek = noop_llseek, /* read uses no f_pos */ }; @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; @@ struct file_operations fops = { ... +.llseek = noop_llseek, /* no read or write fn */ }; ===== End semantic patch ===== Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Julia Lawall <julia@diku.dk> Cc: Christoph Hellwig <hch@infradead.org>
2010-08-15 18:52:59 +02:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_board_minor_table[] `comedi_alloc_board_minor()` allocates and initializes a `struct comedi_file_info` and a `struct comedi_device`, and assigns a board minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_board_minor_table[minor]` where `minor` is the board minor device number. There is no longer anything useful in the `struct comedi_file_info` apart from the pointer to the `struct comedi_device` that was allocated, so the `struct comedi_file_info` is superfluous. Change `comedi_board_minor_table[]` to hold pointers to the actual `struct comedi_device`'s. `comedi_alloc_board_minor()` no longer needs to allocate a `struct comedi_file_info`. Replace `comedi_free_board_file_info()` with `comedi_free_board_dev()` with its parameter pointing to the `struct comedi_device` to be freed (there is no longer a `struct comedi_file_info` to be freed). There are consequential changes to `comedi_dev_from_board_minor()`, `comedi_clear_board_minor()` (which now returns a `struct comedi_device *`), `comedi_free_board_minor()`, `comedi_release_hardware_device()` and `comedi_unlocked_ioctl()` (when dealing with detachment of a dynamically allocated comedi device by the `COMEDI_DEVCONFIG` ioctl). `comedi_dev_from_file_info()` is no longer used as a result of the above changes so remove it. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:16 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: separate board and subdevice minor tables The comedi core reserves minor device numbers from 0 to `COMEDI_NUM_BOARD_MINORS - 1` (0 to 0x30 - 1) for the main comedi "board" devices and reserves minor device numbers from `COMEDI_NUM_BOARD_MINORS` to `COMEDI_NUM_MINORS - 1` (0x30 to 0x100 - 1) for comedi subdevices (or at least those that claim to support asynchronous comedi commands). There is an array `comedi_file_info_table[COMEDI_NUM_MINORS]` used to hold pointers to information for each board minor device number and subdevice minor device number that has been allocated (with NULL pointers for those not allocated), along with a protective lock `comedi_file_info_table_lock`. Since the ranges of board minor device numbers and subdevice minor device numbers do not overlap, we can use separate tables and separate locks for the different types of minor device numbers. This will allow us to use different pointer types for the elements of each table in the future without just using a generic `void *`. (At the moment, the table elements point to a `struct comedi_file_info` allocated dynamically for each allocated board minor device or subdevice minor device, but I plan to get rid of that data structure.) Replace `comedi_file_info_table[COMEDI_NUM_MINORS]` with two new arrays of the same type, `comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS]` for board minors, and `comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS]` for subdevice minors (where `COMEDI_NUM_SUBDEVICE_MINORS` is `COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS`). `comedi_subdevice_minor_table[]` is indexed by the subdevice minor number minus `COMEDI_NUM_BOARD_MINORS` since `COMEDI_NUM_BOARD_MINORS` is the first valid subdevice minor number. Replace `comedi_file_info_table_lock` with `comedi_board_minor_table_lock` for board minors and `comedi_subdevice_minor_table_lock` for subdevice minors. Refactor `comedi_clear_minor()` to call one of two new functions `comedi_clear_board_minor()` and `comedi_clear_subdevice_minor()` depending on the minor device number passed as a parameter. Similarly, refactor `comedi_file_info_from_minor()` to call one of two new functions `comedi_file_info_from_board_minor()` and `comedi_file_info_from_subdevice_minor()` depending on the minor device number parameter. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:04 +01:00
staging: comedi: simplify comedi_subdevice_minor_table[] `comedi_alloc_subdevice_minor()` allocates and initializes a `struct comedi_file_info` and assigns a subdevice minor device number (if there are any available), storing a pointer to the allocated `struct comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the array index corresponding to the subdevice minor device number (indexed by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`). The information stored in the `struct comedi_file_info` can be derived from the subdevice structure (`struct comedi_subdevice`) itself, so the `struct comedi_file_info` is superfluous. Change `comedi_subdevice_minor_table[]` to hold pointers to the actual `struct comedi_subdevice`'s. `comedi_alloc_subdevice_minor()` no longer needs to allocate a `struct comedi_file_info` and `comedi_free_subdevice_info()` no longer has a `struct comedi_file_info` to free. Replace `comedi_file_info_from_minor()` with `comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to a `struct comedi_subdevice` from the table. This has knock-on effects for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and `comedi_write_subdevice()`. In particular, `comedi_read_subdevice()` and `comedi_write_subdevice()` now need to check the subdevice flags to see if the determine whether to override the comedi device's default read/write subdevice. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-04 14:59:15 +01:00
staging: comedi: cleanup all board minors on module exit The comedi core module optionally allocates some legacy board minor devices on module load and cleans these up on module exit. These are used for manual configuration of comedi boards (for those low-level comedi drivers that support manual configuration - mainly for ISA boards). Other board minor devices are created and destroyed dynamically in response to bus device probe and remove requests. The ioctl used for manual configuration (attachment) and removal (detachment) of devices is COMEDI_DEVCONFIG, but that works for any board minor device, including those that were originally created dynamically. If the COMEDI_DEVCONFIG ioctl is used to manually detach an automatically created and attached device, commit 7d3135af399e92cf4c9bbc5f86b6c140aab3b88c ("staging: comedi: prevent auto-unconfig of manually configured devices") ensures that the board minor will no longer be automatically detached and destroyed by a bus device remove request. From that point on the board minor behaves more like one of the comedi "legacy" board minors. (There would be some justification for destroying the board minor instead, but I'd rather leave that decision until removal of board minors has been made safer than it currently is.) Although the board minor behaves more like a legacy board minor, it is not currently cleaned up on module exit. In fact, the module exit code will bug out because this board minor has not been cleaned up. Change comedi_cleanup_legacy_minors() (called from the module exit code, and from the module init code on error) to clean up all board minors. Rename the function to comedi_cleanup_board_minors() to reflect the change in functionality. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-01-28 17:07:39 +00:00
staging: comedi: cleanup all board minors on module exit The comedi core module optionally allocates some legacy board minor devices on module load and cleans these up on module exit. These are used for manual configuration of comedi boards (for those low-level comedi drivers that support manual configuration - mainly for ISA boards). Other board minor devices are created and destroyed dynamically in response to bus device probe and remove requests. The ioctl used for manual configuration (attachment) and removal (detachment) of devices is COMEDI_DEVCONFIG, but that works for any board minor device, including those that were originally created dynamically. If the COMEDI_DEVCONFIG ioctl is used to manually detach an automatically created and attached device, commit 7d3135af399e92cf4c9bbc5f86b6c140aab3b88c ("staging: comedi: prevent auto-unconfig of manually configured devices") ensures that the board minor will no longer be automatically detached and destroyed by a bus device remove request. From that point on the board minor behaves more like one of the comedi "legacy" board minors. (There would be some justification for destroying the board minor instead, but I'd rather leave that decision until removal of board minors has been made safer than it currently is.) Although the board minor behaves more like a legacy board minor, it is not currently cleaned up on module exit. In fact, the module exit code will bug out because this board minor has not been cleaned up. Change comedi_cleanup_legacy_minors() (called from the module exit code, and from the module init code on error) to clean up all board minors. Rename the function to comedi_cleanup_board_minors() to reflect the change in functionality. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-01-28 17:07:39 +00:00