# HG changeset patch
# Parent 4b0b03bb17b3c70e333fb3c637e199669a792b30
rathaxes: abstract away netdev_alloc_skb() from e1000::set_up_device

By adding a new method to Ethernet::Device.

diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
--- a/rathaxes/samples/e1000/socket.blt
+++ b/rathaxes/samples/e1000/socket.blt
@@ -1,4 +1,4 @@
-with Socket, LKM, Device, Ethernet
+with Socket, LKM, Device, DMA, Ethernet
 {
     template type Socket::AbstractSKBuff()
     {
@@ -14,7 +14,7 @@
 
         map
         {
-            k_sk_buff: ((struct sk_buff *)${self});
+            k_sk_buff: ((struct sk_buff *)(${self}));
         }
     }
 
@@ -22,35 +22,34 @@
     {
         decl  data_types()
         {
-            ${Socket::AbstractSKBuff.ref}   skbuff;
-            dma_addr_t                      dma_handle;
+            ${Socket::AbstractSKBuff.ref}       skbuff;
+            ${DMA::AbstractDMAHandle.scalar}    dma_handle;
         }
 
         chunk   LKM::prototypes()
         {
             static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref});
-            static int  rtx_socket_skbuff_map(${Socket::SKBuff.ref}, struct device *, enum dma_data_direction);
-            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref}, struct device *, enum dma_data_direction);
+            static int  rtx_socket_skbuff_map(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar});
+            static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref}, ${Device::AbstractDevice.ref}, ${DMA::DMADirection.scalar});
         }
 
         chunk   LKM::code()
         {
             static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref} self)
             {
-                WARN_ON(!self->skbuff);
+                WARN_ON(!${local.self.sk_buff});
+
+                ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.self.sk_buff.k_sk_buff}->protocol) };
+                static const char * const ip_summed_values[] = {
+                    "none", "unnecessary", "complete", "partial"
+                };
+                struct skb_shared_info *shinfo = skb_shinfo(${local.self.sk_buff.k_sk_buff});
 
                 /*
                  * We should use a Rathaxes log abstraction instead of pr_info here,
                  * but Rathaxes doesn't support functions with a variable number of
                  * arguments yet.
                  */
-                ${Socket::AbstractSKBuff.ref} skb = self->skbuff;
-                ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.skb.k_sk_buff}->protocol) };
-                static const char * const ip_summed_values[] = {
-                    "none", "unnecessary", "complete", "partial"
-                };
-                struct skb_shared_info *shinfo = skb_shinfo(${local.skb.k_sk_buff});
-
                 pr_info(
                         "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
                         "\t      len = %-5u data_len = %-5u head_len = %-5u\n"
@@ -58,53 +57,46 @@
                         "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
                         /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */
                         ethernet_proto.id, ${local.ethernet_proto.str},
-                        ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed],
-                        ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}),
+                        ${local.self.sk_buff.k_sk_buff}->ip_summed, ip_summed_values[${local.self.sk_buff.k_sk_buff}->ip_summed],
+                        ${local.self.sk_buff.k_sk_buff}->len, ${local.self.sk_buff.k_sk_buff}->data_len, skb_headlen(${local.self.sk_buff.k_sk_buff}),
                         shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
                 );
             }
 
             static int rtx_socket_skbuff_map(${Socket::SKBuff.ref} self,
-                                             struct device *dev,
-                                             enum dma_data_direction direction)
+                                             ${Device::AbstractDevice.ref} dev,
+                                             ${DMA::DMADirection.scalar} direction)
             {
-                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
+                WARN_ON(!${local.self.sk_buff});
+                WARN_ON(${local.self.dma_handle});
 
-                WARN_ON(!${local.skb.k_sk_buff});
-                WARN_ON(self->dma_handle);
-
-                self->dma_handle = dma_map_single(
-                        dev,
-                        ${local.skb.k_sk_buff},
-                        skb_headlen(${local.skb.k_sk_buff}),
-                        direction);
-                int err = dma_mapping_error(dev, self->dma_handle);
+                unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff});
+                ${cast local.len as Builtin::number};
+                ${local.self.dma_handle} = ${DMA::map(local.dev, local.self.sk_buff.k_sk_buff, local.len, local.direction)};
+                int err = ${DMA::mapping_error(local.dev, local.self.dma_handle)};
                 if (err)
                 {
-                    self->dma_handle = 0;
+                    ${local.self.dma_handle} = 0;
                     return err;
                 }
                 return 0;
             }
 
             static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref} self,
-                                                         struct device *dev,
-                                                         enum dma_data_direction direction)
+                                                         ${Device::AbstractDevice.ref} dev,
+                                                         ${DMA::DMADirection} direction)
             {
-                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
+                WARN_ON(!${local.self.sk_buff});
 
-                WARN_ON(!${local.skb.k_sk_buff});
-
-                if (self->dma_handle)
+                if (${local.self.dma_handle})
                 {
-                    dma_unmap_single(dev,
-                            self->dma_handle,
-                            skb_headlen(${local.skb.k_sk_buff}),
-                            direction);
-                    self->dma_handle = 0;
+                    unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff});
+                    ${cast local.len as Builtin::number};
+                    ${DMA::unmap(local.dev, local.self.dma_handle, local.len, local.direction)};
+                    ${local.self.dma_handle} = 0;
                 }
-                dev_kfree_skb_any(${local.skb.k_sk_buff});
-                self->skbuff = 0;
+                dev_kfree_skb_any(${local.self.sk_buff.k_sk_buff});
+                ${local.self.sk_buff} = NULL;
             }
         }
 
@@ -115,8 +107,8 @@
          */
         method init(Socket::AbstractSKBuff kernel_skb)
         {
-            ${self}.skbuff = ${kernel_skb};
-            ${self}.dma_handle = 0;
+            ${self.sk_buff} = ${kernel_skb};
+            ${self.dma_handle} = 0;
         }
 
         method dump_infos()
@@ -126,30 +118,37 @@
 
         method   map_to(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_TO_DEVICE);
+            rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_TO_DEVICE);
         }
 
         method   map_from(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
+            rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_FROM_DEVICE);
         }
 
         method   unmap_to_and_free(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_TO_DEVICE);
+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_TO_DEVICE);
         }
 
         method   unmap_from_and_free(Device::AbstractDevice dev)
         {
-            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_FROM_DEVICE);
         }
 
         map
         {
-            // some work may have to be done here in order
-            // to access to some field of the sk_buff.
-            // We should determine if all the sk_buff management
-            // can be abstracted from the user.
+            // Some work may have to be done here in order to access to some
+            // field of the sk_buff. We should determine if all the sk_buff
+            // management can be abstracted from the user. But this is at least
+            // useful for internal use:
+            sk_buff: (${self})->skbuff;
+            // XXX: We need to cast here so we can do things like
+            // var.dma_handle = 0; but the type shouldn't be hardcoded (at the
+            // same time ${DMA:AbstractDMAHandle} couldn't be used because that
+            // would yield to a struct type which you can't assign directly;
+            // but maybe doing the ->data in that case would be acceptable).
+            dma_handle: (*((dma_addr_t *)&(${self})->dma_handle));
         }
     }
 }
diff --git a/rathaxes/samples/e1000/socket.rti b/rathaxes/samples/e1000/socket.rti
--- a/rathaxes/samples/e1000/socket.rti
+++ b/rathaxes/samples/e1000/socket.rti
@@ -1,4 +1,4 @@
-interface Socket : LKM, Device
+interface Socket : LKM, Device, DMA, Builtin
 {
     /* The SKBuff type from the kernel */
     provided type   AbstractSKBuff
@@ -10,14 +10,17 @@
 
     provided type   SKBuff
     {
-        chunk       LKM::prototypes();
-        chunk       LKM::code();
-        decl        data_types();
-        method      init(Socket::AbstractSKBuff);
-        method      dump_infos();
-        method      map_to(Device::AbstractDevice);
-        method      map_from(Device::AbstractDevice);
-        method      unmap_to_and_free(Device::AbstractDevice);
-        method      unmap_from_and_free(Device::AbstractDevice);
+        chunk   LKM::prototypes();
+        chunk   LKM::code();
+        decl    data_types();
+        method  init(Socket::AbstractSKBuff);
+        method  dump_infos();
+        method  map_to(Device::AbstractDevice);
+        method  map_from(Device::AbstractDevice);
+        method  unmap_to_and_free(Device::AbstractDevice);
+        method  unmap_from_and_free(Device::AbstractDevice);
+
+        attribute   Socket::AbstractSKBuff.ref      sk_buff;
+        attribute   DMA::AbstractDMAHandle.scalar   dma_handle;
     }
 }
