extern int errno; /* error number for PM calls */
+PRIVATE int openct[NR_DEVS];
+
FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe));
FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
+FORWARD _PROTOTYPE( int m_do_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_init, (void) );
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr, int safe));
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
PRIVATE struct driver m_dtab = {
m_name, /* current device's name */
m_do_open, /* open or mount */
- do_nop, /* nothing on a close */
+ m_do_close, /* nothing on a close */
m_ioctl, /* specify ram disk geometry */
m_prepare, /* prepare for I/O on a given minor device */
m_transfer, /* do the I/O */
return r;
}
}
+
+ if(m_device < 0 || m_device >= NR_DEVS) {
+ panic("MEM","wrong m_device",m_device);
+ }
+
+ openct[m_device]++;
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * m_do_close *
+ *===========================================================================*/
+PRIVATE int m_do_close(dp, m_ptr)
+struct driver *dp;
+message *m_ptr;
+{
+ int r;
+
+ if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
+
+ if(m_device < 0 || m_device >= NR_DEVS) {
+ panic("MEM","wrong m_device",m_device);
+ }
+
+ if(openct[m_device] < 1) {
+ panic("MEM","closed too often",NO_NUM);
+ }
+ openct[m_device]--;
+
return(OK);
}
+
/*===========================================================================*
* m_init *
*===========================================================================*/
dev_zero[i] = '\0';
}
+ for(i = 0; i < NR_DEVS; i++)
+ openct[i] = 0;
+
/* Set up memory range for /dev/mem. */
m_geom[MEM_DEV].dv_base = cvul64(0);
m_geom[MEM_DEV].dv_size = cvul64(0xffffffff);
if(m_vaddrs[dev] && !cmp64(dv->dv_size, cvul64(ramdev_size))) {
return(OK);
}
+ /* openct is 1 for the ioctl(). */
+ if(openct[dev] != 1) {
+ printf("MEM: MIOCRAMSIZE: %d in use (count %d)\n",
+ dev, openct[dev]);
+ return(EBUSY);
+ }
if(m_vaddrs[dev]) {
- printf("MEM: MIOCRAMSIZE: %d already has a ramdisk\n", dev);
- return(EPERM);
+ u32_t size;
+ if(ex64hi(dv->dv_size)) {
+ panic("MEM","huge old ramdisk", NO_NUM);
+ }
+ size = ex64lo(dv->dv_size);
+ munmap((void *) m_vaddrs[dev], size);
+ m_vaddrs[dev] = (vir_bytes) NULL;
}
#if DEBUG