Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!wuarchive!rice!uupsi!cmcl2!lab!jai From: jai@lab.ultra.nyu.edu (Benchiao Jai) Newsgroups: comp.os.minix Subject: NYUMINIX:KERNEL\MSDISK.C Message-ID: <1991Feb24.071029.6759@cmcl2.nyu.edu> Date: 24 Feb 91 07:10:29 GMT Sender: notes@cmcl2.nyu.edu (Notes Person) Organization: New York University Ultracomputer Research Lab Lines: 246 Nntp-Posting-Host: lab.ultra.nyu.edu /* This file contains the driver for the logical disk /dev/msd* * which is physically an MS-DOS file MINIXDSK in the current directory * from where NYUMINIX was booted. It accepts three messages, for reading, * writing, and control. All use message format m2 and with these parameters: * * m_type DEVICE PROC_NR COUNT POSITION ADDRESS * ------------------------------------------------------------ * | DISK_READ | device | proc nr | bytes | offset | buf ptr | * |------------+--------+---------+-------+--------+---------| * | DISK_WRITE | device | proc nr | bytes | offset | buf ptr | * |------------+--------+---------+-------+--------+---------| * | DISK_IOCTL | device | | | | | * ------------------------------------------------------------ * * The file contains one entry point : * * winchester_task: main entry when system is brought up * */ #include "..\h\const.h" #include "..\h\type.h" #include "..\h\callnr.h" #include "..\h\com.h" #include "..\h\error.h" #include "const.h" #include "type.h" #include "proc.h" void __emit__(); void __int__(int intno); #define int21() __int__(0x21) #define MS_READ 0x3f #define MS_WRITE 0x40 #define M_RESET 0 #define M_READING 1 #define M_WRITING 2 #define M_ERROR 3 #define NR_MSDS 8 extern char get_byte(); extern void put_byte(); PRIVATE message mess; PRIVATE char *MSfilename[NR_MSDS] = {"MINIXDSK.0","MINIXDSK.1","MINIXDSK.2","MINIXDSK.3", "MINIXDSK.4","MINIXDSK.5","MINIXDSK.6","MINIXDSK.7"}; PRIVATE int f_handle[NR_MSDS] = {-1,-1,-1,-1,-1,-1,-1,-1}; PRIVATE long f_size[NR_MSDS]; PRIVATE char sp_filename[80] = ""; PRIVATE int sp_handle = -1; PRIVATE int sp_status = M_RESET; /*===========================================================================* * winchester_task * *===========================================================================*/ PUBLIC winchester_task() { /* Main program of the msdisk driver task. */ int r, caller, proc_nr; /* Open the physical file. */ for (r = 0; r < NR_MSDS; r++) do_reopen(r); /* Main loop. */ while (TRUE) { /* Receive the request. */ receive(ANY, &mess); caller = mess.m_source; proc_nr = mess.PROC_NR; if ( caller < 0 ) panic("msdisk task got message from ", caller); /* Carry out the work. */ switch (mess.m_type) { case DISK_READ: case DISK_WRITE: r = do_rdwt(&mess); break; case DISK_IOCTL:/*r= do_reopen(mess.DEVICE); break;*/ default: r = EINVAL; break; } /* Prepare and send the reply message. */ mess.m_type = TASK_REPLY; mess.REP_PROC_NR = proc_nr; mess.REP_STATUS = r; send(caller, &mess); } } /*===========================================================================* * do_rwdt * *===========================================================================*/ PRIVATE do_rdwt(m_ptr) message *m_ptr; { struct proc *rp; phys_bytes user_phys; int count, dssave, fn_num, device, seg, ofs, i; long offset; extern phys_bytes umap(); device = m_ptr->DEVICE; if (device < 0 || device >= NR_MSDS+2) return(ENXIO); /* bad minor device */ if ( device < NR_MSDS && f_handle[device] < 0 ) return(EIO); offset = m_ptr->POSITION; if ( offset < 0 ) return(ENXIO); count = m_ptr->COUNT; if ( device < NR_MSDS && offset + count > f_size[device] ) count = (int)(f_size[device] - offset); rp = proc_addr(m_ptr->PROC_NR); user_phys = umap(rp, D, (vir_bytes) m_ptr->ADDRESS, (vir_bytes) count); if ( user_phys == 0 ) return(E_BAD_ADDR); fn_num = (m_ptr->m_type == DISK_READ) ? MS_READ : MS_WRITE; dssave = _DS; if ( device < NR_MSDS ) { _BX = f_handle[device]; _CX = *((int *)(&offset)+1); _DX = (int)offset; _AX = 0x4200; int21(); /* Lseek from head. */ _BX = f_handle[device]; _DS = ((unsigned)user_phys >> 4) + (*((int *)(&user_phys)+1) << 12); _DX = (int)user_phys & 0xF; _CX = count; _AH = fn_num; int21(); /* Read or write. */ _DS = dssave; if ( fn_num == MS_WRITE ) do_reopen(device); return(count); } else if ( device == NR_MSDS ) { seg = (int)(user_phys >> 4); ofs = (int)user_phys & 0xF; if ( fn_num == MS_READ ) { if ( sp_status == M_RESET ) return(0); put_byte(seg, ofs, sp_status); if ( sp_status == M_ERROR ) sp_status = M_RESET; return(1); } else { if (count > 79) count = 79; for ( i=0; i= 0 ) return(count); } sp_status = M_ERROR; return(EIO); case M_READING: case M_WRITING: if ( sp_filename[0] == 'C' ) { _BX = sp_handle; _AH = 0x3e; int21(); /* Close file. */ sp_status = M_RESET; return(count); } default: return(EIO); } } } else { if ( sp_status != (fn_num==MS_READ ? M_READING : M_WRITING) ) return(EIO); _BX = sp_handle; _DS = ((unsigned)user_phys >> 4) + (*((int *)(&user_phys)+1) << 12); _DX = ((int)user_phys & 0xF); _CX = count; _AH = fn_num; int21(); /* Read or write. */ count = _AX; _DS = dssave; return(count); } } /*===========================================================================* * do_reopen * *===========================================================================*/ PRIVATE do_reopen(device) int device; { int i,j; if ( f_handle[device] >= 0 ) { _BX = f_handle[device]; _AH = 0x3e; int21(); /* Close file. */ } _DX = (int)(MSfilename[device]); _AX = 0x3d02; int21(); /* Open file for read/write. */ __emit__(0x19,0xd2); /* sbb dx,dx */ __emit__(0x09,0xd0); /* or ax,dx */ i = _AX; f_handle[device] = i; if ( i < 0 ) return(EIO); else { _BX = i; _CX = 0; _DX = 0; _AX = 0x4202; int21(); /* Lseek from end. */ i = _AX; j = _DX; *((int *)(&f_size[device])) = i; *((int *)(&f_size[device])+1) = j; } return(OK); } Brought to you by Super Global Mega Corp .com