Maintains the status of the elomax unit it represents. More...
Public Attributes | |
struct kref | instance_smartptr |
Keeps the reference count of this instance. | |
spinlock_t | instance_protect |
The lock on the instance to protect it against simultaneous multi-threaded access. | |
struct usb_interface * | interface |
The usb-interface under which this unit is known to the usb-core. | |
struct elomax_monitor_data | recently |
Holds the most recent read and written data from and to the unit. | |
struct urb * | read_urb |
The urb used to receive information from the unit. | |
struct urb * | write_urb |
The urb used to send information to the unit. | |
struct semaphore | write_semaphore |
Holds of (puts to sleep) simultaneous writers, so that only one write at a time is active. | |
unsigned char | write_setup_packet [8] |
The setup-packet used to write data to the unit. |
Maintains the status of the elomax unit it represents.
This struct holds:
spinlock_t instance_protect |
The lock on the instance to protect it against simultaneous multi-threaded access.
The instance is operated by multiple threads:
Each thread wanting access to the instance, locks (spin_lock()) the instance before accessing it and unlocks (spin_unlock()) it afterwards. The lock may temporarily delay the thread (because another thread holds the lock), however it will not put the waiting thread to sleep. The functions in this package assure that the lock is held as short as possible.
struct kref instance_smartptr |
Keeps the reference count of this instance.
The instance is constructed dynamically, upon connection of a unit by elomax_instance_construct(). A reference to it (pointer) is kept at multiple places:
This smartptr (reference count) keeps the number of pointers stored, and is incremented/decremented by every copy/release of the pointer. The last pointer release (when the reference counter reaches zero) triggers the free-ing of memory for this instance.
struct usb_interface* interface |
The usb-interface under which this unit is known to the usb-core.
The usb-core remembers every connected unit as an interface. This package attaches its 'personal' data for an elomax unit to this interface (upon connection of the unit to the usb-bus). This way, when the usb-core signals something for an interface, this package can refind its 'personal' data.
The other way around, is the instance attached to the file. So every file operation can refind the 'personal' data for the elomax unit. To be able to submit requests to the usb-core, this field allows to refind the usb-interface belonging to this instance.
struct urb* read_urb |
The urb used to receive information from the unit.
This urb is reserved upon construction of the instance. It then is submitted to the usb-core to receive data from the unit. When the usb-core receives data from the unit, it calls the completion-function elomax_instance_read_complete() which copies the data from this urb to the elomax_instance::recently field and resubmits this read_urb for receiving the next data of the unit.
struct elomax_monitor_data recently |
Holds the most recent read and written data from and to the unit.
The recent communication with the unit is stored in this field. It maintains the recently read bytes from the unit, the recently written bytes to the unit and the status of these read and write. This field is updated by the completion functions elomax_instance_read_copmlete() and elomax_instance_write_complete().
struct semaphore write_semaphore |
Holds of (puts to sleep) simultaneous writers, so that only one write at a time is active.
This semaphore is initialized to 1 and guards the write urb of this instance. The user's file operation elomax_instance_write() claims the semaphore. This semaphore is released when the write urb (submitted by the write who claimed the semaphore) finishes (by function elomax_instance_write_complete()).
Note that a user's write may be delayed (put to sleep) because another user thread holds the semaphore (as long as its write is not finished, that is, the data transferred to the unit [or timeout]).
unsigned char write_setup_packet[8] |
The setup-packet used to write data to the unit.
The elomax unit uses an usb control-write to transfer data from the host to the unit. Such a control-write consists of a setup-packet (host to device), a data-packet (host to device) and an acknowledgement (device to host).
Even though the setup-packet is a const (always contains the same data) it is kept per instance, since it must be allocated in contiguous kernel memory.
struct urb* write_urb |
The urb used to send information to the unit.
This urb is reserved upon construction of the instance. It is then filled with the data, when the user application writes to the device-file, so executing elomax_instance_write(). When the write completes, the function elomax_instance_write_complete() remembers the written data in the elomax_instance::recently field and marks the urb ready for reuse by freeing the semaphore elomax_instance::write_semaphore.