1  #ifndef __DRM_GEM_H__
2  #define __DRM_GEM_H__
3  
4  /*
5   * GEM Graphics Execution Manager Driver Interfaces
6   *
7   * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
8   * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
9   * Copyright (c) 2009-2010, Code Aurora Forum.
10   * All rights reserved.
11   * Copyright © 2014 Intel Corporation
12   *   Daniel Vetter <daniel.vetter@ffwll.ch>
13   *
14   * Author: Rickard E. (Rik) Faith <faith@valinux.com>
15   * Author: Gareth Hughes <gareth@valinux.com>
16   *
17   * Permission is hereby granted, free of charge, to any person obtaining a
18   * copy of this software and associated documentation files (the "Software"),
19   * to deal in the Software without restriction, including without limitation
20   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21   * and/or sell copies of the Software, and to permit persons to whom the
22   * Software is furnished to do so, subject to the following conditions:
23   *
24   * The above copyright notice and this permission notice (including the next
25   * paragraph) shall be included in all copies or substantial portions of the
26   * Software.
27   *
28   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
31   * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
32   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
33   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
34   * OTHER DEALINGS IN THE SOFTWARE.
35   */
36  
37  #include <linux/kref.h>
38  #include <linux/dma-resv.h>
39  #include <linux/list.h>
40  #include <linux/mutex.h>
41  
42  #include <drm/drm_vma_manager.h>
43  
44  struct iosys_map;
45  struct drm_gem_object;
46  
47  /**
48   * enum drm_gem_object_status - bitmask of object state for fdinfo reporting
49   * @DRM_GEM_OBJECT_RESIDENT: object is resident in memory (ie. not unpinned)
50   * @DRM_GEM_OBJECT_PURGEABLE: object marked as purgeable by userspace
51   *
52   * Bitmask of status used for fdinfo memory stats, see &drm_gem_object_funcs.status
53   * and drm_show_fdinfo().  Note that an object can DRM_GEM_OBJECT_PURGEABLE if
54   * it still active or not resident, in which case drm_show_fdinfo() will not
55   * account for it as purgeable.  So drivers do not need to check if the buffer
56   * is idle and resident to return this bit.  (Ie. userspace can mark a buffer
57   * as purgeable even while it is still busy on the GPU.. it does not _actually_
58   * become puregeable until it becomes idle.  The status gem object func does
59   * not need to consider this.)
60   */
61  enum drm_gem_object_status {
62  	DRM_GEM_OBJECT_RESIDENT  = BIT(0),
63  	DRM_GEM_OBJECT_PURGEABLE = BIT(1),
64  };
65  
66  /**
67   * struct drm_gem_object_funcs - GEM object functions
68   */
69  struct drm_gem_object_funcs {
70  	/**
71  	 * @free:
72  	 *
73  	 * Deconstructor for drm_gem_objects.
74  	 *
75  	 * This callback is mandatory.
76  	 */
77  	void (*free)(struct drm_gem_object *obj);
78  
79  	/**
80  	 * @open:
81  	 *
82  	 * Called upon GEM handle creation.
83  	 *
84  	 * This callback is optional.
85  	 */
86  	int (*open)(struct drm_gem_object *obj, struct drm_file *file);
87  
88  	/**
89  	 * @close:
90  	 *
91  	 * Called upon GEM handle release.
92  	 *
93  	 * This callback is optional.
94  	 */
95  	void (*close)(struct drm_gem_object *obj, struct drm_file *file);
96  
97  	/**
98  	 * @print_info:
99  	 *
100  	 * If driver subclasses struct &drm_gem_object, it can implement this
101  	 * optional hook for printing additional driver specific info.
102  	 *
103  	 * drm_printf_indent() should be used in the callback passing it the
104  	 * indent argument.
105  	 *
106  	 * This callback is called from drm_gem_print_info().
107  	 *
108  	 * This callback is optional.
109  	 */
110  	void (*print_info)(struct drm_printer *p, unsigned int indent,
111  			   const struct drm_gem_object *obj);
112  
113  	/**
114  	 * @export:
115  	 *
116  	 * Export backing buffer as a &dma_buf.
117  	 * If this is not set drm_gem_prime_export() is used.
118  	 *
119  	 * This callback is optional.
120  	 */
121  	struct dma_buf *(*export)(struct drm_gem_object *obj, int flags);
122  
123  	/**
124  	 * @pin:
125  	 *
126  	 * Pin backing buffer in memory. Used by the drm_gem_map_attach() helper.
127  	 *
128  	 * This callback is optional.
129  	 */
130  	int (*pin)(struct drm_gem_object *obj);
131  
132  	/**
133  	 * @unpin:
134  	 *
135  	 * Unpin backing buffer. Used by the drm_gem_map_detach() helper.
136  	 *
137  	 * This callback is optional.
138  	 */
139  	void (*unpin)(struct drm_gem_object *obj);
140  
141  	/**
142  	 * @get_sg_table:
143  	 *
144  	 * Returns a Scatter-Gather table representation of the buffer.
145  	 * Used when exporting a buffer by the drm_gem_map_dma_buf() helper.
146  	 * Releasing is done by calling dma_unmap_sg_attrs() and sg_free_table()
147  	 * in drm_gem_unmap_buf(), therefore these helpers and this callback
148  	 * here cannot be used for sg tables pointing at driver private memory
149  	 * ranges.
150  	 *
151  	 * See also drm_prime_pages_to_sg().
152  	 */
153  	struct sg_table *(*get_sg_table)(struct drm_gem_object *obj);
154  
155  	/**
156  	 * @vmap:
157  	 *
158  	 * Returns a virtual address for the buffer. Used by the
159  	 * drm_gem_dmabuf_vmap() helper.
160  	 *
161  	 * This callback is optional.
162  	 */
163  	int (*vmap)(struct drm_gem_object *obj, struct iosys_map *map);
164  
165  	/**
166  	 * @vunmap:
167  	 *
168  	 * Releases the address previously returned by @vmap. Used by the
169  	 * drm_gem_dmabuf_vunmap() helper.
170  	 *
171  	 * This callback is optional.
172  	 */
173  	void (*vunmap)(struct drm_gem_object *obj, struct iosys_map *map);
174  
175  	/**
176  	 * @mmap:
177  	 *
178  	 * Handle mmap() of the gem object, setup vma accordingly.
179  	 *
180  	 * This callback is optional.
181  	 *
182  	 * The callback is used by both drm_gem_mmap_obj() and
183  	 * drm_gem_prime_mmap().  When @mmap is present @vm_ops is not
184  	 * used, the @mmap callback must set vma->vm_ops instead.
185  	 */
186  	int (*mmap)(struct drm_gem_object *obj, struct vm_area_struct *vma);
187  
188  	/**
189  	 * @evict:
190  	 *
191  	 * Evicts gem object out from memory. Used by the drm_gem_object_evict()
192  	 * helper. Returns 0 on success, -errno otherwise.
193  	 *
194  	 * This callback is optional.
195  	 */
196  	int (*evict)(struct drm_gem_object *obj);
197  
198  	/**
199  	 * @status:
200  	 *
201  	 * The optional status callback can return additional object state
202  	 * which determines which stats the object is counted against.  The
203  	 * callback is called under table_lock.  Racing against object status
204  	 * change is "harmless", and the callback can expect to not race
205  	 * against object destruction.
206  	 *
207  	 * Called by drm_show_memory_stats().
208  	 */
209  	enum drm_gem_object_status (*status)(struct drm_gem_object *obj);
210  
211  	/**
212  	 * @rss:
213  	 *
214  	 * Return resident size of the object in physical memory.
215  	 *
216  	 * Called by drm_show_memory_stats().
217  	 */
218  	size_t (*rss)(struct drm_gem_object *obj);
219  
220  	/**
221  	 * @vm_ops:
222  	 *
223  	 * Virtual memory operations used with mmap.
224  	 *
225  	 * This is optional but necessary for mmap support.
226  	 */
227  	const struct vm_operations_struct *vm_ops;
228  };
229  
230  /**
231   * struct drm_gem_lru - A simple LRU helper
232   *
233   * A helper for tracking GEM objects in a given state, to aid in
234   * driver's shrinker implementation.  Tracks the count of pages
235   * for lockless &shrinker.count_objects, and provides
236   * &drm_gem_lru_scan for driver's &shrinker.scan_objects
237   * implementation.
238   */
239  struct drm_gem_lru {
240  	/**
241  	 * @lock:
242  	 *
243  	 * Lock protecting movement of GEM objects between LRUs.  All
244  	 * LRUs that the object can move between should be protected
245  	 * by the same lock.
246  	 */
247  	struct mutex *lock;
248  
249  	/**
250  	 * @count:
251  	 *
252  	 * The total number of backing pages of the GEM objects in
253  	 * this LRU.
254  	 */
255  	long count;
256  
257  	/**
258  	 * @list:
259  	 *
260  	 * The LRU list.
261  	 */
262  	struct list_head list;
263  };
264  
265  /**
266   * struct drm_gem_object - GEM buffer object
267   *
268   * This structure defines the generic parts for GEM buffer objects, which are
269   * mostly around handling mmap and userspace handles.
270   *
271   * Buffer objects are often abbreviated to BO.
272   */
273  struct drm_gem_object {
274  	/**
275  	 * @refcount:
276  	 *
277  	 * Reference count of this object
278  	 *
279  	 * Please use drm_gem_object_get() to acquire and drm_gem_object_put_locked()
280  	 * or drm_gem_object_put() to release a reference to a GEM
281  	 * buffer object.
282  	 */
283  	struct kref refcount;
284  
285  	/**
286  	 * @handle_count:
287  	 *
288  	 * This is the GEM file_priv handle count of this object.
289  	 *
290  	 * Each handle also holds a reference. Note that when the handle_count
291  	 * drops to 0 any global names (e.g. the id in the flink namespace) will
292  	 * be cleared.
293  	 *
294  	 * Protected by &drm_device.object_name_lock.
295  	 */
296  	unsigned handle_count;
297  
298  	/**
299  	 * @dev: DRM dev this object belongs to.
300  	 */
301  	struct drm_device *dev;
302  
303  	/**
304  	 * @filp:
305  	 *
306  	 * SHMEM file node used as backing storage for swappable buffer objects.
307  	 * GEM also supports driver private objects with driver-specific backing
308  	 * storage (contiguous DMA memory, special reserved blocks). In this
309  	 * case @filp is NULL.
310  	 */
311  	struct file *filp;
312  
313  	/**
314  	 * @vma_node:
315  	 *
316  	 * Mapping info for this object to support mmap. Drivers are supposed to
317  	 * allocate the mmap offset using drm_gem_create_mmap_offset(). The
318  	 * offset itself can be retrieved using drm_vma_node_offset_addr().
319  	 *
320  	 * Memory mapping itself is handled by drm_gem_mmap(), which also checks
321  	 * that userspace is allowed to access the object.
322  	 */
323  	struct drm_vma_offset_node vma_node;
324  
325  	/**
326  	 * @size:
327  	 *
328  	 * Size of the object, in bytes.  Immutable over the object's
329  	 * lifetime.
330  	 */
331  	size_t size;
332  
333  	/**
334  	 * @name:
335  	 *
336  	 * Global name for this object, starts at 1. 0 means unnamed.
337  	 * Access is covered by &drm_device.object_name_lock. This is used by
338  	 * the GEM_FLINK and GEM_OPEN ioctls.
339  	 */
340  	int name;
341  
342  	/**
343  	 * @dma_buf:
344  	 *
345  	 * dma-buf associated with this GEM object.
346  	 *
347  	 * Pointer to the dma-buf associated with this gem object (either
348  	 * through importing or exporting). We break the resulting reference
349  	 * loop when the last gem handle for this object is released.
350  	 *
351  	 * Protected by &drm_device.object_name_lock.
352  	 */
353  	struct dma_buf *dma_buf;
354  
355  	/**
356  	 * @import_attach:
357  	 *
358  	 * dma-buf attachment backing this object.
359  	 *
360  	 * Any foreign dma_buf imported as a gem object has this set to the
361  	 * attachment point for the device. This is invariant over the lifetime
362  	 * of a gem object.
363  	 *
364  	 * The &drm_gem_object_funcs.free callback is responsible for
365  	 * cleaning up the dma_buf attachment and references acquired at import
366  	 * time.
367  	 *
368  	 * Note that the drm gem/prime core does not depend upon drivers setting
369  	 * this field any more. So for drivers where this doesn't make sense
370  	 * (e.g. virtual devices or a displaylink behind an usb bus) they can
371  	 * simply leave it as NULL.
372  	 */
373  	struct dma_buf_attachment *import_attach;
374  
375  	/**
376  	 * @resv:
377  	 *
378  	 * Pointer to reservation object associated with the this GEM object.
379  	 *
380  	 * Normally (@resv == &@_resv) except for imported GEM objects.
381  	 */
382  	struct dma_resv *resv;
383  
384  	/**
385  	 * @_resv:
386  	 *
387  	 * A reservation object for this GEM object.
388  	 *
389  	 * This is unused for imported GEM objects.
390  	 */
391  	struct dma_resv _resv;
392  
393  	/**
394  	 * @gpuva:
395  	 *
396  	 * Provides the list of GPU VAs attached to this GEM object.
397  	 *
398  	 * Drivers should lock list accesses with the GEMs &dma_resv lock
399  	 * (&drm_gem_object.resv) or a custom lock if one is provided.
400  	 */
401  	struct {
402  		struct list_head list;
403  
404  #ifdef CONFIG_LOCKDEP
405  		struct lockdep_map *lock_dep_map;
406  #endif
407  	} gpuva;
408  
409  	/**
410  	 * @funcs:
411  	 *
412  	 * Optional GEM object functions. If this is set, it will be used instead of the
413  	 * corresponding &drm_driver GEM callbacks.
414  	 *
415  	 * New drivers should use this.
416  	 *
417  	 */
418  	const struct drm_gem_object_funcs *funcs;
419  
420  	/**
421  	 * @lru_node:
422  	 *
423  	 * List node in a &drm_gem_lru.
424  	 */
425  	struct list_head lru_node;
426  
427  	/**
428  	 * @lru:
429  	 *
430  	 * The current LRU list that the GEM object is on.
431  	 */
432  	struct drm_gem_lru *lru;
433  };
434  
435  /**
436   * DRM_GEM_FOPS - Default drm GEM file operations
437   *
438   * This macro provides a shorthand for setting the GEM file ops in the
439   * &file_operations structure.  If all you need are the default ops, use
440   * DEFINE_DRM_GEM_FOPS instead.
441   */
442  #define DRM_GEM_FOPS \
443  	.open		= drm_open,\
444  	.release	= drm_release,\
445  	.unlocked_ioctl	= drm_ioctl,\
446  	.compat_ioctl	= drm_compat_ioctl,\
447  	.poll		= drm_poll,\
448  	.read		= drm_read,\
449  	.llseek		= noop_llseek,\
450  	.mmap		= drm_gem_mmap, \
451  	.fop_flags	= FOP_UNSIGNED_OFFSET
452  
453  /**
454   * DEFINE_DRM_GEM_FOPS() - macro to generate file operations for GEM drivers
455   * @name: name for the generated structure
456   *
457   * This macro autogenerates a suitable &struct file_operations for GEM based
458   * drivers, which can be assigned to &drm_driver.fops. Note that this structure
459   * cannot be shared between drivers, because it contains a reference to the
460   * current module using THIS_MODULE.
461   *
462   * Note that the declaration is already marked as static - if you need a
463   * non-static version of this you're probably doing it wrong and will break the
464   * THIS_MODULE reference by accident.
465   */
466  #define DEFINE_DRM_GEM_FOPS(name) \
467  	static const struct file_operations name = {\
468  		.owner		= THIS_MODULE,\
469  		DRM_GEM_FOPS,\
470  	}
471  
472  void drm_gem_object_release(struct drm_gem_object *obj);
473  void drm_gem_object_free(struct kref *kref);
474  int drm_gem_object_init(struct drm_device *dev,
475  			struct drm_gem_object *obj, size_t size);
476  void drm_gem_private_object_init(struct drm_device *dev,
477  				 struct drm_gem_object *obj, size_t size);
478  void drm_gem_private_object_fini(struct drm_gem_object *obj);
479  void drm_gem_vm_open(struct vm_area_struct *vma);
480  void drm_gem_vm_close(struct vm_area_struct *vma);
481  int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
482  		     struct vm_area_struct *vma);
483  int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
484  
485  /**
486   * drm_gem_object_get - acquire a GEM buffer object reference
487   * @obj: GEM buffer object
488   *
489   * This function acquires an additional reference to @obj. It is illegal to
490   * call this without already holding a reference. No locks required.
491   */
drm_gem_object_get(struct drm_gem_object * obj)492  static inline void drm_gem_object_get(struct drm_gem_object *obj)
493  {
494  	kref_get(&obj->refcount);
495  }
496  
497  __attribute__((nonnull))
498  static inline void
__drm_gem_object_put(struct drm_gem_object * obj)499  __drm_gem_object_put(struct drm_gem_object *obj)
500  {
501  	kref_put(&obj->refcount, drm_gem_object_free);
502  }
503  
504  /**
505   * drm_gem_object_put - drop a GEM buffer object reference
506   * @obj: GEM buffer object
507   *
508   * This releases a reference to @obj.
509   */
510  static inline void
drm_gem_object_put(struct drm_gem_object * obj)511  drm_gem_object_put(struct drm_gem_object *obj)
512  {
513  	if (obj)
514  		__drm_gem_object_put(obj);
515  }
516  
517  int drm_gem_handle_create(struct drm_file *file_priv,
518  			  struct drm_gem_object *obj,
519  			  u32 *handlep);
520  int drm_gem_handle_delete(struct drm_file *filp, u32 handle);
521  
522  
523  void drm_gem_free_mmap_offset(struct drm_gem_object *obj);
524  int drm_gem_create_mmap_offset(struct drm_gem_object *obj);
525  int drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size);
526  
527  struct page **drm_gem_get_pages(struct drm_gem_object *obj);
528  void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
529  		bool dirty, bool accessed);
530  
531  void drm_gem_lock(struct drm_gem_object *obj);
532  void drm_gem_unlock(struct drm_gem_object *obj);
533  
534  int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
535  void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
536  
537  int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
538  			   int count, struct drm_gem_object ***objs_out);
539  struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
540  long drm_gem_dma_resv_wait(struct drm_file *filep, u32 handle,
541  				    bool wait_all, unsigned long timeout);
542  int drm_gem_lock_reservations(struct drm_gem_object **objs, int count,
543  			      struct ww_acquire_ctx *acquire_ctx);
544  void drm_gem_unlock_reservations(struct drm_gem_object **objs, int count,
545  				 struct ww_acquire_ctx *acquire_ctx);
546  int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
547  			    u32 handle, u64 *offset);
548  
549  void drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock);
550  void drm_gem_lru_remove(struct drm_gem_object *obj);
551  void drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct drm_gem_object *obj);
552  void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj);
553  unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
554  			       unsigned int nr_to_scan,
555  			       unsigned long *remaining,
556  			       bool (*shrink)(struct drm_gem_object *obj));
557  
558  int drm_gem_evict(struct drm_gem_object *obj);
559  
560  /**
561   * drm_gem_object_is_shared_for_memory_stats - helper for shared memory stats
562   *
563   * This helper should only be used for fdinfo shared memory stats to determine
564   * if a GEM object is shared.
565   *
566   * @obj: obj in question
567   */
drm_gem_object_is_shared_for_memory_stats(struct drm_gem_object * obj)568  static inline bool drm_gem_object_is_shared_for_memory_stats(struct drm_gem_object *obj)
569  {
570  	return (obj->handle_count > 1) || obj->dma_buf;
571  }
572  
573  #ifdef CONFIG_LOCKDEP
574  /**
575   * drm_gem_gpuva_set_lock() - Set the lock protecting accesses to the gpuva list.
576   * @obj: the &drm_gem_object
577   * @lock: the lock used to protect the gpuva list. The locking primitive
578   * must contain a dep_map field.
579   *
580   * Call this if you're not proctecting access to the gpuva list with the
581   * dma-resv lock, but with a custom lock.
582   */
583  #define drm_gem_gpuva_set_lock(obj, lock) \
584  	if (!WARN((obj)->gpuva.lock_dep_map, \
585  		  "GEM GPUVA lock should be set only once.")) \
586  		(obj)->gpuva.lock_dep_map = &(lock)->dep_map
587  #define drm_gem_gpuva_assert_lock_held(obj) \
588  	lockdep_assert((obj)->gpuva.lock_dep_map ? \
589  		       lock_is_held((obj)->gpuva.lock_dep_map) : \
590  		       dma_resv_held((obj)->resv))
591  #else
592  #define drm_gem_gpuva_set_lock(obj, lock) do {} while (0)
593  #define drm_gem_gpuva_assert_lock_held(obj) do {} while (0)
594  #endif
595  
596  /**
597   * drm_gem_gpuva_init() - initialize the gpuva list of a GEM object
598   * @obj: the &drm_gem_object
599   *
600   * This initializes the &drm_gem_object's &drm_gpuvm_bo list.
601   *
602   * Calling this function is only necessary for drivers intending to support the
603   * &drm_driver_feature DRIVER_GEM_GPUVA.
604   *
605   * See also drm_gem_gpuva_set_lock().
606   */
drm_gem_gpuva_init(struct drm_gem_object * obj)607  static inline void drm_gem_gpuva_init(struct drm_gem_object *obj)
608  {
609  	INIT_LIST_HEAD(&obj->gpuva.list);
610  }
611  
612  /**
613   * drm_gem_for_each_gpuvm_bo() - iterator to walk over a list of &drm_gpuvm_bo
614   * @entry__: &drm_gpuvm_bo structure to assign to in each iteration step
615   * @obj__: the &drm_gem_object the &drm_gpuvm_bo to walk are associated with
616   *
617   * This iterator walks over all &drm_gpuvm_bo structures associated with the
618   * &drm_gem_object.
619   */
620  #define drm_gem_for_each_gpuvm_bo(entry__, obj__) \
621  	list_for_each_entry(entry__, &(obj__)->gpuva.list, list.entry.gem)
622  
623  /**
624   * drm_gem_for_each_gpuvm_bo_safe() - iterator to safely walk over a list of
625   * &drm_gpuvm_bo
626   * @entry__: &drm_gpuvm_bostructure to assign to in each iteration step
627   * @next__: &next &drm_gpuvm_bo to store the next step
628   * @obj__: the &drm_gem_object the &drm_gpuvm_bo to walk are associated with
629   *
630   * This iterator walks over all &drm_gpuvm_bo structures associated with the
631   * &drm_gem_object. It is implemented with list_for_each_entry_safe(), hence
632   * it is save against removal of elements.
633   */
634  #define drm_gem_for_each_gpuvm_bo_safe(entry__, next__, obj__) \
635  	list_for_each_entry_safe(entry__, next__, &(obj__)->gpuva.list, list.entry.gem)
636  
637  #endif /* __DRM_GEM_H__ */
638