static union overhead * find_overhead(void * cp) { union overhead *op; if (!cheri_gettag(cp)) return (NULL); op = __rederive_pointer(cp); if (op == NULL) { kernel_printf("%s: no region found for %#p\n", __func__, cp); return (NULL); } op--; if (op->ov_magic == MAGIC) return (op); /* * XXX: the above will fail if the users calls free or realloc * with a pointer that has had CSetBounds applied to it. We * should save all allocation ranges to allow us to find the * metadata. */ kernel_printf( "%s: Attempting to free or realloc unallocated memory\n", __func__); CHERI_PRINT_PTR(cp); return (NULL); }
static int CheckDMAAreaGuards(DMA_Area *mem) { ULONG *guard,*topguard; if(!mem->pMemory) return 0; guard = (ULONG*)mem->pMemory; if((guard[0] != botguard0) || (guard[1] != botguard1)) { kernel_printf("CheckDMAAreaGuards: bad guard before data mem = %p pMemory = %p guard[0] = %lu guard[1] = %lu\n",mem,mem->pMemory,guard[0],guard[1]); return -1; } else { topguard = (ULONG *)(mem->pData+mem->ulDataSize); if((topguard[0] != topguard0) || (topguard[1] != topguard1)) { kernel_printf("CheckDMAAreaGuards: bad guard after data mem = %p pMemory = %p guard[0] = %lu guard[1] = %lu\n",mem,mem->pMemory,topguard[0],topguard[1]); return -1; } } return 0; }
static void *AllocateMemory(ULONG size) { char *mem = (char*)malloc(size+(sizeof(ULONG)*4)); ULONG *guard = (ULONG *)mem; if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: AllocateMemory called from interrupt context\n"); system_stop(); } if(mem == 0) { kernel_printf("AllocateMemory: unable to malloc %lu bytes\n",size); return 0; } guard[0] = size; guard[1] = 0x87654321; guard = (ULONG *)(mem+size+(sizeof(ULONG)*2)); guard[0] = 0x89abcdef; guard[1] = 0xfedcba98; return mem+(sizeof(ULONG)*2); }
/* * struct fs32_flushbuf_parms { * unsigned short flag; * unsigned short hVPB; * }; */ int FS32ENTRY fs32_flushbuf(struct fs32_flushbuf_parms *parms) { int rc; struct super_block *sb; if (trace_FS_FLUSHBUF) { kernel_printf("FS_FLUSHBUF - flag = %d, hVPB = 0x%0X", (int)(parms->flag), (int)(parms->hVPB)); } if (Read_Write) { sb = getvolume(parms->hVPB); if ((sb) && (sb->s_magic_internal == SUPER_MAGIC)) { if (sb->s_status == VOL_STATUS_MOUNTED) { kernel_printf("\tmedia is present"); switch (parms->flag) { case FLUSH_RETAIN: case FLUSH_DISCARD: sync_buffers(sb->s_dev, 1); if ((sb->s_op) && (sb->s_op->write_super)) sb->s_op->write_super(sb); sync_inodes(sb->s_dev); sync_buffers(sb->s_dev, 1); rc = NO_ERROR; break; default: rc = ERROR_INVALID_PARAMETER; break; } } else { rc = NO_ERROR; } } else { rc = ERROR_INVALID_PARAMETER; } } else { rc = NO_ERROR; } if (trace_FS_FLUSHBUF) { kernel_printf("FS_FLUSHBUF - flag = %d, hVPB = 0x%0X, rc = %d", (int)(parms->flag), (int)(parms->hVPB), rc); } return rc; }
int pci_init( void ) { struct PCI_DEVICEINFO * dev; // initially we probe the first bus pci_probeBus( 0 ); // search through the linked list of pci devices for( dev=pci_deviceHead ; dev!=NULL ; dev=dev->prev ) kernel_printf( "[PCI] %s %s (%s)\n", dev->vendor_name, dev->device_name, dev->class_name ); // return success return SUCCESS; }
static void FreeMemory(void *mem) { ULONG *guard; ULONG *topguard; ULONG size; if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: FreeMemory called from interrupt context\n"); system_stop(); } if(mem == 0) return; guard = (ULONG *)((char*)mem - (sizeof(ULONG)*2)); size = guard[0]; if(guard[1] != botguard1) { kernel_printf("FreeMemory: bad guard before data mem = %p guard[0] = %lu guard[1] = %lu\n",mem,size,guard[1]); kernel_printf("FreeMemory: **************** freeing anyway ******************\n"); } else { topguard = (ULONG *)((char*)mem+size); if((topguard[0] != topguard0) || (topguard[1] != topguard1)) { kernel_printf("FreeMemory: bad guard after data mem = %p topguard[0] = %lu topguard[1] = %lu\n",mem,topguard[0],topguard[1]); kernel_printf("FreeMemory: **************** freeing anyway ******************\n"); } } guard[0] = guardfreed; guard[1] = guardfreed; free(guard); return; }
static void MemcpyToDMAArea(DMA_Area *mem, ULONG offset, const void* pSrc, unsigned long count) { if((offset+count) > mem->ulDataSize) { kernel_printf("MemcpyToDMAArea: access out of range, size = %lu offset = %lu count = %lu\n",mem->ulDataSize,offset,count); } memcpy(mem->pData+offset,pSrc,count); cache_purge_data(mem->pData+offset,count); CheckDMAAreaGuards(mem); }
static void ReleaseFirmware(const STMFirmware *fw) { if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: ReleaseFirmware called from interrupt context\n"); system_stop(); } free(fw->pData); free((void*)fw); return; }
static void FreeDMAArea(DMA_Area *mem) { ULONG *guard; if(!mem->pMemory) return; if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: FreeDMAArea called from interrupt context\n"); system_stop(); } if(CheckDMAAreaGuards(mem)<0) kernel_printf("FreeDMAArea: ******************* freeing corrupted memory ***************\n"); guard = (ULONG*)mem->pMemory; guard[0] = guardfreed; guard[1] = guardfreed; free(mem->pMemory); memset(mem, 0, sizeof(DMA_Area)); }
static void AllocateDMAArea(DMA_Area *mem, ULONG size, ULONG align, STM_DMA_AREA_ALLOC_FLAGS flags) { ULONG *guard; void *physptr; if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: AllocateDMAArea called from interrupt context\n"); system_stop(); } memset(mem, 0, sizeof(DMA_Area)); if(align<8) align = 8; /* Allow room for top and bottom memory guards */ if(!(flags & (SDAAF_VIDEO_MEMORY|SDAAF_UNCACHED))) { mem->ulAllocatedSize = size+(align*2); mem->ulDataSize = size; mem->pMemory = malloc(mem->ulAllocatedSize); } if(mem->pMemory == 0) { memset(mem, 0, sizeof(DMA_Area)); return; } /* Align the data area in the standard fashion */ mem->pData = (char*)(((ULONG)mem->pMemory + (align-1)) & ~(align-1)); /* Now move it up to allow room for the bottom memory guard */ mem->pData += align; vmem_virt_to_phys(mem->pData,&physptr); mem->ulPhysical = (ULONG)physptr; guard = (ULONG*)mem->pMemory; /* Note: NOT pData!!! */ guard[0] = botguard0; guard[1] = botguard1; guard = (ULONG*)(mem->pData+mem->ulDataSize); guard[0] = topguard0; guard[1] = topguard1; cache_purge_data(mem->pMemory, mem->ulAllocatedSize); }
/* * struct fs32_close_parms { * PTR16 psffsd; * PTR16 psffsi; * unsigned short IOflag; * unsigned short type; * }; */ int FS32ENTRY fs32_close(struct fs32_close_parms *parms) { struct sffsi32 *psffsi; union sffsd32 *psffsd; int rc; psffsi = VDHQueryLin(parms->psffsi); psffsd = VDHQueryLin(parms->psffsd); // // Gets the file structure from psffsd // if (psffsd->f == 0) { ext2_os2_panic(1, "FS_CLOSE - file is NULL"); } if (trace_FS_CLOSE) { kernel_printf("FS_CLOSE(ino = %lu, type = %d)", psffsd->f->f_inode->i_ino, parms->type); } // // The doc isn't clear about the role of the 'type' parameter. It seems we must // only free the resources (file structure in sffsd) at FS_CL_FORSYS time. Otherwise // we'' receive an empty sffsd somewhere else ! // For other 'type' values, maybe we could do a flush ... // if (parms->type != FS_CL_FORSYS) { #ifdef FS_TRACE kernel_printf("***** Non final system close **** - sffsi->sfi_type = %d - Type = %d", psffsi->sfi_type, type); #endif return NO_ERROR; } /* endif */ // // Final close for the system // if ((parms->type == FS_CL_FORSYS) && (Read_Write) && (psffsd->f->f_inode->i_ino != INODE_DASD)) { if (psffsd->f->f_op) { if (psffsd->f->f_op->release) { psffsd->f->f_op->release(psffsd->f->f_inode, psffsd->f); } else { ext2_os2_panic(1, "FS_CLOSE - psffsd->f->f_op->release == NULL : shouldn't occur in this release"); } } else { ext2_os2_panic(1, "FS_CLOSE - psffsd->f->f_op == NULL : shouldn't occur in this release"); } } // // Closes the file // if ((rc = vfs_close(psffsd->f)) != NO_ERROR) { fs_err(FUNC_FS_CLOSE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__); return rc; } #if 0 // // Clean up of sffsd (safety purposes ...) // memset(psffsd, 0, sizeof(union sffsd32)); #endif rc = NO_ERROR; return rc; }
int ino_to_fileinfo( struct inode *pino, char *databuf, UINT32 maxlen, PUINT32 plen, unsigned short level, unsigned short flags, unsigned short attrs, struct dirent *pDir, INT32 position, int TypeOp) { pCommonFileInfo pCommon; pFileName pFile; PINT32 pPosition; *plen = 0; /***************************************************************************/ /*** First field : long position if FF_GETPOS - nothing if FF_NOPOS ***/ /***************************************************************************/ if (TypeOp == TYPEOP_FILEFIND) { if (flags == FF_GETPOS) { if (sizeof(INT32) + *plen > maxlen) { fs_log("ino_to_fileinfo() - Buffer overflow for first field"); return ERROR_BUFFER_OVERFLOW; } pPosition = (PINT32) (databuf + *plen); *pPosition = position; *plen += sizeof(INT32); } } /***************************************************************************/ /***************************************************************************/ /*** Second field : common file information to all level/flags ***/ /***************************************************************************/ if (sizeof(CommonFileInfo) + *plen > maxlen) { kernel_printf("ino_to_fileinfo() - Buffer overflow for second field - len = %lu - maxlen = %lu", (UINT32) sizeof(CommonFileInfo) + (UINT32) (*plen), (UINT32) maxlen); return ERROR_BUFFER_OVERFLOW; } pCommon = (pCommonFileInfo) (databuf + *plen); date_unix2dos(pino->i_ctime, &(pCommon->timeCreate), &(pCommon->dateCreate)); date_unix2dos(pino->i_atime, &(pCommon->timeAccess), &(pCommon->dateAccess)); date_unix2dos(pino->i_mtime, &(pCommon->timeWrite), &(pCommon->dateWrite)); pCommon->cbEOF = pino->i_size; pCommon->cbAlloc = pino->i_blocks; pCommon->attr = FILE_NORMAL; if ((S_ISLNK(pino->i_mode)) || (S_ISBLK(pino->i_mode)) || (S_ISCHR(pino->i_mode)) || (S_ISFIFO(pino->i_mode)) || (S_ISSOCK(pino->i_mode))) { pCommon->attr |= FILE_SYSTEM; /*** UNIXish special files are seen as SYSTEM files ***/ } /* endif */ if (S_ISDIR(pino->i_mode)) { pCommon->attr |= FILE_DIRECTORY; } /* endif */ if ((!(pino->i_mode & S_IWUSR)) && (!(pino->i_mode & S_IWGRP)) && (!(pino->i_mode & S_IWOTH))) { pCommon->attr |= FILE_READONLY; } *plen += sizeof(CommonFileInfo); /***************************************************************************/ /***************************************************************************/ /*** Third field : nothing for level FIL_STANDARD ***/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /*** Third field : Size on disk of EA set for FIL_QUERYEASIZE ***/ /***************************************************************************/ if (level == FIL_QUERYEASIZE) { if (sizeof(INT32) + *plen > maxlen) { fs_log("ino_to_fileinfo() - Buffer overflow for Third field - FIL_QUERYEASIZE"); return ERROR_BUFFER_OVERFLOW; } *((PINT32) (databuf + *plen)) = 0; /*** No EAS in ext2 ***/ *plen += sizeof(INT32); } /***************************************************************************/ /***************************************************************************/ /*** Third field : FEAList for level QUERYEASFROMLIST ***/ /***************************************************************************/ if (level == FIL_QUERYEASFROMLIST) { if (sizeof(INT32) + *plen > maxlen) { fs_log("ino_to_fileinfo() - Buffer overflow for Third field - FIL_QUERYEASFROMLIST"); return ERROR_BUFFER_OVERFLOW; } *((PINT32) (databuf + *plen)) = 4; /*** No EAS in ext2 ***//* this is the length field of FEAList */ *plen += sizeof(INT32); } /***************************************************************************/ /***************************************************************************/ /*** Fourth field : name ***/ /***************************************************************************/ if (TypeOp == TYPEOP_FILEFIND) { if (*plen + sizeof(FileName) + pDir->d_reclen > maxlen) { fs_log("ino_to_fileinfo() - Buffer overflow for fourth field"); return ERROR_BUFFER_OVERFLOW; } pFile = (pFileName) (databuf + *plen); pFile->cbName = (unsigned char)pDir->d_reclen; /* name length WITHOUT '\0' */ strcpy(pFile->szName, pDir->d_name); /* name WITH '\0' */ *plen += sizeof(FileName) + pDir->d_reclen; /* sizeof(FileName) + strlen(Dir.d_name) */ } /***************************************************************************/ return NO_ERROR; }
int myfindnext( struct super_block *p_volume, struct file *p_file, unsigned short attr, struct fsfsi32 *pfsfsi, struct fsfsd32 *pfsfsd, char *pData, unsigned short cbData, unsigned short *pcMatch, unsigned short level, unsigned short flags, UINT32 index_dir, int is_findfirst, int caseRetensive ) { char *left; char *right; UINT32 cur_size; int rc; char *pName; UINT32 len; struct inode *ino; UINT16 nb_found; struct dirent Dir; int fn_flag; pName = ((p_hfind) pfsfsd)->pName; nb_found = 0; if (level == FIL_QUERYEASFROMLIST) { cur_size = sizeof(EAOP); } else { cur_size = 0; } while (nb_found < *pcMatch) { /***********************************************************/ /*** If we are at the end of the parent dir : stop ***/ /***********************************************************/ if (VFS_readdir(p_file, __StackToFlat(&Dir)) != NO_ERROR) { ((p_hfind) pfsfsd)->last = index_dir; *pcMatch = nb_found; if (nb_found > 0) { #ifdef FS_TRACE kernel_printf("myfindnext() - EOD - found %d entries", nb_found); #endif return NO_ERROR; } else { #if 1 if (is_findfirst) { /************************************************************************/ /*** Lib‚ration du buffer stockant les noms de recherche ***/ /************************************************************************/ if ((rc = DevHlp32_VMFree(((p_hfind) pfsfsd)->pName)) != NO_ERROR) { fs_err(FUNC_FS_FINDFIRST, FUNC_G_free, rc, THISFILE, __LINE__); return rc; } /* end if */ /************************************************************************/ if ((rc = vfs_close(p_file)) != NO_ERROR) { fs_err(FUNC_FS_FINDFIRST, FUNC_CLOSE, rc, THISFILE, __LINE__); return rc; } // ((p_hfind)pfsfsd)->FS_CLOSEd = SEARCH_ALREADY_CLOSED; } #else FS_FINDCLOSE(pfsfsi, pfsfsd); ((p_hfind) pfsfsd)->FS_CLOSEd = SEARCH_ALREADY_CLOSED; #endif return ERROR_NO_MORE_FILES; } } /* end if */ /***********************************************************/ /***********************************************************/ /*** If we found an entry, see if it matches ***/ /***********************************************************/ if (caseRetensive) { fn_flag = _FNM_OS2 | _FNM_IGNORECASE; } else { fn_flag = _FNM_OS2; } if (fnmatch(pName, __StackToFlat(Dir.d_name), fn_flag) == 0) { if (p_file->f_inode->i_ino != Dir.d_ino) { if ((ino = iget(p_volume, Dir.d_ino)) == NULL) { fs_err(FUNC_FS_FINDFIRST, FUNC_GET_VINODE, rc, THISFILE, __LINE__); return ERROR_NO_MORE_FILES; } /* endif */ } else { ino = p_file->f_inode; } if (filter_with_attrs(ino, attr | FILE_READONLY, __StackToFlat(Dir.d_name))) { if ((rc = ino_to_fileinfo( ino, pData + cur_size, cbData - cur_size, __StackToFlat(&len), level, flags, attr, __StackToFlat(&Dir), index_dir, TYPEOP_FILEFIND)) != NO_ERROR) { *pcMatch = nb_found; ((p_hfind) pfsfsd)->last = index_dir; fs_log("====> FS_FINDFIRST : erreur ino_to_fileinfo()"); if (p_file->f_inode->i_ino != Dir.d_ino) { iput(ino); } return rc; } nb_found++; cur_size += len; } if (p_file->f_inode->i_ino != Dir.d_ino) { iput(ino); } } /* end if */ /***********************************************************/ index_dir++; } /* end while */ *pcMatch = nb_found; ((p_hfind) pfsfsd)->last = index_dir; #ifdef FS_TRACE kernel_printf("myfindnext() - found %d entries", nb_found); #endif return NO_ERROR; }
/* * This routine reads the superblock and tests if it can be an ext2 file system. * It does NOT use buffers from the cache. */ int check_ext2fs_magic(struct vpfsi32 *pvpfsi, unsigned short hVPB) { int nb_sec; int rc; int rc2; char *buf; struct ext2_super_block *es; // // Allocates a temporary buffer // if ((rc = DevHlp32_VMAlloc(BLOCK_SIZE, VMDHA_NOPHYSADDR, VMDHA_FIXED | VMDHA_CONTIG, __StackToFlat(&buf))) == NO_ERROR) { // // Reads disk block 1 (with blocksize = 1024) // nb_sec = BLOCK_SIZE / pvpfsi->vpi_bsize; if ((rc = fsh32_dovolio( DVIO_OPREAD | DVIO_OPRESMEM | DVIO_OPBYPASS | DVIO_OPNCACHE, DVIO_ALLABORT | DVIO_ALLRETRY | DVIO_ALLFAIL, hVPB, buf, __StackToFlat(&nb_sec), nb_sec )) == NO_ERROR) { es = (struct ext2_super_block *)buf; if (es->s_magic == EXT2_SUPER_MAGIC) { kernel_printf("ext2 signature found in superblock (hVPB = 0x%04X)", hVPB); /* * The volume serial number is a 32 bits CRC checksum of the UUID field */ pvpfsi->vpi_vid = updcrc(es->s_uuid, sizeof(es->s_uuid)); /* * The volume name is truncated to the valid OS/2 volume label length (11 chars) */ strncpy(pvpfsi->vpi_text, es->s_volume_name, sizeof(pvpfsi->vpi_text)); pvpfsi->vpi_text[sizeof(pvpfsi->vpi_text) - 1] = '\0'; rc = NO_ERROR; } else { kernel_printf("ext2 signature NOT found in superblock (hVPB = 0x%04X)", hVPB); rc = ERROR_VOLUME_NOT_MOUNTED; } } else { kernel_printf("check_ext2fs_magic - fsh32_dovolio returned %d", rc); } if ((rc2 = DevHlp32_VMFree((void *)buf)) == NO_ERROR) { /* * Nothing else */ } else { kernel_printf("check_ext2fs_magic - VMFree returned %d", rc); rc = rc2; } } else { kernel_printf("check_ext2fs_magic - VMAlloc returned %d", rc); } return rc; }
static void ext2_setup_super (struct super_block * sb, struct ext2_super_block * es) { #ifdef OS2 if (Errors_Panic) { clear_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_CONT); clear_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_RO); set_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_PANIC); } else { clear_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_PANIC); clear_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_RO); set_opt(sb->u.ext2_sb.s_mount_opt, ERRORS_CONT); } #endif if (es->s_rev_level > EXT2_CURRENT_REV) { printk ("EXT2-fs warning: revision level too high, " "forcing read/only mode\n"); sb->s_flags |= MS_RDONLY; } if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS)) printk ("EXT2-fs warning: mounting unchecked fs, " "running e2fsck is recommended\n"); else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS)) printk ("EXT2-fs warning: mounting fs with errors, " "running e2fsck is recommended\n"); else if (es->s_max_mnt_count >= 0 && es->s_mnt_count >= (unsigned short) es->s_max_mnt_count) printk ("EXT2-fs warning: maximal mount count reached, " "running e2fsck is recommended\n"); else if (es->s_checkinterval && (es->s_lastcheck + es->s_checkinterval <= CURRENT_TIME)) printk ("EXT2-fs warning: checktime reached, " "running e2fsck is recommended\n"); es->s_state &= ~EXT2_VALID_FS; if (!es->s_max_mnt_count) es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT; #ifndef OS2 es->s_mnt_count++; #else // // This is to force Linux to autocheck the ext2fs partition "touched" by OS/2 // this autocheck is enabled unless -no_auto_fsck is specified on the IFS cmd // line // if (auto_fsck) { kernel_printf("e2fsck will be forced next time Linux will mount this partition"); es->s_mnt_count = EXT2_DFL_MAX_MNT_COUNT; } else { es->s_mnt_count++; } #endif es->s_mtime = CURRENT_TIME; mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); sb->s_dirt = 1; #ifndef OS2 // For the moment ..... if (test_opt (sb, DEBUG)) #endif printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, sb->u.ext2_sb.s_frag_size, sb->u.ext2_sb.s_groups_count, EXT2_BLOCKS_PER_GROUP(sb), EXT2_INODES_PER_GROUP(sb), sb->u.ext2_sb.s_mount_opt); #ifndef OS2 // For the moment ..... if (test_opt (sb, CHECK)) { #endif ext2_check_blocks_bitmap (sb); ext2_check_inodes_bitmap (sb); #ifndef OS2 // For the moment ..... } #endif } }
/* * struct fs32_opencreate_parms { * PTR16 pfgenflag; * PTR16 pEABuf; * unsigned short attr; * PTR16 pAction; * unsigned short openflag; * unsigned long openmode; * PTR16 psffsd; * PTR16 psffsi; * unsigned short iCurDirEnd; * PTR16 pName; * PTR16 pcdfsd; * PTR16 pcdfsi; * }; */ int FS32ENTRY fs32_opencreate(struct fs32_opencreate_parms *parms) { char *pName; struct cdfsi32 *pcdfsi; union cdfsd32 *pcdfsd; struct sffsi32 *psffsi; union sffsd32 *psffsd; unsigned short *pAction; int rc; struct super_block *sb; struct file *p_file, *dir; UINT32 openmode, DOSmode; UINT32 accessmode; UINT16 newflag, existflag; char component[CCHMAXPATH]; char parent[CCHMAXPATH]; struct inode *inode; struct inode *inode_parent; struct inode *base; char *tmp; ino_t ino_no; psffsi = VDHQueryLin(parms->psffsi); psffsd = VDHQueryLin(parms->psffsd); if (parms->pcdfsi.seg) pcdfsi = VDHQueryLin(parms->pcdfsi); else pcdfsi = 0; if (parms->pcdfsd.seg) pcdfsd = VDHQueryLin(parms->pcdfsd); else pcdfsd = 0; pName = VDHQueryLin(parms->pName); pAction = VDHQueryLin(parms->pAction); if (trace_FS_OPENCREATE) { kernel_printf("FS_OPENCREATE(%s)", pName); } #ifdef FS_TRACE if (parms->ulOpenMode & OPEN_FLAGS_DASD) { fs_log("OPEN_FLAGS_DASD"); } if (parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH) { fs_log("OPEN_FLAGS_WRITE_THROUGH"); } if (parms->ulOpenMode & OPEN_FLAGS_FAIL_ON_ERROR) { fs_log("OPEN_FLAGS_FAIL_ON_ERROR"); } if (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE) { fs_log("OPEN_FLAGS_NO_CACHE"); } if (parms->ulOpenMode & OPEN_FLAGS_NOINHERIT) { fs_log("OPEN_FLAGS_NO_INHERIT"); } #endif accessmode = parms->ulOpenMode & OPEN_ACCESS_MASK; if (accessmode == OPEN_ACCESS_READONLY) { #ifdef FS_TRACE fs_log("OPEN_ACCESS_READONLY"); #endif openmode = OPENMODE_READONLY; } if (accessmode == OPEN_ACCESS_WRITEONLY) { #ifdef FS_TRACE fs_log("OPEN_ACCESS_WRITEONLY"); #endif openmode = OPENMODE_WRITEONLY; } if (accessmode == OPEN_ACCESS_READWRITE) { #ifdef FS_TRACE fs_log("OPEN_ACCESS_READWRITE"); #endif openmode = OPENMODE_READWRITE; } #ifdef FS_TRACE if (accessmode == OPEN_ACCESS_EXECUTE) { fs_log("OPEN_ACCESS_EXECUTE"); } #endif newflag = parms->openflag & OPEN_ACTION_NEW_MASK; #ifdef FS_TRACE if (newflag == OPEN_ACTION_FAIL_IF_NEW) { fs_log("OPEN_ACTION_FAIL_IF_NEW"); } if (newflag == OPEN_ACTION_CREATE_IF_NEW) { fs_log("OPEN_ACTION_CREATE_IF_NEW"); } #endif existflag = parms->openflag & OPEN_ACTION_EXIST_MASK; #ifdef FS_TRACE if (existflag == OPEN_ACTION_OPEN_IF_EXISTS) { fs_log("OPEN_ACTION_OPEN_IF_EXISTS"); } if (existflag == OPEN_ACTION_FAIL_IF_EXISTS) { fs_log("OPEN_ACTION_FAIL_IF_EXISTS"); } if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS) { fs_log("OPEN_ACTION_REPLACE_IF_EXISTS"); } #endif if ((!Read_Write) && ((accessmode == OPEN_ACCESS_READWRITE) || (accessmode == OPEN_ACCESS_WRITEONLY))) { fs_log("FS_OPENCREATE() - Write access not enabled"); return ERROR_WRITE_PROTECT; } // // Direct access open of the whole device // if (parms->ulOpenMode & OPEN_FLAGS_DASD) { sb = getvolume(psffsi->sfi_hVPB); kernel_printf("OPEN_FLAGS_DASD"); if ((p_file = _open_by_inode(sb, INODE_DASD, openmode)) == 0) { kernel_printf("FS_OPENCREATE() - couldn't DASD open %s", pName); return ERROR_OPEN_FAILED; } psffsd->f = p_file; psffsi->sfi_tstamp = ST_SCREAT | ST_PCREAT; psffsi->sfi_size = p_file->f_inode->i_size; psffsi->sfi_position = p_file->f_pos; date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate)); date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate)); date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate)); return NO_ERROR; } // // Now that we treated the OPEN_FLAGS_DASD special case, lets treat the general case : // Try to open the file readonly // Success : the file exists // if !S_ISDIR && !S_ISREG => error // if OPEN_ACTION_FAIL_IF_EXISTS set => error // if OPEN_ACTION_OPEN_IF_EXISTS set // <test file attrs> // change the open mode and return OK // if OPEN_ACTION_REPLACE_IF_EXISTS set // OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error // OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set // truncate // change openmode and return // Failure : the file does not exist // OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error // OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set // if OPEN_ACTION_CREATE_IF_NEW set // try to create the file // open the file and return // if OPEN_ACTION_FAIL_IF_NEW set => error rc = ERROR_INVALID_PARAMETER; if (parms->iCurDirEnd != CURDIREND_INVALID) { tmp = pName + parms->iCurDirEnd; if ((pcdfsd->u.p_file) && (pcdfsd->u.p_file->f_magic == FILE_MAGIC)) { base = pcdfsd->u.p_file->f_inode; if (base) { sb = base->i_sb; rc = NO_ERROR; } } } else { sb = getvolume(psffsi->sfi_hVPB); if ((sb) && (sb->s_magic_internal == SUPER_MAGIC)) { tmp = skip_drive(pName); base = sb->s_mounted; if (base) { rc = NO_ERROR; } } } if (rc != NO_ERROR) { return rc; } p_file = open_by_name(base, tmp, openmode); if (p_file) { // The file exists // // If it's not a regular file or a directory we cannot open // if (!S_ISREG(p_file->f_inode->i_mode)) { // kernel_printf("Can't FS_OPENCREATE - %s is not a regular file", pName); if ((rc = vfs_close(p_file)) != NO_ERROR) { fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__); return rc; } return ERROR_ACCESS_DENIED; } // // if OPEN_ACTION_FAIL_IF_EXISTS set => error // if (existflag == OPEN_ACTION_FAIL_IF_EXISTS) { #ifdef FS_TRACE fs_log("Can't FS_OPENCREATE() - File exists & OPEN_ACTION_FAIL_IF_EXISTS"); #endif if ((rc = vfs_close(p_file)) != NO_ERROR) { fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__); return rc; } return ERROR_FILE_EXISTS; } // // if OPEN_ACTION_OPEN_IF_EXISTS : OK // if (existflag == OPEN_ACTION_OPEN_IF_EXISTS) { *pAction = FILE_EXISTED; } // // if OPEN_ACTION_REPLACE_IF_EXISTS : truncate // if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS) { p_file->f_inode->i_size = psffsi->sfi_size; p_file->f_inode->i_op->truncate(p_file->f_inode); p_file->f_inode->i_dirt = 1; p_file->f_flags = O_TRUNC; *pAction = FILE_TRUNCATED; #if 0 psffsi->sfi_tstamp = ST_PWRITE | ST_SWRITE; #else /* * Time stamping is done by inode routines - Only propagate value. */ psffsi->sfi_tstamp = ST_PWRITE; #endif } } else { // The file doesn't exist ExtractPath(pName, __StackToFlat(parent)); ExtractName(pName, __StackToFlat(component)); // // We try to open the parent dir // if ((dir = open_by_name(sb->s_mounted, Skip_drive(__StackToFlat(parent)), OPENMODE_READONLY)) == 0) { // kernel_printf("FS_OPENCREATE() - The parent directory %s doesn't seem to exist", parent); return ERROR_PATH_NOT_FOUND; } // // The parent dir exists // // // If the file is open for execution : error (it doesn't even exist) // if (accessmode == OPEN_ACCESS_EXECUTE) { #ifdef FS_TRACE fs_log("Can't FS_OPENCREATE() - File doesn't exist & OPEN_ACCESS_EXECUTE"); #endif if ((rc = vfs_close(dir)) != NO_ERROR) { fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__); return rc; } return ERROR_FILE_NOT_FOUND; } // // If the file is open for writing or readwrite ... // if ((accessmode == OPEN_ACCESS_READONLY) || (accessmode == OPEN_ACCESS_READWRITE) || (accessmode == OPEN_ACCESS_WRITEONLY)) { if (newflag == OPEN_ACTION_FAIL_IF_NEW) { #ifdef FS_TRACE fs_log("Can't FS_OPENCREATE() - File doesn't exist & OPEN_ACTION_FAIL_IF_NEW"); #endif if ((rc = vfs_close(dir)) != NO_ERROR) { fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__); return rc; } return ERROR_OPEN_FAILED; } if (newflag == OPEN_ACTION_CREATE_IF_NEW) { // ino_no = dir->f_inode->i_ino; inode_parent = dir->f_inode; inode_parent->i_count++; if ((rc = vfs_close(dir)) != NO_ERROR) { fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, THISFILE, __LINE__); return rc; } // inode_parent = iget(sb, ino_no); inode_parent->i_count++; down(&inode_parent->i_sem); rc = inode_parent->i_op->create(inode_parent, __StackToFlat(component), strlen(component), S_IRWXU | S_IFREG, __StackToFlat(&inode)); up(&inode_parent->i_sem); if (rc) { kernel_printf("Couldn't create %s", pName); iput(inode_parent); return rc; } ino_no = inode->i_ino; iput(inode_parent); iput(inode); if ((p_file = _open_by_inode(sb, ino_no, openmode)) == 0) { kernel_printf("open_by_inode(%lu) failed in FS_OPENCREATE", ino_no); return ERROR_OPEN_FAILED; } p_file->f_inode->i_size = psffsi->sfi_size; p_file->f_inode->i_dirt = 1; p_file->f_flags = O_CREAT; *pAction = FILE_CREATED; #if 0 psffsi->sfi_tstamp = ST_SCREAT | ST_PCREAT | ST_PWRITE | ST_SWRITE; #else /* * Time stamping is done by inode routines - Only propagate value. */ psffsi->sfi_tstamp = ST_PCREAT | ST_PWRITE; #endif } } } psffsd->f = p_file; /* * Time stamping is done by inode routines - Only propagate value. */ #if 0 psffsi->sfi_tstamp |= ST_PREAD | ST_SREAD; #else /* * Time stamping is done by inode routines - Only propagate value. */ psffsi->sfi_tstamp |= ST_PREAD; #endif psffsi->sfi_size = p_file->f_inode->i_size; psffsi->sfi_position = p_file->f_pos; // kernel_printf("date = %u/%u/%u", (pCommon->dateCreate) & 31, (pCommon->dateCreate >> 5) & 15 , (pCommon->dateCreate) >> 9); date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate)); date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate)); date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate)); psffsi->sfi_DOSattr = (unsigned char)Linux_To_DOS_Attrs(p_file->f_inode, __StackToFlat(component)); if (write_through_support) { if ((parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH) || (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE)) { p_file->f_flags |= O_SYNC; p_file->f_inode->i_flags |= MS_SYNCHRONOUS; } } return NO_ERROR; }
/* * Simple firmware loading over microconnect. * * This is not safe from interrupt context, but that is OK because changes to * AWG done in UpdateHW processing is actually in task context in OS21, not * interrupt context (unlike Linux). */ static int RequestFirmware(const STMFirmware **firmware_p, const char *const name) { STMFirmware *fw = NULL; int fd,ret; struct stat buf; if (!firmware_p || *firmware_p || !name || !*name) { kernel_printf("BUG: RequestFirmware invalid arguments\n"); return -1; } if(task_context(NULL,NULL) == task_context_system) { kernel_printf("BUG: RequestFirmware called from interrupt context\n"); system_stop(); } fw = malloc(sizeof(STMFirmware)); if(!fw) return -1; memset(fw,0,sizeof(STMFirmware)); fd = open(name,O_RDONLY | O_BINARY); if(fd<0) { kernel_printf("BUG: Cannot find AWG firmware file\n"); free(fw); return fd; } if(fstat(fd,&buf)<0) { kernel_printf("BUG: Cannot stat AWG firmware file\n"); free(fw); return -1; } fw->ulDataSize = buf.st_size; fw->pData = malloc(fw->ulDataSize); if(!fw->pData) { kernel_printf("BUG: Cannot allocate AWG firmware cache memory\n"); free(fw); close(fd); return -1; } memset(fw->pData,0,fw->ulDataSize); if((ret = read(fd,fw->pData,fw->ulDataSize))<0) { kernel_printf("BUG: Cannot read AWG firmware cache memory\n"); free(fw); close(fd); return -1; } if(ret != fw->ulDataSize) { printf("BUG: Read AWG firmware returned wrong number of bytes %d instead of %lu\n",ret,fw->ulDataSize); free(fw); close(fd); return -1; } *firmware_p = fw; close(fd); return 0; }
/* * struct fs32_chdir_parms { * unsigned short iCurDirEnd; * PTR16 pDir; * PTR16 pcdfsd; * PTR16 pcdfsi; * unsigned short flag; * }; */ int FS32ENTRY fs32_chdir(struct fs32_chdir_parms *parms) { char *pDir; struct cdfsi32 *pcdfsi; union cdfsd32 *pcdfsd; int rc; struct file *p_file; struct super_block *sb; int valid; char *tmp; struct inode *base; switch (parms->flag) { case CD_EXPLICIT: pcdfsi = VDHQueryLin(parms->pcdfsi); pcdfsd = VDHQueryLin(parms->pcdfsd); pDir = VDHQueryLin(parms->pDir); if (trace_FS_CHDIR) { kernel_printf("FS_CHDIR( CD_EXPLICIT, %s )", pDir); } rc = ERROR_INVALID_PARAMETER; if (parms->iCurDirEnd != CURDIREND_INVALID) { tmp = pDir + parms->iCurDirEnd; if ((pcdfsd->u.p_file) && (pcdfsd->u.p_file->f_magic == FILE_MAGIC)) { base = pcdfsd->u.p_file->f_inode; if (base) { rc = NO_ERROR; } } } else { sb = getvolume(pcdfsi->cdi_hVPB); if ((sb) && (sb->s_magic_internal == SUPER_MAGIC)) { tmp = skip_drive(pDir); base = sb->s_mounted; if (base) { rc = NO_ERROR; } } } if (rc == NO_ERROR) { if ((p_file = open_by_name(base, tmp, OPENMODE_READONLY)) == 0) { rc = ERROR_PATH_NOT_FOUND; } else { if (!S_ISDIR(p_file->f_inode->i_mode)) { kernel_printf("FS_CHDIR( %s ) Not a directory", pDir); vfs_close(p_file); rc = ERROR_ACCESS_DENIED; } else { pcdfsd->u.is_valid = 1; pcdfsd->u.p_file = p_file; rc = NO_ERROR; } } } break; case CD_VERIFY: pcdfsi = VDHQueryLin(parms->pcdfsi); pcdfsd = VDHQueryLin(parms->pcdfsd); if (trace_FS_CHDIR) { kernel_printf("FS_CHDIR : flag = CD_VERIFY hVPB=0x%04X", pcdfsi->cdi_hVPB); } // // Gets the superblock from pcdfsi // sb = getvolume(pcdfsi->cdi_hVPB); valid = 1; if ((p_file = open_by_name(sb->s_mounted, skip_drive(pcdfsi->cdi_curdir), OPENMODE_READONLY)) == 0) { valid = 0; } else { if (!S_ISDIR(p_file->f_inode->i_mode)) { vfs_close(p_file); valid = 0; } if (pcdfsi->cdi_flags & CDI_ISVALID) { vfs_close(pcdfsd->u.p_file); } if (valid) { pcdfsd->u.is_valid = 1; pcdfsd->u.p_file = p_file; return NO_ERROR; } else { vfs_close(p_file); return ERROR_PATH_NOT_FOUND; } } break; case CD_FREE: pcdfsd = VDHQueryLin(parms->pcdfsd); if (trace_FS_CHDIR) { kernel_printf("FS_CHDIR( CD_FREE )"); } if (pcdfsd->u.is_valid == 1) { pcdfsd->u.is_valid = 0; if ((rc = vfs_close(pcdfsd->u.p_file)) != NO_ERROR) { fs_err(FUNC_FS_CHDIR, FUNC_CLOSE, rc, THISFILE, __LINE__); } // return rc; } else { rc = NO_ERROR; } break; default: fs_log("FS_CHDIR : invalid flag"); rc = ERROR_INVALID_PARAMETER; } return rc; }