* Struct Inheritance in drivers/ata/
@ 2011-05-26 20:46 Peter Hamilton
2011-05-27 1:23 ` Greg KH
0 siblings, 1 reply; 4+ messages in thread
From: Peter Hamilton @ 2011-05-26 20:46 UTC (permalink / raw)
To: kernelnewbies
The code in drivers/ata/ uses an implementation of inheritance that I have
not seen before. It's only briefly explained in the header file (
include/linux/libata.h:885):
/*
* ->inherits must be the last field and all the preceding
* fields must be pointers.
*/
The structs are then initialized with .inherits assigned first:
drivers/ata/sata_nv.c:475
static struct ata_port_operations nv_nf2_ops = {
.inherits = &nv_generic_ops,
.freeze = nv_nf2_freeze,
.thaw = nv_nf2_thaw,
};
Is this actually implementing inheritance? Why do all preceding fields need
to be pointers?
As far as I can tell, this style is only found in the ata drivers.
Could anyone explain how this works?
Thanks,
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110526/3c1f4f32/attachment.html
^ permalink raw reply [flat|nested] 4+ messages in thread* Struct Inheritance in drivers/ata/ 2011-05-26 20:46 Struct Inheritance in drivers/ata/ Peter Hamilton @ 2011-05-27 1:23 ` Greg KH 2011-05-27 2:20 ` Peter Hamilton 0 siblings, 1 reply; 4+ messages in thread From: Greg KH @ 2011-05-27 1:23 UTC (permalink / raw) To: kernelnewbies On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote: > The code in drivers/ata/ uses an implementation of inheritance that I have not > seen before. ?It's only briefly explained in the header file ( include/linux/ > libata.h:885): > > /* ? > ?* ->inherits must be the last field and all the preceding > ?* fields must be pointers. > ?*/ > > The structs are then initialized with .inherits assigned first: > > drivers/ata/sata_nv.c:475 > > static struct ata_port_operations nv_nf2_ops = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > ? ? ? ? .inherits ? ? ? ? ? ? ? = &nv_generic_ops, > ? ? ? ? .freeze ? ? ? ? ? ? ? ? = nv_nf2_freeze, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > ? ? ? ? .thaw ? ? ? ? ? ? ? ? ? = nv_nf2_thaw, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > }; ? ? ? > > > Is this actually implementing inheritance? ?Why do all preceding fields need to > be pointers? > > As far as I can tell, this style is only found in the ata drivers. ? I think you are right, but more subsystems need to emulate it, it is very powerful and works very well. I have been wanting to convert the usb-serial layer to use the same thing one of these days. > Could anyone explain how this works? The code is all there that shows it, but basically the driver is telling the core to "use this type of functions, but if I set any others, use them instead." It's a nicer way of doing inheritance in C than we do in other places in the kernel where we are a bit more "verbose" in making it happen. hope this helps, greg k-h ^ permalink raw reply [flat|nested] 4+ messages in thread
* Struct Inheritance in drivers/ata/ 2011-05-27 1:23 ` Greg KH @ 2011-05-27 2:20 ` Peter Hamilton 2011-05-27 4:49 ` Ankit Jain 0 siblings, 1 reply; 4+ messages in thread From: Peter Hamilton @ 2011-05-27 2:20 UTC (permalink / raw) To: kernelnewbies I see that it works, but I'm not exactly following how. Maybe I just don't have enough C experience. But I can't seem to duplicate that functionality. I understand the way I've normally seen inheritance, where: struct Child { struct Parent p; int somethingOnlyForChildren; } Or something similar. Then the Child struct can be casted as a Parent, and since there is no padding before the first piece of data in a struct, every parent attribute is accessed as though the struct were a Parent. I see how it all lines up in memory, but in the case of the kernel code I can't quite follow it. Wouldn't everything assigned to 'inherits' be so much farther down in memory? I feel like I'm missing something. Is there a special way they all need to be accessed? - Peter On Thu, May 26, 2011 at 7:23 PM, Greg KH <greg@kroah.com> wrote: > On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote: > > The code in drivers/ata/ uses an implementation of inheritance that I > have not > > seen before. It's only briefly explained in the header file ( > include/linux/ > > libata.h:885): > > > > /* > > * ->inherits must be the last field and all the preceding > > * fields must be pointers. > > */ > > > > The structs are then initialized with .inherits assigned first: > > > > drivers/ata/sata_nv.c:475 > > > > static struct ata_port_operations nv_nf2_ops = { > > > .inherits = &nv_generic_ops, > > .freeze = nv_nf2_freeze, > > > .thaw = nv_nf2_thaw, > > > }; > > > > > > Is this actually implementing inheritance? Why do all preceding fields > need to > > be pointers? > > > > As far as I can tell, this style is only found in the ata drivers. > > I think you are right, but more subsystems need to emulate it, it is > very powerful and works very well. I have been wanting to convert the > usb-serial layer to use the same thing one of these days. > > > Could anyone explain how this works? > > The code is all there that shows it, but basically the driver is telling > the core to "use this type of functions, but if I set any others, use > them instead." It's a nicer way of doing inheritance in C than we do in > other places in the kernel where we are a bit more "verbose" in making > it happen. > > hope this helps, > > greg k-h > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20110526/a66e84ee/attachment-0001.html ^ permalink raw reply [flat|nested] 4+ messages in thread
* Struct Inheritance in drivers/ata/ 2011-05-27 2:20 ` Peter Hamilton @ 2011-05-27 4:49 ` Ankit Jain 0 siblings, 0 replies; 4+ messages in thread From: Ankit Jain @ 2011-05-27 4:49 UTC (permalink / raw) To: kernelnewbies On Fri, May 27, 2011 at 7:50 AM, Peter Hamilton <peterghamilton@gmail.com> wrote: > I see that it works, but I'm not exactly following how. ?Maybe I just don't > have enough C experience. ?But I can't seem to duplicate that functionality. > > I understand the way I've normally seen inheritance, where: > struct Child { > ? struct Parent p; > ? int somethingOnlyForChildren; > } > > Or something similar. ?Then the Child struct can be casted as a Parent, and > since there is no padding before the first piece of data in a struct, every > parent attribute is accessed as though the struct were a Parent. > I see how it all lines up in memory, but in the case of the kernel code I > can't quite follow it. ?Wouldn't everything assigned to 'inherits' be so > much farther down in memory? ?I feel like I'm missing something. ?Is there a > special way they all need to be accessed? I think an example should clear this. //class type struct klass { void (*foo)(); void (*bar)(int x); struct parent *inherits; }; //object 1, parent struct klass klass_a { //no .inherits .foo = a_foo, .bar = a_bar, }; //object 2, child, inherits klass_a struct klass klass_b { .inherits = &klass_a, .foo = b_foo, }; klass_b inherits klass_a. klass_b "overrides" only foo "member", so klass_b will have the new overriden foo (b_foo), and will "inherit" bar from its parent, a_bar. The relationship is setup as shown above, by using the .inherits field, and final pointers are setup by ata_finalize_port_ops in drivers/ata/libata-core.c . Once the pointers of the various objects have been set to their final values, while honoring the inheritance relationship, the 'inherits' field is no longer required, and the pointers can be used directly. This function is called whenever an ata host is started. See the comments on that function and read the code, should make things clearer. I also just read that code and then replying here, so I could have missed or misunderstood something. -Ankit > - Peter > On Thu, May 26, 2011 at 7:23 PM, Greg KH <greg@kroah.com> wrote: >> >> On Thu, May 26, 2011 at 02:46:08PM -0600, Peter Hamilton wrote: >> > The code in drivers/ata/ uses an implementation of inheritance that I >> > have not >> > seen before. ?It's only briefly explained in the header file ( >> > include/linux/ >> > libata.h:885): >> > >> > /* >> > ?* ->inherits must be the last field and all the preceding >> > ?* fields must be pointers. >> > ?*/ >> > >> > The structs are then initialized with .inherits assigned first: >> > >> > drivers/ata/sata_nv.c:475 >> > >> > static struct ata_port_operations nv_nf2_ops = { >> > >> > ? ? ? ? .inherits ? ? ? ? ? ? ? = &nv_generic_ops, >> > ? ? ? ? .freeze ? ? ? ? ? ? ? ? = nv_nf2_freeze, >> > >> > ? ? ? ? .thaw ? ? ? ? ? ? ? ? ? = nv_nf2_thaw, >> > >> > }; >> > >> > >> > Is this actually implementing inheritance? ?Why do all preceding fields >> > need to >> > be pointers? >> > >> > As far as I can tell, this style is only found in the ata drivers. >> >> I think you are right, but more subsystems need to emulate it, it is >> very powerful and works very well. ?I have been wanting to convert the >> usb-serial layer to use the same thing one of these days. >> >> > Could anyone explain how this works? >> >> The code is all there that shows it, but basically the driver is telling >> the core to "use this type of functions, but if I set any others, use >> them instead." ?It's a nicer way of doing inheritance in C than we do in >> other places in the kernel where we are a bit more "verbose" in making >> it happen. >> >> hope this helps, >> >> greg k-h > > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies at kernelnewbies.org > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-05-27 4:49 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-05-26 20:46 Struct Inheritance in drivers/ata/ Peter Hamilton 2011-05-27 1:23 ` Greg KH 2011-05-27 2:20 ` Peter Hamilton 2011-05-27 4:49 ` Ankit Jain
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).