comparison rathaxes_change_the_abstract_type_notation_in_the_e1000_sample.patch @ 104:c4c33ac02b93

First try at splitting the type nightmare and the refactoring
author Louis Opter <louis@lse.epita.fr>
date Fri, 22 Mar 2013 00:06:00 -0700
parents
children fb20f01ea997
comparison
equal deleted inserted replaced
103:d9af98faac8a 104:c4c33ac02b93
1 # HG changeset patch
2 # Parent 6603911e89e5f98231c90bccf4f4cb9d5534e000
3 rathaxes: change the abstract type notation in the e1000 sample
4
5 Starting with ra24db32bf134 Rathaxes types are generated differently: you
6 don't define entire structures anymore, but only the fields. And the
7 compiler generate a typedef'ed structure on top of it.
8
9 This works fine, except for "abstract types" (the types defined by —and
10 used to interact with— the kernel). We need to define these types as
11 Rathaxes types to interact with them, in Rathaxes, but with
12 ra24db32bf134 it means that we loose (hide) the original type from the
13 kernel, making it very difficult to use "abstract types" with the
14 kernels APIs.
15
16 For example, here the hypothetical generated struct for the abstract
17 type "struct net_device" from Linux would be:
18
19 typedef struct {
20 struct net_device data;
21 } rtx_GeneratedType;
22
23 And here is how we have to use it:
24
25 rtx_GeneratedType *my_struct;
26 kernel_api_function(&my_struct->data);
27
28 This &my_struct->data is actually always a nop, but it's confusing and
29 hard to understand.
30
31 This changeset changes the notation to:
32
33 rtx_GeneratedType *my_struct;
34 kernel_api_function((struct net_device *)my_struct);
35
36 Which is, I believe, more intuitive and coherent with how you would
37 initialize the my_struct pointer here with a return value from the
38 kernel (i.e: with a cast into rtx_GeneratedType *).
39
40
41 diff --git a/rathaxes/samples/e1000/device.blt b/rathaxes/samples/e1000/device.blt
42 --- a/rathaxes/samples/e1000/device.blt
43 +++ b/rathaxes/samples/e1000/device.blt
44 @@ -18,7 +18,7 @@
45
46 map
47 {
48 - data: ${self}->data;
49 + k_device: ((struct device *)${self});
50 }
51 }
52 }
53 diff --git a/rathaxes/samples/e1000/device.rti b/rathaxes/samples/e1000/device.rti
54 --- a/rathaxes/samples/e1000/device.rti
55 +++ b/rathaxes/samples/e1000/device.rti
56 @@ -5,6 +5,6 @@
57 decl data_types();
58 chunk LKM::includes();
59 method init();
60 - attribute Builtin::symbol data;
61 + attribute Builtin::symbol k_device;
62 }
63 }
64 diff --git a/rathaxes/samples/e1000/e1000.blt b/rathaxes/samples/e1000/e1000.blt
65 --- a/rathaxes/samples/e1000/e1000.blt
66 +++ b/rathaxes/samples/e1000/e1000.blt
67 @@ -171,13 +171,17 @@
68
69 static int rtx_e1000_tx_ring_tso_cksum_offload(${e1000::TxRing} *self, ${Socket::SKBuff} *skb)
70 {
71 - ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff;
72 - ${cast local.abs_skb as Socket::AbstractSKBuff};
73 - return skb_is_gso(&${local.abs_skb.data}) || ${local.abs_skb.data}.ip_summed == CHECKSUM_PARTIAL;
74 + /* XXX We can't use ${skb} here because it's a pointer */
75 + ${Socket::AbstractSKBuff} *k_skb = skb->skbuff;
76 + ${cast local.k_skb as Socket::AbstractSKBuff};
77 + return skb_is_gso(${local.k_skb.k_sk_buff}) || ${local.k_skb.k_sk_buff}->ip_summed == CHECKSUM_PARTIAL;
78 }
79
80 static void rtx_e1000_tx_ring_put(${e1000::TxRing} *self, ${Socket::SKBuff} *skb)
81 {
82 + /* XXX We can't use ${skb} here because it's a pointer */
83 + ${Socket::AbstractSKBuff} *k_skb = skb->skbuff;
84 + ${cast local.k_skb as Socket::AbstractSKBuff};
85 WARN_ON(!skb);
86
87 /*
88 @@ -188,17 +192,15 @@
89 * code shouldn't be aware of it and use something more
90 * abstract.
91 */
92 - ${Socket::AbstractSKBuff} *abs_skb = skb->skbuff;
93 - ${cast local.abs_skb as Socket::AbstractSKBuff};
94 ${e1000::TxDescriptor} *tx_desc = &self->base[self->tail];
95 tx_desc->lower.data = cpu_to_le32(
96 E1000_TXD_CMD_EOP |
97 E1000_TXD_CMD_IFCS |
98 E1000_TXD_CMD_RS |
99 - skb_headlen(&${local.abs_skb.data}));
100 + skb_headlen(${local.k_skb.k_sk_buff}));
101 tx_desc->upper.data = 0;
102 tx_desc->buff_addr = cpu_to_le64(skb->dma_handle);
103 - memcpy(&self->skbuffs[self->tail], skb, sizeof(*skb));
104 + memcpy(&self->skbuffs[self->tail], ${local.k_skb.k_sk_buff}, sizeof(*${local.k_skb.k_sk_buff}));
105 self->tail = (self->tail + 1) % ${config.tx_ring_size};
106 }
107
108 @@ -733,7 +735,7 @@
109 hw_ctx->rx_ring.size = ${config.rx_ring_size} * sizeof(*hw_ctx->rx_ring.base);
110 hw_ctx->rx_ring.size = ALIGN(hw_ctx->rx_ring.size, 4096);
111 hw_ctx->rx_ring.base = dma_alloc_coherent(
112 - &${rtx_ether_ctx.device},
113 + ${rtx_ether_ctx.device},
114 hw_ctx->rx_ring.size,
115 &hw_ctx->rx_ring.dma_base,
116 GFP_KERNEL);
117 @@ -751,12 +753,10 @@
118 * Allocate the skbuffs, map them for DMA, and write their address
119 * in the corresponding descriptor.
120 */
121 - ${Ethernet::AbstractDevice} *rtx_ether_dev = ${rtx_ether_ctx.net_device};
122 - ${cast local.rtx_ether_dev as Ethernet::AbstractDevice};
123 for (i = 0; i != ${config.rx_ring_size}; ++i)
124 {
125 - hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff}*) netdev_alloc_skb(
126 - &${rtx_ether_dev.netdev},
127 + hw_ctx->rx_ring.skbuffs[i].skbuff = (${Socket::AbstractSKBuff}*)netdev_alloc_skb(
128 + ${rtx_ether_ctx.net_device.k_net_dev}, /* XXX: .k_net_dev isn't expanded here */
129 ${config.rx_buffer_len});
130 if (!hw_ctx->rx_ring.skbuffs[i].skbuff)
131 {
132 @@ -764,11 +764,11 @@
133 goto err_skbuffs_alloc;
134 }
135 hw_ctx->rx_ring.skbuffs[i].dma_handle = dma_map_single(
136 - &${rtx_ether_ctx.device},
137 - &hw_ctx->rx_ring.skbuffs[i].skbuff->data,
138 + ${rtx_ether_ctx.device},
139 + (struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff, /* XXX leaking cast */
140 ${config.rx_buffer_len},
141 DMA_FROM_DEVICE);
142 - int dma_error = dma_mapping_error(&${rtx_ether_ctx.device},
143 + int dma_error = dma_mapping_error(${rtx_ether_ctx.device},
144 hw_ctx->rx_ring.skbuffs[i].dma_handle);
145 if (dma_error)
146 {
147 @@ -820,7 +820,7 @@
148 hw_ctx->tx_ring.size = ${config.tx_ring_size} * sizeof(*hw_ctx->tx_ring.base);
149 hw_ctx->tx_ring.size = ALIGN(hw_ctx->tx_ring.size, 4096);
150 hw_ctx->tx_ring.base = dma_alloc_coherent(
151 - &${rtx_ether_ctx.device},
152 + ${rtx_ether_ctx.device},
153 hw_ctx->tx_ring.size,
154 &hw_ctx->tx_ring.dma_base,
155 GFP_KERNEL);
156 @@ -863,15 +863,16 @@
157 while (i--)
158 {
159 dma_unmap_single(
160 - &${rtx_ether_ctx.device},
161 + ${rtx_ether_ctx.device},
162 hw_ctx->rx_ring.skbuffs[i].dma_handle,
163 ${config.rx_buffer_len},
164 DMA_FROM_DEVICE);
165 err_skbuffs_map:
166 - dev_kfree_skb(&hw_ctx->rx_ring.skbuffs[i].skbuff->data);
167 + /* XXX leaking cast: */
168 + dev_kfree_skb((struct sk_buff *)hw_ctx->rx_ring.skbuffs[i].skbuff);
169 }
170
171 - dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->rx_ring.size,
172 + dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx->rx_ring.size,
173 hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base);
174 err_rx_ring_alloc:
175 return -ENOMEM;
176 @@ -889,8 +890,13 @@
177 {
178 chunk ::CALL()
179 {
180 - ${e1000::Context} *hw_ctx;
181 - hw_ctx = &${rtx_ether_ctx}->hw_ctx;
182 + /*
183 + * XXX: Not generated if named "hw_ctx" (which is funny because
184 + * it's used and works in the template right above this one):
185 + */
186 + ${e1000::Context} *hw_ctx_;
187 + ${cast local.hw_ctx_ as e1000::Context};
188 + hw_ctx_ = &${rtx_ether_ctx}->hw_ctx;
189
190 /*
191 * Free the rx ring:
192 @@ -900,22 +906,23 @@
193 for (int i = 0; i != ${config.rx_ring_size}; ++i)
194 {
195 dma_unmap_single(
196 - &${rtx_ether_ctx.device},
197 - (dma_addr_t)hw_ctx->rx_ring.skbuffs[i].dma_handle,
198 + ${rtx_ether_ctx.device},
199 + (dma_addr_t)hw_ctx_->rx_ring.skbuffs[i].dma_handle,
200 ${config.rx_buffer_len},
201 DMA_FROM_DEVICE);
202 - dev_kfree_skb(&hw_ctx->rx_ring.skbuffs[i].skbuff->data);
203 + /* XXX Go through the rtx types (Socket::SKBuff, AbstractSKBuff) */
204 + dev_kfree_skb(hw_ctx_->rx_ring.skbuffs[i].skbuff);
205 }
206 - dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->rx_ring.size,
207 - hw_ctx->rx_ring.base, hw_ctx->rx_ring.dma_base);
208 + dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->rx_ring.size,
209 + hw_ctx_->rx_ring.base, hw_ctx_->rx_ring.dma_base);
210 ${Log::info("free_rx_tx: rx ring free'ed")};
211
212 /*
213 * Free the tx ring:
214 * - Free the descriptors array.
215 */
216 - dma_free_coherent(&${rtx_ether_ctx.device}, hw_ctx->tx_ring.size,
217 - hw_ctx->tx_ring.base, hw_ctx->tx_ring.dma_base);
218 + dma_free_coherent(${rtx_ether_ctx.device}, hw_ctx_->tx_ring.size,
219 + hw_ctx_->tx_ring.base, hw_ctx_->tx_ring.dma_base);
220 ${Log::info("free_rx_tx: tx ring free'ed")};
221 }
222 }
223 @@ -973,13 +980,13 @@
224 ${local.skb.init(kernel_skb)};
225 hw_ctx = &${rtx_ether_ctx}->hw_ctx;
226 tx_ring = &hw_ctx->tx_ring;
227 - devp = (${Device::AbstractDevice}*) &${rtx_ether_ctx.device};
228 + devp = (${Device::AbstractDevice}*)${rtx_ether_ctx.device};
229
230 ${Log::info("xmit: skbuff details:")};
231 /*
232 - * skb is not expand on the bound C variable (should be rtx_skbuff),
233 - * which is funny because it works for the sequence template call
234 - * right after.
235 + * skb does not expand on the bound C variable (should be
236 + * rtx_skbuff), which is funny because it works for the
237 + * sequence template call right after.
238 */
239 /*
240 * XXX: doesn't work (I tried to pass self explicitely too):
241 @@ -1012,8 +1019,8 @@
242
243 /* 2. Map the data */
244
245 - /* XXX: ${local.skb.map_to(local.devp)}; */
246 - if (rtx_socket_skbuff_map(&skb, &${devp.data}, DMA_TO_DEVICE))
247 + /* XXX: ${local.skb.map_to(devp.k_device)}; */
248 + if (rtx_socket_skbuff_map(&skb, ${devp.k_device}, DMA_TO_DEVICE))
249 {
250 ${Log::info("xmit: can't DMA map a SKbuff")};
251 goto err_skb_map_to;
252 @@ -1032,7 +1039,7 @@
253 err_offload:
254 err_skb_map_to:
255 /* XXX: ${local.skb.unmap_to_and_free(local.dev)}; */
256 - rtx_socket_skbuff_unmap_and_free(&skb, &${devp.data}, DMA_TO_DEVICE);
257 + rtx_socket_skbuff_unmap_and_free(&skb, ${devp.k_device}, DMA_TO_DEVICE);
258 return NETDEV_TX_OK;
259 }
260 }
261 diff --git a/rathaxes/samples/e1000/ethernet.blt b/rathaxes/samples/e1000/ethernet.blt
262 --- a/rathaxes/samples/e1000/ethernet.blt
263 +++ b/rathaxes/samples/e1000/ethernet.blt
264 @@ -51,7 +51,7 @@
265 {
266 decl data_types()
267 {
268 - struct net_device ndev;
269 + struct net_device data;
270 }
271
272 chunk LKM::includes()
273 @@ -59,9 +59,15 @@
274 #include <linux/netdevice.h>
275 }
276
277 + method init(Builtin::symbol dev)
278 + {
279 + ${self} = (${Ethernet::AbstractDevice} *)${dev};
280 + }
281 +
282 map
283 {
284 - netdev: ${self}->ndev;
285 + k_net_dev: ((struct net_device *)${self});
286 + rtx_ether_ctx: netdev_priv((struct net_device *)${self});
287 }
288 }
289
290 @@ -88,24 +94,33 @@
291 #include <linux/etherdevice.h>
292 }
293
294 - method init(Ethernet::AbstractDevice net_dev, PCI::AbstractDevice pci_dev)
295 + /* XXX: if the first arg is not called rtx_net_dev, it breaks. */
296 + method init(Ethernet::AbstractDevice rtx_net_dev, PCI::AbstractDevice pci_dev)
297 {
298 - ${self} = netdev_priv(&${net_dev.netdev});
299 + ${self} = ${rtx_net_dev.rtx_ether_ctx};
300 /*
301 * We can use -> because we know that ${self} will be always a
302 * pointer, but the ambiguity sucks.
303 */
304 ${self}->pci_dev = ${pci_dev};
305 - ${self}->net_dev = ${net_dev};
306 + ${self}->net_dev = ${rtx_net_dev};
307 }
308
309 map
310 {
311 - device: ${self}->pci_dev->data.dev;
312 + /*
313 + * XXX: I'd like to be able to do things like:
314 + * device: ${self.pci_dev.k_pci_dev}->dev;
315 + *
316 + * Also, using ${PCI::AbstractDevice} instead of directly struct
317 + * pci_dev doesn't work.
318 + */
319 + device: (&((struct pci_dev *)(${self})->pci_dev)->dev);
320 pci_device: ${self}->pci_dev;
321 net_device: ${self}->net_dev;
322 - perm_addr: ${self}->net_dev->ndev.perm_addr;
323 - dev_addr: ${self}->net_dev->ndev.dev_addr;
324 + perm_addr: ((struct net_device *)(${self})->net_dev)->perm_addr;
325 + dev_addr: ((struct net_device *)(${self})->net_dev)->dev_addr;
326 + irq: ((struct pci_dev *)(${self})->pci_dev)->irq;
327 }
328 }
329
330 @@ -125,8 +140,17 @@
331 {
332 static int rtx_ethernet_open(struct net_device *dev)
333 {
334 - ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev);
335 + /*
336 + * XXX The casts are here because the compiler doesn't resolve
337 + * "enclosed" type (e.g: local.var.enclosed) correctly.
338 + */
339 + ${Ethernet::AbstractDevice} *rtx_net_dev;
340 + ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
341 + { /* XXX: I end up with a placeholder if I don't open a scope */
342 + ${local.rtx_net_dev.init(local.dev)};
343 + }
344
345 + ${Ethernet::Device} *rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
346 ${cast local.rtx_ether_ctx as Ethernet::Device};
347
348 int error;
349 @@ -186,8 +210,13 @@
350 {
351 static int rtx_ethernet_close(struct net_device *dev)
352 {
353 - ${Ethernet::Device} *rtx_ether_ctx = netdev_priv(dev);
354 + ${Ethernet::AbstractDevice} *rtx_net_dev;
355 + ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
356 + { /* XXX: I end up with a placeholder if I don't open a scope */
357 + ${local.rtx_net_dev.init(local.dev)};
358 + }
359
360 + ${Ethernet::Device} *rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
361 ${cast local.rtx_ether_ctx as Ethernet::Device};
362
363 /* TODO: change this pointcut into a pointcut/adapter/callback: */
364 @@ -220,9 +249,13 @@
365 {
366 static enum irqreturn rtx_ethernet_interrupt_handler(int irq, void *dev_id)
367 {
368 - ${Ethernet::Device} *rtx_ether_ctx = dev_id;
369 + ${Ethernet::AbstractDevice} *rtx_net_dev = dev_id;
370 + ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
371
372 + ${Ethernet::Device} *rtx_ether_ctx;
373 ${cast local.rtx_ether_ctx as Ethernet::Device};
374 + rtx_ether_ctx = ${local.rtx_net_dev.rtx_ether_ctx};
375 +
376 ${pointcut ::IMPLEMENTATION(local.rtx_ether_ctx)};
377
378 return IRQ_NONE;
379 @@ -252,23 +285,26 @@
380 */
381 chunk PCI::pci_probe_hook(PCI::Device rtx_pci_dev)
382 {
383 + ${Ethernet::AbstractDevice} *rtx_net_dev;
384 ${Ethernet::Device} *rtx_ether_ctx;
385 - ${Ethernet::AbstractDevice} *net_dev;
386 - ${cast local.net_dev as Ethernet::AbstractDevice};
387 + ${cast local.rtx_net_dev as Ethernet::AbstractDevice};
388
389 - net_dev = (${Ethernet::AbstractDevice}*) alloc_etherdev(sizeof(*rtx_ether_ctx));
390 - if (!net_dev)
391 + /* Cast the result back into our "transparent wrapper" type */
392 + rtx_net_dev = (${Ethernet::AbstractDevice}*)alloc_etherdev(sizeof(*rtx_ether_ctx));
393 + if (!rtx_net_dev)
394 {
395 ${Log::info("cannot allocate the ethernet device context")};
396 error = -ENOMEM;
397 goto fail;
398 }
399 - SET_NETDEV_DEV(&${local.net_dev.netdev}, ${rtx_pci_dev.device});
400 - strlcpy(${local.net_dev.netdev}.name, ${config.ifname}, sizeof(${local.net_dev.netdev}.name));
401 - ${local.net_dev.netdev}.irq = ${rtx_pci_dev.irq};
402 - ${local.net_dev.netdev}.netdev_ops = &rtx_ether_ops;
403 + SET_NETDEV_DEV(${local.rtx_net_dev.k_net_dev}, ${rtx_pci_dev.device});
404 + strlcpy(${local.rtx_net_dev.k_net_dev}->name,
405 + ${config.ifname},
406 + sizeof(${local.rtx_net_dev.k_net_dev}->name));
407 + ${local.rtx_net_dev.k_net_dev}->irq = ${rtx_pci_dev.irq};
408 + ${local.rtx_net_dev.k_net_dev}->netdev_ops = &rtx_ether_ops;
409
410 - error = register_netdev(&${local.net_dev.netdev});
411 + error = register_netdev(${local.rtx_net_dev.k_net_dev});
412 if (error)
413 {
414 ${Log::info("cannot register the driver in the net subsystem")};
415 @@ -280,14 +316,11 @@
416 * XXX: the cast is here because the compiler resolve the
417 * type of rtx_pci_dev.pci_device to the type of
418 * rtx_pci_dev instead of the type of rtx_pci_dev.pci_device.
419 - *
420 - * Also, I'm getting placeholder in the generated code if
421 - * I don't open a scope here.
422 */
423 - {
424 - ${PCI::AbstractDevice} *rtx_pdev = ${rtx_pci_dev.pci_device};
425 - ${cast local.rtx_pdev as PCI::AbstractDevice};
426 - ${local.rtx_ether_ctx.init(local.net_dev, local.rtx_pdev)};
427 + ${PCI::AbstractDevice} *workaround = ${rtx_pci_dev.pci_device};
428 + ${cast local.workaround as PCI::AbstractDevice};
429 + { /* XXX: I end up with a placeholder if I don't open a scope */
430 + ${local.rtx_ether_ctx.init(local.rtx_net_dev, local.workaround)};
431 }
432
433 /* Register ourselves in the parent context: */
434 @@ -309,7 +342,7 @@
435 ${pointcut Ethernet::adapter_load_mac_address(local.rtx_ether_ctx)};
436 memcpy(${local.rtx_ether_ctx.perm_addr},
437 ${local.rtx_ether_ctx.dev_addr},
438 - ${local.net_dev.netdev}.addr_len);
439 + ${local.rtx_net_dev.k_net_dev}->addr_len);
440 }
441
442 /* This chunk should be removed (see #26) */
443 @@ -326,15 +359,15 @@
444 */
445 chunk PCI::pci_remove_hook(PCI::Device rtx_pci_dev)
446 {
447 - ${Ethernet::Device} *rtx_ether_ctx = ${rtx_pci_dev.context};
448 - ${Ethernet::AbstractDevice} *rtx_ether_dev = (${Ethernet::AbstractDevice}*) ${local.rtx_ether_ctx.net_device};
449 -
450 + ${Ethernet::Device} *rtx_ether_ctx = ${rtx_pci_dev.rtx_drv_context};
451 + ${cast local.rtx_ether_ctx as Ethernet::Device}; /* XXX */
452 BUG_ON(!rtx_ether_ctx);
453
454 - ${cast local.rtx_ether_ctx as Ethernet::Device};
455 - ${cast local.rtx_ether_dev as Ethernet::AbstractDevice};
456 - unregister_netdev(&${local.rtx_ether_dev.netdev});
457 - free_netdev(&${local.rtx_ether_dev.netdev});
458 + ${Ethernet::AbstractDevice} *rtx_net_dev = ${local.rtx_ether_ctx.net_device};
459 + ${cast local.rtx_net_dev as Ethernet::AbstractDevice}; /* XXX */
460 +
461 + unregister_netdev(${local.rtx_net_dev.k_net_dev});
462 + free_netdev(${local.rtx_net_dev.k_net_dev});
463 }
464
465 /* This chunk should be removed (see #26) */
466 diff --git a/rathaxes/samples/e1000/ethernet.rti b/rathaxes/samples/e1000/ethernet.rti
467 --- a/rathaxes/samples/e1000/ethernet.rti
468 +++ b/rathaxes/samples/e1000/ethernet.rti
469 @@ -16,8 +16,15 @@
470 provided type AbstractDevice
471 {
472 chunk LKM::includes();
473 + method init(Builtin::symbol);
474 decl data_types();
475 - attribute Builtin::symbol netdev;
476 +
477 + attribute Builtin::symbol k_net_dev;
478 + /*
479 + * XXX: should be a Ethernet::Device, but that causes a circular
480 + * dependency.
481 + */
482 + attribute Builtin::symbol rtx_ether_ctx;
483 }
484
485 provided type Device
486 @@ -34,8 +41,9 @@
487 * I'd like to use better names here, but I'd like to understand the
488 * difference between the two first:
489 */
490 - attribute Builtin::symbol perm_addr;
491 - attribute Builtin::symbol dev_addr;
492 + attribute Builtin::symbol perm_addr;
493 + attribute Builtin::symbol dev_addr;
494 + attribute Builtin::symbol irq;
495 }
496
497 required sequence open(Ethernet::Device)
498 diff --git a/rathaxes/samples/e1000/pci.blt b/rathaxes/samples/e1000/pci.blt
499 --- a/rathaxes/samples/e1000/pci.blt
500 +++ b/rathaxes/samples/e1000/pci.blt
501 @@ -16,15 +16,15 @@
502 {
503 }
504
505 - method set_context(Builtin::symbol ctx)
506 + method set_rtx_context(Builtin::symbol ctx)
507 {
508 - pci_set_drvdata(&${self}->data, ${ctx});
509 + pci_set_drvdata(${self.k_pci_dev}, ${ctx});
510 }
511
512 map
513 {
514 - data: ${self}->data;
515 - drv_data: pci_get_drvdata(&${self}->data);
516 + k_pci_dev: ((struct pci_dev *)${self});
517 + rtx_pci_ctx: pci_get_drvdata((struct pci_dev *)${self});
518 }
519 }
520
521 @@ -52,13 +52,13 @@
522 int error;
523 ${PCI::AbstractDevice} *enable_pdev = self->pdev;
524 ${cast local.enable_pdev as PCI::AbstractDevice};
525 - error = pci_enable_device(&${local.enable_pdev.data});
526 + error = pci_enable_device(${local.enable_pdev.k_pci_dev});
527 if (error)
528 return error;
529 - error = pci_request_selected_regions(&${local.enable_pdev.data}, self->bars, ${config.name});
530 + error = pci_request_selected_regions(${local.enable_pdev.k_pci_dev}, self->bars, ${config.name});
531 if (error)
532 return error;
533 - pci_set_master(&${local.enable_pdev.data});
534 + pci_set_master(${local.enable_pdev.k_pci_dev});
535 return 0;
536 }
537
538 @@ -68,8 +68,8 @@
539 ${cast local.disable_pdev as PCI::AbstractDevice};
540 if (self->ioaddr)
541 iounmap(self->ioaddr);
542 - pci_release_selected_regions(&${local.disable_pdev.data}, self->bars);
543 - pci_disable_device(&${local.disable_pdev.data});
544 + pci_release_selected_regions(${local.disable_pdev.k_pci_dev}, self->bars);
545 + pci_disable_device(${local.disable_pdev.k_pci_dev});
546 }
547 }
548
549 @@ -78,7 +78,7 @@
550 ${PCI::AbstractDevice} * workaround = (${PCI::AbstractDevice}*)pdev;
551 ${cast local.workaround as PCI::AbstractDevice};
552 ${self}->pdev = ${pdev};
553 - ${self}->bars = pci_select_bars(&${local.workaround.data}, IORESOURCE_MEM);
554 + ${self}->bars = pci_select_bars(${local.workaround.k_pci_dev}, IORESOURCE_MEM);
555 ${self}->ioaddr = NULL;
556 ${self}->context = NULL;
557 }
558 @@ -97,20 +97,20 @@
559 {
560 ${PCI::AbstractDevice} *select_ioaddr_pdev = ${self}->pdev;
561 ${cast local.select_ioaddr_pdev as PCI::AbstractDevice};
562 - ${self}->ioaddr = pci_ioremap_bar(&${local.select_ioaddr_pdev.data}, ${bar});
563 + ${self}->ioaddr = pci_ioremap_bar(${local.select_ioaddr_pdev.k_pci_dev}, ${bar});
564 }
565
566 - method set_context(Builtin::symbol ctx)
567 + method set_rtx_drv_context(Builtin::symbol ctx)
568 {
569 ${self}->context = ctx;
570 }
571
572 map
573 {
574 - context: ${self}->context;
575 - device: &${self}->pdev->data.dev;
576 + rtx_drv_context: ${self}->context;
577 + device: &((struct pci_dev *)(${self})->pdev)->dev;
578 pci_device: ${self}->pdev;
579 - irq: ${self}->pdev->data.irq;
580 + irq: ((struct pci_dev *)(${self})->pdev)->irq;
581 bars: ${self}->bars;
582 ioaddr: ${self}->ioaddr;
583 BAR_0: 0;
584 @@ -151,7 +151,7 @@
585 ${local.rtx_pci_dev.init(local.rtx_pdev)};
586 }
587
588 - /* ${local.pdev.set_context(local.rtx_pci_dev)}; */
589 + /* ${local.pdev.set_rtx_context(local.rtx_pci_dev)}; */
590 pci_set_drvdata(pdev, rtx_pci_dev);
591
592 /* ${local.rtx_pci_dev.enable()}; */
593 @@ -184,7 +184,7 @@
594 return 0;
595
596 fail:
597 - /* ${local.pdev.set_context(NULL)}; */
598 + /* ${local.pdev.set_rtx_drv_context(NULL)}; */
599 pci_set_drvdata(pdev, NULL);
600 kfree(rtx_pci_dev);
601 return error;
602 @@ -210,7 +210,7 @@
603 {
604 ${PCI::AbstractDevice} *rtx_pdev = (${PCI::AbstractDevice}*)pdev;
605 ${cast local.rtx_pdev as PCI::AbstractDevice};
606 - ${PCI::Device} *rtx_pci_dev = ${rtx_pdev.drv_data};
607 + ${PCI::Device} *rtx_pci_dev = ${rtx_pdev.rtx_pci_ctx};
608
609 BUG_ON(!rtx_pci_dev);
610
611 diff --git a/rathaxes/samples/e1000/pci.rti b/rathaxes/samples/e1000/pci.rti
612 --- a/rathaxes/samples/e1000/pci.rti
613 +++ b/rathaxes/samples/e1000/pci.rti
614 @@ -10,10 +10,15 @@
615
616 chunk LKM::includes();
617 method init(PCI::AbstractDevice);
618 - method set_context(Builtin::symbol);
619 + /*
620 + * XXX: the argument should be a PCI::Device but that causes a circular
621 + * dependency:
622 + */
623 + method set_rtx_context(Builtin::symbol);
624
625 - attribute Builtin::symbol data;
626 - attribute Builtin::symbol drv_data;
627 + attribute Builtin::symbol k_pci_dev;
628 + /* XXX: should be PCI::Device (see above point) */
629 + attribute Builtin::symbol rtx_pci_ctx;
630 }
631
632 provided type PCI::Device
633 @@ -27,9 +32,9 @@
634 method enable();
635 method disable();
636 method select_ioaddr(Builtin::number);
637 - method set_context(Builtin::symbol);
638 + method set_rtx_drv_context(Builtin::symbol);
639
640 - attribute Builtin::symbol context;
641 + attribute Builtin::symbol rtx_drv_context;
642 attribute Device::AbstractDevice device;
643 attribute PCI::AbstractDevice pci_device;
644 attribute Builtin::symbol ioaddr;
645 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
646 --- a/rathaxes/samples/e1000/socket.blt
647 +++ b/rathaxes/samples/e1000/socket.blt
648 @@ -14,7 +14,7 @@
649
650 map
651 {
652 - data: ${self}->data;
653 + k_sk_buff: ((struct sk_buff *)${self});
654 }
655 }
656
657 @@ -46,11 +46,12 @@
658 */
659 ${Socket::AbstractSKBuff} *skb = self->skbuff;
660 ${cast local.skb as Socket::AbstractSKBuff};
661 - ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.data}.protocol) };
662 + ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.k_sk_buff}->protocol) };
663 +
664 static const char * const ip_summed_values[] = {
665 "none", "unnecessary", "complete", "partial"
666 };
667 - struct skb_shared_info *shinfo = skb_shinfo(&${local.skb.data});
668 + struct skb_shared_info *shinfo = skb_shinfo(${local.skb.k_sk_buff});
669
670 pr_info(
671 "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
672 @@ -59,8 +60,8 @@
673 "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
674 /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */
675 ethernet_proto.id, ${local.ethernet_proto.str},
676 - ${local.skb.data}.ip_summed, ip_summed_values[${local.skb.data}.ip_summed],
677 - ${local.skb.data}.len, ${local.skb.data}.data_len, skb_headlen(&${local.skb.data}),
678 + ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed],
679 + ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}),
680 shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
681 );
682 }
683 @@ -72,14 +73,13 @@
684 ${Socket::AbstractSKBuff} *skb = self->skbuff;
685 ${cast local.skb as Socket::AbstractSKBuff};
686
687 - WARN_ON(!skb);
688 - WARN_ON(!${local.skb.data}.data);
689 + WARN_ON(!${local.skb.k_sk_buff});
690 WARN_ON(self->dma_handle);
691
692 self->dma_handle = dma_map_single(
693 dev,
694 - &${local.skb.data}.data,
695 - skb_headlen(&${local.skb.data}),
696 + ${local.skb.k_sk_buff},
697 + skb_headlen(${local.skb.k_sk_buff}),
698 direction);
699 int err = dma_mapping_error(dev, self->dma_handle);
700 if (err)
701 @@ -97,18 +97,17 @@
702 ${Socket::AbstractSKBuff} *skb = self->skbuff;
703 ${cast local.skb as Socket::AbstractSKBuff};
704
705 - WARN_ON(!${local.skb});
706 - WARN_ON(!${local.skb.data}.data);
707 + WARN_ON(!${local.skb.k_sk_buff});
708
709 if (self->dma_handle)
710 {
711 dma_unmap_single(dev,
712 self->dma_handle,
713 - skb_headlen(&${local.skb.data}),
714 + skb_headlen(${local.skb.k_sk_buff}),
715 direction);
716 self->dma_handle = 0;
717 }
718 - dev_kfree_skb_any(&${local.skb.data});
719 + dev_kfree_skb_any(${local.skb.k_sk_buff});
720 self->skbuff = 0;
721 }
722 }
723 @@ -131,22 +130,22 @@
724
725 method map_to(Device::AbstractDevice dev)
726 {
727 - rtx_socket_skbuff_map(${self}, &${dev.data}, DMA_TO_DEVICE);
728 + rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_TO_DEVICE);
729 }
730
731 method map_from(Device::AbstractDevice dev)
732 {
733 - rtx_socket_skbuff_map(${self}, &${dev.data}, DMA_FROM_DEVICE);
734 + rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
735 }
736
737 method unmap_to_and_free(Device::AbstractDevice dev)
738 {
739 - rtx_socket_skbuff_unmap_and_free(${self}, &${dev.data}, DMA_TO_DEVICE);
740 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_TO_DEVICE);
741 }
742
743 method unmap_from_and_free(Device::AbstractDevice dev)
744 {
745 - rtx_socket_skbuff_unmap_and_free(${self}, &${dev.data}, DMA_FROM_DEVICE);
746 + rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
747 }
748
749 map
750 diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
751 --- a/rathaxes/samples/e1000/socket.rti
752 +++ b/rathaxes/samples/e1000/socket.rti
753 @@ -5,7 +5,8 @@
754 {
755 chunk LKM::includes();
756 decl data_types();
757 - attribute Builtin::symbol data;
758 +
759 + attribute Builtin::symbol k_sk_buff;
760 }
761
762 provided type SKBuff