Popular Threads From Freebsd-current:
List Statistics
- Total Threads: 2677
- Total Posts: 6416
Phrases Used to Find This Thread
|
# 1

09-07-2012 02:22 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 2

09-07-2012 03:07 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 3

09-07-2012 04:26 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 4

09-07-2012 04:31 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 5

09-07-2012 04:46 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 6

09-07-2012 04:59 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 7

09-07-2012 05:37 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 8

09-07-2012 05:39 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 9

09-07-2012 06:17 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 10

09-07-2012 04:27 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 11

12-07-2012 04:47 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 12

12-07-2012 04:51 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 13

12-07-2012 06:20 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 14

12-07-2012 08:01 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 15

12-07-2012 01:01 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 16

12-07-2012 02:20 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 12, 2012, at 6:01 AM, John Baldwin wrote:
> New-bus is certainly not the only way to organize a device hierarchy and is
> not perfect, but in your case I suggest you tone down your language until you
> have enough information to develop an informed opinion.
It is also not the only way to represent relationships between objects, or to export services to the rest of the kernel. From earlier descriptions, it seems like some of these relationships aren't very newbus-y. From what I know about FDT, many of them are 'this device's interrupt pin is tied to GPIO 12 on controller 3' which isn't a parent/child relationship, but rather some kind of interrupt cookie you'll need to implement bus_setup_intr.
Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 17

13-07-2012 06:56 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 12, 2012, at 6:01 AM, John Baldwin wrote:
> New-bus is certainly not the only way to organize a device hierarchy and is
> not perfect, but in your case I suggest you tone down your language until you
> have enough information to develop an informed opinion.
It is also not the only way to represent relationships between objects, or to export services to the rest of the kernel. From earlier descriptions, it seems like some of these relationships aren't very newbus-y. From what I know about FDT, many of them are 'this device's interrupt pin is tied to GPIO 12 on controller 3' which isn't a parent/child relationship, but rather some kind of interrupt cookie you'll need to implement bus_setup_intr.
Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> [..]
> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
I will just pass function pointers for now, if things should be done
dirty, let's be explicit about it.
Now, the hinted device attachment did work quite smoothly, however, I
would have a few suggestion:
1) add a call to bus_enumerate_hinted_children() before the call
DEVICE_IDENTIFY() call in bus_generic_driver_added()
this is required to be able to support dynamic loading and attachment
of hinted children.
2) have a generic bus_hinted_child method which would just add a new
child to the bus.
3) have bus_enumerate_hinted_children() and bus_generic_attach()
always ran on device attachment.
There is current +100 explicit call to bus_generic_attach() in the
sys/dev/ tree. This should be done always and implicitly.
4) have bus_generic_detach() always ran prior to device detachment
If not already the case. There is still the same +100 direct call to
bus_generic_detach is the tree.
5) have the bus_generic_* method be the default of their respective method
6) have device_delete_child() called upon device detachment.
As a rule of thumb, when a kld is unloaded there should not be any
remains of anything built previously. Without device_delete_child() or
proper singleton implementation, multiple load/unload sequence of bus
will attempt to attach multiple version of a child, even if the single
child was added prior to the bus_generic_attach() call.
Also, as a rule of thumb, if the same logic is implemented in more
than a few buses, it should be made generic and implicit.
I am lazy, I hate doing the same things over and over, not to say it
raised the likelihood of bugs' introduction...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 18

17-07-2012 07:03 AM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 12, 2012, at 6:01 AM, John Baldwin wrote:
> New-bus is certainly not the only way to organize a device hierarchy and is
> not perfect, but in your case I suggest you tone down your language until you
> have enough information to develop an informed opinion.
It is also not the only way to represent relationships between objects, or to export services to the rest of the kernel. From earlier descriptions, it seems like some of these relationships aren't very newbus-y. From what I know about FDT, many of them are 'this device's interrupt pin is tied to GPIO 12 on controller 3' which isn't a parent/child relationship, but rather some kind of interrupt cookie you'll need to implement bus_setup_intr.
Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> [..]
> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
I will just pass function pointers for now, if things should be done
dirty, let's be explicit about it.
Now, the hinted device attachment did work quite smoothly, however, I
would have a few suggestion:
1) add a call to bus_enumerate_hinted_children() before the call
DEVICE_IDENTIFY() call in bus_generic_driver_added()
this is required to be able to support dynamic loading and attachment
of hinted children.
2) have a generic bus_hinted_child method which would just add a new
child to the bus.
3) have bus_enumerate_hinted_children() and bus_generic_attach()
always ran on device attachment.
There is current +100 explicit call to bus_generic_attach() in the
sys/dev/ tree. This should be done always and implicitly.
4) have bus_generic_detach() always ran prior to device detachment
If not already the case. There is still the same +100 direct call to
bus_generic_detach is the tree.
5) have the bus_generic_* method be the default of their respective method
6) have device_delete_child() called upon device detachment.
As a rule of thumb, when a kld is unloaded there should not be any
remains of anything built previously. Without device_delete_child() or
proper singleton implementation, multiple load/unload sequence of bus
will attempt to attach multiple version of a child, even if the single
child was added prior to the bus_generic_attach() call.
Also, as a rule of thumb, if the same logic is implemented in more
than a few buses, it should be made generic and implicit.
I am lazy, I hate doing the same things over and over, not to say it
raised the likelihood of bugs' introduction...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
>> [..]
>> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>>
> I will just pass function pointers for now, if things should be done
> dirty, let's be explicit about it.
>
> Now, the hinted device attachment did work quite smoothly, however, I
> would have a few suggestion:
> 1) add a call to bus_enumerate_hinted_children() before the call
> DEVICE_IDENTIFY() call in bus_generic_driver_added()
>
> this is required to be able to support dynamic loading and attachment
> of hinted children.
>
> 2) have a generic bus_hinted_child method which would just add a new
> child to the bus.
>
> 3) have bus_enumerate_hinted_children() and bus_generic_attach()
> always ran on device attachment.
>
> There is current +100 explicit call to bus_generic_attach() in the
> sys/dev/ tree. This should be done always and implicitly.
>
> 4) have bus_generic_detach() always ran prior to device detachment
>
> If not already the case. There is still the same +100 direct call to
> bus_generic_detach is the tree.
>
> 5) have the bus_generic_* method be the default of their respective method
>
> 6) have device_delete_child() called upon device detachment.
>
> As a rule of thumb, when a kld is unloaded there should not be any
> remains of anything built previously. Without device_delete_child() or
> proper singleton implementation, multiple load/unload sequence of bus
> will attempt to attach multiple version of a child, even if the single
> child was added prior to the bus_generic_attach() call.
>
> Also, as a rule of thumb, if the same logic is implemented in more
> than a few buses, it should be made generic and implicit.
>
> I am lazy, I hate doing the same things over and over, not to say it
> raised the likelihood of bugs' introduction...
>
could I at least get some feedback on the proposals above ?
Thanks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 19

30-07-2012 10:06 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 12, 2012, at 6:01 AM, John Baldwin wrote:
> New-bus is certainly not the only way to organize a device hierarchy and is
> not perfect, but in your case I suggest you tone down your language until you
> have enough information to develop an informed opinion.
It is also not the only way to represent relationships between objects, or to export services to the rest of the kernel. From earlier descriptions, it seems like some of these relationships aren't very newbus-y. From what I know about FDT, many of them are 'this device's interrupt pin is tied to GPIO 12 on controller 3' which isn't a parent/child relationship, but rather some kind of interrupt cookie you'll need to implement bus_setup_intr.
Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> [..]
> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
I will just pass function pointers for now, if things should be done
dirty, let's be explicit about it.
Now, the hinted device attachment did work quite smoothly, however, I
would have a few suggestion:
1) add a call to bus_enumerate_hinted_children() before the call
DEVICE_IDENTIFY() call in bus_generic_driver_added()
this is required to be able to support dynamic loading and attachment
of hinted children.
2) have a generic bus_hinted_child method which would just add a new
child to the bus.
3) have bus_enumerate_hinted_children() and bus_generic_attach()
always ran on device attachment.
There is current +100 explicit call to bus_generic_attach() in the
sys/dev/ tree. This should be done always and implicitly.
4) have bus_generic_detach() always ran prior to device detachment
If not already the case. There is still the same +100 direct call to
bus_generic_detach is the tree.
5) have the bus_generic_* method be the default of their respective method
6) have device_delete_child() called upon device detachment.
As a rule of thumb, when a kld is unloaded there should not be any
remains of anything built previously. Without device_delete_child() or
proper singleton implementation, multiple load/unload sequence of bus
will attempt to attach multiple version of a child, even if the single
child was added prior to the bus_generic_attach() call.
Also, as a rule of thumb, if the same logic is implemented in more
than a few buses, it should be made generic and implicit.
I am lazy, I hate doing the same things over and over, not to say it
raised the likelihood of bugs' introduction...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
>> [..]
>> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>>
> I will just pass function pointers for now, if things should be done
> dirty, let's be explicit about it.
>
> Now, the hinted device attachment did work quite smoothly, however, I
> would have a few suggestion:
> 1) add a call to bus_enumerate_hinted_children() before the call
> DEVICE_IDENTIFY() call in bus_generic_driver_added()
>
> this is required to be able to support dynamic loading and attachment
> of hinted children.
>
> 2) have a generic bus_hinted_child method which would just add a new
> child to the bus.
>
> 3) have bus_enumerate_hinted_children() and bus_generic_attach()
> always ran on device attachment.
>
> There is current +100 explicit call to bus_generic_attach() in the
> sys/dev/ tree. This should be done always and implicitly.
>
> 4) have bus_generic_detach() always ran prior to device detachment
>
> If not already the case. There is still the same +100 direct call to
> bus_generic_detach is the tree.
>
> 5) have the bus_generic_* method be the default of their respective method
>
> 6) have device_delete_child() called upon device detachment.
>
> As a rule of thumb, when a kld is unloaded there should not be any
> remains of anything built previously. Without device_delete_child() or
> proper singleton implementation, multiple load/unload sequence of bus
> will attempt to attach multiple version of a child, even if the single
> child was added prior to the bus_generic_attach() call.
>
> Also, as a rule of thumb, if the same logic is implemented in more
> than a few buses, it should be made generic and implicit.
>
> I am lazy, I hate doing the same things over and over, not to say it
> raised the likelihood of bugs' introduction...
>
could I at least get some feedback on the proposals above ?
Thanks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Tuesday, July 17, 2012 2:03:14 am Arnaud Lacombe wrote:
> Hi,
>
> On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> > Hi,
> >
> > On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> >> [..]
> >> Honestly, though, I think you'll be more **** when you find out that
the N:1 interface that you want is being done in the wrong domain. But I've
been wrong before and look forward to seeing your replacement.
> >>
> > I will just pass function pointers for now, if things should be done
> > dirty, let's be explicit about it.
> >
> > Now, the hinted device attachment did work quite smoothly, however, I
> > would have a few suggestion:
> > 1) add a call to bus_enumerate_hinted_children() before the call
> > DEVICE_IDENTIFY() call in bus_generic_driver_added()
> >
> > this is required to be able to support dynamic loading and attachment
> > of hinted children.
I'm not sure this is a feature we want to support (to date hinted children
have only been created at boot time).
> > 2) have a generic bus_hinted_child method which would just add a new
> > child to the bus.
Possibly, but hinted children are intentionally opt-in and not enabled
by default.
> > 3) have bus_enumerate_hinted_children() and bus_generic_attach()
> > always ran on device attachment.
> >
> > There is current +100 explicit call to bus_generic_attach() in the
> > sys/dev/ tree. This should be done always and implicitly.
No. One of the problems is that different busses want to do it at
different times. It is usually done last, but some buses may want to
do additional work after the bus_generic_attach().
> > 4) have bus_generic_detach() always ran prior to device detachment
Similar.
> > 5) have the bus_generic_* method be the default of their respective
method
No. However, what would be a good idea (and one thing I've had on my
list), is to create a "bus_generic" driver that uses the bus_generic_*
methods for all it's methods and let bus drivers inherit from that to
get the generic methods if they are appropriate. If you do this, I
would also add a second "bus_generic_rl" that inherits from "bus_generic"
but uses the generic resource list methods for resources.
> > 6) have device_delete_child() called upon device detachment.
No. This is for a bus to decide. This would be horrifically wrong
for things like kldunloading a PCI device driver. Just because you
unload a driver (so that it detaches from devices) does not mean those
physical devices have gone away.
> > As a rule of thumb, when a kld is unloaded there should not be any
> > remains of anything built previously. Without device_delete_child() or
> > proper singleton implementation, multiple load/unload sequence of bus
> > will attempt to attach multiple version of a child, even if the single
> > child was added prior to the bus_generic_attach() call.
Hinted devices should perhaps be removed, yes. However, what other drivers
often do is use a singleton approach instead (despite your claim that they
don't). For example:
static void
ipmi_isa_identify(driver_t *driver, device_t parent)
{
struct ipmi_get_info info;
uint32_t devid;
if (ipmi_smbios_identify(&info) && info.iface_type != SSIF_MODE &&
device_find_child(parent, "ipmi", -1) == NULL) {
...
BUS_ADD_CHILD(parent, 0, "ipmi", -1);
}
}
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
# 20

30-07-2012 11:40 PM
|
|
|
Hi folks,
Ok, yet another Newbus' limitation. Assuming a device exports more
than one interface, and one of its child has need to use more than one
interface, each interfaces cannot register, concurrently, its own
ivar. While I try to always have a single child per
interface/resource, I need to keep some compatibility with the old way
of doing thing (POLA wrt. drivers I cannot/will not convert and
userland). So, it would have been nice if ivar had been per-interface,
not global and unique to one device.
Unless I am mistaken, ivar are the only way for a parent can transmit
information to a child. I can not simply implement a new METHOD to get
that ivar as the device implements multiple time the same function
(actually, up to 4 time for one, 3 for the other, with possible
crossovers...), each one physically distinct. Each child is being tied
to a pair. Thus, I need to pass each child discriminator(s) for each
interfaces right after having been *created*, which cannot be done
later on. Of course, it is out-of-question to have crossover in the
interfaces definitions.
The best way I could achieve this currently is to pass the child's
device to its parent, and do a lookup based on that pointer to get
information I need, but erk....
my 1c,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> Ok, yet another Newbus' limitation. Assuming a device exports more
> than one interface, and one of its child has need to use more than one
> interface, each interfaces cannot register, concurrently, its own
> ivar. While I try to always have a single child per
> interface/resource, I need to keep some compatibility with the old way
> of doing thing (POLA wrt. drivers I cannot/will not convert and
> userland). So, it would have been nice if ivar had been per-interface,
> not global and unique to one device.
There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
So I'm not sure I understand what you are saying here.
The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
enum ivar_namespace {
IVAR_PCI = 1,
IVAR_PCCARD,
IVAR_USB,
etc
};
#define IVAR_SHIFT 16
and the above could be changed to:
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
....
};
and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
> Unless I am mistaken, ivar are the only way for a parent can transmit
> information to a child. I can not simply implement a new METHOD to get
> that ivar as the device implements multiple time the same function
> (actually, up to 4 time for one, 3 for the other, with possible
> crossovers...), each one physically distinct. Each child is being tied
> to a pair. Thus, I need to pass each child discriminator(s) for each
> interfaces right after having been *created*, which cannot be done
> later on. Of course, it is out-of-question to have crossover in the
> interfaces definitions.
ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
> The best way I could achieve this currently is to pass the child's
> device to its parent, and do a lookup based on that pointer to get
> information I need, but erk....
That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
use both interfaces. There is no generic way for dev0 to export
independent ivars for both interface. For now, I restricted the
function of the second interface not to need ivar, but that's kind of
hackish.
- Arnaud
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
>> Unless I am mistaken, ivar are the only way for a parent can transmit
>> information to a child. I can not simply implement a new METHOD to get
>> that ivar as the device implements multiple time the same function
>> (actually, up to 4 time for one, 3 for the other, with possible
>> crossovers...), each one physically distinct. Each child is being tied
>> to a pair. Thus, I need to pass each child discriminator(s) for each
>> interfaces right after having been *created*, which cannot be done
>> later on. Of course, it is out-of-question to have crossover in the
>> interfaces definitions.
>
> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>
>> The best way I could achieve this currently is to pass the child's
>> device to its parent, and do a lookup based on that pointer to get
>> information I need, but erk....
>
> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>
> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
> use both interfaces. There is no generic way for dev0 to export
> independent ivars for both interface. For now, I restricted the
> function of the second interface not to need ivar, but that's kind of
> hackish.
Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
Warner
> - Arnaud
>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>> information to a child. I can not simply implement a new METHOD to get
>>> that ivar as the device implements multiple time the same function
>>> (actually, up to 4 time for one, 3 for the other, with possible
>>> crossovers...), each one physically distinct. Each child is being tied
>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>> interfaces right after having been *created*, which cannot be done
>>> later on. Of course, it is out-of-question to have crossover in the
>>> interfaces definitions.
>>
>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>
>>> The best way I could achieve this currently is to pass the child's
>>> device to its parent, and do a lookup based on that pointer to get
>>> information I need, but erk....
>>
>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>
>> Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>
>> Hi,
>>
>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>> than one interface, and one of its child has need to use more than one
>>>> interface, each interfaces cannot register, concurrently, its own
>>>> ivar. While I try to always have a single child per
>>>> interface/resource, I need to keep some compatibility with the old way
>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>> not global and unique to one device.
>>>
>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>
>>> So I'm not sure I understand what you are saying here.
>>>
>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>> use both interfaces. There is no generic way for dev0 to export
>> independent ivars for both interface. For now, I restricted the
>> function of the second interface not to need ivar, but that's kind of
>> hackish.
>
> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>
I think we should not be talking about the same API here. I have no
idea what you mean by "the key to value translation", nor "Ivar
numbers". What I refer to is that device_set_ivars() /
device_get_ivars() acts on a single instance variables from `struct
device': `ivars'. In that case, I do not really see how to set that
specific field to two distinct values for each interfaces.
- Arnaud
> Warner
>
>> - Arnaud
>>
>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>
>>> enum ivar_namespace {
>>> IVAR_PCI = 1,
>>> IVAR_PCCARD,
>>> IVAR_USB,
>>> etc
>>> };
>>> #define IVAR_SHIFT 16
>>>
>>> and the above could be changed to:
>>>
>>> enum pci_device_ivars {
>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>> PCI_IVAR_SUBDEVICE,
>>> PCI_IVAR_VENDOR,
>>> ....
>>> };
>>>
>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>
>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>
>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>> information to a child. I can not simply implement a new METHOD to get
>>>> that ivar as the device implements multiple time the same function
>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>> crossovers...), each one physically distinct. Each child is being tied
>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>> interfaces right after having been *created*, which cannot be done
>>>> later on. Of course, it is out-of-question to have crossover in the
>>>> interfaces definitions.
>>>
>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>
>>>> The best way I could achieve this currently is to pass the child's
>>>> device to its parent, and do a lookup based on that pointer to get
>>>> information I need, but erk....
>>>
>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>
>>> Warner
>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>> Ok, yet another Newbus' limitation. Assuming a device exports more
>> than one interface, and one of its child has need to use more than one
>> interface, each interfaces cannot register, concurrently, its own
>> ivar. While I try to always have a single child per
>> interface/resource, I need to keep some compatibility with the old way
>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>> userland). So, it would have been nice if ivar had been per-interface,
>> not global and unique to one device.
>
> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>
> So I'm not sure I understand what you are saying here.
>
> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>
> enum ivar_namespace {
> IVAR_PCI = 1,
> IVAR_PCCARD,
> IVAR_USB,
> etc
> };
> #define IVAR_SHIFT 16
>
> and the above could be changed to:
>
> enum pci_device_ivars {
> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> PCI_IVAR_SUBDEVICE,
> PCI_IVAR_VENDOR,
> ....
> };
>
> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>
> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>
ok, I think I got it now. You and I are exactly saying the same thing,
just in different terms; there is no way to currently specify multiple
independent (/overlapping) ivars in a child...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>
>>> Hi,
>>>
>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>> than one interface, and one of its child has need to use more than one
>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>> ivar. While I try to always have a single child per
>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>> not global and unique to one device.
>>>>
>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>
>>>> So I'm not sure I understand what you are saying here.
>>>>
>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>> use both interfaces. There is no generic way for dev0 to export
>>> independent ivars for both interface. For now, I restricted the
>>> function of the second interface not to need ivar, but that's kind of
>>> hackish.
>>
>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>
> I think we should not be talking about the same API here. I have no
> idea what you mean by "the key to value translation", nor "Ivar
> numbers". What I refer to is that device_set_ivars() /
> device_get_ivars() acts on a single instance variables from `struct
> device': `ivars'. In that case, I do not really see how to set that
> specific field to two distinct values for each interfaces.
We are talking about the ivar interface. You are just misunderstanding how it is used.
Let us say that dev0 wants to implement interface A and B. The interface it implements is the device_read _ivar method. That method looks like:
int pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_ivar *iv = device_get_ivar(child);
switch (which) {
case PCI_IVAR_SUBVENDOR:
*result = iv->subvendor;
break;
...
default:
return EINVAL;
}
return 0;
}
So, if you wanted to implement interface A and interface B, you would have to support reading and writing A_IVAR_* and B_IVAR_*. The above routine would look like:
struct mydev_ivar {
int a_1;
int a_2;
int b_1;
int b_2;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
*result = iv->a_1;
break;
case A_IVAR_2:
*result = iv->a_2;
break;
case B_IVAR_1:
*result = iv->b_1;
break;
case B_IVAR_2:
*result = iv->b_2;
break;
default:
return EINVAL;
}
return 0;
}
and similar for the write routine. Now, there are some busses that provide convenience structures and functions for dealing with the ivars. In that case, you'd be able to use the wrapper structures and routines like so:
struct mdev_ivar {
struct a_ivar a;
struct b_ivar b;
};
int mydev_read_ivar(device_t dev, device child, int which, uintpr_t *result)
{
struct mydev_ivar *iv = device_get_ivar(child);
switch (which) {
case A_IVAR_1:
case A_IVAR_2:
return a_helper_read_ivar(&iv->a, which, result);
case B_IVAR_1:
case B_IVAR_2:
return b_helper_read_ivar(&iv->b, which, result);
default:
return EINVAL;
}
return 0;
}
Both of these work only if the A_IVAR values are disjoint from the B_IVAR values. Your mydev device is the one that sets the ivar on dev1, in your example, so it would know how to malloc and create the mydev_ivar structure, even if the interfaces it is implementing provide helper functions, like I've outlined above.
Warner
> - Arnaud
>
>> Warner
>>
>>> - Arnaud
>>>
>>>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>>>
>>>> enum ivar_namespace {
>>>> IVAR_PCI = 1,
>>>> IVAR_PCCARD,
>>>> IVAR_USB,
>>>> etc
>>>> };
>>>> #define IVAR_SHIFT 16
>>>>
>>>> and the above could be changed to:
>>>>
>>>> enum pci_device_ivars {
>>>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>>>> PCI_IVAR_SUBDEVICE,
>>>> PCI_IVAR_VENDOR,
>>>> ....
>>>> };
>>>>
>>>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>>>
>>>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>>>
>>>>> Unless I am mistaken, ivar are the only way for a parent can transmit
>>>>> information to a child. I can not simply implement a new METHOD to get
>>>>> that ivar as the device implements multiple time the same function
>>>>> (actually, up to 4 time for one, 3 for the other, with possible
>>>>> crossovers...), each one physically distinct. Each child is being tied
>>>>> to a pair. Thus, I need to pass each child discriminator(s) for each
>>>>> interfaces right after having been *created*, which cannot be done
>>>>> later on. Of course, it is out-of-question to have crossover in the
>>>>> interfaces definitions.
>>>>
>>>> ivars are but one way to communicate this. However, they are the generic way to convert a key to a value and store a key on a value. I don't really understand what you are trying to say here, perhaps an example would help illustrate what you are trying to do, since I don't quite understand the problem here.
>>>>
>>>>> The best way I could achieve this currently is to pass the child's
>>>>> device to its parent, and do a lookup based on that pointer to get
>>>>> information I need, but erk....
>>>>
>>>> That doesn't make any sense. The child's parent already sets that child's ivar when the child is created. The child's parent already gets a pointer to the child when asked to do the key to value translation. Again, perhaps an example would help here.
>>>>
>>>> Warner
>>
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>> than one interface, and one of its child has need to use more than one
>>> interface, each interfaces cannot register, concurrently, its own
>>> ivar. While I try to always have a single child per
>>> interface/resource, I need to keep some compatibility with the old way
>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>> userland). So, it would have been nice if ivar had been per-interface,
>>> not global and unique to one device.
>>
>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>
>> So I'm not sure I understand what you are saying here.
>>
>> The problem, more basically, is that the ivar keys are not unique. Currently, there's no bits used in the key to define the values to be non-overlapping. For example:
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> We could easily reserve the upper 16-bits of this field to be that key. This value could then be used to differentiate them. But this wouldn't scale too well. Given that there's only about a dozen or two in the tree, that's right at the moment, it wouldn't be hard to do something like:
>>
>> enum ivar_namespace {
>> IVAR_PCI = 1,
>> IVAR_PCCARD,
>> IVAR_USB,
>> etc
>> };
>> #define IVAR_SHIFT 16
>>
>> and the above could be changed to:
>>
>> enum pci_device_ivars {
>> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
>> PCI_IVAR_SUBDEVICE,
>> PCI_IVAR_VENDOR,
>> ....
>> };
>>
>> and then we'd have an unambiguous key, and the bus could easily implement multiple interfaces.
>>
>> but then again, most of the existing interfaces in the kernel are mutually exclusive, so you could implement this just for your new interfaces.
>>
> ok, I think I got it now. You and I are exactly saying the same thing,
> just in different terms; there is no way to currently specify multiple
> independent (/overlapping) ivars in a child...
There's no way to support overlapping IVAR keys, yes. However, if you are designing the ivars for multiple inheritance, then you'll need to make them non-overlapping. Thankfully, this is trivial to do.
Warner
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>
> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>
>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>
>>>> Hi,
>>>>
>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>> than one interface, and one of its child has need to use more than one
>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>> ivar. While I try to always have a single child per
>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>> not global and unique to one device.
>>>>>
>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>
>>>>> So I'm not sure I understand what you are saying here.
>>>>>
>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>> use both interfaces. There is no generic way for dev0 to export
>>>> independent ivars for both interface. For now, I restricted the
>>>> function of the second interface not to need ivar, but that's kind of
>>>> hackish.
>>>
>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>
>> I think we should not be talking about the same API here. I have no
>> idea what you mean by "the key to value translation", nor "Ivar
>> numbers". What I refer to is that device_set_ivars() /
>> device_get_ivars() acts on a single instance variables from `struct
>> device': `ivars'. In that case, I do not really see how to set that
>> specific field to two distinct values for each interfaces.
>
> We are talking about the ivar interface. You are just misunderstanding how it is used.
>
yes I indeed did... silly, silly me :-)
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Monday, July 09, 2012 12:39:03 am Warner Losh wrote:
>
> On Jul 8, 2012, at 9:59 PM, Arnaud Lacombe wrote:
>
> > Hi,
> >
> > On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
> >>
> >> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
> >>> Ok, yet another Newbus' limitation. Assuming a device exports more
> >>> than one interface, and one of its child has need to use more than one
> >>> interface, each interfaces cannot register, concurrently, its own
> >>> ivar. While I try to always have a single child per
> >>> interface/resource, I need to keep some compatibility with the old way
> >>> of doing thing (POLA wrt. drivers I cannot/will not convert and
> >>> userland). So, it would have been nice if ivar had been per-interface,
> >>> not global and unique to one device.
> >>
> >> There's one pointer for the ivars. The bus code gets to determine what
the ivar looks like, because the interface is totally private to the bus. So
long as it returns the right thing for any key that's presented, it doesn't
matter quite how things are done.
> >>
> >> So I'm not sure I understand what you are saying here.
> >>
> >> The problem, more basically, is that the ivar keys are not unique.
Currently, there's no bits used in the key to define the values to be non-
overlapping. For example:
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> We could easily reserve the upper 16-bits of this field to be that key.
This value could then be used to differentiate them. But this wouldn't scale
too well. Given that there's only about a dozen or two in the tree, that's
right at the moment, it wouldn't be hard to do something like:
> >>
> >> enum ivar_namespace {
> >> IVAR_PCI = 1,
> >> IVAR_PCCARD,
> >> IVAR_USB,
> >> etc
> >> };
> >> #define IVAR_SHIFT 16
> >>
> >> and the above could be changed to:
> >>
> >> enum pci_device_ivars {
> >> PCI_IVAR_SUBVENDOR = IVAR_PCI << IVAR_SHIFT,
> >> PCI_IVAR_SUBDEVICE,
> >> PCI_IVAR_VENDOR,
> >> ....
> >> };
> >>
> >> and then we'd have an unambiguous key, and the bus could easily implement
multiple interfaces.
> >>
> >> but then again, most of the existing interfaces in the kernel are
mutually exclusive, so you could implement this just for your new interfaces.
> >>
> > ok, I think I got it now. You and I are exactly saying the same thing,
> > just in different terms; there is no way to currently specify multiple
> > independent (/overlapping) ivars in a child...
>
> There's no way to support overlapping IVAR keys, yes. However, if you are
designing the ivars for multiple inheritance, then you'll need to make them
non-overlapping. Thankfully, this is trivial to do.
Also, I think we should do this in general. We already have one example (e.g.
ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
provide both ACPI and PCI IVARs to child devices). I think we should assign
each bus it's own IVAR range. It would make it easier to determine if a
specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
should be changed to start at, say, 200 and 300.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>
>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>
>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>
>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>
>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>> ivar. While I try to always have a single child per
>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>> not global and unique to one device.
>>>>>>
>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>
>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>
>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>> independent ivars for both interface. For now, I restricted the
>>>>> function of the second interface not to need ivar, but that's kind of
>>>>> hackish.
>>>>
>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>
>>> I think we should not be talking about the same API here. I have no
>>> idea what you mean by "the key to value translation", nor "Ivar
>>> numbers". What I refer to is that device_set_ivars() /
>>> device_get_ivars() acts on a single instance variables from `struct
>>> device': `ivars'. In that case, I do not really see how to set that
>>> specific field to two distinct values for each interfaces.
>>
>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>
> yes I indeed did... silly, silly me :-)
>
Actually, no. I wasn't that silly, neither was I misunderstanding
anything beside how *you* wanted it to be used, which is, I sorry to
say, unacceptable. The last thing I want is to pollute an interface
with a single-purpose, hand-crafted, bus. I was to just throw away all
that ivar stuff and go into hinted child configuration for now,
waiting for FDT... but of course, I figured out after a few hours that
hinted child attachment requires `bus_hinted_child' to be set in the
parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
to explicitly pollute my code. All this stuff should be done
implicitly to support N:1 interfaces/client relationship. N
*independent* interfaces being provided by a single driver; of course,
I'm not even going back to require those interface being provided by
multiple drivers, it is already a dead end.
I am not even sure any driver in the tree provides more than one interface...
For whatever reason, I am more and more thinking that this all
new-bus[0] stuff is *way* overkill, static, bloated at will, and
missing critical features; a huge PITA to use, for the intended
purpose.
/me ****.
- Arnaud
[0]: damn, why is it even called "newbus", this stuff is 14 years old.
It really belongs to a museum, not production code...
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Mon, Jul 9, 2012 at 11:27 AM, John Baldwin <> wrote:
> Also, I think we should do this in general. We already have one example (e.g.
> ACPI IVARs start at 100 so that things like the ACPI PCI bus driver can
> provide both ACPI and PCI IVARs to child devices). I think we should assign
> each bus it's own IVAR range. It would make it easier to determine if a
> specific IVAR is event supported. Certainly I think ISA and PCI at a minimum
> should be changed to start at, say, 200 and 300.
>
What's the point doing that ? Let's just resign to the conclusion that
FreeBSD devices' subsystem provides no dynamic way for a client device
to deals with multiple bus driver. Instead all possible combination
have to be harcoded and hand-crafted, when at all possible, to look
like they're coming from a single bus...
But again, newbus is 14 years old...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 11, 2012, at 9:47 PM, Arnaud Lacombe wrote:
> Hi,
>
> On Mon, Jul 9, 2012 at 1:17 AM, Arnaud Lacombe <> wrote:
>> Hi,
>>
>> On Mon, Jul 9, 2012 at 12:37 AM, Warner Losh <> wrote:
>>>
>>> On Jul 8, 2012, at 9:46 PM, Arnaud Lacombe wrote:
>>>
>>>> On Sun, Jul 8, 2012 at 11:31 PM, Warner Losh <> wrote:
>>>>>
>>>>> On Jul 8, 2012, at 9:26 PM, Arnaud Lacombe wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sun, Jul 8, 2012 at 10:07 PM, Warner Losh <> wrote:
>>>>>>>
>>>>>>> On Jul 8, 2012, at 7:22 PM, Arnaud Lacombe wrote:
>>>>>>>> Ok, yet another Newbus' limitation. Assuming a device exports more
>>>>>>>> than one interface, and one of its child has need to use more than one
>>>>>>>> interface, each interfaces cannot register, concurrently, its own
>>>>>>>> ivar. While I try to always have a single child per
>>>>>>>> interface/resource, I need to keep some compatibility with the old way
>>>>>>>> of doing thing (POLA wrt. drivers I cannot/will not convert and
>>>>>>>> userland). So, it would have been nice if ivar had been per-interface,
>>>>>>>> not global and unique to one device.
>>>>>>>
>>>>>>> There's one pointer for the ivars. The bus code gets to determine what the ivar looks like, because the interface is totally private to the bus. So long as it returns the right thing for any key that's presented, it doesn't matter quite how things are done.
>>>>>>>
>>>>>>> So I'm not sure I understand what you are saying here.
>>>>>>>
>>>>>> dev0 implements two interfaces: A and B. dev1, child of dev0, needs to
>>>>>> use both interfaces. There is no generic way for dev0 to export
>>>>>> independent ivars for both interface. For now, I restricted the
>>>>>> function of the second interface not to need ivar, but that's kind of
>>>>>> hackish.
>>>>>
>>>>> Only if the IVARs for interface A and interface B have overlapping values. If the Ivar keys don't overlap, then there's no problems at all. Certainly less hackish than not using them at all. Since dev0 knows the layout of the ivar that it set on its child, this presents no problems at all. It would return the values from A from the right part of the ivar, and those from B in the right part. Apart from the coordination of Ivar numbers, as I outlined in my last post, there's no issue here.
>>>>>
>>>> I think we should not be talking about the same API here. I have no
>>>> idea what you mean by "the key to value translation", nor "Ivar
>>>> numbers". What I refer to is that device_set_ivars() /
>>>> device_get_ivars() acts on a single instance variables from `struct
>>>> device': `ivars'. In that case, I do not really see how to set that
>>>> specific field to two distinct values for each interfaces.
>>>
>>> We are talking about the ivar interface. You are just misunderstanding how it is used.
>>>
>> yes I indeed did... silly, silly me :-)
>>
> Actually, no. I wasn't that silly, neither was I misunderstanding
> anything beside how *you* wanted it to be used, which is, I sorry to
> say, unacceptable. The last thing I want is to pollute an interface
> with a single-purpose, hand-crafted, bus. I was to just throw away all
> that ivar stuff and go into hinted child configuration for now,
> waiting for FDT... but of course, I figured out after a few hours that
> hinted child attachment requires `bus_hinted_child' to be set in the
> parent, as does bus_enumerate_hinted_children() / bus_generic_attach()
> to explicitly pollute my code. All this stuff should be done
> implicitly to support N:1 interfaces/client relationship. N
> *independent* interfaces being provided by a single driver; of course,
> I'm not even going back to require those interface being provided by
> multiple drivers, it is already a dead end.
>
> I am not even sure any driver in the tree provides more than one interface...
>
> For whatever reason, I am more and more thinking that this all
> new-bus[0] stuff is *way* overkill, static, bloated at will, and
> missing critical features; a huge PITA to use, for the intended
> purpose.
>
> /me ****.
>
> - Arnaud
>
> [0]: damn, why is it even called "newbus", this stuff is 14 years old.
> It really belongs to a museum, not production code...
I'm sorry you feel that way.
Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
Warner_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> I'm sorry you feel that way.
>
> Honestly, though, I think you'll be more ****ed when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
> acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI interfaces.
>
Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
see a single pcib(4) interface being exported. Moreover, I do not seem
to be able to find any clue that would led any ACPI devices to attach
on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
up in acpi_pcib_read_ivar() ?
Thks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Thursday, July 12, 2012 3:01:36 am Arnaud Lacombe wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > I'm sorry you feel that way.
> >
> > Honestly, though, I think you'll be more **** when you find out that the
N:1 interface that you want is being done in the wrong domain. But I've been
wrong before and look forward to seeing your replacement.
> >
> > acpi_pcib_acpi.c, btw, implements both PCIB interfaces and ACPI
interfaces.
> >
> Does it ? From the definition of `acpi_pcib_acpi_methods', I can only
> see a single pcib(4) interface being exported. Moreover, I do not seem
> to be able to find any clue that would led any ACPI devices to attach
> on acpi_pcib_acpi(4), neither to find how could acpi_get_flags() ends
> up in acpi_pcib_read_ivar() ?
acpi_get_handle() is certainly supported.
Relevant code snippets:
sys/dev/acpica/acpivar.h:
/*
* Note that the low ivar values are reserved to provide
* interface compatibility with ISA drivers which can also
* attach to ACPI.
*/
#define ACPI_IVAR_HANDLE 0x100
#define ACPI_IVAR_UNUSED 0x101 /* Unused/reserved. */
#define ACPI_IVAR_PRIVATE 0x102
#define ACPI_IVAR_FLAGS 0x103
/*
* Accessor functions for our ivars. Default value for BUS_READ_IVAR is
* (type) 0. The accessor functions don't check return values.
*/
#define __ACPI_BUS_ACCESSOR(varp, var, ivarp, ivar, type) \
\
static __inline type varp ## _get_ ## var(device_t dev) \
{ \
uintptr_t v = 0; \
BUS_READ_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, &v); \
return ((type) v); \
} \
\
static __inline void varp ## _set_ ## var(device_t dev, type t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, \
ivarp ## _IVAR_ ## ivar, v); \
}
__ACPI_BUS_ACCESSOR(acpi, handle, ACPI, HANDLE, ACPI_HANDLE)
__ACPI_BUS_ACCESSOR(acpi, private, ACPI, PRIVATE, void *)
__ACPI_BUS_ACCESSOR(acpi, flags, ACPI, FLAGS, int)
sys/dev/acpica/acpi_pcib_acpi.c:
/*
* Support for standard PCI bridge ivars.
*/
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_hpcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_DOMAIN:
*result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
return (0);
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)sc->ap_flags;
return (0);
}
return (ENOENT);
}
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t
*result)
{
struct acpi_pcib_softc *sc = device_get_softc(dev);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)sc->ap_handle;
return (0);
}
return (pcib_read_ivar(dev, child, which, result));
}
This is used by the ACPI PCI bus driver to detect buses that are enumerated
via ACPI and to then provide the ACPI_IVAR_HANDLE for all such PCI devices.
Note that ACPI PCI uses its own ivars structure (acpi_pci_devinfo) that
extends the base PCI ivars to add ACPI handle and flags.
sys/dev/acpi/acpi_pci.c:
struct acpi_pci_devinfo {
struct pci_devinfo ap_dinfo;
ACPI_HANDLE ap_handle;
int ap_flags;
};
...
static int
acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct acpi_pci_devinfo *dinfo;
dinfo = device_get_ivars(child);
switch (which) {
case ACPI_IVAR_HANDLE:
*result = (uintptr_t)dinfo->ap_handle;
return (0);
case ACPI_IVAR_FLAGS:
*result = (uintptr_t)dinfo->ap_flags;
return (0);
}
return (pci_read_ivar(dev, child, which, result));
}
...
static int
acpi_pci_attach(device_t dev)
{
...
/*
* First, PCI devices are added as in the normal PCI bus driver.
* Afterwards, the ACPI namespace under the bridge driver is
* walked to save ACPI handles to all the devices that appear in
* the ACPI namespace as immediate descendants of the bridge.
*
* ****: Sometimes PCI devices show up in the ACPI namespace that
* pci_add_children() doesn't find. We currently just ignore
* these devices.
*/
pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, NULL, dev, NULL);
...
}
The main use of this feature is to get PCI interrupt routing to work correctly
for ACPI bridges (i.e. using ACPI's _PRT method to route interrupts for all
ACPI-enumerated bridges). The first way this is accomplished is by having
each ACPI PCI bridge driver export it's own handle as the handle for it's
child. This allows the ACPI PCI bus driver to detect a bus that is enumerated
via ACPI and export ACPI handle ivars for each PCI device:
sys/dev/acpica/acpi_pci.c:
static int
acpi_pci_probe(device_t dev)
{
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
device_set_desc(dev, "ACPI PCI bus");
return (0);
}
(Note: it is calling acpi_get_handle() on a pcib device!)
Secondly, to handle PCI-PCI bridges the ACPI PCI-PCI bridge driver checks for
a valid ACPI handle on each PCI-PCI bridge device and returns a higher
priority to claim that bridge (rather than the generic PCI-PCI bridge driver).
Note again that it is calling acpi_get_handle() on a PCI device:
sys/dev/acpica/acpi_pcib_pci.c:
static int
acpi_pcib_pci_probe(device_t dev)
{
if (pci_get_class(dev) != PCIC_BRIDGE ||
pci_get_subclass(dev) != PCIS_BRIDGE_PCI ||
acpi_disabled("pci"))
return (ENXIO);
if (acpi_get_handle(dev) == NULL)
return (ENXIO);
if (pci_cfgregopen() == 0)
return (ENXIO);
device_set_desc(dev, "ACPI PCI-PCI bridge");
return (-1000);
}
New-bus is certainly not the only way to organize a device hierarchy and is
not perfect, but in your case I suggest you tone down your language until you
have enough information to develop an informed opinion.
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Jul 12, 2012, at 6:01 AM, John Baldwin wrote:
> New-bus is certainly not the only way to organize a device hierarchy and is
> not perfect, but in your case I suggest you tone down your language until you
> have enough information to develop an informed opinion.
It is also not the only way to represent relationships between objects, or to export services to the rest of the kernel. From earlier descriptions, it seems like some of these relationships aren't very newbus-y. From what I know about FDT, many of them are 'this device's interrupt pin is tied to GPIO 12 on controller 3' which isn't a parent/child relationship, but rather some kind of interrupt cookie you'll need to implement bus_setup_intr.
Warner
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> [..]
> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>
I will just pass function pointers for now, if things should be done
dirty, let's be explicit about it.
Now, the hinted device attachment did work quite smoothly, however, I
would have a few suggestion:
1) add a call to bus_enumerate_hinted_children() before the call
DEVICE_IDENTIFY() call in bus_generic_driver_added()
this is required to be able to support dynamic loading and attachment
of hinted children.
2) have a generic bus_hinted_child method which would just add a new
child to the bus.
3) have bus_enumerate_hinted_children() and bus_generic_attach()
always ran on device attachment.
There is current +100 explicit call to bus_generic_attach() in the
sys/dev/ tree. This should be done always and implicitly.
4) have bus_generic_detach() always ran prior to device detachment
If not already the case. There is still the same +100 direct call to
bus_generic_detach is the tree.
5) have the bus_generic_* method be the default of their respective method
6) have device_delete_child() called upon device detachment.
As a rule of thumb, when a kld is unloaded there should not be any
remains of anything built previously. Without device_delete_child() or
proper singleton implementation, multiple load/unload sequence of bus
will attempt to attach multiple version of a child, even if the single
child was added prior to the bus_generic_attach() call.
Also, as a rule of thumb, if the same logic is implemented in more
than a few buses, it should be made generic and implicit.
I am lazy, I hate doing the same things over and over, not to say it
raised the likelihood of bugs' introduction...
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
Hi,
On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> Hi,
>
> On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
>> [..]
>> Honestly, though, I think you'll be more **** when you find out that the N:1 interface that you want is being done in the wrong domain. But I've been wrong before and look forward to seeing your replacement.
>>
> I will just pass function pointers for now, if things should be done
> dirty, let's be explicit about it.
>
> Now, the hinted device attachment did work quite smoothly, however, I
> would have a few suggestion:
> 1) add a call to bus_enumerate_hinted_children() before the call
> DEVICE_IDENTIFY() call in bus_generic_driver_added()
>
> this is required to be able to support dynamic loading and attachment
> of hinted children.
>
> 2) have a generic bus_hinted_child method which would just add a new
> child to the bus.
>
> 3) have bus_enumerate_hinted_children() and bus_generic_attach()
> always ran on device attachment.
>
> There is current +100 explicit call to bus_generic_attach() in the
> sys/dev/ tree. This should be done always and implicitly.
>
> 4) have bus_generic_detach() always ran prior to device detachment
>
> If not already the case. There is still the same +100 direct call to
> bus_generic_detach is the tree.
>
> 5) have the bus_generic_* method be the default of their respective method
>
> 6) have device_delete_child() called upon device detachment.
>
> As a rule of thumb, when a kld is unloaded there should not be any
> remains of anything built previously. Without device_delete_child() or
> proper singleton implementation, multiple load/unload sequence of bus
> will attempt to attach multiple version of a child, even if the single
> child was added prior to the bus_generic_attach() call.
>
> Also, as a rule of thumb, if the same logic is implemented in more
> than a few buses, it should be made generic and implicit.
>
> I am lazy, I hate doing the same things over and over, not to say it
> raised the likelihood of bugs' introduction...
>
could I at least get some feedback on the proposals above ?
Thanks,
- Arnaud
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Tuesday, July 17, 2012 2:03:14 am Arnaud Lacombe wrote:
> Hi,
>
> On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> > Hi,
> >
> > On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> >> [..]
> >> Honestly, though, I think you'll be more **** when you find out that
the N:1 interface that you want is being done in the wrong domain. But I've
been wrong before and look forward to seeing your replacement.
> >>
> > I will just pass function pointers for now, if things should be done
> > dirty, let's be explicit about it.
> >
> > Now, the hinted device attachment did work quite smoothly, however, I
> > would have a few suggestion:
> > 1) add a call to bus_enumerate_hinted_children() before the call
> > DEVICE_IDENTIFY() call in bus_generic_driver_added()
> >
> > this is required to be able to support dynamic loading and attachment
> > of hinted children.
I'm not sure this is a feature we want to support (to date hinted children
have only been created at boot time).
> > 2) have a generic bus_hinted_child method which would just add a new
> > child to the bus.
Possibly, but hinted children are intentionally opt-in and not enabled
by default.
> > 3) have bus_enumerate_hinted_children() and bus_generic_attach()
> > always ran on device attachment.
> >
> > There is current +100 explicit call to bus_generic_attach() in the
> > sys/dev/ tree. This should be done always and implicitly.
No. One of the problems is that different busses want to do it at
different times. It is usually done last, but some buses may want to
do additional work after the bus_generic_attach().
> > 4) have bus_generic_detach() always ran prior to device detachment
Similar.
> > 5) have the bus_generic_* method be the default of their respective
method
No. However, what would be a good idea (and one thing I've had on my
list), is to create a "bus_generic" driver that uses the bus_generic_*
methods for all it's methods and let bus drivers inherit from that to
get the generic methods if they are appropriate. If you do this, I
would also add a second "bus_generic_rl" that inherits from "bus_generic"
but uses the generic resource list methods for resources.
> > 6) have device_delete_child() called upon device detachment.
No. This is for a bus to decide. This would be horrifically wrong
for things like kldunloading a PCI device driver. Just because you
unload a driver (so that it detaches from devices) does not mean those
physical devices have gone away.
> > As a rule of thumb, when a kld is unloaded there should not be any
> > remains of anything built previously. Without device_delete_child() or
> > proper singleton implementation, multiple load/unload sequence of bus
> > will attempt to attach multiple version of a child, even if the single
> > child was added prior to the bus_generic_attach() call.
Hinted devices should perhaps be removed, yes. However, what other drivers
often do is use a singleton approach instead (despite your claim that they
don't). For example:
static void
ipmi_isa_identify(driver_t *driver, device_t parent)
{
struct ipmi_get_info info;
uint32_t devid;
if (ipmi_smbios_identify(&info) && info.iface_type != SSIF_MODE &&
device_find_child(parent, "ipmi", -1) == NULL) {
...
BUS_ADD_CHILD(parent, 0, "ipmi", -1);
}
}
--
John Baldwin
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
On Mon, 2012-07-30 at 17:06 -0400, John Baldwin wrote:
> On Tuesday, July 17, 2012 2:03:14 am Arnaud Lacombe wrote:
> > Hi,
> >
> > On Fri, Jul 13, 2012 at 1:56 PM, Arnaud Lacombe <> wrote:
> > > Hi,
> > >
> > > On Thu, Jul 12, 2012 at 1:20 AM, Warner Losh <> wrote:
> > >> [..]
> > >> Honestly, though, I think you'll be more **** when you find out that
> the N:1 interface that you want is being done in the wrong domain. But I've
> been wrong before and look forward to seeing your replacement.
> > >>
> > > I will just pass function pointers for now, if things should be done
> > > dirty, let's be explicit about it.
> > >
> > > Now, the hinted device attachment did work quite smoothly, however, I
> > > would have a few suggestion:
> > > 1) add a call to bus_enumerate_hinted_children() before the call
> > > DEVICE_IDENTIFY() call in bus_generic_driver_added()
> > >
> > > this is required to be able to support dynamic loading and attachment
> > > of hinted children.
>
> I'm not sure this is a feature we want to support (to date hinted children
> have only been created at boot time).
It seems to me that the bus should be in control of calling
bus_enumerate_hinted_children() at whatever time works best for it.
Also, shouldn't it only ever be called once?
The comment block for BUS_HINTED_CHILD in bus_if.h says "This method is
only called in response to the parent bus asking for hinted devices to
be enumerated." I think one of the implications of that is that any
given bus may not call bus_enumerate_hinted_children() because it may
not be able to do anything for hinted children. Adding a
"hint.somedev.0.at=somebus" and then forcing the bus to enumerate hinted
children amounts to forcing the bus to adopt a child it may not be able
to provide resources for, which sounds like a panic or crash waiting to
happen (or at best, no crash but nothing useful happens either).
-- Ian
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-"
)
|
NewsArc Lists
| Culture Pages
| Computing Archive
| Media-Pages
Link to this page on your blog or website by copying the HTML code below and pasting it into your site:
|
|