lkml.org 
[lkml]   [1997]   [Jan]   [28]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateTue, 28 Jan 1997 01:52:19 -0500 (EST)
FromIon Badulescu <>
SubjectRe: Small fixes for 2.1.23
Hi,

On Mon, 27 Jan 1997, Linus Torvalds wrote:

> The select->poll changes make the source compile, but do not actually do
> quite the right thing. The poll changes weren't only a matter of naming
> changes, but also changed semantics somewhat (I don't do naming changes
> just to change names usually: there is a reason why I didn't want
> unmodified code to compile - it needs to get subtly fixed first). 
> 
> Anyway, I should have made the changes clear in my announcement of 2.1.23,
> but I was too lazy. The changes in the poll behaviour can be broken down
> into four different sub-areas:

[snip]

Thanks, Linus, the explanation made it all clear - I had seen in the other
drivers that poll_wait was being called unconditionally, but I didn't know
why. The attached patch attempts to do the Right Thing with the sound
driver, I hope I got it all right. There is plenty of goto's in one of the
files, simply because they were there before, masked by returns, and I was
afraid I might lose some cases if I converted them to some more structured
code. 

Hannu will probably come up with his own version in a week or two, in the
meanwhile this patch should do it for the rest of us. :-)

The other changes are also here (floppy, softdog, binfmt_script and
/proc/swap).


Ionut

--
  It is better to keep your mouth shut and be thought a fool,
            than to open it and remove all doubt.

--- linux-2.1.23/fs/proc/array.c.old	Sun Jan 26 05:07:45 1997
+++ linux-2.1.23/fs/proc/array.c	Sun Jan 26 17:25:47 1997
@@ -1011,6 +1011,7 @@
 extern int get_md_status (char *);
 extern int get_rtc_status (char *);
 extern int get_locks_status (char *);
+extern int get_swaparea_info (char *);
 #ifdef __SMP_PROF__
 extern int get_smp_prof_list(char *);
 #endif
@@ -1088,6 +1089,9 @@
 
                 case PROC_MTAB:
                        return get_filesystem_info( page );
+
+                case PROC_SWAP:
+                       return get_swaparea_info(page);
 #ifdef CONFIG_RTC
 		case PROC_RTC:
 			return get_rtc_status(page);
--- linux-2.1.23/fs/proc/root.c.old	Sun Jan 26 05:07:45 1997
+++ linux-2.1.23/fs/proc/root.c	Sun Jan 26 17:27:59 1997
@@ -510,6 +510,10 @@
 	PROC_MTAB, 6, "mounts",
 	S_IFREG | S_IRUGO, 1, 0, 0,
 };
+static struct proc_dir_entry proc_root_swaps = {
+	PROC_MTAB, 5, "swaps",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+};
 static struct proc_dir_entry proc_root_profile = {
 	PROC_PROFILE, 7, "profile",
 	S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
@@ -572,6 +576,7 @@
 	proc_register(&proc_root, &proc_root_locks);
 
 	proc_register(&proc_root, &proc_root_mounts);
+	proc_register(&proc_root, &proc_root_swaps);
 
 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
 #ifdef CONFIG_SUN_OPENPROMFS
--- linux-2.1.23/fs/binfmt_script.c.old	Sun Jan 26 05:07:30 1997
+++ linux-2.1.23/fs/binfmt_script.c	Sun Jan 26 17:06:41 1997
@@ -76,7 +76,6 @@
 	/*
 	 * OK, now restart the process with the interpreter's inode.
 	 */
-	bprm->filename = interp;
 	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
 	if (retval)
 		return retval;
--- linux-2.1.23/mm/swapfile.c.old	Sun Jan 26 05:07:49 1997
+++ linux-2.1.23/mm/swapfile.c	Sun Jan 26 17:29:04 1997
@@ -18,6 +18,7 @@
 #include <linux/swap.h>
 #include <linux/fs.h>
 #include <linux/swapctl.h>
+#include <linux/malloc.h>
 #include <linux/blkdev.h> /* for blk_size */
 #include <linux/vmalloc.h>
 
@@ -393,6 +394,8 @@
 
 	nr_swap_pages -= p->pages;
 	iput(p->swap_file);
+	if (p->swap_filename)
+		kfree(p->swap_filename);
 	p->swap_file = NULL;
 	p->swap_device = 0;
 	vfree(p->swap_map);
@@ -406,6 +409,37 @@
 	return err;
 }
 
+int get_swaparea_info(char *buf)
+{
+	struct swap_info_struct *ptr = swap_info;
+	int i, j, len = 0, usedswap;
+
+	len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+	for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
+		if (ptr->flags & SWP_USED) {
+			if (ptr->swap_filename)
+				len += sprintf(buf + len, "%-31s ", ptr->swap_filename);
+			else
+				len += sprintf(buf + len, "(null)\t\t\t");
+			if (ptr->swap_file)
+				len += sprintf(buf + len, "file\t\t");
+			else
+				len += sprintf(buf + len, "partition\t");
+			usedswap = 0;
+			for (j = 0; j < ptr->max; ++j)
+				switch (ptr->swap_map[j]) {
+					case 128:
+					case 0:
+						continue;
+					default:
+						usedswap++;
+				}
+			len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), 
+				usedswap << (PAGE_SHIFT - 10), ptr->prio);
+		}
+	return len;
+}
+
 /*
  * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
  *
@@ -418,6 +452,7 @@
 	unsigned int type;
 	int i, j, prev;
 	int error = -EPERM;
+	char *tmp;
 	struct file filp;
 	static int least_priority = 0;
 
@@ -434,6 +469,7 @@
 	if (type >= nr_swapfiles)
 		nr_swapfiles = type+1;
 	p->flags = SWP_USED;
+	p->swap_filename = NULL;
 	p->swap_file = NULL;
 	p->swap_device = 0;
 	p->swap_map = NULL;
@@ -541,6 +577,12 @@
 		prev = i;
 	}
 	p->next = i;
+	if (!getname(specialfile, &tmp)) {
+		if ((p->swap_filename =
+		    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
+			strcpy(p->swap_filename, tmp);
+		putname(tmp);
+	}
 	if (prev < 0) {
 		swap_list.head = swap_list.next = p - swap_info;
 	} else {
--- linux-2.1.23/include/linux/swap.h.old	Sat Nov 23 05:29:04 1996
+++ linux-2.1.23/include/linux/swap.h	Sun Jan 26 17:25:47 1997
@@ -19,6 +19,7 @@
 struct swap_info_struct {
 	unsigned int flags;
 	kdev_t swap_device;
+	char *swap_filename;
 	struct inode * swap_file;
 	unsigned char * swap_map;
 	unsigned char * swap_lockmap;
--- linux-2.1.23/include/linux/proc_fs.h.old	Sun Jan 26 05:21:20 1997
+++ linux-2.1.23/include/linux/proc_fs.h	Sun Jan 26 17:25:47 1997
@@ -43,6 +43,7 @@
 	PROC_CMDLINE,
 	PROC_SYS,
 	PROC_MTAB,
+	PROC_SWAP,
 	PROC_MD,
 	PROC_RTC,
 	PROC_LOCKS,
--- linux-2.1.23/drivers/block/floppy.c.old	Sun Jan 26 05:07:10 1997
+++ linux-2.1.23/drivers/block/floppy.c	Sun Jan 26 18:56:58 1997
@@ -4128,7 +4128,6 @@
 extern char *get_options(char *str, int *ints);
 
 char *floppy=NULL;
-MODULE_PARM(floppy, "s");
 
 static void parse_floppy_cfg_string(char *cfg)
 {
--- linux-2.1.23/drivers/char/softdog.c.old	Thu Dec 12 09:51:09 1996
+++ linux-2.1.23/drivers/char/softdog.c	Sun Jan 26 17:37:29 1997
@@ -46,6 +46,7 @@
  
 struct timer_list watchdog_ticktock;
 static int timer_alive = 0;
+static int in_use = 0;
 
 
 /*
@@ -70,8 +71,9 @@
  
 static int softdog_open(struct inode *inode, struct file *file)
 {
-	if(timer_alive)
+	if(in_use)
 		return -EBUSY;
+	in_use = 1;
 	MOD_INC_USE_COUNT;
 	/*
 	 *	Activate timer
@@ -94,6 +96,7 @@
 	MOD_DEC_USE_COUNT;
 	timer_alive=0;
 #endif	
+	in_use = 0;
 }
 
 static void softdog_ping(void)
--- linux-2.1.23/drivers/sound/dmabuf.c.old	Sun Nov 24 09:32:06 1996
+++ linux-2.1.23/drivers/sound/dmabuf.c	Tue Jan 28 01:39:25 1997
@@ -11,7 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
-
+#include <linux/poll.h>
 
 #include "sound_config.h"
 
@@ -1834,109 +1834,70 @@
 {
 }
 
-int
-DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+DMAbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
+  unsigned int mask = 0;
   struct dma_buffparms *dmap;
   unsigned long   flags;
 
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (!(audio_devs[dev]->open_mode))
-	return 0;
-
-      dmap = audio_devs[dev]->dmap_in;
-
-      if (dmap->mapping_flags & DMA_MAP_MAPPED)
-	{
-	  if (dmap->qlen)
-	    return 1;
-
-	  save_flags (flags);
-	  cli ();
-
-	  in_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&in_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-
-      if (dmap->dma_mode != DMODE_INPUT)
-	{
-	  if (dmap->dma_mode == DMODE_NONE &&
-	      audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
-	      !dmap->qlen &&
-	      audio_devs[dev]->go)
-	    {
-	      unsigned long   flags;
-
-	      save_flags (flags);
-	      cli ();
-	      activate_recording (dev, dmap);
-	      restore_flags (flags);
-	    }
-	  return 0;
-	}
-
-      if (!dmap->qlen)
-	{
-	  save_flags (flags);
-	  cli ();
-
-	  in_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&in_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_OUT:
-      dmap = audio_devs[dev]->dmap_out;
-
-      if (dmap->mapping_flags & DMA_MAP_MAPPED)
-	{
-	  if (dmap->qlen)
-	    return 1;
+  save_flags (flags);
+  cli ();
 
-	  save_flags (flags);
-	  cli ();
+  in_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&in_sleeper[dev], wait);
+  out_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&out_sleeper[dev], wait);
 
-	  out_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&out_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-
-      if (dmap->dma_mode == DMODE_INPUT)
-	{
-	  return 0;
-	}
+  restore_flags (flags);
 
-      if (dmap->dma_mode == DMODE_NONE)
-	{
-	  return 1;
-	}
+/* sel_in */
+  dmap = audio_devs[dev]->dmap_in;
+  if (!(audio_devs[dev]->open_mode))
+    goto sel_out;
+  if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+    if (dmap->qlen)
+      mask |= POLLIN | POLLRDNORM;
+    goto sel_out;
+  }
+  if (dmap->dma_mode != DMODE_INPUT) {
+    if (dmap->dma_mode == DMODE_NONE &&
+	audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
+	!dmap->qlen &&
+	audio_devs[dev]->go) {
+      unsigned long   flags;
 
-      if (!space_in_queue (dev))
-	{
-	  save_flags (flags);
-	  cli ();
+      save_flags (flags);
+      cli ();
+      activate_recording (dev, dmap);
+      restore_flags (flags);
+    }
+    goto sel_out;
+  }
+  if (!dmap->qlen)
+    goto sel_out;
+  mask |= POLLIN | POLLRDNORM;
 
-	  out_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&out_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      return 1;
-      break;
+ sel_out:
+  dmap = audio_devs[dev]->dmap_out;
 
-    case SEL_EX:
-      return 0;
-    }
+  if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+    if (dmap->qlen)
+      mask |= POLLOUT | POLLWRNORM;
+    goto sel_ex;
+  }
+  if (dmap->dma_mode == DMODE_INPUT)
+    goto sel_ex;
+  if (dmap->dma_mode == DMODE_NONE) {
+    mask |= POLLOUT | POLLWRNORM;
+    goto sel_ex;
+  }
+  if (!space_in_queue (dev))
+    goto sel_ex;
+  mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+sel_ex:
+  return mask;
 }
 
 
--- linux-2.1.23/drivers/sound/sound_calls.h.old	Fri Nov 15 03:14:55 1996
+++ linux-2.1.23/drivers/sound/sound_calls.h	Tue Jan 28 01:37:43 1997
@@ -18,7 +18,7 @@
 void DMAbuf_reset_dma (int dev);
 void DMAbuf_inputintr(int dev);
 void DMAbuf_outputintr(int dev, int underflow_flag);
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int DMAbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 void DMAbuf_start_device(int dev);
 void DMAbuf_start_devices(unsigned int devmask);
 void DMAbuf_reset (int dev);
@@ -36,7 +36,7 @@
 	   unsigned int cmd, caddr_t arg);
 void audio_init_devices (void);
 
-int audio_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int audio_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *	System calls for the /dev/sequencer
@@ -56,7 +56,7 @@
 void seq_input_event(unsigned char *event, int len);
 void seq_copy_to_input (unsigned char *event, int len);
 
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int sequencer_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *	System calls for the /dev/midi
@@ -72,7 +72,7 @@
 void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
 void MIDIbuf_init(void);
 
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int MIDIbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *
--- linux-2.1.23/drivers/sound/audio.c.old	Sun Jan 26 19:13:45 1997
+++ linux-2.1.23/drivers/sound/audio.c	Tue Jan 28 01:39:00 1997
@@ -12,7 +12,7 @@
  * for more info.
  */
 #include <linux/config.h>
-
+#include <linux/poll.h>
 
 #include "sound_config.h"
 
@@ -542,44 +542,31 @@
    */
 }
 
-int
-audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+audio_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
   char           *dma_buf;
+  unsigned int	  mask = 0;
   int             buf_no, buf_ptr, buf_size;
 
   dev = dev >> 4;
 
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
-	{
-	  return 0;		/* Not recording */
-	}
-
-      return DMAbuf_select (dev, file, sel_type, wait);
-      break;
-
-    case SEL_OUT:
-      if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX))
-	{
-	  return 0;		/* Wrong direction */
-	}
-
-      if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
-	{
-	  return 1;		/* There is space in the current buffer */
-	}
-
-      return DMAbuf_select (dev, file, sel_type, wait);
-      break;
+  mask = DMAbuf_poll (dev, file, wait);
 
-    case SEL_EX:
-      return 0;
-    }
+/* sel_in */
+  if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
+    mask &= ~(POLLIN | POLLRDNORM); /* Wrong direction */
+
+/* sel_out */
+  if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX)) {
+    mask &= ~(POLLOUT | POLLWRNORM); /* Wrong direction */
+    goto sel_ex;
+  }
+  if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
+    mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+ sel_ex:
+  return mask;
 }
 
 
--- linux-2.1.23/drivers/sound/midibuf.c.old	Fri Nov 15 03:15:25 1996
+++ linux-2.1.23/drivers/sound/midibuf.c	Tue Jan 28 01:39:39 1997
@@ -11,6 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
+#include <linux/poll.h>
 
 
 #include "sound_config.h"
@@ -497,40 +498,21 @@
       }
 }
 
-int
-MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+MIDIbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
-  dev = dev >> 4;
-
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (!DATA_AVAIL (midi_in_buf[dev]))
-	{
-
-	  input_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&input_sleeper[dev], wait);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_OUT:
-      if (SPACE_AVAIL (midi_out_buf[dev]))
-	{
-
-	  midi_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&midi_sleeper[dev], wait);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_EX:
-      return 0;
-    }
+  unsigned int mask = 0;
 
-  return 0;
+  input_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&input_sleeper[dev], wait);
+  midi_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&midi_sleeper[dev], wait);
+
+  if (DATA_AVAIL (midi_in_buf[dev]))
+    mask |= POLLIN | POLLRDNORM;
+  if (!SPACE_AVAIL (midi_out_buf[dev]))
+    mask |= POLLOUT | POLLWRNORM;
+  return mask;
 }
 
 
--- linux-2.1.23/drivers/sound/sequencer.c.old	Fri Nov 15 03:15:37 1996
+++ linux-2.1.23/drivers/sound/sequencer.c	Tue Jan 28 01:39:49 1997
@@ -11,6 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
+#include <linux/poll.h>
 
 
 #define SEQUENCER_C
@@ -1768,50 +1769,28 @@
   return -EINVAL;
 }
 
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+sequencer_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
+  unsigned int	  mask = 0;
   unsigned long   flags;
 
-  dev = dev >> 4;
-
-  switch (sel_type)
-    {
-    case SEL_IN:
-      save_flags (flags);
-      cli ();
-      if (!iqlen)
-	{
-
-	  midi_sleep_flag.opts = WK_SLEEP;
-	  select_wait (&midi_sleeper, wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      restore_flags (flags);
-      return 1;
-      break;
+  save_flags (flags);
+  cli ();
 
-    case SEL_OUT:
-      save_flags (flags);
-      cli ();
-      if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
-	{
+  midi_sleep_flag.opts = WK_SLEEP;
+  poll_wait (&midi_sleeper, wait);
+  seq_sleep_flag.opts = WK_SLEEP;
+  poll_wait (&seq_sleeper, wait);
 
-	  seq_sleep_flag.opts = WK_SLEEP;
-	  select_wait (&seq_sleeper, wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      restore_flags (flags);
-      return 1;
-      break;
+  restore_flags (flags);
 
-    case SEL_EX:
-      return 0;
-    }
+  if (iqlen)
+    mask |= POLLIN | POLLRDNORM;
+  if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+    mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+  return mask;
 }
 
 
--- linux-2.1.23/drivers/sound/soundcard.c.old	Sun Jan 26 05:07:24 1997
+++ linux-2.1.23/drivers/sound/soundcard.c	Tue Jan 28 01:34:47 1997
@@ -192,29 +192,29 @@
   return err;
 }
 
-static int
-sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
+static unsigned int
+sound_poll (struct file *file, poll_table * wait)
 {
   int             dev;
 
-  dev = MINOR (inode->i_rdev);
+  dev = MINOR (file->f_inode->i_rdev);
 
   files[dev].flags = file->f_flags;
 
-  DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
+  DEB (printk ("sound_poll(dev=%d)\n", dev));
 
   switch (dev & 0x0f)
     {
 #ifdef CONFIG_SEQUENCER
     case SND_DEV_SEQ:
     case SND_DEV_SEQ2:
-      return sequencer_select (dev, &files[dev], sel_type, wait);
+      return sequencer_poll (dev, &files[dev], wait);
       break;
 #endif
 
 #ifdef CONFIG_MIDI
     case SND_DEV_MIDIN:
-      return MIDIbuf_select (dev, &files[dev], sel_type, wait);
+      return MIDIbuf_poll (dev, &files[dev], wait);
       break;
 #endif
 
@@ -222,7 +222,7 @@
     case SND_DEV_DSP:
     case SND_DEV_DSP16:
     case SND_DEV_AUDIO:
-      return audio_select (dev, &files[dev], sel_type, wait);
+      return audio_poll (dev, &files[dev], wait);
       break;
 #endif
 
@@ -327,7 +327,7 @@
   sound_read,
   sound_write,
   NULL,				/* sound_readdir */
-  sound_select,
+  sound_poll,
   sound_ioctl,
   sound_mmap,
   sound_open,


\
 
 \ /
  Last update: 2005-03-22 12:38    [from the cache]
©2003-2008