aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-09 14:52:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-09 14:52:14 -0500
commitd9e8a3a5b8298a3c814ed37ac5756e6f67b6be41 (patch)
treeffa1cf8b367b3f32155f6336d7b86b781a368019 /include
parent2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff)
parentb9bdcbba010c2e49c8f837ea7a49fe006b636f41 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx: (22 commits) ioat: fix self test for multi-channel case dmaengine: bump initcall level to arch_initcall dmaengine: advertise all channels on a device to dma_filter_fn dmaengine: use idr for registering dma device numbers dmaengine: add a release for dma class devices and dependent infrastructure ioat: do not perform removal actions at shutdown iop-adma: enable module removal iop-adma: kill debug BUG_ON iop-adma: let devm do its job, don't duplicate free dmaengine: kill enum dma_state_client dmaengine: remove 'bigref' infrastructure dmaengine: kill struct dma_client and supporting infrastructure dmaengine: replace dma_async_client_register with dmaengine_get atmel-mci: convert to dma_request_channel and down-level dma_slave dmatest: convert to dma_request_channel dmaengine: introduce dma_request_channel and private channels net_dma: convert to dma_find_channel dmaengine: provide a common 'issue_pending_all' implementation dmaengine: centralize channel allocation, introduce dma_find_channel dmaengine: up-level reference counting to the module level ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/async_tx.h17
-rw-r--r--include/linux/atmel-mci.h6
-rw-r--r--include/linux/dmaengine.h181
-rw-r--r--include/linux/dw_dmac.h31
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/net/netdma.h11
6 files changed, 81 insertions, 168 deletions
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index 0f50d4cc4360..45f6297821bd 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -59,9 +59,7 @@ enum async_tx_flags {
59}; 59};
60 60
61#ifdef CONFIG_DMA_ENGINE 61#ifdef CONFIG_DMA_ENGINE
62void async_tx_issue_pending_all(void); 62#define async_tx_issue_pending_all dma_issue_pending_all
63enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
64void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx);
65#ifdef CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL 63#ifdef CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL
66#include <asm/async_tx.h> 64#include <asm/async_tx.h>
67#else 65#else
@@ -77,19 +75,6 @@ static inline void async_tx_issue_pending_all(void)
77 do { } while (0); 75 do { } while (0);
78} 76}
79 77
80static inline enum dma_status
81dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
82{
83 return DMA_SUCCESS;
84}
85
86static inline void
87async_tx_run_dependencies(struct dma_async_tx_descriptor *tx,
88 struct dma_chan *host_chan)
89{
90 do { } while (0);
91}
92
93static inline struct dma_chan * 78static inline struct dma_chan *
94async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx, 79async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx,
95 enum dma_transaction_type tx_type, struct page **dst, int dst_count, 80 enum dma_transaction_type tx_type, struct page **dst, int dst_count,
diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h
index 2a2213eefd85..2f1f95737acb 100644
--- a/include/linux/atmel-mci.h
+++ b/include/linux/atmel-mci.h
@@ -3,7 +3,7 @@
3 3
4#define ATMEL_MCI_MAX_NR_SLOTS 2 4#define ATMEL_MCI_MAX_NR_SLOTS 2
5 5
6struct dma_slave; 6#include <linux/dw_dmac.h>
7 7
8/** 8/**
9 * struct mci_slot_pdata - board-specific per-slot configuration 9 * struct mci_slot_pdata - board-specific per-slot configuration
@@ -28,11 +28,11 @@ struct mci_slot_pdata {
28 28
29/** 29/**
30 * struct mci_platform_data - board-specific MMC/SDcard configuration 30 * struct mci_platform_data - board-specific MMC/SDcard configuration
31 * @dma_slave: DMA slave interface to use in data transfers, or NULL. 31 * @dma_slave: DMA slave interface to use in data transfers.
32 * @slot: Per-slot configuration data. 32 * @slot: Per-slot configuration data.
33 */ 33 */
34struct mci_platform_data { 34struct mci_platform_data {
35 struct dma_slave *dma_slave; 35 struct dw_dma_slave dma_slave;
36 struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; 36 struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
37}; 37};
38 38
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index adb0b084eb5a..64dea2ab326c 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -29,32 +29,6 @@
29#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
30 30
31/** 31/**
32 * enum dma_state - resource PNP/power management state
33 * @DMA_RESOURCE_SUSPEND: DMA device going into low power state
34 * @DMA_RESOURCE_RESUME: DMA device returning to full power
35 * @DMA_RESOURCE_AVAILABLE: DMA device available to the system
36 * @DMA_RESOURCE_REMOVED: DMA device removed from the system
37 */
38enum dma_state {
39 DMA_RESOURCE_SUSPEND,
40 DMA_RESOURCE_RESUME,
41 DMA_RESOURCE_AVAILABLE,
42 DMA_RESOURCE_REMOVED,
43};
44
45/**
46 * enum dma_state_client - state of the channel in the client
47 * @DMA_ACK: client would like to use, or was using this channel
48 * @DMA_DUP: client has already seen this channel, or is not using this channel
49 * @DMA_NAK: client does not want to see any more channels
50 */
51enum dma_state_client {
52 DMA_ACK,
53 DMA_DUP,
54 DMA_NAK,
55};
56
57/**
58 * typedef dma_cookie_t - an opaque DMA cookie 32 * typedef dma_cookie_t - an opaque DMA cookie
59 * 33 *
60 * if dma_cookie_t is >0 it's a DMA request cookie, <0 it's an error code 34 * if dma_cookie_t is >0 it's a DMA request cookie, <0 it's an error code
@@ -89,23 +63,13 @@ enum dma_transaction_type {
89 DMA_MEMSET, 63 DMA_MEMSET,
90 DMA_MEMCPY_CRC32C, 64 DMA_MEMCPY_CRC32C,
91 DMA_INTERRUPT, 65 DMA_INTERRUPT,
66 DMA_PRIVATE,
92 DMA_SLAVE, 67 DMA_SLAVE,
93}; 68};
94 69
95/* last transaction type for creation of the capabilities mask */ 70/* last transaction type for creation of the capabilities mask */
96#define DMA_TX_TYPE_END (DMA_SLAVE + 1) 71#define DMA_TX_TYPE_END (DMA_SLAVE + 1)
97 72
98/**
99 * enum dma_slave_width - DMA slave register access width.
100 * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
101 * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
102 * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
103 */
104enum dma_slave_width {
105 DMA_SLAVE_WIDTH_8BIT,
106 DMA_SLAVE_WIDTH_16BIT,
107 DMA_SLAVE_WIDTH_32BIT,
108};
109 73
110/** 74/**
111 * enum dma_ctrl_flags - DMA flags to augment operation preparation, 75 * enum dma_ctrl_flags - DMA flags to augment operation preparation,
@@ -132,32 +96,6 @@ enum dma_ctrl_flags {
132typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t; 96typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
133 97
134/** 98/**
135 * struct dma_slave - Information about a DMA slave
136 * @dev: device acting as DMA slave
137 * @dma_dev: required DMA master device. If non-NULL, the client can not be
138 * bound to other masters than this.
139 * @tx_reg: physical address of data register used for
140 * memory-to-peripheral transfers
141 * @rx_reg: physical address of data register used for
142 * peripheral-to-memory transfers
143 * @reg_width: peripheral register width
144 *
145 * If dma_dev is non-NULL, the client can not be bound to other DMA
146 * masters than the one corresponding to this device. The DMA master
147 * driver may use this to determine if there is controller-specific
148 * data wrapped around this struct. Drivers of platform code that sets
149 * the dma_dev field must therefore make sure to use an appropriate
150 * controller-specific dma slave structure wrapping this struct.
151 */
152struct dma_slave {
153 struct device *dev;
154 struct device *dma_dev;
155 dma_addr_t tx_reg;
156 dma_addr_t rx_reg;
157 enum dma_slave_width reg_width;
158};
159
160/**
161 * struct dma_chan_percpu - the per-CPU part of struct dma_chan 99 * struct dma_chan_percpu - the per-CPU part of struct dma_chan
162 * @refcount: local_t used for open-coded "bigref" counting 100 * @refcount: local_t used for open-coded "bigref" counting
163 * @memcpy_count: transaction counter 101 * @memcpy_count: transaction counter
@@ -165,7 +103,6 @@ struct dma_slave {
165 */ 103 */
166 104
167struct dma_chan_percpu { 105struct dma_chan_percpu {
168 local_t refcount;
169 /* stats */ 106 /* stats */
170 unsigned long memcpy_count; 107 unsigned long memcpy_count;
171 unsigned long bytes_transferred; 108 unsigned long bytes_transferred;
@@ -176,13 +113,14 @@ struct dma_chan_percpu {
176 * @device: ptr to the dma device who supplies this channel, always !%NULL 113 * @device: ptr to the dma device who supplies this channel, always !%NULL
177 * @cookie: last cookie value returned to client 114 * @cookie: last cookie value returned to client
178 * @chan_id: channel ID for sysfs 115 * @chan_id: channel ID for sysfs
179 * @class_dev: class device for sysfs 116 * @dev: class device for sysfs
180 * @refcount: kref, used in "bigref" slow-mode 117 * @refcount: kref, used in "bigref" slow-mode
181 * @slow_ref: indicates that the DMA channel is free 118 * @slow_ref: indicates that the DMA channel is free
182 * @rcu: the DMA channel's RCU head 119 * @rcu: the DMA channel's RCU head
183 * @device_node: used to add this to the device chan list 120 * @device_node: used to add this to the device chan list
184 * @local: per-cpu pointer to a struct dma_chan_percpu 121 * @local: per-cpu pointer to a struct dma_chan_percpu
185 * @client-count: how many clients are using this channel 122 * @client-count: how many clients are using this channel
123 * @table_count: number of appearances in the mem-to-mem allocation table
186 */ 124 */
187struct dma_chan { 125struct dma_chan {
188 struct dma_device *device; 126 struct dma_device *device;
@@ -190,73 +128,47 @@ struct dma_chan {
190 128
191 /* sysfs */ 129 /* sysfs */
192 int chan_id; 130 int chan_id;
193 struct device dev; 131 struct dma_chan_dev *dev;
194
195 struct kref refcount;
196 int slow_ref;
197 struct rcu_head rcu;
198 132
199 struct list_head device_node; 133 struct list_head device_node;
200 struct dma_chan_percpu *local; 134 struct dma_chan_percpu *local;
201 int client_count; 135 int client_count;
136 int table_count;
202}; 137};
203 138
204#define to_dma_chan(p) container_of(p, struct dma_chan, dev) 139/**
205 140 * struct dma_chan_dev - relate sysfs device node to backing channel device
206void dma_chan_cleanup(struct kref *kref); 141 * @chan - driver channel device
207 142 * @device - sysfs device
208static inline void dma_chan_get(struct dma_chan *chan) 143 * @dev_id - parent dma_device dev_id
209{ 144 * @idr_ref - reference count to gate release of dma_device dev_id
210 if (unlikely(chan->slow_ref)) 145 */
211 kref_get(&chan->refcount); 146struct dma_chan_dev {
212 else { 147 struct dma_chan *chan;
213 local_inc(&(per_cpu_ptr(chan->local, get_cpu())->refcount)); 148 struct device device;
214 put_cpu(); 149 int dev_id;
215 } 150 atomic_t *idr_ref;
216} 151};
217 152
218static inline void dma_chan_put(struct dma_chan *chan) 153static inline const char *dma_chan_name(struct dma_chan *chan)
219{ 154{
220 if (unlikely(chan->slow_ref)) 155 return dev_name(&chan->dev->device);
221 kref_put(&chan->refcount, dma_chan_cleanup);
222 else {
223 local_dec(&(per_cpu_ptr(chan->local, get_cpu())->refcount));
224 put_cpu();
225 }
226} 156}
227 157
228/* 158void dma_chan_cleanup(struct kref *kref);
229 * typedef dma_event_callback - function pointer to a DMA event callback
230 * For each channel added to the system this routine is called for each client.
231 * If the client would like to use the channel it returns '1' to signal (ack)
232 * the dmaengine core to take out a reference on the channel and its
233 * corresponding device. A client must not 'ack' an available channel more
234 * than once. When a channel is removed all clients are notified. If a client
235 * is using the channel it must 'ack' the removal. A client must not 'ack' a
236 * removed channel more than once.
237 * @client - 'this' pointer for the client context
238 * @chan - channel to be acted upon
239 * @state - available or removed
240 */
241struct dma_client;
242typedef enum dma_state_client (*dma_event_callback) (struct dma_client *client,
243 struct dma_chan *chan, enum dma_state state);
244 159
245/** 160/**
246 * struct dma_client - info on the entity making use of DMA services 161 * typedef dma_filter_fn - callback filter for dma_request_channel
247 * @event_callback: func ptr to call when something happens 162 * @chan: channel to be reviewed
248 * @cap_mask: only return channels that satisfy the requested capabilities 163 * @filter_param: opaque parameter passed through dma_request_channel
249 * a value of zero corresponds to any capability 164 *
250 * @slave: data for preparing slave transfer. Must be non-NULL iff the 165 * When this optional parameter is specified in a call to dma_request_channel a
251 * DMA_SLAVE capability is requested. 166 * suitable channel is passed to this routine for further dispositioning before
252 * @global_node: list_head for global dma_client_list 167 * being returned. Where 'suitable' indicates a non-busy channel that
168 * satisfies the given capability mask. It returns 'true' to indicate that the
169 * channel is suitable.
253 */ 170 */
254struct dma_client { 171typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
255 dma_event_callback event_callback;
256 dma_cap_mask_t cap_mask;
257 struct dma_slave *slave;
258 struct list_head global_node;
259};
260 172
261typedef void (*dma_async_tx_callback)(void *dma_async_param); 173typedef void (*dma_async_tx_callback)(void *dma_async_param);
262/** 174/**
@@ -323,14 +235,10 @@ struct dma_device {
323 dma_cap_mask_t cap_mask; 235 dma_cap_mask_t cap_mask;
324 int max_xor; 236 int max_xor;
325 237
326 struct kref refcount;
327 struct completion done;
328
329 int dev_id; 238 int dev_id;
330 struct device *dev; 239 struct device *dev;
331 240
332 int (*device_alloc_chan_resources)(struct dma_chan *chan, 241 int (*device_alloc_chan_resources)(struct dma_chan *chan);
333 struct dma_client *client);
334 void (*device_free_chan_resources)(struct dma_chan *chan); 242 void (*device_free_chan_resources)(struct dma_chan *chan);
335 243
336 struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)( 244 struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
@@ -362,9 +270,8 @@ struct dma_device {
362 270
363/* --- public DMA engine API --- */ 271/* --- public DMA engine API --- */
364 272
365void dma_async_client_register(struct dma_client *client); 273void dmaengine_get(void);
366void dma_async_client_unregister(struct dma_client *client); 274void dmaengine_put(void);
367void dma_async_client_chan_request(struct dma_client *client);
368dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan, 275dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan,
369 void *dest, void *src, size_t len); 276 void *dest, void *src, size_t len);
370dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan, 277dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan,
@@ -406,6 +313,12 @@ __dma_cap_set(enum dma_transaction_type tx_type, dma_cap_mask_t *dstp)
406 set_bit(tx_type, dstp->bits); 313 set_bit(tx_type, dstp->bits);
407} 314}
408 315
316#define dma_cap_zero(mask) __dma_cap_zero(&(mask))
317static inline void __dma_cap_zero(dma_cap_mask_t *dstp)
318{
319 bitmap_zero(dstp->bits, DMA_TX_TYPE_END);
320}
321
409#define dma_has_cap(tx, mask) __dma_has_cap((tx), &(mask)) 322#define dma_has_cap(tx, mask) __dma_has_cap((tx), &(mask))
410static inline int 323static inline int
411__dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp) 324__dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp)
@@ -475,11 +388,25 @@ static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie,
475} 388}
476 389
477enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); 390enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie);
391#ifdef CONFIG_DMA_ENGINE
392enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
393#else
394static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
395{
396 return DMA_SUCCESS;
397}
398#endif
478 399
479/* --- DMA device --- */ 400/* --- DMA device --- */
480 401
481int dma_async_device_register(struct dma_device *device); 402int dma_async_device_register(struct dma_device *device);
482void dma_async_device_unregister(struct dma_device *device); 403void dma_async_device_unregister(struct dma_device *device);
404void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
405struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
406void dma_issue_pending_all(void);
407#define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
408struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
409void dma_release_channel(struct dma_chan *chan);
483 410
484/* --- Helper iov-locking functions --- */ 411/* --- Helper iov-locking functions --- */
485 412
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index 04d217b442bf..d797dde247f7 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -22,14 +22,34 @@ struct dw_dma_platform_data {
22}; 22};
23 23
24/** 24/**
25 * enum dw_dma_slave_width - DMA slave register access width.
26 * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
27 * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
28 * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
29 */
30enum dw_dma_slave_width {
31 DW_DMA_SLAVE_WIDTH_8BIT,
32 DW_DMA_SLAVE_WIDTH_16BIT,
33 DW_DMA_SLAVE_WIDTH_32BIT,
34};
35
36/**
25 * struct dw_dma_slave - Controller-specific information about a slave 37 * struct dw_dma_slave - Controller-specific information about a slave
26 * @slave: Generic information about the slave 38 *
27 * @ctl_lo: Platform-specific initializer for the CTL_LO register 39 * @dma_dev: required DMA master device
40 * @tx_reg: physical address of data register used for
41 * memory-to-peripheral transfers
42 * @rx_reg: physical address of data register used for
43 * peripheral-to-memory transfers
44 * @reg_width: peripheral register width
28 * @cfg_hi: Platform-specific initializer for the CFG_HI register 45 * @cfg_hi: Platform-specific initializer for the CFG_HI register
29 * @cfg_lo: Platform-specific initializer for the CFG_LO register 46 * @cfg_lo: Platform-specific initializer for the CFG_LO register
30 */ 47 */
31struct dw_dma_slave { 48struct dw_dma_slave {
32 struct dma_slave slave; 49 struct device *dma_dev;
50 dma_addr_t tx_reg;
51 dma_addr_t rx_reg;
52 enum dw_dma_slave_width reg_width;
33 u32 cfg_hi; 53 u32 cfg_hi;
34 u32 cfg_lo; 54 u32 cfg_lo;
35}; 55};
@@ -54,9 +74,4 @@ struct dw_dma_slave {
54#define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */ 74#define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */
55#define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */ 75#define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */
56 76
57static inline struct dw_dma_slave *to_dw_dma_slave(struct dma_slave *slave)
58{
59 return container_of(slave, struct dw_dma_slave, slave);
60}
61
62#endif /* DW_DMAC_H */ 77#endif /* DW_DMAC_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 114091be8872..f24556813375 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1125,9 +1125,6 @@ struct softnet_data
1125 struct sk_buff *completion_queue; 1125 struct sk_buff *completion_queue;
1126 1126
1127 struct napi_struct backlog; 1127 struct napi_struct backlog;
1128#ifdef CONFIG_NET_DMA
1129 struct dma_chan *net_dma;
1130#endif
1131}; 1128};
1132 1129
1133DECLARE_PER_CPU(struct softnet_data,softnet_data); 1130DECLARE_PER_CPU(struct softnet_data,softnet_data);
diff --git a/include/net/netdma.h b/include/net/netdma.h
index f28c6e064e8f..8ba8ce284eeb 100644
--- a/include/net/netdma.h
+++ b/include/net/netdma.h
@@ -24,17 +24,6 @@
24#include <linux/dmaengine.h> 24#include <linux/dmaengine.h>
25#include <linux/skbuff.h> 25#include <linux/skbuff.h>
26 26
27static inline struct dma_chan *get_softnet_dma(void)
28{
29 struct dma_chan *chan;
30 rcu_read_lock();
31 chan = rcu_dereference(__get_cpu_var(softnet_data).net_dma);
32 if (chan)
33 dma_chan_get(chan);
34 rcu_read_unlock();
35 return chan;
36}
37
38int dma_skb_copy_datagram_iovec(struct dma_chan* chan, 27int dma_skb_copy_datagram_iovec(struct dma_chan* chan,
39 struct sk_buff *skb, int offset, struct iovec *to, 28 struct sk_buff *skb, int offset, struct iovec *to,
40 size_t len, struct dma_pinned_list *pinned_list); 29 size_t len, struct dma_pinned_list *pinned_list);