]> Zhao Yanbai Git Server - minix.git/commitdiff
New MEM driver for recovery.
authorJorrit Herder <jnherder@minix3.org>
Thu, 20 Oct 2005 20:26:02 +0000 (20:26 +0000)
committerJorrit Herder <jnherder@minix3.org>
Thu, 20 Oct 2005 20:26:02 +0000 (20:26 +0000)
drivers/at_wini/at_wini.c
drivers/libdriver/driver.c
drivers/memory/memory.c

index 552eb3c6c74f4739e0b4ebd2eddf32692d10e2d4..59421efb05d2f09a1e52b2afe2215c9d35982aaa 100644 (file)
@@ -6,7 +6,7 @@
  *   at_winchester_task:       main entry when system is brought up
  *
  * Changes:
- *   Aug 19, 2005   ata pci support, supports SATA  (Ben Gras)
+ *   Aug 19, 2005   ATA PCI support, supports SATA  (Ben Gras)
  *   Nov 18, 2004   moved AT disk driver to user-space  (Jorrit N. Herder)
  *   Aug 20, 2004   watchdogs replaced by sync alarms  (Jorrit N. Herder)
  *   Mar 23, 2000   added ATAPI CDROM support  (Michael Temari)
@@ -194,8 +194,8 @@ int w_next_drive = 0;
 
 /* Variables. */
 
-/* wini is indexed by controller first, then drive (0-3).
- * controller 0 is always the 'compatability' ide controller, at
+/* The struct wini is indexed by controller first, then drive (0-3).
+ * Controller 0 is always the 'compatability' ide controller, at
  * the fixed locations, whether present or not.
  */
 PRIVATE struct wini {          /* main drive struct, one entry per drive */
@@ -235,7 +235,8 @@ PRIVATE int w_controller;           /* selected controller */
 PRIVATE struct device *w_dv;           /* device's base and size */
 
 FORWARD _PROTOTYPE( void init_params, (void)                           );
-FORWARD _PROTOTYPE( void init_drive, (struct wini *, int, int, int, int, int, int));
+FORWARD _PROTOTYPE( void init_drive, (struct wini *, int, int, int, 
+                                       int, int, int));
 FORWARD _PROTOTYPE( void init_params_pci, (int)                        );
 FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr)         );
 FORWARD _PROTOTYPE( struct device *w_prepare, (int dev)                );
index 50a2fcf7d77747ff26606e8fc39d40c753523338..1eb91425d3ed62e2403c5036a396b7a0bd3dad86 100644 (file)
@@ -87,23 +87,22 @@ struct driver *dp;  /* Device dependent entry points. */
   while (TRUE) {
 
        /* Wait for a request to read or write a disk block. */
-       if(receive(ANY, &mess) != OK) continue;
+       if (receive(ANY, &mess) != OK) continue;
 
        device_caller = mess.m_source;
        proc_nr = mess.PROC_NR;
 
        /* Now carry out the work. */
        switch(mess.m_type) {
-       case DEV_OPEN:          r = (*dp->dr_open)(dp, &mess);  break;
+       case DEV_OPEN:          r = (*dp->dr_open)(dp, &mess);  break;  
        case DEV_CLOSE:         r = (*dp->dr_close)(dp, &mess); break;
        case DEV_IOCTL:         r = (*dp->dr_ioctl)(dp, &mess); break;
        case CANCEL:            r = (*dp->dr_cancel)(dp, &mess);break;
        case DEV_SELECT:        r = (*dp->dr_select)(dp, &mess);break;
-
        case DEV_READ:  
-       case DEV_WRITE:   r = do_rdwt(dp, &mess);       break;
+       case DEV_WRITE:         r = do_rdwt(dp, &mess); break;
        case DEV_GATHER: 
-       case DEV_SCATTER: r = do_vrdwt(dp, &mess);      break;
+       case DEV_SCATTER:       r = do_vrdwt(dp, &mess);        break;
 
        case HARD_INT:          /* leftover interrupt or expired timer. */
                                if(dp->dr_hw_int) {
@@ -138,6 +137,7 @@ struct driver *dp;  /* Device dependent entry points. */
   }
 }
 
+
 /*===========================================================================*
  *                             init_buffer                                  *
  *===========================================================================*/
index 280b8c9ce82bb500cc74268c9bb7af262aae8dad..5581d6cd3b9c4f68c44041ec1b8e178850452bf1 100644 (file)
@@ -205,12 +205,8 @@ PRIVATE int m_do_open(dp, m_ptr)
 struct driver *dp;
 message *m_ptr;
 {
-/* Check device number on open.  (This used to give I/O privileges to a 
- * process opening /dev/mem or /dev/kmem. This may be needed in case of 
- * memory mapped I/O. With system calls to do I/O this is no longer needed.)
- */
+/* Check device number on open. */
   if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
-
   return(OK);
 }
 
@@ -220,6 +216,9 @@ message *m_ptr;
 PRIVATE void m_init()
 {
   /* Initialize this task. All minor devices are initialized one by one. */
+  phys_bytes ramdev_size;
+  phys_bytes ramdev_base;
+  message m;
   int i, s;
 
   if (OK != (s=sys_getkinfo(&kinfo))) {
@@ -244,6 +243,22 @@ PRIVATE void m_init()
       }
   }
 
+  /* See if there are already RAM disk details at the Data Store server. */
+  m.DS_KEY = MEMORY_MAJOR;
+  if (OK == (s = _taskcall(DS_PROC_NR, DS_RETRIEVE, &m))) {
+       ramdev_size = m.DS_VAL_L1;
+       ramdev_base = m.DS_VAL_L2;
+       printf("MEM retrieved size %u and base %u from DS, status %d\n",
+               ramdev_size, ramdev_base, s);
+       if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, 
+               (vir_bytes *) &s, ramdev_base, ramdev_size))) {
+               panic("MEM","Couldn't install remote segment.",s);
+       }
+       m_geom[RAM_DEV].dv_base = cvul64(ramdev_base);
+       m_geom[RAM_DEV].dv_size = cvul64(ramdev_size);
+       printf("MEM stored retrieved details as new RAM disk\n");
+  }
+
   /* Initialize /dev/zero. Simply write zeros into the buffer. */
   for (i=0; i<ZERO_BUF_SIZE; i++) {
        dev_zero[i] = '\0';
@@ -283,19 +298,19 @@ message *m_ptr;                           /* pointer to control message */
  * - MIOCRAMSIZE: to set the size of the RAM disk.
  */
   struct device *dv;
-  if ((dv = m_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
 
   switch (m_ptr->REQUEST) {
     case MIOCRAMSIZE: {
        /* FS wants to create a new RAM disk with the given size. */
        phys_bytes ramdev_size;
        phys_bytes ramdev_base;
+       message m;
        int s;
 
-       if (m_ptr->PROC_NR != FS_PROC_NR) {
-           report("MEM", "warning, MIOCRAMSIZE called by", m_ptr->PROC_NR);
-           return(EPERM);
-       }
+       /* Only FS can create RAM disk, and only on RAM disk device. */
+       if (m_ptr->PROC_NR != FS_PROC_NR) return(EPERM);
+       if (m_ptr->DEVICE != RAM_DEV) return(EINVAL);
+        if ((dv = m_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
 
        /* Try to allocate a piece of memory for the RAM disk. */
        ramdev_size = m_ptr->POSITION;
@@ -303,13 +318,26 @@ message *m_ptr;                           /* pointer to control message */
             report("MEM", "warning, allocmem failed", errno);
             return(ENOMEM);
         }
-       dv->dv_base = cvul64(ramdev_base);
-       dv->dv_size = cvul64(ramdev_size);
 
-       if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s, 
-               ramdev_base, ramdev_size))) {
+       /* Store the values we got in the data store so we can retrieve
+        * them later on, in the unfortunate event of a crash.
+        */
+       m.DS_KEY = MEMORY_MAJOR;
+       m.DS_VAL_L1 = ramdev_size;
+       m.DS_VAL_L2 = ramdev_base;
+       if (OK != (s = _taskcall(DS_PROC_NR, DS_PUBLISH, &m))) {
+               panic("MEM","Couldn't store RAM disk details at DS.",s);
+       }
+       printf("MEM stored size %u and base %u at DS, status %d\n",
+           ramdev_size, ramdev_base, s);
+
+       if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, 
+               (vir_bytes *) &s, ramdev_base, ramdev_size))) {
                panic("MEM","Couldn't install remote segment.",s);
        }
+
+       dv->dv_base = cvul64(ramdev_base);
+       dv->dv_size = cvul64(ramdev_size);
        break;
     }
     case MIOCMAP:
@@ -329,7 +357,6 @@ message *m_ptr;                             /* pointer to control message */
                return r;
        r= sys_vm_map(m_ptr->PROC_NR, do_map,
                (phys_bytes)mapreq.base, mapreq.size, mapreq.offset);
-       printf("m_ioctl MIOC(UN)MAP: result %d\n", r);
        return r;
     }